天天看點

快速建構不同UI樣式的清單擴充卡方法-AbsAdapter

由于公司的産品開發周期短,需求變化快,如果每次都要建立一個擴充卡類去實作不同的清單形式,難免會增加項目代碼備援和複雜性,多少也會影響開發速度。基于此,本人建構了一個能适應此種開發場景的“百變”擴充卡AbsAdapter:

import android.content.Context;
import android.database.DataSetObservable;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.support.annotation.Nullable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.SpinnerAdapter;
import android.widget.TextView;

import java.util.List;

import absadapter.com.R;

/**
 * Created by zhangming on 16/4/14. 
 */
public abstract class AbsBaseAdapter<T> implements ListAdapter, SpinnerAdapter {
    private final DataSetObservable mDataSetObservable = new DataSetObservable();

    private final int[] layResIds;

    @Nullable
    private final Context mContext;

    @Nullable
    private List<T> dataModel;

    /**
     * @param context 
     * @param layResIds 泛型資料結構
     * @param dataModel 不同的layout數組
     */
    public AbsBaseAdapter(Context context, List<T> dataModel, int... layResIds) {
        this.mContext = context;
        this.layResIds = layResIds;
        this.dataModel = dataModel;
    }

    public boolean hasStableIds() {
        return false;
    }

    public void registerDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.registerObserver(observer);
    }

    public void unregisterDataSetObserver(DataSetObserver observer) {
        mDataSetObservable.unregisterObserver(observer);
    }

    /**
     * Notifies the attached observers that the underlying data has been changed
     * and any View reflecting the data set should refresh itself.
     */
    public void notifyDataSetChanged() {
        mDataSetObservable.notifyChanged();
    }

    /**
     * Notifies the attached observers that the underlying data is no longer valid
     * or available. Once invoked this adapter is no longer valid and should
     * not report further data set changes.
     */
    public void notifyDataSetInvalidated() {
        mDataSetObservable.notifyInvalidated();
    }

    public boolean areAllItemsEnabled() {
        return true;
    }

    public boolean isEnabled(int position) {
        return true;
    }

    public int getItemViewType(int position) {
        return 0;
    }

    public int getViewTypeCount() {
        return 1;
    }

    public boolean isEmpty() {
        return getCount() == 0;
    }

    @Override
    final public View getView(int position, View convertView, ViewGroup parent) {
        AbsViewHolder viewHolder;
        int layResId = getItemViewType(position);
        if (convertView == null) {
            convertView = View.inflate(mContext, layResIds[layResId], null);
            viewHolder = new AbsViewHolder(convertView);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (AbsViewHolder) convertView.getTag();
        }

        T element = dataModel.get(position);
        if (onItemAdapter(viewHolder, element, position)) {
            //可以在此處添加處理代碼
            return convertView;
        }
        convertView.setTag(R.id.absadapter_id, element);
        return convertView;
    }

    @Override
    final public View getDropDownView(int position, View convertView, ViewGroup parent) {
        return getView(position, convertView, parent);
    }

    /**
     * @param viewHolder 綁定到view的holder,可以直接綁定資料
     * @param element  
     * @param position 
     * @return false, 如果想要繼續後面的操作;true,立馬傳回
     */
    protected abstract boolean onItemAdapter(AbsViewHolder viewHolder, T element, int position);//初始化UI資料

    @Override
    public int getCount() {
        return dataModel == null ? 0 : dataModel.size();
    }

    @Override
    public T getItem(int position) {
        return dataModel.get(position);
    }

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

    protected static class AbsViewHolder {
        private final View convertView;

        public AbsViewHolder(View convertView) {
            this.convertView = convertView;
        }

        public void setTextOrButton(int viewId, String text) {
            ((TextView) convertView.findViewById(viewId)).setText(text);
        }

        public void setTextOrButton(int viewId, int resid) {
            ((TextView) convertView.findViewById(viewId)).setText(resid);
        }

        public void setImageView(int viewId, int resid) {
            ((ImageView) convertView.findViewById(viewId)).setImageResource(resid);
        }

        public void setImageView(int viewId, Bitmap bitmap) {
            ((ImageView) convertView.findViewById(viewId)).setImageBitmap(bitmap);
        }

        public View findViewById(int viewId) {
            return convertView.findViewById(viewId);
        }

        public TextView findTextViewById(int viewId) {
            return (TextView) convertView.findViewById(viewId);
        }

        public ImageView findImageViewById(int viewId) {
            return (ImageView) convertView.findViewById(viewId);
        }

        public Button findButtonById(int viewId) {
            return (Button) convertView.findViewById(viewId);
        }
    }
}
           

示例:

listView = (AbsListView) findViewById(R.id.listview);
        List<Model> models = new ArrayList<>();
        models.add(new Model("http://img1.3lian.com/2015/w7/98/d/22.jpg"));
        models.add(new Model("http://img1.3lian.com/2015/w7/90/d/5.jpg"));
        models.add(new Model("http://pic1.nipic.com/2008-12-09/200812910493588_2.jpg"));
        models.add(new Model("http://pic1.nipic.com/2008-12-25/2008122510134038_2.jpg"));
        models.add(new Model("http://hiphotos.baidu.com/praisejesus/pic/item/e8df7df89fac869eb68f316d.jpg"));
        models.add(new Model("http://img5.imgtn.bdimg.com/it/u=1956790230,2945275299&fm=21&gp=0.jpg"));
        models.add(new Model("http://pic39.nipic.com/20140226/18071023_162553457000_2.jpg"));
        models.add(new Model("http://img3.imgtn.bdimg.com/it/u=2465434175,3103099436&fm=21&gp=0.jpg"));
        models.add(new Model("http://imgsrc.baidu.com/forum/pic/item/645b8701a18b87d6e716e197070828381e30fdae.jpg"));
        models.add(new Model("http://img4.imgtn.bdimg.com/it/u=865698757,1509853491&fm=21&gp=0.jpg"));
        models.add(new Model("http://img1.3lian.com/2015/w7/98/d/21.jpg"));
        models.add(new Model("http://img5.imgtn.bdimg.com/it/u=1849768669,2102852722&fm=21&gp=0.jpg"));
        //這樣簡單一處new代碼即可完成資料到view的綁定。
        listView.setAdapter(new AbsListAdapter(this, models, R.layout.layout_image) {
            @Override
            protected boolean onItemAdapter(AbsViewHolder viewHolder, Object element, int position) {
                Model item = (Model) element;
                ImageLoader.getInstance().displayImage(item.url, viewHolder.findImageViewById(R.id.imageview));
                return super.onItemAdapter(viewHolder, element, position);
            }
        });
           

繼續閱讀