2013-04-16 8 views
24

पर कार्ड फ्लिप एनीमेशन प्रदर्शित करना हम सभीका उपयोग करके "card filp" एनिमेशन बनाने के तरीके के बारे में article जानते हैं। लेकिन मैं यह on apis < 3.0 कैसे बना सकता हूं?पुराने एंड्रॉइड

अद्यतन:

जब तक अच्छा और आसान से उपयोग android-FlipView तरह पुस्तकालयों मुझे नहीं लगता कि आप वास्तव में इस तरह के कठिन तरीकों के माध्यम से जाने की जरूरत है वहाँ के रूप में ...

उत्तर

57

मिले जवाब।

गतिविधि लेआउट फ़ाइल:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/main_activity_root" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:background="@android:color/transparent" > 

<RelativeLayout 
android:id="@+id/main_activity_card_face" 
android:layout_width="300dp" 
android:layout_height="407dp" 
android:layout_centerHorizontal="true" 
android:layout_centerVertical="true" 
android:background="@drawable/front" 
android:clickable="true" 
android:onClick="onCardClick" 
android:padding="5dp" > 
</RelativeLayout> 

<RelativeLayout 
android:id="@+id/main_activity_card_back" 
android:layout_width="300dp" 
android:layout_height="407dp" 
android:layout_centerHorizontal="true" 
android:layout_centerVertical="true" 
android:background="@drawable/back" 
android:clickable="true" 
android:onClick="onCardClick" 
android:visibility="gone" > 
</RelativeLayout> 

</RelativeLayout> 

लेआउट फ़ाइल दो दृश्य समूहों flips के रूप में आप दृश्य समूह के अंदर कुछ और डाल सकता है और यह काम करना चाहिए आप ALL ANDROID VERSIONS पर फ्लिप एनीमेशन करना चाहते हैं, इस का उपयोग करें।

public void onCardClick(View view) 
{ 
     flipCard(); 
} 

private void flipCard() 
{ 
    View rootLayout = findViewById(R.id.main_activity_root); 
    View cardFace = findViewById(R.id.main_activity_card_face); 
    View cardBack = findViewById(R.id.main_activity_card_back); 

    FlipAnimation flipAnimation = new FlipAnimation(cardFace, cardBack); 

    if (cardFace.getVisibility() == View.GONE) 
    { 
     flipAnimation.reverse(); 
    } 
    rootLayout.startAnimation(flipAnimation); 
} 

और अंत में FlipAnimation वर्ग:: अब गतिविधि के अंदर तरीकों जो फ्लिप एनीमेशन कोड बुला हैंडल पर देखने की सुविधा देता है

public class FlipAnimation extends Animation 
{ 
    private Camera camera; 

    private View fromView; 
    private View toView; 

    private float centerX; 
    private float centerY; 

    private boolean forward = true; 

    /** 
    * Creates a 3D flip animation between two views. 
    * 
    * @param fromView First view in the transition. 
    * @param toView Second view in the transition. 
    */ 
    public FlipAnimation(View fromView, View toView) 
    { 
     this.fromView = fromView; 
     this.toView = toView; 

     setDuration(700); 
     setFillAfter(false); 
     setInterpolator(new AccelerateDecelerateInterpolator()); 
    } 

    public void reverse() 
    { 
     forward = false; 
     View switchView = toView; 
     toView = fromView; 
     fromView = switchView; 
    } 

