1. 程式人生 > >封裝一個ListView萬能介面卡

封裝一個ListView萬能介面卡

剛開始接觸android的時候,有些東西並不會在意,可能自己並沒有寫太多的原因,隨著專案越來越大,我們重複的工作做得越來越多,這個時候我們就會想著怎麼才能簡化我們的程式碼,android中的ListView用的還是很多的,所以就做了一個簡化的萬能介面卡Adapter,主要就是利用JAVA中的命令模式進行開發的,如果有特別的功能,可自行在程式碼裡新增修改,經過修改,本介面卡可以多佈局進行顯示

這個是例項

public class MainActivity extends AppCompatActivity {

    private ListView list_view;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list_view = findViewById(R.id.list_view);
        List<String> data = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            data.add("第" + i);
        }
        final Adapter<String> adapter = new Adapter<>(getApplicationContext());
        adapter.setData(data);
        adapter.addLayout(0, R.layout.item1);
        adapter.addLayout(1, R.layout.item2);
        adapter.setOnGetLayoutType(new OnGetLayoutType<String>() {
            @Override
            public int getLayoutType(int postion, List<String> data) {
                return postion % 2 == 0 ? 0 : 1;
            }
        });
        adapter.setOnGetView(new OnGetView<String>() {
            @Override
            public void getView(ViewHolder viewHolder, final int position, List<String> data) {
                TextView textView = viewHolder.getView(R.id.text);
                textView.setTextColor(Color.BLACK);
                textView.setText(data.get(position));
                RadioButton radio = viewHolder.getView(R.id.radio);
                radio.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        adapter.updateData(list_view, position, "我");
                    }
                });
            }
        });
        list_view.setAdapter(adapter);
    }

    public static class Adapter<T> extends BaseAdapter {

        private Context context;
        private List<T> data;
        private OnGetView<T> onGetView;
        private OnGetLayoutType<T> onGetLayoutType;
        private Map<Integer, Integer> layoutTypeMap;

        Adapter(Context context) {
            this.context = context;
            data = new ArrayList<>();
            layoutTypeMap = new HashMap<>();
        }

        @Override
        public int getViewTypeCount() {
            if (layoutTypeMap.size() <= 0) {
                return 0;
            }
            return layoutTypeMap.size();
        }

        @Override
        public int getItemViewType(int position) {
            return onGetLayoutType.getLayoutType(position, this.data);
        }

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

        @Override
        public Object getItem(int position) {
            return data.get(position);
        }

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

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            int type = getItemViewType(position);
            ViewHolder viewHolder = null;
            //因為考慮到item佈局重用的情況,優化ListView
            if (convertView == null) {
                convertView = LayoutInflater.from(context)
                    .inflate(layoutTypeMap.get(type), parent, false);
                viewHolder = new ViewHolder(convertView);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            if (onGetView != null) {
                onGetView.getView(viewHolder, position, this.data);
            }
            return viewHolder.getConvertView();
        }

        //獲取資料
        public List<T> getData() {
            return this.data;
        }

        //設定資料
        public void setData(List<T> data) {
            if (data == null) {
                data = new ArrayList<T>();
            }
            this.data = data;
            this.notifyDataSetChanged();
        }

        //更新資料
        public void updateData(List<T> data) {
            if (data == null) {
                data = new ArrayList<T>();
            }
            this.data = data;
            this.notifyDataSetChanged();
        }

        //新增資料
        public void addData(List<T> data) {
            if (this.data == null) {
                data = new ArrayList<T>();
            }
            this.data.addAll(data);
            this.notifyDataSetChanged();
        }

        //區域性更新資料
        public void updateData(ListView listView, int position, T data) {
            if (data != null) {
                if (this.data == null) {
                    this.data = new ArrayList<T>();
                }
                this.data.set(position, data);

                //獲得第一條資料
                int firstVisiblePosition = listView.getFirstVisiblePosition();
                //獲取最後一條資料
                int lastVisiblePosition = listView.getLastVisiblePosition();
                if (position >= firstVisiblePosition && position <= lastVisiblePosition) {
                    /**獲取指定位置view物件 ,如果存在頭部佈局,所以減去頭佈局**/
                    View view = listView.getChildAt(position - firstVisiblePosition);
                    getView(position, view, listView);
                }
            }
        }

        //添加布局--兩者都不能為空
        public void addLayout(int type, int layoutId) {
            layoutTypeMap.put(type, layoutId);
        }

        public void setOnGetView(OnGetView<T> onGetView) {
            this.onGetView = onGetView;
        }

        //新建一個介面-把給使用者的操作集中到一塊,給使用者操作,採用java的命令模式,可自行學習
        public interface OnGetView<T> {

            void getView(ViewHolder viewHolder, final int position, List<T> data);
        }

        //用於返回指定佈局的型別
        public void setOnGetLayoutType(OnGetLayoutType<T> onGetLayoutType) {
            this.onGetLayoutType = onGetLayoutType;
        }

        public interface OnGetLayoutType<T> {

            int getLayoutType(int postion, List<T> data);
        }

        //封裝一個萬能的ViewHolder
        static class ViewHolder {

            //用於儲存控制元件
            private SparseArray<View> views;
            private View convertView;

            public ViewHolder(View convertView) {
                this.convertView = convertView;
                views = new SparseArray();
            }

            //獲得控制元件
            public <T extends View> T getView(int viewId) {
                View view = views.get(viewId);
                if (view == null) {
                    view = convertView.findViewById(viewId);
                    views.put(viewId, view);
                }
                return (T) view;
            }

            //獲得佈局
            public View getConvertView() {
                return convertView;
            }
        }
    }
}

