Home > Software engineering >  Weird Band Color on the Selected Item's Surface
Weird Band Color on the Selected Item's Surface

Time:06-02

I have a weird issue when the selection is highlighted in a recycler view. This problem occurs as of API level 30 and above as per my tests. I did not observed any problem like this within the lower API levels, at least APIs below 28.

A screenshot of API 30 A screenshot of API 27
enter image description here enter image description here
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

Both phones was running the same version of the application. As you can see in the left picture there is a band within the highlighted area. In this area there are 2 discrete TextViews and some gap between them.

Let's take a look at the highlighting color xml named him_selector.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>

The following xml is the list item design.

<?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>

In both phones the same item xml and color exist. The highlighting is made by activating the AygitMaterialcardView which is a custom class that extends MaterialCardView. The activation is made by setting the View.setActivated() method to true.

The custom card implementation:

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();
    }
}

CodePudding user response:

Attributes to Mike M. for the solution for this matter. Thanks to his guidance that I could see that the cause of the issue was the translucent background color which caused by alpha settings of the selector.

<?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>

There are two solutions to get rid of that glitch:

  1. Is to set to elevation of the card to zero and trade-off the shadow.
  2. Is to remove the alpha from the selection color.

Since I didn't want to trade-off the shadow for my design requirements, I decided to get rid of the alpha and make the selection color totally solid.

  • Related