美文网首页
多条目选择下落动画-使用于条件筛选

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

作者: cao苗子 | 来源:发表于2019-08-23 16:53 被阅读0次

    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

    相关文章

      网友评论

          本文标题:多条目选择下落动画-使用于条件筛选

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