美文网首页
Adapter设计模式-如何将Adapter设计模式运用到实际开

Adapter设计模式-如何将Adapter设计模式运用到实际开

作者: _风听雨声 | 来源:发表于2020-04-11 12:13 被阅读0次

    引言

    适配器在生活中非常常见,如手机充电适配器、笔记本电脑电源适配器、电源转接插头...等等。手机充电适配器将家用220V电压转换成充电电压,两孔插座转换三孔插座,这些都是适配器在生活中直观的体现。在Android开发中,RecyclerView、ListView、ViewPager的Adapter都是运用了适配器的设计模式,是适配器模式运用的直观体现。


    adapter.png

    Adapter的作用

    主要是起到转换的作用(对象适配器、类适配器)。比如RecyclreView,需要的是view,我们的数据是一个数据的List,我们需要将这个数据的List转换成一个个的itemView(View)给RecyclerView去addView。


    简单示例.png

    这个例子效果比较简单,有4个tab,区域、价格、户型、更多,点击时分别对应不同的选择菜单的container,假设每一个container内的样式都是不一样的,那么用适配器模式怎么去实现呢?

    实现思路

    1.创建MenuSelectorView,继承自LinearLayoutCompat(其他的ViewGroup也可以)
    2.实例化Tab容器的layout、menu的Container布局、阴影的布局都添加进MenuSelectorView
    private void initView() {
            setOrientation(VERTICAL);
            mTabLayout = new LinearLayoutCompat(getContext());
            LinearLayoutCompat.LayoutParams tabLayoutParams = new LinearLayoutCompat.LayoutParams(
                    LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
            mTabLayout.setLayoutParams(tabLayoutParams);
            addView(mTabLayout);
    
            mMenuContainer = new FrameLayout(getContext());
            addView(mMenuContainer);
            mShadowView = new View(getContext());
            mShadowView.setBackgroundColor(shadowColor);
            mShadowView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    closeMenu();
                }
            });
            mMenuContainer.addView(mShadowView);
    
            mMenuLayout = new FrameLayout(getContext());
            mMenuLayout.setBackgroundColor(Color.WHITE);
            mMenuContainer.addView(mMenuLayout);
            mMenuContainer.setVisibility(GONE);
        }
    
    3.在onMeasure方法获取控件宽高并设置给对应的layout
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int containerLayoutHeight = MeasureSpec.getSize(heightMeasureSpec);
            FrameLayout.LayoutParams menuLayoutParams = (FrameLayout.LayoutParams) mMenuLayout.getLayoutParams();
            menuViewHeight = containerLayoutHeight * 75 / 100;
            menuLayoutParams.height = menuViewHeight;
            mMenuLayout.setLayoutParams(menuLayoutParams);
        }
    
    4.定义抽象基类BaseAdapter,添加3个子类需要实现的抽象方法

    public abstract View getTabView(int position, ViewGroup parent);
    public abstract View getMenuView(int position, ViewGroup parent);
    public abstract int getItemCount();

    两个子类可以选择实现的方法(用于菜单切换时tab的状态切换)

    public void menuOpen(int position, View tabView) {}
    public void menuClose(int position, View tabView) {}

    public static abstract class BaseAdapter {
    
            public abstract View getTabView(int position, ViewGroup parent);
    
            public abstract View getMenuView(int position, ViewGroup parent);
    
            public abstract int getItemCount();
    
            public void menuOpen(int position, View tabView) {
    
            }
    
            public void menuClose(int position, View tabView) {
    
            }
        }
    
    5.定义setAdapter方法,接收BaseAdapter的实现类,并将adapter中的tabView和menuView添加到第二步已经定义好的容器
     public void setAdapter(BaseAdapter adapter) {
            this.mAdapter = adapter;
            if (mAdapter != null) {
                int itemCount = mAdapter.getItemCount();
                for (int i = 0; i < itemCount; i++) {
                    View tabView = mAdapter.getTabView(i, this);
                    tabView.setTag(i);
                    mTabViews.add(tabView);
                    addTabView(tabView);
    
                    View menuView = mAdapter.getMenuView(i, this);
                    addMenuView(menuView);
                }
    
            }
        }
    
    6.创建menu打开和切换的方法,并加上动画
    private void exChangeMenu(int clickPosition) {
            mMenuLayout.getChildAt(mCurrentPosition).setVisibility(GONE);
            mAdapter.menuClose(mCurrentPosition, mTabLayout.getChildAt(mCurrentPosition));
            mCurrentPosition = clickPosition;
            mMenuLayout.getChildAt(mCurrentPosition).setVisibility(VISIBLE);
            mAdapter.menuOpen(mCurrentPosition, mTabLayout.getChildAt(mCurrentPosition));
        }
    
    
        private void addMenuView(View menuView) {
            menuView.setVisibility(GONE);
            mMenuLayout.addView(menuView);
        }
    
    
        private AnimatorSet openAnimatorSet;
    
        public void openMenu() {
            if (isAnimatorStarting) return;
            if (openAnimatorSet == null) {
                openAnimatorSet = new AnimatorSet();
                ObjectAnimator openAnimator = ObjectAnimator.ofFloat(mMenuLayout, "translationY",
                        -menuViewHeight, 0);
                ObjectAnimator shadowAlphaAnimator = ObjectAnimator.ofFloat(mShadowView, "alpha",
                        0f, 1f);
                openAnimatorSet.playTogether(openAnimator, shadowAlphaAnimator);
                openAnimatorSet.setDuration(ANIMATORDURATION);
                openAnimatorSet.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        isMenuOpen = true;
                        isAnimatorStarting = false;
                    }
    
                    @Override
                    public void onAnimationStart(Animator animation) {
                        mShadowView.setVisibility(VISIBLE);
                        isAnimatorStarting = true;
                    }
                });
            }
            openAnimatorSet.start();
    
        }
    
        private AnimatorSet closeAnimatorSet;
    
        private void closeMenu() {
            if (isAnimatorStarting) return;
            if (closeAnimatorSet == null) {
                closeAnimatorSet = new AnimatorSet();
                ObjectAnimator openAnimator = ObjectAnimator.ofFloat(mMenuLayout, "translationY",
                        0, -menuViewHeight);
                ObjectAnimator shadowAlphaAnimator = ObjectAnimator.ofFloat(mShadowView, "alpha",
                        1f, 0f);
                closeAnimatorSet.playTogether(openAnimator, shadowAlphaAnimator);
                closeAnimatorSet.setDuration(ANIMATORDURATION);
                closeAnimatorSet.addListener(new AnimatorListenerAdapter() {
    
                    @Override
                    public void onAnimationStart(Animator animation) {
                        super.onAnimationStart(animation);
                        isAnimatorStarting = true;
                    }
    
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        mShadowView.setVisibility(GONE);
                        isMenuOpen = false;
                        isAnimatorStarting = false;
                    }
                });
            }
            closeAnimatorSet.start();
        }
    
    7.创建BaseAdapter子类,继承自BaseAdapter,实现对应的方法
    public class MenuSelectorAdapter extends MenuSelectorView.BaseAdapter {
        private String[] tabs = new String[]{"区域", "价格", "户型", "更多"};
        private Context mContext;
        private LayoutInflater mInflater;
    
        public MenuSelectorAdapter(Context context) {
            this.mContext = context;
            mInflater = LayoutInflater.from(context);
        }
    
        @Override
        public View getTabView(int position, ViewGroup parent) {
            TextView tabView = new TextView(mContext);
            tabView.setText(tabs[position]);
            LinearLayoutCompat.LayoutParams tabParams = new LinearLayoutCompat.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            tabParams.weight = 1;
            tabView.setLayoutParams(tabParams);
            tabView.setPadding(dp2px(10), dp2px(10), dp2px(10), dp2px(10));
            tabView.setTextColor(Color.BLACK);
            tabView.setGravity(Gravity.CENTER);
            return tabView;
        }
    
        @Override
        public View getMenuView(int position, ViewGroup parent) {
            TextView menuView = (TextView) mInflater.inflate(R.layout.layout_menu, parent, false);
            menuView.setText(tabs[position]);
            return menuView;
        }
    
        @Override
        public int getItemCount() {
            return tabs.length;
        }
    
        @Override
        public void menuOpen(int position, View tabView) {
            TextView tb = (TextView) tabView;
            tb.setTextColor(Color.RED);
        }
    
        @Override
        public void menuClose(int position, View tabView) {
            TextView tb = (TextView) tabView;
            tb.setTextColor(Color.BLACK);
        }
    
        private int dp2px(int dp) {
            return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mContext.getResources().getDisplayMetrics());
        }
    }
    
    8.将MenuSelectorView添加到布局文件,并将实例化好的BaseAdapter子类传入
    public class MainActivity extends AppCompatActivity {
        private MenuSelectorView mSelectorView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mSelectorView = findViewById(R.id.menuSelectorView);
            mSelectorView.setAdapter(new MenuSelectorAdapter(this));
        }
    }
    

    相关文章

      网友评论

          本文标题:Adapter设计模式-如何将Adapter设计模式运用到实际开

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