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

Posted 山城码农

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 分享一个处理BaseAdapter,getView()多次加载的方法相关的知识,希望对你有一定的参考价值。

一: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{
                    //不是第一次加载,不处理任何事
                }     
}       

 

 

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

以上是关于android 分享一个处理BaseAdapter,getView()多次加载的方法的主要内容,如果未能解决你的问题,请参考以下文章

Android:BaseAdapter 怎么用?

Android BaseAdapter用法

13.Android-ListView使用BaseAdapter/ArrayAdapter/SimpleAdapter适配器使用

带有 BaseAdapter 的 Android ListView 内的 ImageButton

如何将数据添加到 listView 的自定义 BaseAdapter - Android

Android 的 BaseAdapter 是适配器模式的一个例子吗?