SetClipToOutline не работает с RecyclerView - PullRequest
0 голосов
/ 05 мая 2018

У меня есть два 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 голосов
/ 21 сентября 2018

Вы изменяете фон вашего представления, чтобы оно имело другой контур, чем вы установили ранее в 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() в конструкторе виджета.

...