Android custom View for flipped cards

Source: Internet
Author: User
Tags image flip

Android custom View for flipped cards

Generally, a View has only one side, but you can customize a View to achieve the flip effect like a book flip.

Rotating View:


/*** Construct a flip card in two ways ** 1: directly provide a View in a specific naming format * 2: provide two linear la S (front and back) * 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; // The current view private Context context; public FlipView (Context cont Ext) {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_l L. setOnClickListener (this); m_second_ll.setOnClickListener (this); addView (view, ViewGroup. layoutParams. MATCH_PARENT, ViewGroup. layoutParams. MATCH_PARENT);}/*** @ param ll1 front * @ param ll2 back */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. layoutPa Rams. MATCH_PARENT, ViewGroup. layoutParams. MATCH_PARENT); addView (m_second_ll, ViewGroup. layoutParams. MATCH_PARENT, ViewGroup. layoutParams. MATCH_PARENT);}/*** flag = 0 flip to front * flag = 1 flip to back * @ 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 RotateAnim Ation (cX, cY, RotateAnimation. ROTATE_DECREASE); else if (flag = 1) rotateAnim = new round (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, Rotate Animation. 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 (latency & 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 );}}}
Let's take a look at the usage:



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);/********** the first method (to actively call initViews) * *********** // firstLL = (LinearLayout) LayoutInflater. from (this ). inflate (R. layout. flip_view1, null); // secondLL = (LinearLayout) LayoutInflater. from (this ). inflate (R. layout. flip_view2, null);/********** second method **************/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 );}}
Since a View has two sides, you need to actively set the front and back content.



FlipView. addViews (firstLL, secondLL); the first parameter is the front view, and the second parameter is the opposite view. Both views are linear. I provide two ways to set the front and back sides. If you have a little understanding about the layout, this is actually the same

Rotation tool class (refer to others online ):

When the public class RotateAnimation extends Animation {/** value is true, you can clearly view the Animation rotation direction. */Public static final boolean DEBUG = false;/** the value is displayed along the positive side of the Y axis. If the value is reduced by 1, the animation rotates counterclockwise. */Public static final boolean ROTATE_DECREASE = true;/** it is displayed along the positive side of the Y axis. If the value is reduced by 1, the animation rotates clockwise. */Public static final boolean ROTATE_INCREASE = false;/** maximum depth on the Z axis. */Public static final float DEPTH_Z = 310.0f;/** animation display duration. */Public static final long DURATION = 800l;/** image flip type. */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; // set the animation DURATION setDuration (DURATION) ;}@ Overridepublic void initialize (int width, int height, int parentWidth, int parentHeight) {// call this method after the constructor and before applyTransformation. Super. initialize (width, height, parentWidth, parentHeight); camera = new Camera ();} @ Overrideprotected void applyTransformation (float interpolatedTime, Transformation transformation) {// interpolatedTime: Specifies the animation progress value, the value range is 0 ~ 1, 0.5 is just half flipped 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;} // Rotation Angle float degree = from + (to-from) * interpolatedTime; boolean overHalf = (interpolatedTime> 0.5f); if (overHalf) {// if you flip over half of the text, you need to flip 180 degrees to ensure that the number is still readable text rather than mirroring. Degree = degree-180;} // rotation depth float depth = (0.5f-Math. abs (interpolatedTime-0.5f) * DEPTH_Z; final Matrix matrix = transformation. getMatrix (); camera. save (); // depth -- the distance from the screen to camera. translate (0.0f, 0.0f, depth); // rotate on the X axis // camera. rotateX (degree); // rotate camera with the Y axis. rotateY (degree); camera. getMatrix (matrix); camera. restore (); if (DEBUG) {if (overHalf) {matrix. preTranslate (-centerX * 2,-centerY); matrix. pos TTranslate (centerX * 2, centerY) ;}} else {// ensure that the image flip process is always at the center of the component./** preTranslate refers to the translation before setScale, postTranslate refers to the Translation after setScale. Their parameters are the translation distance, * rather than the coordinates of the destination! * Since the scale is centered on (), to align the center of the interface with (), preTranslate (-centerX, *-centerY) is required. After setScale is complete, call postTranslate (centerX, * centerY) and move the image back. The animation effect is that the screen image of the activity is continuously scaled from the center. * Note: centerX and centerY are coordinates of the center of the interface */matrix. preTranslate (-centerX,-centerY); matrix. postTranslate (centerX, centerY) ;}/ ** listens on the animation progress. Content to be updated when the value is over half. */Private InterpolatedTimeListener listener; public void setInterpolatedTimeListener (InterpolatedTimeListener listener) {this. listener = listener;}/** specifies the animation progress listener. */Public static interface InterpolatedTimeListener {public void interpolatedTime (float interpolatedTime );}}









Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

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.