android 分享一个处理BaseAdapter,getView()多次加载的方法_移动开发_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > 移动开发 > android 分享一个处理BaseAdapter,getView()多次加载的方法

android 分享一个处理BaseAdapter,getView()多次加载的方法

 2017/11/1 3:11:36  喝着啤酒敲代码  程序员俱乐部  我要评论(0)
  • 摘要:一:BaseAdapter介绍BaseAdapter是listview,gridview等列表,使用的数据适配器,它的主要用途是将一组数据传到ListView、Spinner、Gallery及GridView等UI显示组件,如果listView列表的数据项过多,如1000项,我们如果把这1000项全部放到界面中去,软件直接内存溢出了,BaseAdapter刚才可以帮我们解决这个问题,BaseAdapter工作原理图如下:从上图中看出,如果我们有1000个数据项,实际显示的只有7项
  • 标签:android 方法 view 一个 ASE 分享

一:BaseAdapter介绍

  BaseAdapter是listview,gridview等列表,使用的数据适配器,它的主要用途是将一组数据传到ListView、Spinner、Gallery及GridView等UI显示组件,如果listView列表的数据项过多,如1000项,我们如果把这1000项全部放到界面中去,软件直接内存溢出了,BaseAdapter刚才可以帮我们解决这个问题,BaseAdapter工作原理图如下:

       从上图中看出,如果我们有1000个数据项,实际显示的只有7项,其它的缓存在Recycler中,Recycler类似于消息对列,用来保存未显示在ui上的数据项,如果顶部(或底部)通过滚动,从listView界面中滑出,Recycler就将该数据项,添加到消息对列,如上图中,第一项已经从界面中滑出,当第一项重新滑进的时候,android会判断第一项是否加载过,如果有那么就重新设置第一项的数据源,然后显示。当第一次加载数据项,或者上滑,或者下滑显示数据项的时候,就会调用getView()方法,然而很多时候,getView()方法系统会调用多次,调用多次就会多次刷新界面,性能会降低,比如界面会卡顿等。

/**

@params position 需要显示的数据下标,从0开始
@params view      显示的视图
@ViewGroup         视图的组
*/
public View getView(int position, View view, ViewGroup viewGroup) 

二:解决办法

  1:网上常用的方法

<ListView
        android:id="@+id/lv_messages"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"  >
</ListView>

     网上说执行多次原因是因为每显示一个VIew,它都去测量view的高度,执行measure方法,导致getView执行多次,但该listView嵌套在ScrollView时,BaseAdapter的getView()方法一样会调用多次。

  2:重写ListView的onMeasure和onLayout方法。

  我重写ListView的onMeasure和onLayout方法,定义一个,是否第一加载的变量boolean isOnMeasure=false,然后在BastAdapter的getView方法,判断是否第一次加载界面,通过这个方法来处理这个问题.

  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        isOnMeasure = true;
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        isOnMeasure = false;
        super.onLayout(changed, l, t, r, b);
    }

三:完整代码

  1:重写listView

public class ScrollListView extends ListView {
    private boolean isOnMeasure;

    public boolean isMeasure() {
        return isOnMeasure;
    }

    public ScrollListView(Context context) {

        super(context);
    }

    public ScrollListView(Context context, AttributeSet attrs) {

        super(context, attrs);
    }

    public ScrollListView(Context context, AttributeSet attrs, int defStyle) {

        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        isOnMeasure = true;
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        isOnMeasure = false;
        super.onLayout(changed, l, t, r, b);
    }
}

  2:activity的xml 

 <view.ScrollListView
                android:id="@+id/orderGoodsList"
                style="@style/list_normal"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_below="@id/line3"
                android:background="@color/gray_f2"
                android:divider="@color/gray_f2"
                android:dividerHeight="1dip" >
</view.ScrollListView>

  3:适配器代码

protected ViewGroup viewGroup;
@Override
    public void initData(View view, Object viewHolder, int position) { 
        if (!((BaseGridView) viewGroup).isMeasure()) {
                     //第一次加载,处理界面ui
                }else{
                    //不是第一次加载,不处理任何事
                }     
}       

 

 

如果你有更好的方法,也请你留下分享一下你的方法,谢谢!

发表评论
用户名: 匿名