所选项目表面上的奇怪带颜色

Weird Band Color on the Selected Item's Surface

当在回收站视图中突出显示选择时,我遇到了一个奇怪的问题。根据我的测试,此问题发生在 API 级别 30 及以上。我没有在较低的 API 水平内观察到任何此类问题,至少 APIs 在 28 以下。

A screenshot of API 30 A screenshot of API 27
This screenshot is taken from a Motorola G5S Plus which running Android 11 This one is taken from General Mobile 6 which is running Android 8.1.0

两部手机 运行 应用程序的版本相同。正如您在左图中看到的那样,在突出显示的区域内有一条带。在这个区域有 2 个离散的 TextViews 和它们之间的一些间隙。

我们来看看名为him_selector.xml:

的高亮颜色xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:alpha="0.4" android:color="?attr/colorSecondaryVariant" android:state_activated="true"/>
    <item android:color="?attr/colorSurface"/>
</selector>

以下xml为列表项设计

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <import type="android.view.View"/>
        <import type="com.himtec.himtec_kontrol.ui.viewmodel.AygitListelemeVM"/>

        <variable name="kipSurukle" type="boolean"/>
        <variable name="gozde" type="boolean"/>

    </data>

    <com.himtec.himtec_kontrol.ui.AygitMaterialCardView
        android:id="@+id/amcv_aygit"
        style="@style/Widget.Himtec.MaterialCardView.Elevated.RoundCorners.Large"
        android:layout_width="match_parent"
        android:layout_height="@dimen/him_card_device_height"
        android:layout_margin="@dimen/him_card_device_margin"
        android:checkable="false"
        android:clickable="true"
        android:clipChildren="true"
        android:clipToPadding="false"
        android:focusable="true"
        app:cardBackgroundColor="@color/him_selector" <!-- I use that color selector as card's background color to highlight it when it is selected -->
        app:cardMaxElevation="@dimen/him_card_drag_elevation"
        app:cardPreventCornerOverlap="false">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/cl_aygit"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:duplicateParentState="true">

            <View
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:background="?attr/colorPrimary"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="@id/gl_aygit_model_icerik_hiza"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <com.google.android.material.imageview.ShapeableImageView
                android:id="@+id/iv_nokta_simge"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:contentDescription="@string/cd_aygitSimgesi"
                android:duplicateParentState="true"
                android:scaleType="center"
                android:tint="?attr/colorSurface"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/gl_aygit_model_icerik_hiza"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@drawable/him_aygit_simge_selector"
                tools:srcCompat="@drawable/him_aygit_simge_selector" />


            <com.google.android.material.textview.MaterialTextView
                android:id="@+id/tv_nokta_ad"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:gravity="center_vertical"
                android:padding="2dp"
                android:singleLine="true"
                android:textAlignment="gravity"
                android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
                app:layout_constraintBottom_toTopOf="@+id/mtv_eklenme"
                app:layout_constraintEnd_toStartOf="@+id/tus_sirala"
                app:layout_constraintStart_toStartOf="@+id/gl_aygit_model_icerik_hiza"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_goneMarginEnd="@dimen/him_card_content_padding_8dp" />

            <com.google.android.material.textview.MaterialTextView
                android:id="@+id/mtv_eklenme"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:gravity="center_vertical"
                android:padding="2dp"
                android:singleLine="true"
                android:text="@string/sc_eklendi"
                android:textAlignment="gravity"
                android:textSize="12sp"
                app:layout_constraintBottom_toTopOf="@+id/mtv_son_baglanma"
                app:layout_constraintStart_toStartOf="@+id/gl_aygit_model_icerik_hiza"
                app:layout_constraintTop_toBottomOf="@+id/tv_nokta_ad"
                app:layout_constraintVertical_chainStyle="packed" />

            <com.google.android.material.textview.MaterialTextView
                android:id="@+id/mtv_eklenme_deger"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="5dp"
                android:gravity="center_vertical"
                android:padding="2dp"
                android:singleLine="true"
                android:textAlignment="gravity"
                android:textSize="12sp"
                app:layout_constraintBaseline_toBaselineOf="@+id/mtv_eklenme"
                app:layout_constraintEnd_toStartOf="@+id/tus_sirala"
                app:layout_constraintStart_toEndOf="@id/br_aygit_model_alt_bilgi_baslik"
                app:layout_goneMarginEnd="@dimen/him_card_content_padding_8dp" />

            <com.google.android.material.textview.MaterialTextView
                android:id="@+id/mtv_son_baglanma"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:gravity="center_vertical"
                android:padding="2dp"
                android:singleLine="true"
                android:text="@string/sc_sonBaglanti"
                android:textAlignment="gravity"
                android:textSize="12sp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="@+id/gl_aygit_model_icerik_hiza"
                app:layout_constraintTop_toBottomOf="@+id/mtv_eklenme" />

            <com.google.android.material.textview.MaterialTextView
                android:id="@+id/mtv_son_baglanma_deger"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="5dp"
                android:gravity="center_vertical"
                android:padding="2dp"
                android:singleLine="true"
                android:textAlignment="gravity"
                android:textSize="12sp"
                app:layout_constraintBaseline_toBaselineOf="@+id/mtv_son_baglanma"
                app:layout_constraintEnd_toStartOf="@+id/tus_sirala"
                app:layout_constraintStart_toEndOf="@id/br_aygit_model_alt_bilgi_baslik"
                app:layout_goneMarginEnd="@dimen/him_card_content_padding_8dp" />


            <Button
                android:id="@+id/tus_sirala"
                style="@style/Widget.Himtec.Button.TextButton"
                android:layout_width="36dp"
                android:layout_height="0dp"
                android:visibility="@{kipSurukle ? View.VISIBLE : View.GONE}"
                app:icon="@drawable/him_surukle_24"
                app:iconPadding="0dp"
                app:iconSize="24dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <androidx.constraintlayout.widget.Barrier
                android:id="@+id/br_aygit_model_alt_bilgi_baslik"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:barrierDirection="end"
                app:constraint_referenced_ids="mtv_eklenme,mtv_son_baglanma"
                tools:layout_editor_absoluteX="169dp" />

            <androidx.constraintlayout.widget.Guideline
                android:id="@+id/gl_aygit_model_icerik_hiza"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintGuide_begin="82dp" />

        </androidx.constraintlayout.widget.ConstraintLayout>

    </com.himtec.himtec_kontrol.ui.AygitMaterialCardView>
