多条目选择下落动画-使用于条件筛选

2019-08-23  本文已影响0人  cao苗子

1.先看效果图

多条目选择下落动画.gif

2.分析

根部局是一个Linearlayout
其中包含:
第一个布局是一个 LinearLayout 用于包含TabView
第二个是一个FrameLayout,这个frameLayout中包含背景View,和内容view是FrameLayout

    private void initLayout() {

        //设置方向
        setOrientation(VERTICAL);
        mTabView = new LinearLayout(getContext());
        mTabView.setOrientation(HORIZONTAL);
        ViewGroup.LayoutParams mTabViewParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,mTabViewHeight);
        mTabView.setLayoutParams(mTabViewParams);
        addView(mTabView);

        View mLineView = new View(getContext());
        mLineView.setBackgroundColor(mLineViewColor);
        mLineView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1));
        addView(mLineView);

        mMenuView = new FrameLayout(getContext());
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
        layoutParams.weight = 1;
        mMenuView.setLayoutParams(layoutParams);

        addView(mMenuView);

        mBottomView = new View(getContext());
        mBottomView.setBackgroundColor(Color.parseColor("#80000000"));
        mBottomView.setVisibility(GONE);
        mBottomView.setAlpha(0f);
        mMenuView.addView(mBottomView);

        mBottomView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                closeContentView();
            }
        });

        mContentView = new FrameLayout(getContext());
        mContentView.setBackgroundColor(Color.WHITE);
        mMenuView.addView(mContentView);

    }

3.效果分析

一开始都是隐藏,当用户点击的时候才显示

 mBottomView.setVisibility(GONE);
        mBottomView.setAlpha(0f);

 //因为 设置View的 setVisibility 会重复调用这个方法
        if(mContentViewHeight == 0) {
            int height = MeasureSpec.getSize(heightMeasureSpec);
            mContentViewHeight = (int) (height * 0.76f);
            ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
            layoutParams.height = mContentViewHeight;
            mContentView.setLayoutParams(layoutParams);
            //往上移动这个布局 达到隐藏的功能
            mContentView.setTranslationY(-mContentViewHeight);
        }

设置点击事件

/**
     * 设置tab的点击事件
     * @param tabView
     */
    private void setTabViewOnclickListener( View tabView) {
        tabView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                mOnClickPosition = (int) view.getTag(-100);
                //关闭状态
                if (mCurrentPosition == -1) {
                    openContentView();
                } else {
                    //不是同一个,先把上一个隐藏 切换显示
                    if (mCurrentPosition != mOnClickPosition) {
                        View currentView = mContentView.getChildAt(mCurrentPosition);
                        if (currentView != null) {
                            currentView.setVisibility(GONE);
                            mAdapter.contentViewClose(mTabView.getChildAt(mCurrentPosition));
                        }
                        mCurrentPosition = mOnClickPosition;
                        View showView = mContentView.getChildAt(mCurrentPosition);
                        if (showView != null) {
                            showView.setVisibility(VISIBLE);
                            mAdapter.contentViewOpen(mTabView.getChildAt(mCurrentPosition));
                        }
                    } else {
                        closeContentView();
                    }
                }
            }
        });
    }

4.打开和关闭动画

4.1打开动画

 /**
     * 打开动画
     */
    public void openContentView(){
        if(mAnimationExecute){
           return;
        }
        if(mOpenAnimatorSet == null) {
            mOpenAnimatorSet = new AnimatorSet();
            ObjectAnimator contentViewAnimation = ObjectAnimator.ofFloat(mContentView, "translationY", -mContentViewHeight, 0);
            ObjectAnimator bottomViewAnimation = ObjectAnimator.ofFloat(mBottomView, "alpha", 0f, 1f);
            mOpenAnimatorSet.setDuration(mAnimationDuration);
            mOpenAnimatorSet.playTogether(contentViewAnimation, bottomViewAnimation);
            mOpenAnimatorSet.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    mAnimationExecute = true;
                    View view = mContentView.getChildAt(mOnClickPosition);
                    if (view != null) {
                        view.setVisibility(VISIBLE);
                    }
                    mBottomView.setVisibility(VISIBLE);
                    mAdapter.contentViewOpen(mTabView.getChildAt(mOnClickPosition));
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    mAnimationExecute = false;
                    mCurrentPosition = mOnClickPosition;
                }
            });
        }
        if(!mAnimationExecute) {
            mOpenAnimatorSet.start();
        }

    }

4.2关闭动画

 /**
     * 关闭动画
     */
    public void closeContentView(){
        if(mCloseAnimatorSet == null) {
            mCloseAnimatorSet = new AnimatorSet();
            ObjectAnimator contentViewAnimation = ObjectAnimator.ofFloat(mContentView, "translationY", 0, -mContentViewHeight);
            ObjectAnimator bottomViewAnimation = ObjectAnimator.ofFloat(mBottomView, "alpha", 1f, 0f);
            mCloseAnimatorSet.setDuration(mAnimationDuration);
            mCloseAnimatorSet.playTogether(contentViewAnimation, bottomViewAnimation);
            mCloseAnimatorSet.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    View view = mContentView.getChildAt(mCurrentPosition);
                    if (view != null) {
                        view.setVisibility(GONE);
                    }
                    mBottomView.setVisibility(GONE);
                    mCurrentPosition = -1;
                    mAnimationExecute = false;
                }

                @Override
                public void onAnimationStart(Animator animation) {
                    mAnimationExecute = true;
                    mAdapter.contentViewClose(mTabView.getChildAt(mCurrentPosition));
                }
            });
        }
         if(!mAnimationExecute) {
             mCloseAnimatorSet.start();
         }
    }