    @Override 
    public void initialize(int width, int height, int parentWidth, int parentHeight) 
    { 
     super.initialize(width, height, parentWidth, parentHeight); 
     centerX = width/2; 
     centerY = height/2; 
     camera = new Camera(); 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) 
    { 
     // Angle around the y-axis of the rotation at the given time 
     // calculated both in radians and degrees. 
     final double radians = Math.PI * interpolatedTime; 
     float degrees = (float) (180.0 * radians/Math.PI); 

     // Once we reach the midpoint in the animation, we need to hide the 
     // source view and show the destination view. We also need to change 
     // the angle by 180 degrees so that the destination does not come in 
     // flipped around 
     if (interpolatedTime >= 0.5f) 
     { 
      degrees -= 180.f; 
      fromView.setVisibility(View.GONE); 
      toView.setVisibility(View.VISIBLE); 
     } 

     if (forward) 
      degrees = -degrees; //determines direction of rotation when flip begins 

     final Matrix matrix = t.getMatrix(); 
     camera.save(); 
     camera.rotateY(degrees); 
     camera.getMatrix(matrix); 
     camera.restore(); 
     matrix.preTranslate(-centerX, -centerY); 
     matrix.postTranslate(centerX, centerY); 
    } 

यहाँ मूल पोस्ट के लिए लिंक है: Displaying card flip animation on old android

@FMMobileFelipeMenezes से अद्यतन करें।

final Matrix matrix = t.getMatrix(); 
camera.save(); 
camera.translate(0, 0, Math.abs(degrees)*2); 
camera.getMatrix(matrix); 
camera.rotateY(degrees); 
camera.getMatrix(matrix); 
camera.restore(); 
matrix.preTranslate(-centerX, -centerY); 
matrix.postTranslate(centerX, centerY); 

अद्यतन @Hesam से अच्छा ट्यूटोरियल है कि मैं इसे पढ़ने के लिए सलाह देते हैं नहीं है:

यदि आप एक चिकनी पैमाने फ्लिप करने के साथ एनीमेशन चाहते हैं, कोड के इस भाग (applyTransformation) करने के लिए बदल । हालांकि यह टुकड़ों के आधार पर एंड्रॉइड ट्यूटोरियल जितना अच्छा नहीं है, लेकिन यदि आप लेआउट और विचारों के साथ-साथ पुराने एपीआई पर एनीमेशन असाइन करना चाहते हैं तो इसे पढ़ने और उपयोगी होने के लायक है।

Use Android's scale animation to simulate a 3D flip

Improved project on github by @LenaBru

+1

आप कमाल कर रहे हैं! – David

+0

बढ़िया! इस भयानक कोड के लिए आपको टैंक करें। केवल एक प्रश्न: मैं एक टुकड़े में कैसे घुमा सकता हूं जो वर्तमान गतिविधि में नहीं है? मैं फ्रैगमेंट से 'Fragment.getView()' के साथ दृश्य प्राप्त कर सकता हूं लेकिन फिर अगर मैं एनीमेशन शुरू करता हूं तो यह एक त्रुटि की बात आती है। – Cilenco

+0

सिलेंको, खंड वर्ग को फिर से परिभाषित करने का प्रयास करें और इस कोड को अंदर रखें। या एक एक्शन श्रोता बनाएँ। वैसे भी मुझे यकीन है कि अगर वह मदद नहीं है। अभी तक टुकड़ों से निपटें नहीं। –

2

अच्छा ट्यूटोरियल है कि मैं इसे पढ़ने के लिए सलाह देते हैं नहीं है। हालांकि यह टुकड़ों के आधार पर एंड्रॉइड ट्यूटोरियल जितना अच्छा नहीं है, लेकिन यदि आप लेआउट और विचारों के साथ-साथ पुराने एपीआई पर एनीमेशन असाइन करना चाहते हैं तो इसे पढ़ने और उपयोगी होने के लायक है।

Use Android's scale animation to simulate a 3D flip

7

मैं नीचे Flextra कोड का इस्तेमाल किया, और यदि आप एक चिकनी पैमाने फ्लिप करने के साथ एनीमेशन चाहते हैं, (applyTransformation) के लिए कोड के इस भाग को बदलें:

final Matrix matrix = t.getMatrix(); 
    camera.save(); 
    camera.translate(0, 0, Math.abs(degrees)*2); 
    camera.getMatrix(matrix); 
    camera.rotateY(degrees); 
    camera.getMatrix(matrix); 
    camera.restore(); 
    matrix.preTranslate(-centerX, -centerY); 
    matrix.postTranslate(centerX, centerY); 
5

मैं यह सब के साथ खेला दिन, और आखिरकार अंतिम लक्ष्य हासिल किया - दो दृश्यों की रोटेशन एनीमेशन जैसी चिकनी कार्डफ्लिप!

मैं डेमो परियोजना डाल here

public class FlipAnimation extends Animation { 
    private Camera camera; 

    private View fromView; 
    private View toView; 

    private float centerX; 
    private float centerY; 

    private boolean forward = true; 


    /** 
    * Creates a 3D flip animation between two views. 
    * 
    * @param fromView 
    *   First view in the transition. 
    * @param toView 
    *   Second view in the transition. 
    */ 
    public FlipAnimation(View fromView, View toView) { 
     this.fromView = fromView; 
     this.toView = toView; 

     setDuration(1500); 
     setFillAfter(false); 
     // setInterpolator(new AccelerateDecelerateInterpolator()); 
     setInterpolator(new LinearInterpolator()); 
    } 

    public void reverse() { 

     if (forward) { 
      View switchView = toView; 
      toView = fromView; 
      fromView = switchView; 
     } 
     forward = false; 
    } 

    @Override 
    public void initialize(int width, int height, int parentWidth, int parentHeight) { 
     super.initialize(width, height, parentWidth, parentHeight); 
     centerX = width/2; 
     centerY = height/2; 
     camera = new Camera(); 
    } 


    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     // Angle around the y-axis of the rotation at the given time 
     // calculated both in radians and degrees. 
     final double radians = Math.PI * interpolatedTime; 
     float degrees = (float) (180.0 * radians/Math.PI); 


     //scale down the views a bit, so that they would look nice when the rotation begins 

     if (interpolatedTime <= 0.05f) { 
      fromView.setScaleX(1 - interpolatedTime); 
      fromView.setScaleY(1 - interpolatedTime); 
      toView.setScaleX(1 - interpolatedTime); 
      toView.setScaleY(1 - interpolatedTime); 
     } 

