Appcompat CardView и Picasso без закругленных углов

Я не знаю, где именно я должен решить эту проблему, если это моя вина, что-то в Picasso Lib Wrong или в библиотеке Cardview.

В основном у меня есть CardView, содержащий изображение (полная закрытая карта) и наложение TextView.

При запуске кода на устройстве Android 5.0 все работает нормально, а изображение получает закругленные углы.

Однако, если я запускаю его на устройстве до 5.0, изображение перекрывает Cardlayout и не имеет закругленных углов.

Вы можете увидеть сравнение на этом изображении: comparison

Вот несколько фрагментов кода:

layout_row.xml

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/pandaImage"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_centerInParent="true"
        android:scaleType="centerCrop" />

    <TextView
        android:id="@+id/pandaName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/pandaImage"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:background="@color/photo_tint"
        android:clickable="true"
        android:focusable="true"
        android:gravity="center"
        android:textColor="@android:color/white"
        android:textSize="24sp" />

</RelativeLayout>

И адаптер Recycler, загружающий образ:

@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
    Photo p = photos.get(i);
    Picasso.with(mContext).load(p.getUrl()).fit().into(viewHolder.mImage);
    viewHolder.mPandaName.setText(p.getTitle());
}

person Angelo    schedule 24.10.2014    source источник
comment
Что произойдет, если вы установите изображение в качестве фона для карты?   -  person JacksOnF1re    schedule 22.01.2015


Ответы (5)


Согласно документам, это так, как задумано:

Из-за дороговизны отсечения закругленных углов на платформах до L CardView не отсекает свои дочерние элементы, которые пересекаются со закругленными углами. Вместо этого он добавляет заполнение, чтобы избежать такого пересечения (см. setPreventCornerOverlap(boolean), чтобы изменить это поведение).

Дополнительные сведения см. в CardView документации.

person Kevin Coppock    schedule 24.10.2014
comment
при установке setPreventCornerOverlap(false) на устройствах pre L изображение превышает CardView и выравнивается с тенью. Есть какие-нибудь мысли по этому поводу? - person mike.b93; 13.11.2014
comment
@mike.b93 Я полагаю, вы ссылаетесь на эту ошибку code.google.com /p/android/issues/detail?id=77821 мой комментарий, кажется, решает проблему Pre-L. По крайней мере, на одном устройстве, на котором я тестировал. - person Nathan Schwermann; 05.12.2014

Как упомянул @kcoppock, это сделано специально.

Вот что бы я сделал в этой ситуации.

1) Вы можете использовать интерфейс Picasso Transformation, чтобы указать пользовательское преобразование для вашего изображения (в наш случай - изображение со скругленными углами)

2) Примените это преобразование к запросу Picasso на устройствах pre-L.

3) Поскольку CardView добавляет некоторое поле для изображения - избавьтесь от него на устройствах pre-L, вызвав setPreventOverlap(false)

Вернемся к коду:

Пользовательское преобразование:

public class RoundedTransformation implements com.squareup.picasso.Transformation {
    private final int radius;
    private final int margin;

    public RoundedTransformation(final int radius, final int margin) {
        this.radius = radius;
        this.margin = margin;
    }

    @Override
    public Bitmap transform(final Bitmap source) {
        final Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));

        Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        canvas.drawRoundRect(new RectF(margin, margin, source.getWidth() - margin, source.getHeight() - margin), radius, radius, paint);

        if (source != output) {
            source.recycle();
        }

        return output;
    }

    @Override
    public String key() {
        return "rounded(radius=" + radius + ", margin=" + margin + ")";
    }
}

Пикассо:

//feel free to play with radius to match your CardView
Picasso.with(mContext).load(p.getUrl()).transform(new RoundedTransformation(12, 0)).fit().into(viewHolder.mImage);
person Pavel Dudka    schedule 24.10.2014
comment
setPreventOverlap(false) — очень важный вызов при работе с фоном карт. Очень хорошо, что упомянули это здесь. - person Richard Le Mesurier; 02.10.2015
comment
отличное решение! как сделать только верхний угол закругленным, а нижний квадратным? - person jiawen; 26.12.2015
comment
@jiawen, к сожалению, для достижения эффекта одного закругленного угла требуется немного больше работы, чем просто вызов одного API. Обычно требуется рисование в два прохода. Вы можете обратиться к аналогичным вопросам на SO - person Pavel Dudka; 26.12.2015
comment
@ПавелДудка. Я нашел здесь хорошее решение: github.com/wasabeef/picasso-transformations/blob/master/ Позволяет настроить угол, который нужно скруглить. - person jiawen; 27.12.2015

У меня это работает так:

  1. Замените ImageView на RoundedImageView (https://github.com/vinc3m1/RoundedImageView).
  2. Установите атрибут riv_corner_radius на RoundedImageView таким же, как угол CardView.
  3. Установите cardPreventCornerOverlap в false на CardView (app:cardPreventCornerOverlap="false").
  4. Теперь это выглядит одинаково на L и pre-L.
person NightfuryN    schedule 07.01.2016

Если вы хотите иметь глобальное решение этой проблемы, вы можете использовать Carbon CardView. Он правильно обрезает свой контент до закругленных углов на всех устройствах обратно в Froyo. Смотрите изображение:

введите здесь описание изображения

person Zielony    schedule 01.10.2015

Используйте код ниже.

Важно! не задавайте фон для ImageView в XML.

<android.support.v7.widget.CardView 
                                    android:layout_width="match_parent"
                                    android:layout_height="130dp"
                                    app:cardCornerRadius="5dp"
                                    app:cardElevation="0dp"
                                    app:cardUseCompatPadding="true">

    <RelativeLayout
        android:id="@+id/rl_target_marry"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/textView2"
        >

        <ImageView
            android:id="@+id/img_target_marry"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY"
            />
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:foreground="?attr/selectableItemBackground">

            <TextView
                android:id="@+id/textView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_gravity="right|center_vertical"
                android:layout_marginRight="16dp"
                android:text="Marry"
                android:textColor="@color/colorWhite"
                android:textSize="28sp"/>

        </FrameLayout>

    </RelativeLayout>
</android.support.v7.widget.CardView>
person ThoIam    schedule 24.06.2017