5.设置tabView的布局显示(Adapter设计模式)

使用Adapter设计模式,给tabVIew添加布局并且也给内容也添加布局
看代码:

 /**
     * 设置adapter
     * @param adapter
     */
    public void setAdapter(BaseListMenuAdapter adapter){
        if(adapter == null){
            throw new IllegalArgumentException("请设置->BaseListMenuAdapter");
        }
        this.mAdapter = adapter;
        for (int i = 0; i < mAdapter.getCount(); i++) {
            View tabView = mAdapter.getTabView(i, mTabView);
            if(tabView != null){
                LayoutParams layoutParams = new LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT);
                layoutParams.weight = 1;
                layoutParams.gravity = Gravity.CENTER;
                tabView.setLayoutParams(layoutParams);
                mTabView.addView(tabView);
                tabView.setTag(-100,i);
                setTabViewOnclickListener(tabView);
            }
            View contentView = mAdapter.getContentView(i, mContentView);
            if(contentView != null){
                contentView.setVisibility(GONE);
                mContentView.addView(contentView);
            }
        }
    }

循环列表,然后添加view。一般列表数据都是从后台接口返回的。
下面再看一下baseAdapter的代码,可以自己在添加一些功能,我这里想到了几个就写了几个而已。findViewById还是可以再优化的,比如可以建立一个集合来进行缓存就可以了。还有数据改变之后去刷新tabView的数据,可以自己写一个notifyDataSetChanged的方法,自己想想应该怎么写?

/**
 * created by panshimu
 * on 2019/8/23
 */
public abstract class BaseListMenuAdapter {
    public abstract int getCount();
    public abstract View getTabView(int position, ViewGroup parent);
    public abstract View getContentView(int position,ViewGroup parent);
    public abstract void contentViewClose(View tabView);
    public abstract void contentViewOpen(View tabView);
}

下面就是 ListMenuAdapter 继承 BaseListMenuAdapter 类似 ListView的adapter,这种就是模仿listView写的。可以自己再去添加很多很多方法

/**
 * created by panshimu
 * on 2019/8/23
 */
public class ListMenuAdapter extends BaseListMenuAdapter{
    private List<String> mData;
    private LayoutInflater mInflater;

    public ListMenuAdapter(Context context,List<String> mData) {
        this.mData = mData;
        this.mInflater = LayoutInflater.from(context);
    }

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

    @Override
    public View getTabView(int position, ViewGroup parent) {
        View tabView = mInflater.inflate(R.layout.ui_tab_view,parent,false);
        TextView tvTab = tabView.findViewById(R.id.tv_tab);
        tvTab.setText(mData.get(position));
        return tabView;
    }

    @Override
    public View getContentView(int position, ViewGroup parent) {
        View contentView = mInflater.inflate(R.layout.ui_content_view,parent,false);
        TextView tvContent = contentView.findViewById(R.id.tv_content);
        tvContent.setText(mData.get(position));
        return contentView;
    }

    @Override
    public void contentViewClose(View tabView) {
        TextView tvTab = tabView.findViewById(R.id.tv_tab);
        tvTab.setTextColor(Color.GRAY);
    }

    @Override
    public void contentViewOpen(View tabView) {
        TextView tvTab = tabView.findViewById(R.id.tv_tab);
        tvTab.setTextColor(Color.RED);
    }
}

6.如果使用

是不是很简单?

public class MainActivity extends AppCompatActivity {
    private ListMenuView mListMenuView;
    private List<String> mData;
     @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        addData();
        mListMenuView = findViewById(R.id.list_menu_view);
        ListMenuAdapter listMenuAdapter = new ListMenuAdapter(this, mData);
        mListMenuView.setAdapter(listMenuAdapter);
     }

    private void addData() {
        mData = new ArrayList<>();
        mData.add("推荐");
        mData.add("热点");
        mData.add("关注");
        mData.add("视频");
        mData.add("游戏");
    }
}

下面再贴出布局xml的代码:
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    tools:context=".MainActivity">

    <TextView
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
       />
    <com.miaozi.listmenuview.ListMenuView
        android:id="@+id/list_menu_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <TextView
        android:layout_marginBottom="50dp"
        android:layout_centerHorizontal="true"
        android:textColor="#000"
        android:layout_alignParentBottom="true"
        android:text="我是底部"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

ui_content_view.xml
这里可以根据项目的需要自行设计和修改,比如是一个列表模式的listView或是等等其他联动的布局都是可以的,它的根部局是 FrameLayout 所以可以随便设计

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv_content"
        android:textColor="#000"
        android:textSize="15sp"
        android:text="wo de "
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

剩下的就是 ui_tab_view.xml 这个是tabView的每一个item的布局,我这里是一个TextView,在项目的开发中一个都是一个TextView和一个Imageview配合使用 当选中的时候 imageview箭头向下或是向上等等效果

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv_tab"
        android:textColor="@android:color/darker_gray"
        android:textSize="15sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

好了就这么多了。
我写这个主要是为了练习属性动画的使用。
最后在留下源码地址,需要的同学可以自己下载
https://github.com/panshimu/ListMenuView

有问题随时问,看到会答复的,谢谢!

QQ:362976241

上一篇下一篇

猜你喜欢

热点阅读