2015-06-20 8 views
60

Per https://developer.android.com/training/material/animations.htmlRund offenbaren Übergang für neue Aktivität

Die ViewAnimationUtils.createCircularReveal() Methode ermöglicht es Ihnen, belebtes einen Beschneidungs ​​Kreis, um eine Ansicht ein- oder auszublenden.

Um eine bisher unsichtbare Ansicht mit dieser Wirkung zeigen:

// previously invisible view 
View myView = findViewById(R.id.my_view); 

// get the center for the clipping circle 
int cx = (myView.getLeft() + myView.getRight())/2; 
int cy = (myView.getTop() + myView.getBottom())/2; 

// get the final radius for the clipping circle 
int finalRadius = Math.max(myView.getWidth(), myView.getHeight()); 

// create the animator for this view (the start radius is zero) 
Animator anim = 
    ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius); 

// make the view visible and start the animation 
myView.setVisibility(View.VISIBLE); 
anim.start(); 

Dieser Blick offenbaren gemeint ist. Wie kann ich dies verwenden, um eine gesamte Aktivität ohne gemeinsame Elemente anzuzeigen?

Konkret möchte ich, dass meine searchActivity von der Suchaktionsschaltfläche in der Symbolleiste kreisförmig anzeigt.

+0

Haben Sie Glück dabei? – StuStirling

+0

Nein. Ich suche nicht mehr aktiv danach. –

Antwort

73

Nach einer Lösung für einen halben Tag ohne Ergebnis suchte ich eine eigene Implementierung. Ich verwende eine transparente Aktivität mit einem übereinstimmenden Stammlayout. Das Root-Layout ist eine Ansicht, die dann mit createCircularReveal() angezeigt werden kann.

Mein Code sieht wie folgt aus:

Thema Definition in styles.xml

<style name="Theme.Transparent" parent="Theme.AppCompat.Light.NoActionBar"> 
    <item name="android:windowIsTranslucent">true</item> 
    <item name="android:statusBarColor">@android:color/transparent</item> 
    <item name="android:windowBackground">@android:color/transparent</item> 
</style> 

Aktivität Definition in AndroidManifest.xml

<activity 
     android:name=".ui.CircularRevealActivity" 
     android:theme="@style/Theme.Transparent" 
     android:launchMode="singleTask" 
     /> 

dann erklärte ich ein Layout für Meine Aktivität (Ich habe DrawerLayout gewählt, damit ich einen NavDrawer haben kann. Eve ry Layout soll hier arbeiten.)

<android.support.v4.widget.DrawerLayout 
    android:id="@+id/drawer_layout" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    > 

    <FrameLayout 
     android:id="@+id/root_layout" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:background="@color/honey_melon" 
     > 

     <!-- Insert your actual layout here --> 

    </FrameLayout> 

</android.support.v4.widget.DrawerLayout> 

wichtig, die FrameLayout mit dem root_layout id ist. Diese Ansicht wird in der Aktivität angezeigt.

Schließlich implementiert ich CircularRevealActivity und überschrieb onCreate():

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    overridePendingTransition(R.anim.do_not_move, R.anim.do_not_move); 

    setContentView(R.layout.activity_reveal_circular); 

    if (savedInstanceState == null) { 
     rootLayout.setVisibility(View.INVISIBLE); 

     ViewTreeObserver viewTreeObserver = rootLayout.getViewTreeObserver(); 
     if (viewTreeObserver.isAlive()) { 
      viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
       @Override 
       public void onGlobalLayout() { 
        circularRevealActivity(); 
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 
         rootLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
        } else { 
         rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
        } 
       } 
      }); 
     } 
    } 
} 

Es war wichtig, circularRevealActivity() in eine OnGlobalLayoutListener zu setzen, denn die Aussicht für die Animation gezogen werden muss.

circularRevealActivity() sieht aus wie Ishaan Vorschlag:

private void circularRevealActivity() { 

    int cx = rootLayout.getWidth()/2; 
    int cy = rootLayout.getHeight()/2; 

    float finalRadius = Math.max(rootLayout.getWidth(), rootLayout.getHeight()); 

    // create the animator for this view (the start radius is zero) 
    Animator circularReveal = ViewAnimationUtils.createCircularReveal(rootLayout, cx, cy, 0, finalRadius); 
    circularReveal.setDuration(1000); 

    // make the view visible and start the animation 
    rootLayout.setVisibility(View.VISIBLE); 
    circularReveal.start(); 
} 

bearbeiten 1

Die Definition für R.anim.do_not_move hinzugefügt wurde. Es sollte jedoch auch ohne diese Zeile funktionieren, wenn Ihr Design keine Standardübergänge für Aktivitäten angibt. Lassen Sie mich

R.anim.do_not_move wissen:

