【问题标题】:RecyclerView Animation on Item Click项目单击时的 RecyclerView 动画
【发布时间】:2014-12-24 22:22:43
【问题描述】:

我正在尝试实现我自己的 recyclerview 动画 - 我想在不使用任何外部库的情况下实现这一目标。这是理论上的动画应该的样子。

用户单击列表上的一个项目,然后会出现一个打开另一个视图的动画。

在高层次上用最少的代码,可能只是伪代码为了创建一些这样的动画,流程是什么?

另外我想指出,如果用户点击同一个项目或另一个项目,动画也应该能够反向完成

我对@9​​87654323@ 类不是很熟悉,想了解更多关于它以及与之相关的动画。

【问题讨论】:

  • 你见过this question吗?
  • 我认为您需要自己进行研究,然后发布具体问题。对我来说,这只是一个太大的问题,并带来了任何研究,这应该看起来像我怎样才能让它工作。我的想法。总之祝你圣诞快乐! ;)
  • Tanis 谢谢我没有看到这个问题,但我的思路是正确的,因为在 RecyclerView 中更多地强调了 ViewHolder - 所以我的想法是编写一个自定义视图来保存展开布局并将 onItemClickListener 或 onItemTouchListener 绑定到列表项。

标签: android animation touch android-recyclerview onitemclick


【解决方案1】:

解决方案:

我解决这个问题的方法是实现一个监听器View.OnClickListenerViewHolderextends RecyclerView.ViewHolder。于是我们得到如下代码:

public static class ExampleViewHolder extends RecyclerView.ViewHolder 
    implements View.OnClickListener {

    private int originalHeight = 0;
    private boolean isViewExpanded = false;
    private YourCustomView yourCustomView

    // ..... CODE ..... //

}

在动画过程中使用了变量originalHeightisViewExpanded。在构造函数中,我将视图初始化为View.OnClickListener,如下所示:

public ExampleViewHolder(View v) {
     super(v);
     v.setOnClickListener(this);

     // Initialize other views, like TextView, ImageView, etc. here

     // If isViewExpanded == false then set the visibility 
     // of whatever will be in the expanded to GONE

     if (isViewExpanded == false) {
         // Set Views to View.GONE and .setEnabled(false)
         yourCustomView.setVisibility(View.GONE);
         yourCustomView.setEnabled(false);
     }

 }

现在构造函数已经处理好了,我们要配置当用户单击单个 RecyclerView 项目时会发生什么。这里有用的类是ValueAnimatorAnimation 对象。我们像这样重写onClick 方法来完成这个:

@Override
public void onClick(final View view) {
    // If the originalHeight is 0 then find the height of the View being used 
    // This would be the height of the cardview
    if (originalHeight == 0) {
            originalHeight = view.getHeight();
        }

    // Declare a ValueAnimator object
    ValueAnimator valueAnimator;
        if (!mIsViewExpanded) {
            yourCustomView.setVisibility(View.VISIBLE);
            yourCustomView.setEnabled(true);
            mIsViewExpanded = true;
            valueAnimator = ValueAnimator.ofInt(originalHeight, originalHeight + (int) (originalHeight * 2.0)); // These values in this method can be changed to expand however much you like
        } else {
            mIsViewExpanded = false;
            valueAnimator = ValueAnimator.ofInt(originalHeight + (int) (originalHeight * 2.0), originalHeight);

            Animation a = new AlphaAnimation(1.00f, 0.00f); // Fade out

            a.setDuration(200);
            // Set a listener to the animation and configure onAnimationEnd
            a.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    yourCustomView.setVisibility(View.INVISIBLE);
                    yourCustomView.setEnabled(false);
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });

            // Set the animation on the custom view
            yourCustomView.startAnimation(a);
        }
        valueAnimator.setDuration(200);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            public void onAnimationUpdate(ValueAnimator animation) {
                Integer value = (Integer) animation.getAnimatedValue();
                view.getLayoutParams().height = value.intValue();
                view.requestLayout();
            }
        });


        valueAnimator.start();

    }

现在,当您在 RecyclerView 上触摸单个卡片视图时(假设您有 CardView 设置,那么它应该展开。确保在您的 xml 文件中正确声明您的 customView(例如,如果您想要 CardView当您触摸它时向下展开,然后在其他视图下方正确分配 customView 并在声明它时将可见性设置为消失,然后当动画开始时,如上面的代码中那样,然后将可见性设置为 Visible 并启用视图。

希望这可以帮助某人。

【讨论】:

  • 感谢 AndyRoid!这对我真的很有帮助。在我的情况下,CardView 的高度因每个项目而异,但“CustomView”对于所有项目都是相同的。是否可以计算卡片在不可见的情况下完全展开所需的高度?在我的情况下,使用 originalHeight * x 不起作用。
  • 为什么要感谢?如果您有更多项目,向上或向下屏幕的错误,请使用标签:)
  • 我使用了类似的解决方案,但是有问题。扩展视图下方的所有视图都将卡入到位,但我希望它们顺利向下移动。 @AndyRoid,你有同样的行为吗?
【解决方案2】:

@AndyRoid 答案的一个更简单的替代方法是使用 android:animateLayoutChanges="true" 属性。这样你就不需要写任何动画代码了;但是,如果您需要控制动画,这不是一个可行的方法。

你仍然需要创建一个OnClickListener

class CardTapListener implements View.OnClickListener {
    @Override
    public void onClick(View v) {
        View someView = v.findViewById(R.id.view_to_expand);

        if (someView.getVisibility() == View.GONE) {
            someView.setVisibility(View.VISIBLE);
        }
        else if (someView.getVisibility() == View.VISIBLE){
            someView.setVisibility(View.GONE);
        }

    }
}

附加到每个ViewHolder:

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_layout, viewGroup, false);
    v.setOnClickListener(new CardTapListener());
    return new ItemViewHolder(v);
}

绑定新项目时不要忘记折叠视图:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
    ...
    // Collapse (probably opened by user previously) view
    ItemViewHolder itemHolder = (ItemViewHolder) viewHolder;
    itemHolder.description.setVisibility(View.GONE);
    ...

}

view_holder_layout.xml:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:animateLayoutChanges="true"
    android:orientation="vertical">

 ...

    <AnyViewHere
        android:visibility="gone"
        android:id="@+id/view_to_expand" />

 </LinearLayout>

【讨论】:

    猜你喜欢
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多