1. 程式人生 > >當點選一個View時,顯示下面隱藏的一個View(摺疊的動畫效果)

當點選一個View時,顯示下面隱藏的一個View(摺疊的動畫效果)

先寫一個簡單的佈局 , 用於點選和隱藏 , 如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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:orientation
="vertical" tools:context="com.eg.lyx.demo.MainActivity">
<TextView android:layout_width="match_parent" android:layout_height="100dp" android:background="#fadfaf" android:gravity="center" android:text="點選下面的箭頭可以摺疊放開View"/> <ImageButton
android:id="@+id/iBtn" android:layout_width="match_parent" android:layout_height="50dp" android:layout_gravity="center" android:background="#FFFFFF" android:src="@drawable/arrow_bottom_black"/>
<LinearLayout android:id="@+id/content" android:layout_width
="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:visibility="gone">
<TextView android:layout_width="match_parent" android:layout_height="70dp" android:background="#afc7fa" android:ellipsize="end" android:gravity="center" android:singleLine="true" android:text="CtsCardLocationMgr.INSTANCE.INSTANCE.isFromRedPoint沒有製為true"/> <TextView android:layout_width="match_parent" android:layout_height="70dp" android:background="#daaffa" android:gravity="center" android:text="smartIP為空44139"/> </LinearLayout> </LinearLayout>

通過一個ValueAnimator來實現摺疊的動畫效果 , 程式碼如下:

package com.lyx.folddemo;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity {

    private LinearLayout mFoldedView;
    private float mDensity;
    private int mFoldedViewMeasureHeight;
    private ImageView iBtn;

    private boolean isFold = false;//是否是收起狀態
    boolean isAnimating = false;//是否正在執行動畫

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iBtn = (ImageView) findViewById(R.id.iBtn);
        mFoldedView = (LinearLayout) findViewById(R.id.content);
        showIbtn();

        //獲取畫素密度
        mDensity = getResources().getDisplayMetrics().density;
        //獲取佈局的高度
        int w = View.MeasureSpec.makeMeasureSpec(0,
                View.MeasureSpec.UNSPECIFIED);
        int h = View.MeasureSpec.makeMeasureSpec(0,
                View.MeasureSpec.UNSPECIFIED);
        mFoldedView.measure(w, h);
        int height = mFoldedView.getMeasuredHeight();
        mFoldedViewMeasureHeight = (int) (mDensity * height + 0.5);

        iBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //如果動畫正在執行,直接return,相當於點選無效了,不會出現當快速點選時,
                // 動畫的執行和ImageButton的圖示不一致的情況
                if (isAnimating) return;
                //如果動畫沒在執行,走到這一步就將isAnimating製為true , 防止這次動畫還沒有執行完畢的
                //情況下,又要執行一次動畫,當動畫執行完畢後會將isAnimating製為false,這樣下次動畫又能執行
                isAnimating = true;

                if (mFoldedView.getVisibility() == View.GONE) {
                    //開啟動畫
                    animateOpen(mFoldedView);
                } else {
                    //關閉動畫
                    animateClose(mFoldedView);
                }
            }


        });
    }

    /**
     * 展示ImageButton圖示
     */
    private void showIbtn() {
        if (isFold) {
            iBtn.setImageResource(R.drawable.aa);
        } else {
            iBtn.setImageResource(R.drawable.arrow_bottom_black);
        }
        isFold = !isFold;
    }


    private void animateOpen(LinearLayout view) {
        view.setVisibility(View.VISIBLE);
        ValueAnimator animator = createDropAnimator(view, 0, mFoldedViewMeasureHeight);
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                isAnimating = false;
            }
        });
        animator.start();
    }

    private void animateClose(final LinearLayout view) {
        int origHeight = view.getHeight();
        ValueAnimator animator = createDropAnimator(view, origHeight, 0);
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                view.setVisibility(View.GONE);
                isAnimating = false;
            }
        });
        animator.start();
    }

    private ValueAnimator createDropAnimator(final View view, int start, int end) {
        showIbtn();
        ValueAnimator animator = ValueAnimator.ofInt(start, end);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (int) animation.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
                layoutParams.height = value;
                view.setLayoutParams(layoutParams);
            }
        });
        return animator;
    }


}

實現的效果如下:
這裡寫圖片描述

說一下一開始寫這個效果出現的坑 , 就是最初我沒有加isAnimating開關 , 就是動畫是否執行完畢的開關 , 當我快速的點選摺疊按鈕 , 會出現按鈕圖示紊亂的情況 , 即當箭頭向上時 , View已經收起了 , 效果圖如下:
這裡寫圖片描述
這是因為當快速點選時 , 動畫的執行和ImageButton的圖示改變不一致 , 就是可能動畫還沒執行 , 圖示已經改變了 .所以我加了個isAnimating開關 , 已防止這個情況出現.
由於本人語言組織能力不足 , 哈哈…擔心表達的不清楚 , 囉嗦的比較多 , 請各位看官包涵!