<set xmlns:android="http://schemas.android.com/apk/res/android"> 
<translate 
    android:fromYDelta="0" 
    android:toYDelta="0" 
    android:duration="@android:integer/config_mediumAnimTime" 
    /> 
</set> 
+0

Danke für solch eine ausführliche Antwort. Funktioniert es für dich? Ich werde es diese Woche ausprobieren. –

+0

Arbeiten wie ein Charme für mich. Ich hatte einfach das Gefühl, dass diese kreisförmige Enthüllung möglich sein sollte, ohne zwei Aktivitäten in einem zusammenzufassen ... Wenn es Probleme gibt, lassen Sie es mich wissen. –

+1

funktioniert gut. Ich änderte den cx und cy Wert, um den Ursprungspunkt zu ändern – ch3tanz

7

die startRadius und endRadius Argumente die CircularReveal Animation Swap umkehren.Außerdem müssen Sie eine AnimatorListener und in der onAnimationEnd() Callback-Methode einrichten, wo Sie finishAfterTransition() aufrufen können. Dies ist, wenn Sie die up navigation drücken oder klicken Sie auf die back button.

+0

Sie sollten sagen, wie Sie die umgekehrte Animation im Detail erreichen können. – Pei

4
+1

Funktioniert nur auf APi 23+, ansonsten Standard-Animation –

+0

Wie auch immer, um diese auf der Rückseite zu verwenden, um zu früheren Aktivitäten zurückzukehren? – Dahnark

1

ou haben den Kreis Ansicht zu ziehen, und danach sollten Sie eine Animation erstellen Sie es .

den Kreis Ansicht erstellen:

public class Circle extends View { 

    private static final int START_ANGLE_POINT = 90; 

    private final Paint paint; 
    private final RectF rect; 

    private float angle; 

    public Circle(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     final int strokeWidth = 40; 

     paint = new Paint(); 
     paint.setAntiAlias(true); 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setStrokeWidth(strokeWidth); 
     //Circle color 
     paint.setColor(Color.RED); 

     //size 200x200 example 
     rect = new RectF(strokeWidth, strokeWidth, 200 + strokeWidth, 200 + strokeWidth); 

     //Initial Angle (optional, it can be zero) 
     angle = 120; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     canvas.drawArc(rect, START_ANGLE_POINT, angle, false, paint); 
    } 

    public float getAngle() { 
     return angle; 
    } 

    public void setAngle(float angle) { 
     this.angle = angle; 
    } 
} 

die Animation Klasse Erstellen des neuen Blickwinkel zu setzen:

public class CircleAngleAnimation extends Animation { 

    private Circle circle; 

    private float oldAngle; 
    private float newAngle; 

    public CircleAngleAnimation(Circle circle, int newAngle) { 
     this.oldAngle = circle.getAngle(); 
     this.newAngle = newAngle; 
     this.circle = circle; 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation transformation) { 
     float angle = oldAngle + ((newAngle - oldAngle) * interpolatedTime); 

     circle.setAngle(angle); 
     circle.requestLayout(); 
    } 
} 

Put Kreis in Ihr Layout:

<com.package.Circle 
    android:id="@+id/circle" 
    android:layout_width="300dp" 
    android:layout_height="300dp" /> 

Und endlich beginnen, die Animation:

Circle circle = (Circle) findViewById(R.id.circle); 

CircleAngleAnimation animation = new CircleAngleAnimation(circle, 240); 
animation.setDuration(1000); 
circle.startAnimation(animation); 
+0

das ist nicht wat user gefragt, aber trotzdem hat mir das sehr geholfen –

4

Wenn Sie die kreisförmige Laibung beim Verlassen der Aktivität umkehren möchten, verwenden Sie die folgende Änderung an onBackPressed().

@Override 
public void onBackPressed() { 

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     int cx = rootLayout.getWidth(); 
     int cy = 0; 
     float finalRadius = Math.max(rootLayout.getWidth(), rootLayout.getHeight()); 
     Animator circularReveal = ViewAnimationUtils.createCircularReveal(rootLayout, cx, cy, finalRadius, 0); 

     circularReveal.addListener(new Animator.AnimatorListener() { 
      @Override 
      public void onAnimationStart(Animator animator) { 

      } 

      @Override 
      public void onAnimationEnd(Animator animator) { 
       rootLayout.setVisibility(View.INVISIBLE); 
       finish(); 
      } 

      @Override 
      public void onAnimationCancel(Animator animator) { 

      } 

      @Override 
      public void onAnimationRepeat(Animator animator) { 

      } 
     }); 
     circularReveal.setDuration(400); 
     circularReveal.start(); 
    }else{ 
     super.onBackPressed(); 
    } 
} 
Verwandte Themen