通用ListViewAdapter_ViewHolder

一方面,为了优化ListView显示,另一方面也是为了能够提高开发效率,不得不说。弄一个通用的ListViewAdapter是非常之必须的。因此,我们需要解决的问题有Item布局的获取,以及getView()方法中Item内容的获取更新。其他不说,先直接贴出Adapter与ViewHolder(据说提升至少50%以上的效率噢)的代码先。

1.通用ListAdapter

public abstract class ADBaseAdapter<T> extends BaseAdapter {

    private Context mContext;
    private List<T> mInfos = new ArrayList<>();

    public ADBaseAdapter(Context context, List<T> infos) {
        this.mContext = context;
        this.mInfos = infos;
    }

    // 根据Data内容更新
    protected void updataAdapter(List<T> infos) {
        this.mInfos = infos;
        this.notifyDataSetChanged();
    }

    // 针对TextView的文本设置
    protected void setValue(int textViewId, String str, ADViewHolder holder) {
        holder.setText(textViewId, str);
    }

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

    @Override
    public Object getItem(int position) {
        if (mInfos.size() > position)
            return mInfos.get(position);
        return null;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ADViewHolder holder = ADViewHolder.get(mContext, getLayoutId(), parent, convertView);
        renderData(holder, (T) getItem(position));
        return holder.getConvertView();
    }

    // 获取Item的布局
    protected abstract int getLayoutId();

    // 相当于getView()方法
    protected abstract void renderData(ADViewHolder holder, T item);
}

以上小编还而外定义了一个updataAdapter();的方法,估计这里大家会有疑问,为什么不直接在映射的列表数据改变的时候直接调用adapter.notifyDataSetChanged();就行了呢。当然是可以的,但是相信有经验的亲们很多时候都会遇到调用该方法仍无法更新的情况,这是因为notifyDataSetChanged();要求adapter指向的数据必须地址一致才行。小编遇到过一钟情况是这样的,Fragment的嵌套,由于生命周期的问题导致原adapter的数据对象地址发生改变,以至于notifyDataSetChanged();无法更新列表数据,所以强烈建议直接更新adapter当中的data内容再执行notifyDataSetChanged();操作。当然,大家也可以根据自己的需求仅实现插入,删除等,不一定要重新为adapter当中的data赋值。

2.通用ViewHolder

public class ADViewHolder {

    // http://blog.csdn.net/xyz_fly/article/details/7931943 二分法存储,按照键值从小到大排序
    private final SparseArray<View> mViews = new SparseArray<>();
    private View mConvertView;

    public ADViewHolder(Context context, int LayoutID, ViewGroup parent) {

        mConvertView = LayoutInflater.from(context).inflate(LayoutID, parent, false);
        mConvertView.setTag(this);
    }

    public static ADViewHolder get(Context context, int LayoutID, ViewGroup parent, View convertView) {
        if (convertView == null)
            return new ADViewHolder(context, LayoutID, parent);
        return (ADViewHolder) convertView.getTag();
    }

    public View getConvertView() {
        return mConvertView;
    }

    /** * @param viewId 控件ID * @param <T> 对象类型 * @return 根据ID获取到的控件 */
    public <T extends View> T getView(int viewId) {
        View view = mViews.get(viewId);
        if (view == null) {
            view = mConvertView.findViewById(viewId);
            mViews.put(viewId, view);
        }
        return (T) view;
    }

    /** * 这里仅以TextView为例,其他的可以更具需求再做衍生 * * @param viewId 控件ID * @param str 设置文本内容 */
    public void setText(int viewId, String str) {
        ((TextView) getView(viewId)).setText(str);
    }
}

3.继承实例

public class MyViewListAdapter extends ADBaseAdapter {

    public MyViewListAdapter(Context context, List infos) {
        super(context, infos);
    }

    @Override
    protected int getLayoutId() {
        return R.layout.item_list_myview;
    }

    @Override
    protected void renderData(ADViewHolder holder, Object item) {

        String contentStr = (String) item;
        /* * 这里仅以某个TextView的id为例设置其文本内容 */
        setValue(R.id.item_tv_myview, contentStr, holder);
    }
}

以上为此章所要呈现的主要内容,是小编从以往开发项目简练出来再叙述的,希望能够帮上大家的忙。最后面小编再给大家来点小菜滋润下。

  1. ListView部分属性设置(涉及嵌套的时候偶尔出现属性设置无效果产生的时候请在代码中动态设置
    • android:divider=”@color/”; // 分割线颜色
    • android:divider=”@null”; // 不显示分割线
    • android:dividerHeight=”2dp”; // 分割线大小
    • android:scrollbars=”none”; // 隐藏右侧滚动条
    • android:listSelector=”@color/”; // Item点击背景颜色
  2. ListView常用方法
    • listView.getFirstVisiblePosition();// 获取可视区域内第一条Item
    • listView.getLastVisiblePosition();// 获取可视区域内最后一条Item

你可能感兴趣的:(ListView,Adapter,notify,viewholder)