android 多个标题和子标题 点击时过度动画效果

先看下效果图:

这里写图片描述

实现步骤如下:

1.布局文件(条目的标题 和 条目标题对应的内容)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv_item_one_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:padding="10dip"
        android:text="条目一的标题"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tv_item_one_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:paddingLeft="30dip"
        android:text="条目一的内容\r\n条目一的内容\r\n条目一的内容\r\n"
        android:visibility="gone" />

    <TextView
        android:id="@+id/tv_item_two_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:padding="10dip"
        android:text="条目二的标题"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tv_item_two_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:paddingLeft="30dip"
        android:text="条目二的内容\r\n条目二的内容\r\n条目二的内容\r\n"
        android:visibility="gone" />

    <TextView
        android:id="@+id/tv_item_three_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:padding="10dip"
        android:text="条目三的标题"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tv_item_three_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:paddingLeft="30dip"
        android:text="条目三的内容\r\n条目三的内容\r\n条目三的内容\r\n"
        android:visibility="gone" />

    <TextView
        android:id="@+id/tv_item_four_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:padding="10dip"
        android:text="条目四的标题"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tv_item_four_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:paddingLeft="30dip"
        android:text="条目四的内容\r\n条目四的内容\r\n条目四的内容\r\n"
        android:visibility="gone" />

    <TextView
        android:id="@+id/tv_item_five_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:padding="10dip"
        android:text="条目五的标题"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tv_item_five_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:paddingLeft="30dip"
        android:text="条目五的内容\r\n条目五的内容\r\n条目五的内容\r\n"
        android:visibility="gone" />

</LinearLayout>

实现此动画的前提:
将所有的title和对应的content封装ViewBean中,然后将所有ViewBean放到List中
ViewBean的代码如下:

public class ViewBean {

    private View viewTitle;
    private View viewLayout;

    public View getViewTitle() {
        return viewTitle;
    }
    public void setViewTitle(View viewTitle) {
        this.viewTitle = viewTitle;
    }
    public View getViewLayout() {
        return viewLayout;
    }
    public void setViewLayout(View viewLayout) {
        this.viewLayout = viewLayout;
    }
}

同时还需要依赖一个类ExpandAnimation (这是牛人们写好的一个类 直接复制去就行了)

import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.LinearLayout.LayoutParams;

public class ExpandAnimation extends Animation {

    private View mAnimatedView;
    private LayoutParams mViewLayoutParams;
    private int mMarginStart, mMarginEnd;
    private boolean mIsVisibleAfter = false;
    private boolean mWasEndedAlready = false;

    /**
     * Initialize the animation
     * @param view The layout we want to animate
     * @param duration The duration of the animation, in ms
     */
    public ExpandAnimation(View view, int duration) {

        setDuration(duration);
        mAnimatedView = view;
        mViewLayoutParams = (LayoutParams) view.getLayoutParams();

        // decide to show or hide the view
        mIsVisibleAfter = (view.getVisibility() == View.VISIBLE);

        mMarginStart = mViewLayoutParams.bottomMargin;
        mMarginEnd = (mMarginStart == 0 ? (0- view.getHeight()) : 0);

        view.setVisibility(View.VISIBLE);
    }
    /**
     * show current animation status
     * @return
     */
    public boolean toggle() {
        return !mIsVisibleAfter;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);

        if (interpolatedTime < 1.0f) {

            // Calculating the new bottom margin, and setting it
            mViewLayoutParams.bottomMargin = mMarginStart
                    + (int) ((mMarginEnd - mMarginStart) * interpolatedTime);

            // Invalidating the layout, making us seeing the changes we made
            mAnimatedView.requestLayout();

        // Making sure we didn't run the ending before (it happens!)
        } else if (!mWasEndedAlready) {
            mViewLayoutParams.bottomMargin = mMarginEnd;
            mAnimatedView.requestLayout();

            if (mIsVisibleAfter) {
                mAnimatedView.setVisibility(View.GONE);
            }
            mWasEndedAlready = true;
        }
    }
}

2.主程序代码如下:


public class MainActivity extends Activity {

