How to zoom an item in a recyclerview when the user touches it?

我是研究僧i 提交于 2020-12-04 08:51:54

问题


I am developing an application in which should have a vertical Recyclerview in which the items will be enlarged when touched by users and decreased when the user releases them.

In my research I have not found a way to build it. The most similar to what I look for are the Facebook reactions as in the GIF below.

facebook reactions

How can I do it? Thanks in advance


回答1:


Аll items are visible to user, there is no views to recycle. So IMHO RecyclerView here is redundant. I suggest you to use separate Views. As I understand the main difficulty here is animation. This type of animations can be easily done with Transition API. Just change image sizes then call TransitionManager.beginDelayedTransition with Transition which will animate all changes. In this example changes are simple, default AutoTransition can animate them. Here is my implementation:

import androidx.appcompat.app.AppCompatActivity;
import androidx.transition.AutoTransition;
import androidx.transition.Transition;
import androidx.transition.TransitionManager;

public class MainActivity extends AppCompatActivity {

    private ViewGroup parent;

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

        parent = findViewById(R.id.parent);

        for (int i = 0; i < parent.getChildCount(); i++) {
            int position = i;
            parent.getChildAt(i).setOnClickListener(v -> {
                onImageClicked(position);
            });
        }
    }

    private void onImageClicked(int position) {
        Transition transition = new AutoTransition();
        TransitionManager.beginDelayedTransition(parent, transition);

        int SIZE_MAX = dpToPx(100);
        int SIZE_MIN = dpToPx(40);

        for (int i = 0; i < parent.getChildCount(); i++) {
            View childAt = parent.getChildAt(i);
            int size = i == position ? SIZE_MAX : SIZE_MIN;
            childAt.setLayoutParams(new LayoutParams(size, size));
        }
    }

    public int dpToPx(int dp) {
        return (int) (dp * getResources().getDisplayMetrics().density);
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#eee">

    <View
        app:layout_constraintBottom_toBottomOf="@+id/parent"
        app:layout_constraintLeft_toLeftOf="@+id/parent"
        app:layout_constraintRight_toRightOf="@+id/parent"
        android:layout_width="300dp"
        android:layout_height="50dp"
        android:layout_centerInParent="true"
        android:background="#50b0" />

    <LinearLayout
        android:id="@+id/parent"
        android:layout_width="300dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        android:gravity="bottom"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <include layout="@layout/image" />
        <include layout="@layout/image" />
        <include layout="@layout/image" />
        <include layout="@layout/image" />
        <include layout="@layout/image" />
        <include layout="@layout/image" />
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

image.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="50dp"
    android:layout_height="50dp"
    android:src="@drawable/circle"
    android:scaleType="centerCrop"/>

At start each image size is 50dp. Total width is 6*50 =300dp. After click selected image size is 100dp, others are 40dp so total width is 100+5*40=300dp. I mean that why total width doesn't change while clicking.

You can put GIFs into ImageView instead of my red circles with Glide or other library. Another thing is you need to move animation logic from click events to touch events.




回答2:


<!-- This initially-hidden ImageView will hold the expanded/zoomed version of
     the images above. Without transformations applied, it takes up the entire
     screen. To achieve the "zoom" animation, this view's bounds are animated
     from the bounds of the thumbnail button above, to its final laid-out
     bounds.
     -->

<ImageView
    android:id="@+id/expanded_image"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="invisible"
    android:contentDescription="@string/description_zoom_touch_close" />

visit https://developer.android.com/training/animation/zoom for more detail



来源:https://stackoverflow.com/questions/57729483/how-to-zoom-an-item-in-a-recyclerview-when-the-user-touches-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!