ListView高效刷新——刷新单条数据

在使用ListView时,需要刷新数据的时候,我们通常的做法是调用mAdapter.notifyDataSetChanged()刷新界面,毫无疑问这很简单,现在咱们测试一下其效率,并对其进行优化。

1.罗列代码:

MainActivity 的内容:

package com.example.androidtest;

import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {
    ListView mListView;
    TextViewAdapter mAdapter;
    TextView notifyView;
    TextView refreshItemView;

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case 0x11: {
        //使用一般方法刷新UI
            String targetString = "2";
            int targetIndex = -1;
            // 1.查找text内容为"2"的下标;
            for (int j = 0; j < mListView.getCount(); j++) {
                String itemString = (String) mListView.getItemAtPosition(j);
                if (targetString.equals(itemString)) {
                    targetIndex = j;
                    break;
                }

            }
            if (targetIndex >= 0) {
                mAdapter.setGreenItem(targetIndex);
                ***mAdapter.notifyDataSetChanged();***
            }
        }
            break;

        case 0x22: {
        //使用高效的方法刷新UI(当然如果postion不在页面上,不需要刷新)
            // 1.我们想要修改text内容为"2"的Item的位置
            String targetString = "2";
            int targetIndex = -1;
            for (int j = 0; j < mListView.getCount(); j++) {
                String itemString = (String) mListView.getItemAtPosition(j);
                if (targetString.equals(itemString)) {
                    targetIndex = j;
                    break;
                }

            }
            if (targetIndex >= 0) {
                mAdapter.setGreenItem(targetIndex);
                int startShownIndex = mListView.getFirstVisiblePosition();
                int endShownIndex = mListView.getLastVisiblePosition();
                ***if (targetIndex >= startShownIndex
                        && targetIndex <= endShownIndex) {
                    View view = mListView.getChildAt(targetIndex
                            - startShownIndex);
                    mListView.getAdapter()
                            .getView(targetIndex, view, mListView);
                }***

            }

        }

            break;
        default:
            break;
        }

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout outLayout = new LinearLayout(this);
        outLayout.setOrientation(LinearLayout.VERTICAL);

        notifyView = new TextView(this);
        notifyView.setId(0x11);
        notifyView.setLayoutParams(new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, 100));
        notifyView.setText("调用notifyDataSetChange刷新数据");
        notifyView.setGravity(Gravity.CENTER);

        refreshItemView = new TextView(this);
        refreshItemView.setId(0x22);
        refreshItemView.setLayoutParams(new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, 100));
        refreshItemView.setText("调用refresh Item刷新数据");
        refreshItemView.setGravity(Gravity.CENTER);

        mListView = new ListView(this);

        outLayout.addView(notifyView);
        outLayout.addView(refreshItemView);
        outLayout.addView(mListView);
        setContentView(outLayout);
        mAdapter = new TextViewAdapter(this);
        mListView.setAdapter(mAdapter);
        notifyView.setOnClickListener(this);
        refreshItemView.setOnClickListener(this);

    }

}

2.TextViewAdapter 的内容:

package com.example.androidtest;

import android.content.Context;
import android.graphics.Color;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class TextViewAdapter extends BaseAdapter {
    Context mContext;
    int mGreenPostion = -1;

    public TextViewAdapter(Context context) {
        mContext = context;
    }

    /** * 为了简单起见,这里仅仅允许设置一个Item的背景色为绿色 * * @param position */
    public void setGreenItem(int position) {
        mGreenPostion = position;
        // 注意为了提高UI效率这个直接调用notifyDataSetChange();
    }

    @Override
    public int getCount() {
        return 10;
    }

    @Override
    public String getItem(int position) {
        return position + "";
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if (convertView == null) {
            viewHolder = new ViewHolder();
            TextView outerLayout = new TextView(mContext);
            outerLayout.setGravity(Gravity.CENTER);
            outerLayout.setTextSize(50);
            outerLayout.setTextColor(Color.BLUE);
            AbsListView.LayoutParams outerParams = new AbsListView.LayoutParams(
                    new LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, 300));
            outerLayout.setLayoutParams(outerParams);
            viewHolder.itemLayout = outerLayout;
            convertView = outerLayout;
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.itemLayout.setText(getItem(position));
        if (position == mGreenPostion) {
            viewHolder.itemLayout.setBackgroundColor(Color.GREEN);
        } else {
            viewHolder.itemLayout.setBackgroundColor(Color.WHITE);
        }
        System.err.println("-------position--" + position);
        return convertView;
    }

    class ViewHolder {
        TextView itemLayout;

    }

}

结果比较:

1.调用常规的notifyDataSetChange的时候,getView的调用情况如下:
ListView高效刷新——刷新单条数据_第1张图片
2.调用精致的refreshItem(自鸣得意的一个名字),结果如下:

仅仅调用了一次,amazing!!!

结论:

使用adapter.notifyDataSetChange方法简单,但效果不佳;使用精致的方法:

if (targetIndex >= startShownIndex
                        && targetIndex <= endShownIndex) {
                    View view = mListView.getChildAt(targetIndex
                            - startShownIndex);
                    mListView.getAdapter()
                            .getView(targetIndex, view, mListView);
                }

刷新UI会大大提高。
参考地址:http://stackoverflow.com/questions/2123083/android-listview-refresh-single-row

你可能感兴趣的:(优化,ListView)