打造一个万能的适配器!!!

作者: 987edf3ecfa4 | 来源:发表于2019-05-26 21:19 被阅读2次

    最近项目中 经常用listView和GridView ,可以说是项目中Listview GridView几乎是必用的组件,Android也提供一套机制,为这些控件绑定数据,那就是Adapter
    最近抽了时间,自己也打造了一个万能的适配器

    看我们之前的一些写法:

    public class ImageViewAdapter2 extends RecyclerView.Adapter<ImageViewAdapter2.MyViewHolder> {
        private SweatQuestryModel deviceDataBean;
        private Context context;
        private ArrayList<String> urls = null;
        public ImageViewAdapter2(Context context, SweatQuestryModel deviceDataBean) {
            this.context = context;
            this.deviceDataBean = deviceDataBean;
            initImageUrl(deviceDataBean);
        }
    
        private void initImageUrl(SweatQuestryModel deviceDataBean) {
            urls = new ArrayList<>();
            if(urls != null){
                urls.addAll(deviceDataBean.getList());
            }
        }
    
        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(context).inflate(R.layout.item_imageview, null);
            MyViewHolder holder = new MyViewHolder(view);
            return holder;
        }
    
        @Override
        public void onBindViewHolder(MyViewHolder holder, final int position) {
            GlideUtil.loadNetImg2(context, holder.image, urls.get(position) , R.drawable.default_square_image);
            holder.image.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Bundle bundle = new Bundle();
                    bundle.putStringArrayList("imgUrls",urls);
                    bundle.putInt("position", position);
                    bundle.putInt("type", PictureActivity.TYPE_NET_IMG);
                    ActivityUtils.showActivity(context, PictureActivity.class, bundle);
                }
            });
    
        }
    
        @Override
        public int getItemCount() {
            return deviceDataBean == null ? 0 : 9;
        }
    
        class MyViewHolder extends RecyclerView.ViewHolder {
            ImageView image;
    
            public MyViewHolder(View itemView) {
                super(itemView);
                image = (ImageView) itemView.findViewById(R.id.sweat_recycler_image);
            }
        }
    }
    

    这样用起来虽然还不错,但每次都需要去继承一个BaseAdapter,然后实现里面的一大堆方法,而我们每次最关心的无非就是getView方法,其余的方法几乎都是相同代码。这里是不是就可以优化起来呢?在其次,我们在使用Adapter的时候,为了优化性能,常常会创建一个Holder。而Holder里面每次存放的都是View,对Holer的操作无非也就是初始化,绑定数据,复用。这里是不是也可以抽取抽取?
    如果我们封装后:

    /**
     * 类功能描述:</br>
     *v Viewholder
     * @author yuyahao
     * @version 1.0 </p> 修改时间:</br> 修改备注:</br>
     */
    public class VolTeamAdapter extends CommonAdapter<Bean> {
    
        private Context context;
        public VolTeamAdapter(Context context, List<Bean> listDatas,   int layoutId) {
            super(context, listDatas, layoutId);
        }
    
        @Override
        protected void fillData(ViewHolder holder, int position) {
            TextView actNum = holder.getView(R.id.team_item_active_num);
            TextView time = holder.getView(R.id.team_item_time);
            TextView title = holder.getView(R.id.team_item_title);
            ImageView icon = holder.getView(R.id.team_item_icon);
            Bean item = listDatas.get(position);
            actNum.setText(String.valueOf(item.getActiveSum()) + "个");
            time.setText(String.valueOf(item.getTimeSun()) + "h");
            title.setText(item.getName());
    
            GlideUtil.loadNetImgC(context,icon, item.getPhoto(), R.drawable.bg_app_title);
        }
    }
    

    这样是不是简单多了。每次 写adapter都可以这样用。

    第一步:构造 BaseAdapter

    **
     * 类功能描述:</br>
     *v 使用
     * @author yuyahao
     * @version 1.0 </p> 修改时间:</br> 修改备注:</br>
     */
    public class VolTeamAdapter extends CommonAdapter<Bean> {
    
        private Context context;
        public VolTeamAdapter(Context context, List<Bean> listDatas,   int layoutId) {
            super(context, listDatas, layoutId);
            this.context = context;
        }
    
        @Override
        protected void fillData(ViewHolder holder, int position) {
            TextView actNum = holder.getView(R.id.team_item_active_num);
            TextView time = holder.getView(R.id.team_item_time);
            TextView title = holder.getView(R.id.team_item_title);
            ImageView icon = holder.getView(R.id.team_item_icon);
            Bean item = listDatas.get(position);
            actNum.setText(String.valueOf(item.getActiveSum()) + "个");
            time.setText(String.valueOf(item.getTimeSun()) + "h");
            title.setText(item.getName());
    
            GlideUtil.loadNetImgC(context,icon, item.getPhoto(), R.drawable.bg_app_title);
        }
    }
    

    好了,别卖关子了,直接上全部代码。

    /**
     * 类功能描述:</br>
     *v Viewholder
     * @author yuyahao
     * @version 1.0 </p> 修改时间:</br> 修改备注:</br>
     */
    public abstract class CommonAdapter<T> extends BaseAdapter {
        /*** 上下文的Context*/
        protected Context mContext;
    
    
        /*** list的数据*/
        protected List<T> listDatas;
    
        /** Item布局ID*/
        protected int layoutId;
    
    
        public CommonAdapter(Context context, List<T> listDatas, int layoutId) {
            this.mContext = context;
            this.listDatas = listDatas;
            this.layoutId = layoutId;
        }
    
        @Override
        public int getCount() {
            return listDatas == null ? 0 : listDatas.size();
        }
    
    /**
     * 获取当前点击的Item的数据时用
     * 在onItemClick中 parent.getAdapter().getItem(),获取当前点击的Item的数据
     */
        @Override
        public Object getItem(int position) {
            return listDatas.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        /**
         *加载每一个Item,该方法是最关键的
         */
    @   Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = ViewHolder.getViewHolder(mContext, convertView,  parent, layoutId, position);
            fillData(holder, position);
            return holder.getMConvertView();
        }
    
        /**
         *
         * 抽象方法,用于子类实现,填充数据
         * @param holder
         * @param position
         */
        protected abstract void fillData(ViewHolder holder, int position);
    }
    

    第二步Holer的通用化

    /**
     * 类功能描述:</br>
     *v Viewholder
     * @author yuyahao
     * @version 1.0 </p> 修改时间:</br> 修改备注:</br>
     */
    public class ViewHolder {
        private  int mPosition;
        /**
         * View容器,用于存放Holer中的View
         * 据网上说是 SparseArray是这样的
         * SparseArray 是Android推荐使用的一个优化容器,相当于一个Map<integer,View>
         */
        private SparseArray<View> mViews;
    
        /**
         * Item布局View convertView
         */
        private View mConvertView;
        public ViewHolder(Context context, ViewGroup parent, int layoutId) {
            mViews = new SparseArray<View>();
            mConvertView = LayoutInflater.from(context).inflate(layoutId, null);
            mConvertView.setTag(this);
        }
    
        /**
         * 获取ViewHolder
         * @param context
         *  上下文
         * @param convertView
         * @param parent
         * @param layoutId
         *            布局layout Id
         * @param
         * @return
         */
    
        public static ViewHolder getViewHolder(Context context, View convertView,  ViewGroup parent, int layoutId) {
            if (convertView == null)
                return new ViewHolder(context, parent, layoutId);
            return (ViewHolder) convertView.getTag();
        }
    
    
    
        public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {
            this.mViews = new SparseArray<View>();
            this.mPosition = position;
            this.mConvertView = LayoutInflater.from(context).inflate(layoutId,
                    parent, false);
            this.mConvertView.setTag(this);
        }
        /**
         * 拿到一个ViewHolder对象
         * @param context
         * @param convertView
         * @param parent
         * @param layoutId
         * @param position
         * @return
         */
        public static ViewHolder getViewHolder(Context context, View convertView, ViewGroup parent, int layoutId, int position) {
            if (null == convertView) {
                return new ViewHolder(context, parent, layoutId, position);
            } else {
                ViewHolder holder = (ViewHolder) convertView.getTag();
                holder.mPosition = position;
                return holder;
            }
        }
        /**
         * 获取Holder中的ItemView
         * @param viewId
         * @return
         */
        @SuppressWarnings("unchecked")
        public <T extends View> T getView(int viewId) {
            View item = mViews.get(viewId);
            if (item == null) {
                item = mConvertView.findViewById(viewId);
                mViews.put(viewId, item);
            }
            return (T) item;
        }
    
        /** * 获取convertView***/
        public View getMConvertView() {
            return mConvertView;
        }
    
    }
    

    这样已经写完。

    第三步使用

    /**
     * 类功能描述:</br>
     *v 使用
     * @author yuyahao
     * @version 1.0 </p> 修改时间:</br> 修改备注:</br>
     */
    public class VolTeamAdapter extends CommonAdapter<Bean> {
    
        private Context context;
        public VolTeamAdapter(Context context, List<Bean> listDatas,   int layoutId) {
            super(context, listDatas, layoutId);
            this.context = context;
        }
    
        @Override
        protected void fillData(ViewHolder holder, int position) {
            TextView actNum = holder.getView(R.id.team_item_active_num);
            TextView time = holder.getView(R.id.team_item_time);
            TextView title = holder.getView(R.id.team_item_title);
            ImageView icon = holder.getView(R.id.team_item_icon);
            Bean item = listDatas.get(position);
            actNum.setText(String.valueOf(item.getActiveSum()) + "");
            time.setText(String.valueOf(item.getTimeSun()) + "");
            title.setText(item.getName());
    
            GlideUtil.loadNetImgC(context,icon, item.getPhoto(), R.drawable.bg_app_title);
        }
    }
    

    mainActivity:

    public class MyTextActivity extends BaseActivity{
        private Context cnt;
        @Bind(R.id.lv_list)
        ListView  lv_list;
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addViewFillInRoot(R.layout.ctivity_mytext);
            ButterKnife.bind(this);
            cnt = this;
            initView();
        }
    
    
        private void initView() {
            try {
                List<Bean>  list = DataTest.getMyTestList();
                VolTeamAdapter volTeamAdapter = new VolTeamAdapter(cnt,list,R.layout.my_listr);
                lv_list.setAdapter(volTeamAdapter);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal" android:layout_width="match_parent"
        android:gravity="center_vertical"
        android:layout_height="match_parent">
        <ImageView
            android:layout_width="@dimen/dp80"
            android:layout_height="@dimen/dp80"
            android:background="@drawable/default_head"
            android:scaleType="fitXY"
            android:id="@+id/team_item_icon"/>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_marginLeft="@dimen/dp10"
            android:orientation="vertical"
            android:layout_height="@dimen/dp80">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/team_item_title"
                android:gravity="center_vertical"
                android:layout_weight="1"
                android:text="卡卡罗特"/>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_weight="1"
                android:layout_height="match_parent"
                android:gravity="center_vertical">
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="天不排名"
                    android:id="@+id/team_item_time"/>
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="@dimen/dp20"
                    android:text="战斗值: "
    
                    android:id="@+id/team_item_active_num"/>
    
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
    

    效果图:

    在这里插入图片描述

    最后送福利了,现在关注我并且加入群聊可以获取包含源码解析,自定义View,动画实现,架构分享等。 内容难度适中,篇幅精炼,每天只需花上十几分钟阅读即可。 大家可以跟我一起探讨,欢迎加群探讨,有flutter—性能优化—移动架构—资深UI工程师 —NDK相关专业人员和视频教学资料,还有更多面试题等你来拿~ 群号:661841852


    点我加入群聊【Android开发行业交流】

    相关文章

      网友评论

        本文标题:打造一个万能的适配器!!!

        本文链接:https://www.haomeiwen.com/subject/hvzftctx.html