這個就是萬能的介面卡,我已經在專案中使用了,至今還沒發現bug,如果出現問題可進行留言

     public static class Adapter<T> extends BaseAdapter {

        private Context context;
        private List<T> data;
        private OnGetView<T> onGetView;
        private OnGetLayoutType<T> onGetLayoutType;
        private Map<Integer, Integer> layoutTypeMap;

        Adapter(Context context) {
            this.context = context;
            data = new ArrayList<>();
            layoutTypeMap = new HashMap<>();
        }

        @Override
        public int getViewTypeCount() {
            if (layoutTypeMap.size() <= 0) {
                return 0;
            }
            return layoutTypeMap.size();
        }

        @Override
        public int getItemViewType(int position) {
            return onGetLayoutType.getLayoutType(position, this.data);
        }

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

        @Override
        public Object getItem(int position) {
            return data.get(position);
        }

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

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            int type = getItemViewType(position);
            ViewHolder viewHolder = null;
            //因為考慮到item佈局重用的情況,優化ListView
            if (convertView == null) {
                convertView = LayoutInflater.from(context)
                    .inflate(layoutTypeMap.get(type), parent, false);
                viewHolder = new ViewHolder(convertView);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            if (onGetView != null) {
                onGetView.getView(viewHolder, position, this.data);
            }
            return viewHolder.getConvertView();
        }

        //獲取資料
        public List<T> getData() {
            return this.data;
        }

        //設定資料
        public void setData(List<T> data) {
            if (data == null) {
                data = new ArrayList<T>();
            }
            this.data = data;
            this.notifyDataSetChanged();
        }

        //更新資料
        public void updateData(List<T> data) {
            if (data == null) {
                data = new ArrayList<T>();
            }
            this.data = data;
            this.notifyDataSetChanged();
        }

        //新增資料
        public void addData(List<T> data) {
            if (this.data == null) {
                data = new ArrayList<T>();
            }
            this.data.addAll(data);
            this.notifyDataSetChanged();
        }

        //區域性更新資料
        public void updateData(ListView listView, int position, T data) {
            if (data != null) {
                if (this.data == null) {
                    this.data = new ArrayList<T>();
                }
                this.data.set(position, data);

                //獲得第一條資料
                int firstVisiblePosition = listView.getFirstVisiblePosition();
                //獲取最後一條資料
                int lastVisiblePosition = listView.getLastVisiblePosition();
                if (position >= firstVisiblePosition && position <= lastVisiblePosition) {
                    /**獲取指定位置view物件 ,如果存在頭部佈局,所以減去頭佈局**/
                    View view = listView.getChildAt(position - firstVisiblePosition);
                    getView(position, view, listView);
                }
            }
        }

        //添加布局--兩者都不能為空
        public void addLayout(int type, int layoutId) {
            layoutTypeMap.put(type, layoutId);
        }

        public void setOnGetView(OnGetView<T> onGetView) {
            this.onGetView = onGetView;
        }

        //新建一個介面-把給使用者的操作集中到一塊,給使用者操作,採用java的命令模式,可自行學習
        public interface OnGetView<T> {

            void getView(ViewHolder viewHolder, final int position, List<T> data);
        }

        //用於返回指定佈局的型別
        public void setOnGetLayoutType(OnGetLayoutType<T> onGetLayoutType) {
            this.onGetLayoutType = onGetLayoutType;
        }

        public interface OnGetLayoutType<T> {

            int getLayoutType(int postion, List<T> data);
        }

        //封裝一個萬能的ViewHolder
        static class ViewHolder {

            //用於儲存控制元件
            private SparseArray<View> views;
            private View convertView;

            public ViewHolder(View convertView) {
                this.convertView = convertView;
                views = new SparseArray();
            }

            //獲得控制元件
            public <T extends View> T getView(int viewId) {
                View view = views.get(viewId);
                if (view == null) {
                    view = convertView.findViewById(viewId);
                    views.put(viewId, view);
                }
                return (T) view;
            }

            //獲得佈局
            public View getConvertView() {
                return convertView;
            }
        }
    }