当前位置: 首页 > 知识库问答 >
问题:

Android-Swife可以在背景上使用动画来删除RecyclerView

楚嘉玉
2023-03-14

据我所知,为RecolyerView实现一个在被刷项下方有背景的Swipe-to-Dississ的一种可能性(就像在许多google应用程序中一样)是为ItemTouchHelper实现一个简单的回调,并在onChildDraw方法中绘制背景。

这是我的实现:

ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
    // create objects once and avoid allocating them in the onChildDraw method
    Drawable background;
    Drawable icon;
    int iconMargin;
    boolean initialized;

    private void init() {
        background = new ColorDrawable(Color.RED);
        icon = ContextCompat.getDrawable(mAppContext, R.drawable.ic_delete_white_24dp);
        iconMargin = (int) mAppContext.getResources().getDimension(R.dimen.fab_margin);
        initialized = true;
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return false;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
        // remove swiped item from the list and notify the adapter
        int position = viewHolder.getAdapterPosition();
        mItemList.remove(position);
        mRecyclerViewAdapter.notifyDataSetChanged();
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
            if (dX > 0) {
                View itemView = viewHolder.itemView;
                // if viewHolder has been swiped away, don't do anything
                if (viewHolder.getAdapterPosition() == -1) {
                    return;
                }
                if (!initialized) {
                    init();
                }
                // draw background
                int dXSwipe = (int) (dX * 1.05); // increase slightly dX to avoid view flickering, compensating loss of precision due to int conversion 
                background.setBounds(itemView.getLeft(), itemView.getTop(),
                itemView.getLeft() + dXSwipe, itemView.getBottom());
                background.draw(c);
                // draw icon
                int top = (itemView.getTop() + itemView.getBottom() - icon.getIntrinsicHeight()) / 2;
                int left = itemView.getLeft() + iconMargin;
                icon.setBounds(left, top, left + icon.getIntrinsicWidth(), top + icon.getIntrinsicHeight());
                icon.draw(c);
            }
        }
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        }
    };
    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
    itemTouchHelper.attachToRecyclerView(mRecyclerView);

现在,问题是如何在下面的背景中动画视图。这个动画的一个例子可以从google Calendar中获得:当事件或提醒被滑动时,左边的图标会相应地按水平位移的量缩放。

有没有人知道如何做到这一点?是否需要一种不同的方法,也许在ViewWholder中有两个视图,一个在另一个上,就像这里建议的RecolyerView滑动,下面有一个视图?

共有1个答案

方建明
2023-03-14

我知道怎么做了。

对于那些有兴趣的人来说,解决方案是使用两个视图(前景和背景),并随着滑动的进行对背景进行动画化。

布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="wrap_content"
    android:background="@color/item_delete_background">

    <ImageView
        android:id="@+id/item_delete_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="@dimen/fab_margin"
        android:layout_marginStart="@dimen/fab_margin"
        app:srcCompat="@drawable/ic_delete_white_24dp" />

    <android.support.constraint.ConstraintLayout
        android:id="@+id/item_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/gray_bg">

        <!--recyclerview item layout-->

    </android.support.constraint.ConstraintLayout>

</FrameLayout>

视图持有者:

class MyViewHolder extends RecyclerView.ViewHolder {
    private ConstraintLayout mItemLayout;
    private ImageView mItemDeleteIcon;

    MyViewHolder(View v) {
        super(v);
        mItemLayout = (ConstraintLayout) v.findViewById(R.id.item_layout);
        mEventDeleteIcon = (ImageView) v.findViewById(R.id.item_delete_icon);
    }

    View getViewToSwipe() {
        return mItemLayout;
    }

    View getViewToAnimate() {
        return mItemDeleteIcon;
    }
}

和ItemTouchHelper回调:

