如何使项目角夹在微调器弹出窗口内?

Posted

技术标签:

【中文标题】如何使项目角夹在微调器弹出窗口内?【英文标题】:How to make items corners clip inside spinner popup? 【发布时间】:2020-11-19 15:03:31 【问题描述】:

我制作了一个角半径为 16dp 的自定义 popupBackground。问题是,该弹出窗口中的项目可能具有不会跟随其父弹出窗口旋转的背景颜色,并且我不知道如何做到这一点,因为我没有看到任何“ClipToBounds”类型的属性。点击一个项目时,涟漪效应也会发生同样的情况。代表我现在拥有的图像以及用于生成它的代码:

微调器定义:

<androidx.appcompat.widget.AppCompatSpinner
    android:id="@+id/ItemOptionsSpinner"
    android:layout_
    android:layout_
    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" />

drawable 文件夹内的 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_
    android:layout_>
    <TextView
        android:id="@+id/ItemText"
        android:layout_
        android:layout_
        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_
        android:layout_
        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;

【问题讨论】:

【参考方案1】:

这个原因是SelectedItemBackgroundColor会影响微调器DropDownView的样式。如果你没有为item设置selected color,你不会看到这个现象。

如果你需要为SelectedItem设置BackgroundColor,有一种方法可以减少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方法设置颜色。即将&lt;padding android:top="15dip" android:bottom="15dip" /&gt;放在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>

那么效果如下:

【讨论】:

感谢您的意见。您的回答引导我完成了一个可能的解决方案,为具有适当角半径的顶部/底部项目制作了一个可绘制对象,但仍然,弹出窗口内列表视图的每个项目的涟漪效应都有这些角。所以结束了将&lt;padding android:top="15dip" android:bottom="15dip" /&gt; 放在 spinner_background.xml 的形状标签内,因此角是否圆角不再重要。太多的工作使之成​​为可能。 @dbalboa 哦,太好了!您可以将其更新为答案,并记住对其进行标记。它将帮助其他再次遇到此问题的人。 @dbalboa 感谢您标记我的答案。我已经在我的回答中更新了您的解决方案,其他有相同问题的人也会知道。

以上是关于如何使项目角夹在微调器弹出窗口内?的主要内容,如果未能解决你的问题,请参考以下文章

Kivy reStructuredText 渲染器弹出窗口?

引导日期选择器弹出窗口未显示突出显示的当前日期

当值最初在范围内设置时,日期选择器弹出格式不起作用

Android 深层链接 - 不显示意图选择器弹出窗口,强制打开应用

手机浏览器会阻止弹出窗口,请问怎么取消?

在python中通过sendkeys上传文件会打开一个文件选择器弹出窗口