起因

最近在看一些开源项目时,经常看到了RecyclerView,这是安卓5.0推出的一个新的控件,可以代替传统的ListView,已经这么久了还没有用过,所以决定试一试。另外在做这个的工程中看到了另外一个九宫格的图片加载库,也顺便试用了一下。

ListView 使用

首先,说一下ListView,这个是最常用的控件之一,大家都比较熟。这里自己简单记录一下。

这是目标结果,获取Gank.io上的妹子的图片地址并且进行获取展示。

Android 控件使用教程(一)—— ListView 展示图片_经验

首先,在xml配置文件中添加ListView的代码声明。

<ListView
    android:id="@+id/lv_listview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:padding="2dp"
    android:scrollbarStyle="outsideOverlay"
    android:scrollbars="vertical"/>

然后在ListViewActivity.java中使用ButterKnife进行控件绑定。

@Bind(R.id.lv_listview)
ListView listview;

记得代码中添加这句:

ButterKnife.bind(this);

下面进行数据获取并且放到一个ArrayList中,我这里只存放了图片的地址,其实可以定义图片更多属性,进行存放。数据获取选用了张洪洋的Okhttp-utils,非常方便,可以学习。数据源是大名鼎鼎的gank.io中的妹纸们。接口免费调用,同学们还是节省点用。

private String url = "http://gank.io/api/random/data/福利/20";

OkHttpUtils
        .get()
        .url(url)
        .build()
        .execute(new StringCallback() {
            @Override
            public void onError(Call call, Exception e) {
                Toast.makeText(ListViewActivity.this, "网络异常,请稍后重试", Toast.LENGTH_LONG).show();
            }

            @Override
            public void onResponse(String response) {
                if (response == null) {
                    Toast.makeText(ListViewActivity.this, "网络异常,请稍后重试", Toast.LENGTH_LONG).show();
                    return;
                }
                display(response);
            }
        });

返回数据格式如下:

{
    "error": false,
    "results": [
        {
            "_id": "56cc6d1c421aa95caa707523",
            "_ns": "ganhuo",
            "createdAt": "2015-11-04T10:33:50.564Z",
            "desc": "11.5",
            "publishedAt": "2015-11-05T04:02:52.968Z",
            "type": "福利",
            "url": "http://ww4.sinaimg.cn/large/7a8aed7bjw1exp4h479xfj20hs0qoq6t.jpg",
            "used": true,
            "who": "张涵宇"
        }
    ]
}

获得的数据需要放在ArrayList中:

private List<String> urls;
urls = new ArrayList<>();
JSONObject result = JSONObject.parseObject(response);
JSONArray jsonArray = result.getJSONArray("results");
for (int i = 0; i < jsonArray.size(); i++) {
    JSONObject temp = jsonArray.getJSONObject(i);
    urls.add(temp.getString("url"));
}

对于ArrayList中的图片的展示,必须使用Adapter.首先定义xml文件item_image.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_margin="2dp"
             android:foreground="?selectableItemBackground">

    <ImageView
        android:id="@+id/picture"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitCenter"
        tools:ignore="ContentDescription"
        tools:src="@color/primary_light"/>

</FrameLayout>

再在Adapter中进行代码解析,下面代码只是可用的水准,有改进空间。

public class ListViewAdapter extends BaseAdapter {

    private final Context context;
    private final LayoutInflater inflater;
    private List<String> urls;

    public ListViewAdapter(Context context, List<String> urls) {
        this.context = context;
        this.inflater = LayoutInflater.from(context);
        this.urls = urls;
    }

    @Override
    public int getCount() {
        return urls.size();
    }

    @Override
    public Object getItem(int i) {
        return urls.get(i);
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder viewHolder = null;
        view = inflater.inflate(
                R.layout.item_image, null);
        viewHolder = new ViewHolder();
        viewHolder.imageView = (ImageView) view.findViewById(R.id.picture);
        String url = urls.get(i);

        Log.i("url", url);

        Picasso.with(context)
                .load(url)
                .into(viewHolder.imageView);

        ViewCompat.setTransitionName(viewHolder.imageView, url);
        return view;
    }


    public class ViewHolder {
        public ImageView imageView;
    }

}

最后进行ArrayList中的数据和Adapter进行绑定,即可展示:

    adapter = new ListViewAdapter(ListViewActivity.this, urls);
    Log.i("urls", urls.toString());
    listview.setAdapter(adapter);

上述的数据获取和展示,我封装了一下为以下函数:

private void display(String response) {
    JSONObject result = JSONObject.parseObject(response);
    JSONArray jsonArray = result.getJSONArray("results");
    for (int i = 0; i < jsonArray.size(); i++) {
        JSONObject temp = jsonArray.getJSONObject(i);
        urls.add(temp.getString("url"));
    }
    adapter = new ListViewAdapter(ListViewActivity.this, urls);
    Log.i("urls", urls.toString());
    listview.setAdapter(adapter);
}

这个函数利用了fastjson解析数据,response中的数据无论多少个,都可以快速解析并展示。

至此,网络数据的获取和在ListView中的展示全部完成,不得不说非常简单方便。

结语

这是最常用的ListView的使用,并没有多少新意,项目已开源在:https://github.com/fuxuemingzhu/ViewAdapterTest,欢迎Star和交流学习。

下篇对RecyclerView进行测试使用。