2016-10-19 7 views
0

Ряби из точки касанияКак установить карту зрения рябь?

Google начало указывать разработчик приложений, когда они используют пульсацию анимацию в Material Design стилизованного UIs, где эта зыбь, кажется, не исходит из точки касания, инициировавшая анимации.

Использование поисковой системы Google, единственное, что я нашел, которое, казалось, объясняло, как сделать эту работу, было комментарий к проблеме в библиотеке TwoWayView от Lucas Rocha. К счастью, этого комментария было достаточно для меня, чтобы создать что-то, что, кажется, работает.

Как мистер Мясник намекает в своем твиттере, ключ представляется методом setHotspot() на Drawable. Добавленный в API Level 21, это учит рисовать «горячую точку», и RippleDrawable, по-видимому, использует это как точку эманации для эффекта пульсации. setHotspot() принимает пару значений поплавка, предположительно, с помощью функции setHotspot() внутри OnTouchListener, поскольку MotionEvent сообщает о позициях X/Y события касания со значениями float.

Это пример приложения демонстрирует использование setHotspot() в контексте RecyclerView, как часть главы более 50 страниц, над которой я работаю для следующего обновления книги. Этот RecyclerView использует LinearLayoutManager для репликации базовой структуры классического ListView. Мои строки основаны на CardView:

`` `XML

Таким образом, если пользователь касается строки, я размножать точки касания к фону, как его точки доступа. Я специально возвращаю false, чтобы указать, что мы не потребляем событие touch, поэтому оно будет продолжаться до остальных обработчиков событий, если это необходимо.

Без этого вызова setHotspot(), RippleDrawable, по-видимому, по умолчанию для центра drawable. Таким образом, в случае строки для RecyclerView в стиле списка эффект рябь будет исходить из центра строки. setHotspot(), привязанный к событию касания, изменяет точку эманации.

<?xml version="1.0" encoding="utf-8"?> 
 
<android.support.v7.widget.CardView 
 
    xmlns:android="http://schemas.android.com/apk/res/android" 
 
    xmlns:cardview="http://schemas.android.com/apk/res-auto" 
 
    android:layout_width="match_parent" 
 
    android:layout_height="wrap_content" 
 
    android:layout_margin="4dp" 
 
    cardview:cardCornerRadius="4dp"> 
 

 
    <LinearLayout 
 
    android:id="@+id/row_content" 
 
    android:layout_width="match_parent" 
 
    android:layout_height="wrap_content" 
 
    android:orientation="horizontal" 
 
    android:background="?android:attr/selectableItemBackground"> 
 

 
    <!-- other widgets in here --> 
 

 
    </LinearLayout> 
 

 
    </LinearLayout> 
 

 
</android.support.v7.widget.CardView> 
 
``` 
 

 
The LinearLayout that the CardView wraps has ?android:attr/selectableItemBackground as its background, pulling in a theme attribute. If this app runs on API Level 21, that background will be a RippleDrawable. 
 

 
When I set up the row, I attach an OnTouchListener to set the hotspot, but only on API Level 21+ devices (as setHotspot() does not exist before then): 
 

 
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
 
    row.setOnTouchListener(new View.OnTouchListener() { 
 
    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
 
    @Override 
 
    public boolean onTouch(View v, MotionEvent event) { 
 
     v 
 
     .findViewById(R.id.row_content) 
 
     .getBackground() 
 
     .setHotspot(event.getX(), event.getY()); 
 

 
     return(false); 
 
    } 
 
    }); 
 
}

Это похоже на работу. Я понятия не имею, является ли это официальным правильным ответом, поскольку я не видел никакого кода из Google для того, как его реализовать (например, поиск образцов SDK для setHotspot() ничего не вызывает). В частности, вызов setHotspot() непосредственно на фоне меня беспокоит (нужно ли сначала вызвать mutate()?). Итак, представьте себе зерно соли, размером около 15 см на боку, и возьмите это зерно соли с этой реализацией.

ответ

0

Показать анимации обеспечивают зрительскую непрерывность при показе или скрыть группу элементов пользовательского интерфейса. Метод ViewAnimationUtils.createCircularReveal() позволяет вам анимировать обтравочный круг, чтобы открыть или скрыть представление.

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

View myView = findViewById(R.id.my_view); 

// get the center for the clipping circle 
int cx = myView.getWidth()/2; 
int cy = myView.getHeight()/2; 

// get the final radius for the clipping circle 
float finalRadius = (float) Math.hypot(cx, cy); 

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

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

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

// get the center for the clipping circle 
int cx = myView.getWidth()/2; 
int cy = myView.getHeight()/2; 

// get the initial radius for the clipping circle 
float initialRadius = (float) Math.hypot(cx, cy); 

// create the animation (the final radius is zero) 
Animator anim = 
    ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0); 

// make the view invisible when the animation is done 
anim.addListener(new AnimatorListenerAdapter() { 
    @Override 
    public void onAnimationEnd(Animator animation) { 
     super.onAnimationEnd(animation); 
     myView.setVisibility(View.INVISIBLE); 
    } 
}); 

// start the animation 
anim.start();