Как сделать так, чтобы углы предметов обрезались внутри всплывающего окна счетчика?

Я сделал собственный popupBackground с угловым радиусом 16dp. Проблема в том, что элементы внутри этого всплывающего окна могут иметь цвет фона, который не повторяется после его родительского всплывающего окна, и я не понимаю, как это сделать, поскольку я не вижу никакого свойства типа ClipToBounds. То же самое происходит с эффектом пульсации при нажатии на элемент. Изображение, представляющее то, что у меня есть прямо сейчас, и код, используемый для его создания:

Всплывающие элементы

Определение спиннера:

<androidx.appcompat.widget.AppCompatSpinner
    android:id="@+id/ItemOptionsSpinner"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:dropDownWidth="wrap_content"
    android:popupBackground="@drawable/spinner_background"
    android:paddingRight="0dp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintHorizontal_bias="1"
    android:spinnerMode="dropdown"
    android:visibility="invisible" />

spinner_background.xml внутри папки с возможностью рисования:

<?xml version="1.0" encoding="utf-8"?>
<shape 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="16dp" />
    <solid android:color="?android:colorBackground" />
</shape>

SpinnerItemLineDropLayout.xml, представление, используемое для отображения каждого элемента:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/MainLayout"
    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"
    android:paddingHorizontal="@dimen/activityHorizontalPadding"
    android:paddingVertical="@dimen/activityVerticalPadding"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/ItemText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/CheckImage"
        style="@style/DefaultTextAppearance.Medium.Big" />
    <ImageView
        android:id="@+id/CheckImage"
        android:paddingLeft="12dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/HelpText"
        app:layout_constraintRight_toRightOf="parent"
        android:src="@drawable/ic_check_black_18dp"
        android:tint="@color/colorPrimaryDark"
        tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout>

Код, который я использую внутри адаптера для заполнения элементов, просто для демонстрации того, как я устанавливаю цвет фона самого элемента в зависимости от того, выбран ли элемент счетчиком или нет:

public override View GetDropDownView(Int32 position, View convertView, ViewGroup parent)
{
    var view = convertView ?? (parent?.Context == null ? null : LayoutInflater.FromContext(parent.Context)?.Inflate(Resource.Layout.SpinnerItemLineDropLayout, null));

    var mainLayout = view.FindViewById<ConstraintLayout>(Resource.Id.MainLayout);
    var itemTextView = view.FindViewById<TextView>(Resource.Id.ItemText);
    var checkImageView = view.FindViewById<ImageView>(Resource.Id.CheckImage);

    itemTextView.Text = this._items[position].Text.GetText();

    checkImageView.SetImageResource(this.SelectedPosition == position ? Resource.Drawable.ic_check_black_18dp : 0);

    if (this.SelectedPosition == position)
        mainLayout.SetBackgroundColor(Color.ParseColor(view.Context.GetString(Resource.Color.colorControlHighlight)));

    return view;
}

person dbalboa    schedule 19.11.2020    source источник


Ответы (1)


Причина в том, что BackgroundColor элемента SelectedItem повлияет на стиль счетчика DropDownView. Если вы не установите выбранный цвет для элемента, вы не увидите этого явления.

Если вам нужно установить BackgroundColor для SelectedItem, есть способ уменьшить эффект для DropDownView. Но это не обходной путь, потому что он не может полностью решить это явление.

Пример кода выглядит следующим образом:

if (this.SelectedPosition == position)
        
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.SetShape(ShapeType.Rectangle);//shape
gradientDrawable.SetCornerRadius(16f);//set circle Radius
gradientDrawable.SetColor(Resource.Color.ripple_material_dark);//background color

mainLayout.SetBackgroundDrawable(gradientDrawable);//set backgroundcolor

Здесь мы используем SetBackgroundDrawable для установки цвета, потому что это может быть задано формой.

Кроме того, вы можете изменить код spinner_background.xml, чтобы уменьшить их различие:

<?xml version="1.0" encoding="utf-8" ?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
  <corners android:radius="8dp" />
  <solid android:color="?android:colorBackground" />
</shape>

Эффект:

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

===========================Обновление===================== ==============

Как комментарий dbalboa, для этого есть другое возможное решение, а также можно использовать метод SetBackgroundColor для установки цвета. Это размещение <padding android:top="15dip" android:bottom="15dip" /> внутри тега формы spinner_background.xml.

Полный код выглядит следующим образом:

<?xml version="1.0" encoding="utf-8" ?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
  <corners android:radius="8dp" />
  <padding android:top="5dip" android:bottom="5dip"/>
  <solid android:color="?android:colorBackground" />
</shape>

Тогда эффект следующий:

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

person Junior Jiang    schedule 20.11.2020
comment
Спасибо за ваш вклад. Ваш ответ помог мне найти возможное решение, сделал рисование для верхнего/нижнего элемента с правильным радиусом угла, но тем не менее волновой эффект для каждого элемента списка внутри всплывающего окна имеет эти углы. Так закончилось размещение <padding android:top="15dip" android:bottom="15dip" /> внутри тега формы spinner_background.xml, поэтому больше не имеет значения, закруглены углы или нет. Слишком много работы, чтобы это стало возможным. - person dbalboa; 23.11.2020
comment
@dbalboa О, это здорово! Вы можете обновить его как ответ и не забудьте отметить это. Это поможет другим, у кого снова возникнет эта проблема. - person Junior Jiang; 24.11.2020
comment
@dbalboa Спасибо, что отметили мой ответ. Я обновил ваше решение в своем ответе, тогда другие, у кого есть такая же проблема, также узнают об этом. - person Junior Jiang; 25.11.2020