如何在 Android CardView 上添加滑动功能?

How to add swipe functionality on Android CardView?

我有一个 CardView,其中包含两个 TextView 和两个 ImageView。我希望能够左右滑动到 "dismiss"。我实际上想向右滑动以发送 Intent,但这可以稍后完成。现在,我希望能够通过向左或向右滑动来关闭 CardView。我也想要滑动的动画

我尝试使用 romannurik's SwipeDismissTouchListener,但 CardView 没有响应滑动。

如果有人有比 romannurik's 自定义侦听器更好的解决方案,请分享。

这是我的 CardView 布局:

<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/generate"
    map:cardCornerRadius="@dimen/_3sdp"
    map:cardElevation="@dimen/_8sdp"
    android:id="@+id/restaurantContainer">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="horizontal">

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

                <ImageView
                    android:id="@+id/thumbnail"
                    android:layout_width="@dimen/_75sdp"
                    android:layout_height="@dimen/_75sdp"
                    android:layout_margin="@dimen/_5sdp" />

                <ImageView
                    android:id="@+id/rating"
                    android:layout_width="@dimen/_75sdp"
                    android:layout_height="@dimen/_15sdp"
                    android:layout_margin="@dimen/_5sdp" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/name"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_margin="@dimen/_5sdp"
                    android:gravity="top"
                    android:textAppearance="?android:attr/textAppearanceLarge" />

                <TextView
                    android:id="@+id/categories"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_margin="@dimen/_5sdp"
                    android:textAppearance="?android:attr/textAppearanceMedium" />
            </LinearLayout>

        </LinearLayout>

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">

            <com.google.android.gms.maps.MapView
                android:id="@+id/mapView"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                map:cameraZoom="14"
                map:liteMode="true"
                map:mapType="normal" />

        </LinearLayout>

    </LinearLayout>

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

我如何设置 SwipeDismissTouchListener:

RelativeLayout rootLayout;
CardView restaurantCardView;

...

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        rootLayout = (RelativeLayout) inflater.inflate(R.layout.fragment_main, container, false);

        restaurantCardView = (CardView) rootLayout.findViewById(R.id.restaurantContainer);

        restaurantCardView.setOnTouchListener(new SwipeDismissTouchListener(restaurantCardView, null, new SwipeDismissTouchListener.DismissCallbacks() {
            @Override
            public boolean canDismiss(Object token) {
                Log.d("Chris", "canDismiss() called with: " + "token = [" + token + "]");
                return true;
            }

            @Override
            public void onDismiss(View view, Object token) {
                Log.d("Chris", "onDismiss() called with: " + "view = [" + view + "], token = [" + token + "]");
            }
        }));
    ....

    return rootLayout;

我可以看到来自 canDismiss(...) 的日志,但不能来自 onDismiss(...)

你必须把它放在 RecyclerView 里面(你的 CardView 是那里唯一的项目)

然后,用ItemTouchHelper.SimpleCallbackitemTouchHelper.attachToRecyclerView(recyclerView);

它会给你动画并且在

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
}

您可以根据滑动方向指定特定的动作。

在此处查看完整说明:Swipe to Dismiss for RecyclerView

此外,您必须在 RecyclerView:

中禁用垂直滚动
public class UnscrollableLinearLayoutManager extends LinearLayoutManager {
    public UnscrollableLinearLayoutManager(Context context) {
        super(context);
    }

    @Override
    public boolean canScrollVertically() {
        return false;
    }
}

.....

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new UnscrollableLinearLayoutManager(this));
recyclerView.setAdapter(new RestaurantCardAdapter());

否则 - 一旦您尝试向上或向下滚动 - 您会看到 RecyclerView 的 end-of-list 动画。

更新:

这是我用来测试的RecyclerView.Adapter

private class RestaurantCardAdapter extends RecyclerView.Adapter {
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new RestaurantViewHolder(new RestaurantCard(parent.getContext()));
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {}

    @Override
    public int getItemCount() {
        return 1;
    }

    private class RestaurantViewHolder extends RecyclerView.ViewHolder {
        public RestaurantViewHolder(View itemView) {
            super(itemView);
        }
    }
}

RestaurantCard - 只是一个自定义 View(在我们的例子中扩展 CardView):

public class RestaurantCard extends CardView {
    public RestaurantCard(Context context) {
        super(context);
        initialize(context);
    }

    public RestaurantCard(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize(context);
    }

    private void initialize(Context context){
        LayoutInflater.from(context).inflate(R.layout.card, this);
        // ImageView imageView = (ImageView)getView.findViewById(...);
    }
}