美文网首页
2019-04-23设计模式-适配器模式

2019-04-23设计模式-适配器模式

作者: 猫KK | 来源:发表于2019-04-23 15:34 被阅读0次

    将现有类型转化成需要的类型

    举一个简单的例子:手机充电器就是一个适配器,将交流电(现有类型),转换成手机需要的直流电(需要的类型)。在android中最直观的就是ListView:将后台的数据list(现有类型)通过Adapter转化成ListView展示的view(需要要的类型)。下面通过仿照ListView,来学习Adapter模式

    自定一个View,继承自ScrollView,使得可以滑动

        public class MyList extends ScrollView {
    
        private LinearLayout mContent;
    
        public MyList(Context context) {
            this(context, null);
        }
    
        public MyList(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public MyList(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            mContent = new LinearLayout(context);
            mContent.setHorizontalGravity(LinearLayout.HORIZONTAL);
            addView(mContent, 0);
        }
    
        @Override
        public void addView(View child) {
            mContent.addView(child);
        }
    }
    

    在 MyList 中增加一个 LinearLayout ,重写 addView 方法,将 childView 增加到 LinearLayout 中。按照一般的逻辑,当后台给我们返回数据,我们需要往 MyList 中增加数据时:

        protected void initView() {
            //模拟后台数据,解析成一个 String 类型的列表
            List<String> date = new ArrayList<>();
            for (int i = 0; i < 100; i++) {
                date.add("" + i);
            }
    
            MyList myList = findViewById(R.id.my_list);
            //循环列表,在 MyList 中增加数据
            for (String s : date) {
                TextView itemView = (TextView) LayoutInflater.from(this).inflate(R.layout.login_text_view, null);
                itemView.setText(s);
                myList.addView(itemView);
            }
        }
    

    像上面这样写没什么不对,但看起来不好,下面我们仿照ListView的Adapter来改写。定义 Adapter 接口

        
    public interface Adapter {
        int getCount();
    
        View getItem(int position, ViewGroup parent);
    }
    

    定义两个方法,分别返回列表数和 MyList 需要了view类型,继续,实现一个真实的Adapter:

        public class MyListAdapter implements Adapter {
    
        private Context mContext;
        private List<String> mDate;
    
        public MyListAdapter(Context context, List<String> date) {
            this.mContext = context;
            this.mDate = date;
        }
    
        @Override
        public int getCount() {
            return mDate.size();
        }
    
        @Override
        public View getItem(int position, ViewGroup parent) {
            TextView itemView = (TextView) LayoutInflater.from(mContext).inflate(R.layout.login_text_view, parent, false);
            itemView.setText(mDate.get(position));
            return itemView;
        }
    }
    

    通过 MyListAdapter 的构造方法将 List<String> 传进来,通过将 getItem 方法,将适配好的view对象传出去,达到将 List<String> 的数据类型转化成 MyList 需要的View数据类型。接下来改写一下 MyList

        public class MyList extends ScrollView {
    
        private LinearLayout mContent;
        private Adapter mAdapter;
    
        public MyList(Context context) {
            this(context, null);
        }
    
        public MyList(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public MyList(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            mContent = new LinearLayout(context);
            mContent.setOrientation(LinearLayout.VERTICAL);
            addView(mContent, 0);
        }
    
        @Override
        public void addView(View child) {
            mContent.addView(child);
        }
    
        public void setAdapter(Adapter adapter) {
            this.mAdapter = adapter;
            if (mAdapter == null) {
                return;
            }
            int count = mAdapter.getCount();
            for (int i = 0; i < count; i++) {
                addView(mAdapter.getItem(i, mContent));
            }
        }
    }
    

    仿照ListView,增加一个 setAdapter 方法,通过 Adapter.getItem 获取对应的View添加到 LinearLayout 中。在Activity中使用:

        protected void initView() {
    
            List<String> date = new ArrayList<>();
            for (int i = 0; i < 100; i++) {
                date.add("" + i);
            }
    
            MyList myList = findViewById(R.id.my_list);
            MyListAdapter adapter = new MyListAdapter(this, date);
            myList.setAdapter(adapter);
        }
    

    通过 Adapter 将 List<String> 类型的数据类型转化成 MyList 需要的View数据类型

    相关文章

      网友评论

          本文标题:2019-04-23设计模式-适配器模式

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