</layout>

两部手机中存在相同的项目 xml 和颜色。突出显示是通过激活 AygitMaterialcardView 实现的,它是扩展 MaterialCardView 的自定义 class。通过将 View.setActivated() 方法设置为 true 来进行激活。

自定义卡片实现:

public class AygitMaterialCardView extends MaterialCardView {
    private static final String E = AygitMaterialCardView.class.getSimpleName();

    /* Uygulamaya özel tanımlanan durumlar */
    private static final int DURUM_HICBIRI = 0;
    private static final int DURUM_GOZDE = 1;
    private static final int DURUM_SURUKLE = 2;

    private static final int[] HIM_AYGIT_DURUMLAR = {
            R.attr.durum_hicbiri,
            R.attr.durum_gozde,
            R.attr.durum_surukleme
    };

    private boolean gozde;
    private boolean surukleme;
    private int durum;

    public AygitMaterialCardView(Context context) {
        super(context);
    }

    /* XML kaynaktan ilklenirken bu oluşturucu çağrılıyor */
    public AygitMaterialCardView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected int[] onCreateDrawableState(int extraSpace) {
        final int[] drawableStates = super.onCreateDrawableState(extraSpace +1);

        // Fazladan gözde durumunu ekleyeceğiz
        if(gozde) {
            int[] d = { HIM_AYGIT_DURUMLAR[DURUM_GOZDE] };
            mergeDrawableStates(drawableStates, d);
        }
        if(surukleme) {
            int[] d = { HIM_AYGIT_DURUMLAR[DURUM_SURUKLE] };
            mergeDrawableStates(drawableStates, d);
        }
        return drawableStates;
    }

    public boolean isGozde() {
        return gozde;
    }

    public void setGozde(boolean gozde) {
        if(gozde == this.gozde) return;
        this.gozde = gozde;
        refreshDrawableState();
        invalidate();
        requestLayout();
    }

    public boolean isSurukleme() {
        return surukleme;
    }

    public void setSurukleme(boolean surukleme) {
        if(surukleme == this.surukleme) return;
        this.surukleme = surukleme;
        refreshDrawableState();
        invalidate();
        requestLayout();
    }
}

感谢 Mike M. 解决此问题。感谢他的指导,我可以看出问题的原因是由选择器的 alpha 设置引起的半透明背景色。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:alpha="0.4" android:color="?attr/colorSecondaryVariant" android:state_activated="true"/>
    <item android:color="?attr/colorSurface"/>
</selector>

有两种解决方案可以消除该故障:

  1. 就是把卡片的仰角设置为零,trade-off阴影。
  2. 就是去掉选区颜色的alpha。

由于我不想 trade-off 我的设计要求的阴影,我决定摆脱 alpha 并使选择颜色完全纯色。