安卓开发,listView相关(五),数据更新,适配器刷新(全部刷新和局部刷新)

1.数据更新

前面介绍了listView的数据绑定,在getView()方法中对组件设置值的时候,无论有无数据都需要对其赋值,有则赋值为数据内容,否则手动恢复默认状态,防止重用而导致显示错乱。
那么,数据更新也是常用的,例如,点击按钮改变文字内容,或者点击某一行进入另外一个页面,亦或者长按之后弹出一个选项框,等等。

2.适配器刷新

适配器的加载决定lsitView最终显示的内容。

2.1全部刷新

调用adapter的 notifyDataSetChanged();可以让adapter重新加载当前显示的行的数据。例如屏幕上仅显示了4567项,则仅加载4567的数据( 就算只显示了一条边也算显示项),重新加载就会使adapter调用getView()方法。

示例如下:
mainActivity中写上listView的行点击事件
//行点击事件
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
	list.set(position,"行修改");
	adapter.notifyDataSetChanged();
}}) ;

在adapter中为按钮设置点击事件,代码如下:

holder.bt.setOnClickListener(new MyClick(position));

其中click事件写成了类,这样写的好处是可以传递参数并分离getView的代码,让getView的代码变得小一些。
你可以把类独立写成一个java文件,也可以写在adapter文件里面编程adapter的内部类
其他一些例如一些大面积设置的代码也可以写成方法并传递position和viewholder,在方法中进行处理。
一些动态适配的代码若每一行都是一样的则可以放在最开始声明View的if块里(当然,写成一个方法然后调用)。
这样后期维护的时候,代码就比较好改了,否则一旦getView代码几百上前行,鼠标的滑轮会哭的。

class MyClick implements View.OnClickListener {

    private int click_position;

    public MyClick(int click_position) {
        this.click_position = click_position;
    }

    @Override
    public void onClick(View view) {

        list.set(click_position,"修改");
        notifyDataSetChanged();
    }
}


若你需要同时设置listView的行点击事件和每一行按钮的点击事件,那么在list_item.xml的根布局下加上一条属性即可
android:descendantFocusability="blocksDescendants"

按钮会抢占,listView的焦点使得listView无法响应行点击事件或长按事件等等。一个一个的将item的按钮的焦点设为false太麻烦,

2.2,局部刷新

全部刷新会导致一些没必要刷新的内容被刷新,当数据量比较小或者每行的内容比较少的时候,使用全部刷新是没有问题的。但数据量多了或是每行的内容较多的时候,再全部刷新则会导致listView卡顿
使用view或者viewHolder进行刷新将不会让适配器全部刷新。
获取view和viewHolder的方式:
/**
     * 单独更新组件
     * @param position
     *      更新组件的下标
     */
    public void updateData(int position){
        //获取当前显示项的第一行和最后一行
        int firstVisible = lv.getFirstVisiblePosition();
        int lastVisible = lv.getLastVisiblePosition();
        //获取该行的view(因为listView仅会维护当前的显示项,所以根据下标获取时,0为当前显示行
        // 的第一行即firstVisible,所以获取当前行应该用当前行减去firstVisible)
        View view = lv.getChildAt(position - firstVisible);
        if(view != null){   //若获取的时候该行被滑出屏幕则会返回空
            //获取viewHolder
//            ViewHolder holder = (ViewHolder) view.getTag();
//            holder.tv.setText("change");
            //若不使用ViewHolder,也可以直接使用view
            TextView tv = (TextView) view.findViewById(R.id.item_textView);
            tv.setText("change");
        }


备注:1.测试:通过在getView的第一行写输出语句输出position即可观察修改时getView的调用情况
   2单独刷新:单独刷新的时候,注意不要让xml文件中的listView的宽高为wrap_content,因为wrap_content会在开始的时候绘制一次,显示之前根据子组件再绘制一次(即使没有什么改变),这时的绘制将使adapter调用notify使局部更新看上去失效了。


猜你喜欢

转载自blog.csdn.net/qq_26559913/article/details/53817263
今日推荐