    private TextView tv_title_one, tv_title_two, tv_title_three, tv_title_four, tv_title_five;
    private TextView tv_content_one, tv_content_two, tv_content_three, tv_content_four, tv_content_five;
    private List<ViewBean> viewList;
    private boolean animState = true;
    private View lastView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        findViews();
        initViews();
    }


    private void findViews() {
        tv_title_one = (TextView) this.findViewById(R.id.tv_item_one_title);
        tv_title_two = (TextView) this.findViewById(R.id.tv_item_two_title);
        tv_title_three = (TextView) this.findViewById(R.id.tv_item_three_title);
        tv_title_four = (TextView) this.findViewById(R.id.tv_item_four_title);
        tv_title_five = (TextView) this.findViewById(R.id.tv_item_five_title);
        tv_content_one = (TextView) this.findViewById(R.id.tv_item_one_content);
        tv_content_two = (TextView) this.findViewById(R.id.tv_item_two_content);
        tv_content_three = (TextView) this.findViewById(R.id.tv_item_three_content);
        tv_content_four = (TextView) this.findViewById(R.id.tv_item_four_content);
        tv_content_five = (TextView) this.findViewById(R.id.tv_item_five_content);
    }


    private void initViews() {
        viewList = new ArrayList<ViewBean>();
        //1.将所有的viewTitle和viewLayout封装成ViewBean,并且用list保存
        ViewBean bean;

        bean = new ViewBean();
        bean.setViewTitle(tv_title_one);
        bean.setViewLayout(tv_content_one);
        viewList.add(bean);

        bean = new ViewBean();
        bean.setViewTitle(tv_title_two);
        bean.setViewLayout(tv_content_two);
        viewList.add(bean);

        bean = new ViewBean();
        bean.setViewTitle(tv_title_three);
        bean.setViewLayout(tv_content_three);
        viewList.add(bean);

        bean = new ViewBean();
        bean.setViewTitle(tv_title_four);
        bean.setViewLayout(tv_content_four);
        viewList.add(bean);

        bean = new ViewBean();
        bean.setViewTitle(tv_title_five);
        bean.setViewLayout(tv_content_five);
        viewList.add(bean);

        setAnimation(viewList);
    }


    private void setAnimation(List<ViewBean> viewList) {
        for (ViewBean bean : viewList) {
            final View viewTitle = bean.getViewTitle();
            final View viewLayout = bean.getViewLayout();
            viewTitle.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    //给title对应的layout执行动画的操作
                    executeAnimation(viewTitle,viewLayout);
                }
            });
        }
    }

    private void executeAnimation(View viewTitle, View viewLayout) {
        /**
         * 执行动画的view如果是隐藏状态,自动展开,展开后将其设置为可见状态
         * 执行动画的view如果是可见状态,自动隐藏,隐藏后将其设置为不可见状态。
         */
        if (animState) { //表示当前可以执行动画
            ExpandAnimation anim = new ExpandAnimation(viewLayout, 300);
            boolean toggle = anim.toggle();
            if (toggle) {//表示当前动画已经展开
                /**
                 * 如果lastView == null 
                 * 说明之前没有执行过动画
                 *  如果lastView != null 
                 * 说明执行过动画,再执行动画的时候需要将lastview给收回,收回之后再执行当前的动画
                 */
                if (lastView == null) {
                    lastView = viewLayout;
                } else {
                    if (lastView == viewLayout) {
                        lastView = null;
                    } else {
                        executeAnimation(viewTitle, lastView);
                        lastView = viewLayout;
                    }
                }
            } else {//当前动画已经关闭
                /**
                 * 打开第二个动画的时候,需要将上一个viewLayout(lastView)对应的title恢复为正常的状态
                 */
                for (ViewBean bean : viewList) {
                    if (lastView == bean.getViewLayout()) {//找到lastView对应的那个viewbean
                        lastView = null;
                    }
                }
            }
            viewLayout.startAnimation(anim);
            anim.setAnimationListener(animationListener);
        } else {
            System.out.println("can't play animation");
        }

    }

    Animation.AnimationListener animationListener = new AnimationListener() {

        @Override
        public void onAnimationEnd(Animation animation) {
            animState = true;
        }
        @Override
        public void onAnimationStart(Animation animation) {
            animState = false;
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }
    };

}

至此,就可以实现这种比较舒服的过度效果了~(gif图有点卡顿,手机上很流畅)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值