中国水系Android第一个版本

写这个例子的目的是供同事和开发Android的朋友学习借鉴。

这个版本不是凭空冒出来的,就像爱因斯坦做手工的故事(不知道的见这里)一样,还有更丑的“小凳子”,它们是:

参考它们可以了解版本的演进过程。可能降低学习曲线。

这个版本的首页:

imageimage

点击条目,会弹出带图片的详细信息界面:

imageimage

这里的图片是从维基百科直接下载的,并会缓存在本地。

另外,就是对横竖屏使用了不同的布局:

imageimage

下面介绍一下实现的要点。

异步延时加载的处理

以前我都是自己写异步加载,比如用Java concurrent编写异步加载图片功能android异步加载ListView中的图片。其实android自己有个AsyncTask,可以方便的做这个事情。这次尝试使用了一下。

我目前的基本理解是AsyncTask简化了异步开发。

因为如果自己写,需要创建线程执行后台操作,比如下载图片文件,然后还是要通过handler通知ui线程将图片文件显示到界面上。

AsyncTask提供了需要实现的方法,一些方法AsyncTask会创建线程执行,比如doInBackground,而onPostExecute方法,AsyncTask会自行调用handler通知ui线程执行。

这部分代码见DetailViewActivity的内部类:

private class ShowImageTask extends AsyncTask<String, Void, Void> {

    private String fileName;

    @Override
    protected Void doInBackground(String… params) {
        fileName = params[1] + ".jpg";

        File cacheFile = new File(getCacheDir(), fileName);
        if (!cacheFile.exists()) {
            //创建临时文件,用于下载图片使用
            File tempFile = new File(getCacheDir(), "tmp");
            HttpClient client = new DefaultHttpClient();
            HttpGet get = new HttpGet(params[0]);
            try {
                HttpResponse response = client.execute(get);
                FileOutputStream outputStream = new FileOutputStream(
                        tempFile);
                InputStream inputStream = response.getEntity().getContent();
                for (int i = inputStream.read(); i != -1; i = inputStream
                        .read()) {
                    outputStream.write(i);
                }
                inputStream.close();
                outputStream.close();
               
                /**
                 * 改名临时文件,改为对应河流id的jpg文件
                 * 这样做是为了防止图片下载不全的问题
                 */
                tempFile.renameTo(cacheFile);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        try {
            imageView.setImageDrawable(Drawable.createFromStream(
                    new FileInputStream(new File(getCacheDir(), fileName)),
                    "river.jpg"));
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        imageLoadProgressBar.setVisibility(View.GONE);
    }

 

这里还需要注意的是,使用了httpclient api来下载图片,这部分如果不明白,可参见更简单的示例android编写访问http的代码。只不过这里是使字节流。

下载的图片放在哪里?这里没有选择放在sd卡这样的外存中,而是放在内存里。内存可存储在两个位置:

  • 存放在应用的files目录下,不过不能直接操作目录,只能通过openFileOutput()操作文件流,当不存在的时候自动创建
  • 存放在应用的cache目录下,可操作文件目录,通过getCacheDir()方法可获取目录File对象

在这里使用cache目录的方式,因为要操作文件并且涉及到文件改名等。

有关Content Provider和数据库

示例使用了Content Provider,而且是:

sqlite+Content Provider+CursorAdapter+Loader+ListView

示例中详细界面是Activity,设置了dialog的theme,看上去像对话框。这样做的考虑是结构简单,两个Activity是通过intent来松散耦合的。在intent中传递的是river的id。

这样,content provider需要能处理对集合的查询和对指定id的查询:

switch (uriMatcher.match(uri)) {//判断是访问river集合还是指定id访问单条记录
case ITEMS:
    cursor = database.query("rivers", projection, selection,
            selectionArgs, null, null, sortOrder);
    cursor.setNotificationUri(getContext().getContentResolver(), uri);
    return cursor;
case ITEM:
    cursor = database.query("rivers", projection, _ID + "="
            + uri.getPathSegments().get(1), selectionArgs, null, null,
            sortOrder);
    cursor.setNotificationUri(getContext().getContentResolver(), uri);
    return cursor;
default:
    throw new IllegalArgumentException("unknown uri: " + uri);
}

横竖屏的处理

这个处理其实很简单。基本思路是针对横竖屏有不同的布局文件,android会在配置变化自动识别并加载对应文件。

image

如图所示,可知目录的命名方法。

源代码见:

http://easymorse.googlecode.com/svn/tags/CustomListViewDemo-0.5.1/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值