2015-06-20 3 views
60

Согласно https://developer.android.com/training/material/animations.htmlКруговые показывают переход к новой деятельности

Метод ViewAnimationUtils.createCircularReveal() позволяет Вам одушевленных обтравочный круг, чтобы раскрыть или скрыть вид.

Чтобы раскрыть ранее невидимый вид использования этого эффекта:

// 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(); 

Это означало, чтобы показать вид. Как я могу использовать это для кругового раскрытия всей деятельности без каких-либо общих элементов?

В частности, я хотел бы, чтобы мой поиск показал, что круговая индикация открывается с помощью кнопки поиска на панели инструментов.

+0

Любые удачи на этом? – StuStirling

+0

Нет. Не активно его искать. –

ответ

73

После поиска решения в течение полудня без результата, я придумал собственную реализацию. Я использую прозрачную активность с подходящим корневым макетом. Корневая компоновка - это вид, который затем может быть обнаружен с помощью createCircularReveal().

Мой код выглядит следующим образом:

Тема Определение в 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> 

активность Определение в AndroidManifest.xml

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

я объявил макет моя работа (я выбрал DrawerLayout, так что у меня может быть NavDrawer. Eve раскладка ры должны работать здесь.)

<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> 

Немаловажным является FrameLayout с идентификатором root_layout. Эта точка зрения будет раскрыта в этой деятельности.

Наконец я реализовал CircularRevealActivity и переписал 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); 
        } 
       } 
      }); 
     } 
    } 
} 

Это было важно, чтобы положить circularRevealActivity() в OnGlobalLayoutListener, потому что вид должен быть нарисован для анимации.

circularRevealActivity() выглядит предложение Ishaan в:

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(); 
} 

Edit 1

было добавлено определение для R.anim.do_not_move. Тем не менее, он должен работать и без этой строки, если в вашем проекте не указаны переходы по умолчанию для действий. Дайте мне знать,

R.anim.do_not_move:

<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

Спасибо за такой сложный ответ. Он работает на вас? Я отдам его на этой неделе. –

+0

Работаю как очарование для меня. У меня просто было ощущение, что это круговое раскрытие должно быть возможным без объединения двух действий в один ... Если есть проблемы, дайте мне знать. –

+1

отлично работает. Я изменил значение cx и cy, чтобы изменить точку начала. – ch3tanz

7

, чтобы полностью изменить CircularReveal анимационные переставляет startRadius и endRadius аргументов.Также вам нужно будет установить AnimatorListener, а в методе обратного вызова onAnimationEnd() вы можете позвонить finishAfterTransition(). Это происходит при нажатии up navigation или на back button.

+0

Вы должны сказать, как добиться обратной анимации в деталях. – Pei

4
+1

Работает только с APi 23+, в противном случае по умолчанию стандартная анимация –

+0

В любом случае, чтобы использовать эту кнопку на задней панели, чтобы вернуться к предыдущей активности? – Dahnark

1

Ты должен сделать вид круга, и после этого вы должны создать анимацию к нему ,

Создание Круговое:

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; 
    } 
} 

Создание класса анимации, чтобы установить новый угол:

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 круг в макете:

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

И, наконец, начиная со анимация:

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

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

Это не нравится, но это все равно помогло мне –

4

Если вы хотите обратить вспять круговое обнаружение при уходе с работы, используйте следующую модификацию 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(); 
    } 
}