SetClipToOutline不适用于RecyclerView

时间:2018-05-05 09:00:24

标签: android android-recyclerview rounded-corners

我的应用程序中有两个RecyclerViews,我使用“SetClipToOutline”来获取图像的圆角/圆形视图。在一个RecyclerView中,我获得了所需的效果。但是,当我尝试对其他RecyclerView执行相同操作时,它会失败。

我将只展示它不起作用的代码,以及我试图使其工作的代码。否则,将会有太多的代码供你们阅读。

我的XML: `

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="wrap_content"
    android:gravity="center">

    <ImageView
        android:id="@+id/imageview_swipe_profile_container"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_gravity="center"
        android:layout_marginBottom="10dp"
        android:layout_marginEnd="10dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/profile_photo_container"
        app:layout_constraintDimensionRatio="h,3:4"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

`

我的RecyclerViewAdapter(java文件):

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.Collections;

public class SwipeAdapter extends RecyclerView.Adapter<SwipeAdapter.CustomViewHolder> {

    private final Context context;
    private ArrayList<SwipeMatchCandidate> candidates = new ArrayList<>();

    SwipeAdapter(Context context) {
        this.context = context;
    }

    @NonNull
    @Override
    public SwipeAdapter.CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        assert layoutInflater != null;
        View v = layoutInflater.inflate(R.layout.swipe_one_profile_in_list, parent, false);
        return new CustomViewHolder(v);
    }

    @Override
    public void onBindViewHolder(@NonNull SwipeAdapter.CustomViewHolder holder, int position) {

        // Sets rounded corners on the profile image. This doesn't work for some reason (maybe because
        // clip is on the background and we set background to be the image.
        // However, it is the correct code and should likely be under the OnBindViewHolder.
        holder.profileImage.setClipToOutline(true);

        SwipeMatchCandidate candidate = candidates.get(position);

        holder.profileImage.setBackground(candidate.colors.get(0));


    }

    @Override
    public int getItemCount() {
        return candidates.size();
    }

    void addMatchCandidate(SwipeMatchCandidate swipeMatchCandidate) {
        candidates.add(swipeMatchCandidate);
    }

    ItemTouchHelper.Callback createHelperCallback() {
        /*
         * First Param is for Up/Down motion, second is for Left/Right.
         * Note that we can supply 0, one constant (e.g. ItemTouchHelper.LEFT), or two constants (e.g.
         * ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) to specify what directions are allowed.
         */

        return new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {

            //not used, as the first parameter above is 0
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
                                  RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(final RecyclerView.ViewHolder viewHolder, int swipeDir) {
                int position = viewHolder.getAdapterPosition();
                candidates.remove(position);
                notifyItemRemoved(position);
            }
        };
    }

    class CustomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        View profileImage;

        CustomViewHolder(View itemView) {
            super(itemView);

            profileImage = itemView.findViewById(R.id.imageview_swipe_profile_container);
            profileImage.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            int pos = this.getAdapterPosition();
            SwipeMatchCandidate candidate = candidates.get(pos);
            Collections.rotate(candidate.colors, 1);

            profileImage.setBackground(candidate.colors.get(0));

        }
    }
}

我认为我使用SetClipToOutline方法在此适配器中?这就是我在其他RecyclerView工作时所做的。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

您正在更改视图的背景,因此它的轮廓与您之前在xml中设置的轮廓不同(可能是四舍五入的轮廓)。 您可以在此处阅读有关裁剪视图的更多信息和概述: https://developer.android.com/training/material/shadows-clipping https://developer.android.com/reference/android/graphics/Outline#canClip()

尝试设置ImageView内容而不是背景。

考虑使用此:

@Override
public void onBindViewHolder(@NonNull SwipeAdapter.CustomViewHolder holder, int position) {
    SwipeMatchCandidate candidate = candidates.get(position);
    holder.profileImage.setImageDrawable(ColorDrawable(candidate.colors.get(0)));
}

或者如果您的颜色集合返回ColorDrawable而不是Color Int:

@Override
public void onBindViewHolder(@NonNull SwipeAdapter.CustomViewHolder holder, int position) {
    SwipeMatchCandidate candidate = candidates.get(position);
    holder.profileImage.setImageDrawable(candidate.colors.get(0));
}

请记住将View.setClipToOutline()添加到Viewholder构造函数中。