Android 自訂實現翻轉卡片的View

來源:互聯網
上載者:User

標籤:

     一般一個View只有一面,但是可以自訂一個View,實現像翻書那樣的翻轉效果。

    旋轉View:

           

/** * 兩種方式構造一個翻轉卡片 * 1:直接提供一個特定命名格式的View * 2:提供兩個線性布局(正面和,反面) * Created by lip on 2015/4/8. */public class FlipView extends LinearLayout implements View.OnClickListener,RotateAnimation.InterpolatedTimeListener{    private LinearLayout m_first_ll, m_second_ll;    private boolean enableRefresh;    private LinearLayout view;    private View clickView;//當前的view    private Context context;    public FlipView(Context context)    {        super(context);        this.context=context;        //initViews();    }    public FlipView(Context context,AttributeSet attrs)    {        super(context,attrs);        this.context=context;        //initViews();    }    /**     */    public void initViews()    {        view=(LinearLayout)inflate(context,R.layout.flip_view,null);        m_first_ll=(LinearLayout)view.findViewById(R.id.first_ll);        m_second_ll=(LinearLayout)view.findViewById(R.id.second_ll);        m_first_ll.setOnClickListener(this);        m_second_ll.setOnClickListener(this);        addView(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);    }    /**     * @param ll1 正面     * @param ll2  反面     */    public void addViews(LinearLayout ll1,LinearLayout ll2)    {        m_first_ll=ll1;        m_second_ll=ll2;        m_first_ll.setOnClickListener(this);        m_second_ll.setOnClickListener(this);        addView(m_first_ll, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);        addView(m_second_ll, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);    }    /**     * flag=0 翻到正面     * flag=1 翻到反面     * @param flag     */    public void show(int flag)    {        enableRefresh = true;        RotateAnimation rotateAnim = null;        float cX = this.getWidth() / 2.0f;        float cY = this.getHeight() / 2.0f;        if(flag==0)        rotateAnim = new RotateAnimation(cX, cY,                RotateAnimation.ROTATE_DECREASE);        else if(flag==1)            rotateAnim = new RotateAnimation(cX, cY,                    RotateAnimation.ROTATE_INCREASE);        if (rotateAnim != null) {            rotateAnim.setInterpolatedTimeListener(this);            rotateAnim.setFillAfter(true);            this.startAnimation(rotateAnim);        }    }    @Override    public void onClick(View v) {        Log.d("click:",v.toString());        enableRefresh = true;        clickView=v;        RotateAnimation rotateAnim = null;        float cX = this.getWidth() / 2.0f;        float cY = this.getHeight() / 2.0f;        if (m_first_ll==v) {            rotateAnim = new RotateAnimation(cX, cY,                    RotateAnimation.ROTATE_INCREASE);        } else if (m_second_ll == v) {            rotateAnim = new RotateAnimation(cX, cY,                    RotateAnimation.ROTATE_DECREASE);        }        if (rotateAnim != null) {            rotateAnim.setInterpolatedTimeListener(this);            rotateAnim.setFillAfter(true);            this.startAnimation(rotateAnim);        }    }    @Override    public void interpolatedTime(float interpolatedTime) {        if (enableRefresh && interpolatedTime > 0.5f) {            setHint();            enableRefresh = false;        }    }    public void setHint() {        if (clickView == m_first_ll) {            m_first_ll.setVisibility(View.GONE);            m_second_ll.setVisibility(View.VISIBLE);        } else if (clickView==m_second_ll) {            m_second_ll.setVisibility(View.GONE);            m_first_ll.setVisibility(View.VISIBLE);        }    }}
 來看看使用方法:

      

public class FlipActivity extends Activity{    private FlipView flipView;    LinearLayout firstLL,secondLL;    LinearLayout root;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //setContentView(R.layout.activity_flip);        initViews();    }    private void initViews()    {        root=(LinearLayout)LayoutInflater.from(this).inflate(R.layout.activity_flip,null);        flipView=(FlipView)root.findViewById(R.id.flip_view);        /*********第一種方式(要主動調用initViews)*************///        firstLL=(LinearLayout)LayoutInflater.from(this).inflate(R.layout.flip_view1,null);//        secondLL=(LinearLayout)LayoutInflater.from(this).inflate(R.layout.flip_view2,null);        /*********第二種方式*************/        firstLL=(LinearLayout)root.findViewById(R.id.root_ll1);        secondLL=(LinearLayout)root.findViewById(R.id.root_ll2);        root.removeView(firstLL);        root.removeView(secondLL);        flipView.addViews(firstLL,secondLL);        setContentView(root);    }}
  既然一個View 有兩面,那當然需要主動去設定正面和反面的內容了。

   flipView.addViews(firstLL,secondLL);第一個參數就是正面的view,第二個參數是反面的view,這兩個view都是線性布局。我提供了兩種設定正反面的的方式,如果要是對於布局有一點瞭解,其實這是一樣的
</pre><p>    旋轉工具類(網上參考別人的):</p><p>          <pre name="code" class="java">public class RotateAnimation extends Animation {/** 值為true時可明確查看動畫的旋轉方向。 */public static final boolean DEBUG = false;/** 沿Y軸正方向看,數值減1時動畫逆時針旋轉。 */public static final boolean ROTATE_DECREASE = true;/** 沿Y軸正方向看,數值減1時動畫順時針旋轉。 */public static final boolean ROTATE_INCREASE = false;/** Z軸上最大深度。 */public static final float DEPTH_Z = 310.0f;/** 動畫顯示時間長度。 */public static final long DURATION = 800l;/** 圖片翻轉類型。 */private final boolean type;private final float centerX;private final float centerY;private Camera camera;public RotateAnimation(float cX, float cY, boolean type) {centerX = cX;centerY = cY;this.type = type;// 設定動畫時間長度setDuration(DURATION);}@Overridepublic void initialize(int width, int height, int parentWidth,int parentHeight) {// 在建構函式之後、applyTransformation()之前調用本方法。super.initialize(width, height, parentWidth, parentHeight);camera = new Camera();}@Overrideprotected void applyTransformation(float interpolatedTime,Transformation transformation) {// interpolatedTime:動畫進度值,範圍為0~1,0.5為正好翻轉一半if (listener != null) {listener.interpolatedTime(interpolatedTime);}float from = 0.0f, to = 0.0f;if (type == ROTATE_DECREASE) {from = 0.0f;to = 180.0f;} else if (type == ROTATE_INCREASE) {from = 360.0f;to = 180.0f;}// 旋轉的角度float degree = from + (to - from) * interpolatedTime;boolean overHalf = (interpolatedTime > 0.5f);if (overHalf) {// 翻轉過半的情況下,為保證數字仍為可讀的文字而非鏡面效果的文字,需翻轉180度。degree = degree - 180;}// 旋轉深度float depth = (0.5f - Math.abs(interpolatedTime - 0.5f)) * DEPTH_Z;final Matrix matrix = transformation.getMatrix();camera.save();// 深度——》相當於與螢幕的距離camera.translate(0.0f, 0.0f, depth);// 以x軸旋轉// camera.rotateX(degree);// 以y軸旋轉camera.rotateY(degree);camera.getMatrix(matrix);camera.restore();if (DEBUG) {if (overHalf) {matrix.preTranslate(-centerX * 2, -centerY);matrix.postTranslate(centerX * 2, centerY);}} else {// 確保圖片的翻轉過程一直處於組件的中心點位置/* * preTranslate是指在setScale前平移,postTranslate是指在setScale後平移,它們參數是平移的距離, * 而不是平移目的地的座標! * 由於縮放是以(0,0)為中心的,所以為了把介面的中心與(0,0)對齊,就要preTranslate(-centerX, * -centerY),setScale完成後, 調用postTranslate(centerX, * centerY),再把圖片移回來,這樣看到的動畫效果就是activity的介面圖片從中心不停的縮放了 * 注:centerX和centerY是介面中心的座標 */matrix.preTranslate(-centerX, -centerY);matrix.postTranslate(centerX, centerY);}}/** 用於監聽動畫進度。當值過半時需更新的內容。 */private InterpolatedTimeListener listener;public void setInterpolatedTimeListener(InterpolatedTimeListener listener) {this.listener = listener;}/** 動畫進度監聽器。 */public static interface InterpolatedTimeListener {public void interpolatedTime(float interpolatedTime);}}
    xml布局:

     

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"                xmlns:tools="http://schemas.android.com/tools"                android:orientation="vertical"                android:layout_width="match_parent"                android:layout_height="match_parent">    <cn.xindrace.viewflip.FlipView        android:id="@+id/flip_view"        android:layout_width="match_parent"        android:layout_height="match_parent"/>    <LinearLayout        android:id="@+id/root_ll1"        android:orientation="vertical"        android:layout_width="wrap_content"        android:layout_height="wrap_content">        <TextView            android:layout_width="match_parent"            android:layout_height="match_parent"            android:text="It is the first side"/>    </LinearLayout>    <LinearLayout        android:id="@+id/root_ll2"        android:orientation="vertical"        android:layout_width="wrap_content"        android:layout_height="wrap_content">        <TextView            android:layout_width="match_parent"            android:layout_height="match_parent"            android:text="It is the first side"/>    </LinearLayout></LinearLayout>

    




Android 自訂實現翻轉卡片的View

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.