     // Once we reach the midpoint in the animation, we need to hide the 
     // source view and show the destination view. We also need to change 
     // the angle by 180 degrees so that the destination does not come in 
     //It is very important to call "toView.bringToFront()" and not play with the 
     // visibility of the views, because if you apply this animation more than once, 
     //the subsequent calls may fail 
     if (interpolatedTime >= 0.5f) { 
      degrees -= 180.f; 
      toView.bringToFront(); 
      //these two lines force a layout redraw 
      ((View)toView.getParent()).requestLayout(); 
      ((View)toView.getParent()).invalidate(); 


     } 

     //scale the views back to their original size (Assuming original size was 1) 
     if (interpolatedTime >= 0.95f) { 
      fromView.setScaleX(interpolatedTime); 
      fromView.setScaleY(interpolatedTime); 
      toView.setScaleX(interpolatedTime); 
      toView.setScaleY(interpolatedTime); 
     } 

     if (forward) 
      degrees = -degrees; // determines direction of rotation when flip 
           // begins 

     final Matrix matrix = t.getMatrix(); 
     camera.save(); 
     camera.translate(0, 0, Math.abs(degrees) * 2); 
     camera.getMatrix(matrix); 
     camera.rotateY(degrees); 
     camera.getMatrix(matrix); 
     camera.restore(); 
     matrix.preTranslate(-centerX, -centerY); 
     matrix.postTranslate(centerX, centerY); 
    } 
} 

और यह इस

import android.content.Context; 
import android.os.Bundle; 
import android.os.Handler; 
import android.support.v4.app.FragmentActivity; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Toast; 

public class MainActivity extends FragmentActivity { 

private boolean showingBack; 
private FragmentLeft left = new FragmentLeft(); 
private FragmentRight right = new FragmentRight(); 
private Context context; 
private Handler handler; 
private FlipAnimation flipAnimation; 
private FlipAnimation backFlip; 

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

    context = this; 
    handler = new Handler(getMainLooper()); 

    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, right, "fragmentRight").commit(); 
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, left, "fragmentLeft").commit(); 
    findViewById(R.id.flip).setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      flipAnimation = new FlipAnimation(left.getView(), right.getView()); 
      backFlip = new FlipAnimation(left.getView(), right.getView()); 
      handler.removeCallbacks(rotate); 
      handler.postDelayed(rotate, 100); 
     } 

    }); 
} 

    private Runnable rotate = new Runnable() { 

     @Override 
     public void run() { 
      //put a variable showingBack, do not rely on view properties to flip 
      if (!showingBack) { 
       //very important to flip both views, so that when the 
       //left view goes to back and right view goes to front, 
       //the right view finishes the rotation 
       left.getView().startAnimation(flipAnimation); 
       right.getView().startAnimation(flipAnimation); 
       Toast.makeText(context, "flip", Toast.LENGTH_LONG).show(); 
       showingBack = true; 
      } else { 
       showingBack = false; 
       backFlip.reverse(); 
       Toast.makeText(context, "backflip", Toast.LENGTH_LONG).show(); 
       //very important to flip both views, so that when the 
       //right view goes to back and right view goes to front, 
       //the left view finishes the rotation 
       left.getView().startAnimation(backFlip); 
       right.getView().startAnimation(backFlip); 

      } 
     } 
    }; 

} 

इन की तरह फोन के टुकड़े कर रहे हैं

import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

public class FragmentRight extends Fragment { 


    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.fragment_right, container,false); 
    } 
} 

import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

public class FragmentLeft extends Fragment { 


    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.fragment_left, container,false); 
    } 
} 

और अंत में दृश्य ही

activity_main.xml

<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:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    android:background="#ff151515" 
    tools:context="com.example.flipviewtest.MainActivity" > 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/hello_world" /> 

    <FrameLayout 
     android:id="@+id/fragment_container" 
     android:layout_width="200dp" 
     android:layout_height="200dp" 
     android:layout_centerInParent="true" > 
    </FrameLayout> 

    <Button 
     android:id="@+id/flip" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:text="flip" /> 

</RelativeLayout> 

fragment_left.xml

<?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:orientation="vertical" 
    android:background="#ffff0000" 
    > 

    <View 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:background="#ff0ffff0" 
     android:layout_margin="20dp" /> 

</LinearLayout> 

fragment_right.xml

<?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="#ff00ff00" 
    android:orientation="vertical" > 

    <View 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_margin="10dp" 
     android:background="#ff0000ff" /> 

</LinearLayout> 

टिप्पणी Flextra की और @FMMobileFelipeMenezes से लिया कोड के कुछ जवाब देती

+0

एनीमेशन के दौरान पृष्ठभूमि रंग (या छवि) को बदलने के लिए संभव है? – David

संबंधित मुद्दे