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

2020-04-11  本文已影响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));
    }
}
上一篇下一篇

猜你喜欢

热点阅读