ItemTouchHelper.SimpleCallback mItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {

    // override methods

    public void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
                                float dX, float dY,
                                int actionState, boolean isCurrentlyActive) {
        // get the view which is currently swiped
        ConstraintLayout itemLayout = (ConstraintLayout) ((MyViewHolder) viewHolder).getViewToSwipe();
        // calculate relative horizontal displacement
        // with proportion dXRelative : 1 = dX : (layoutWidth / 3)
        float dXRelative = dX / itemLayout.getWidth() * 3;
        // check size boundaries
        if (dXRelative > 1) {
            dXRelative = 1;
        }
        if (dXRelative < 0) {
            dXRelative = 0;
        }
        // animate the icon with scaling on both dimensions
        ((MyViewHolder) viewHolder).getViewToAnimate().animate().scaleX(dXRelative).scaleY(dXRelative).setDuration(0).start();
        // call draw over
        getDefaultUIUtil().onDrawOver(c, recyclerView, ((MyViewHolder) viewHolder).getViewToSwipe(), dX, dY, actionState, isCurrentlyActive);
    }
};

基本行为(视图保持器中的前景/背景)的实现是在下面的文章中完成的:使用ItemTouchHelper进行Swipe-to-Dississ,并在swiped Out后面显示另一个视图。

希望这对某人有用。

 类似资料:
  • 我正在尝试创建背景色CSS3关键帧动画后的第一个动画,这是一个背景图像。我无法创建另一个动画后,文字动画淡出。文本动画褪色后,我想背景的不透明度转到0.3,并再次褪色在文本。下面是我所拥有的。 请在此处查看完整代码:codepen:https://codepen.io/imdaone/pen/jjryyv

  • 我想为游戏乒乓球创建一个简单的游戏菜单。在背景中有一个球在边缘反弹,只是为了看起来漂亮。现在我想在这个菜单屏幕上添加按钮。但是背景不再画了。所以我想画一个实时背景,但是按钮应该仍然留在前面。这个实时背景是用循环实现的。下面是GUI类和DrawStartMenueClass。 我听说过图层,但是每个人都在NetBeans中用某种工具来使用它们,我有日蚀,所以我没有那个机会。我想你可以把按钮和背景放在

  • 问题内容: 是否可以在背景图片上使用? 我已经试过了这段代码,它只是模糊了除背景图像之外的所有内容: 我已经搜索了一段时间,但是找不到任何描述该操作方法的资源。 问题答案: 将来的用户 :IE7,IE8,IE9,IE10,IE11或当前版本的EDGE不支持此功能。 除非您有备用广告,否则请勿在真实的网站上使用。 如果您正在寻找不依赖额外标记的解决方案,则可以将背景图像应用到主体上的伪元素并进行过滤

  • 问题内容: 我正在使用Android手机作为主要处理器并使用摄像头检测运动的机器人项目。我从OpenCV获得了Android二进制包并正确安装它。我可以使用OpenCV本机相机捕获图像并将其显示在屏幕上。我在使用背景减法类时遇到问题。我可以在构造函数中创建一个新的BackgroundSubtractorMOG对象,但是当我尝试运行下面的代码时,它强制退出了,我从本地代码中收到错误“ Backgro

  • 本文向大家介绍Android利用动画实现背景逐渐变暗,包括了Android利用动画实现背景逐渐变暗的使用技巧和注意事项,需要的朋友参考一下 前言 之前写了一篇Android-实现底部弹出PopupWindow并让背景逐渐变暗,介绍利用Handler动态改变背景透明度从而达到变暗的效果。现在补充一种方法,使用动画来实现相同的效果。 ValueAnimator 和 Interpolator 今天的主角

  • 问题内容: 我试图通过使用CSS过渡来更改悬停元素的背景颜色。我想通过使其从底部向上滚动来做到这一点。我可以使用此功能淡化背景,但我希望它向上滑动: 另一个想法是,将背景应用到一个单独的元素上会更好吗? 问题答案: 为了 向上滑动背景色, 您需要使用背景图片或某种渐变,同时逐步调整: