带有单选按钮的Android颜色选择器

3
我想创建一个单选按钮组来选择颜色。类似于这样的东西:enter image description here 我该如何实现这样的效果?在原始的 RadioButton 上没有找到任何颜色属性。我需要创建一个自定义控件吗?如果是,有人可以简单地提示一下基本步骤吗,这样我就可以进行一些新的研究了吗?我非常新手安卓开发,并尝试通过实践学习...

1
创建您的自定义单选按钮或使用imageView、imageButton或button与drawable。 - Mohammad Tauqir
3个回答

5
你可以尝试使用自定义单选按钮,或者使用或膨胀视图来实现这种颜色选择器。使用xml:您需要在drawable文件夹中创建两个可绘制资源文件。第一个如下所示:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">

<solid android:color="#e91e63" />
<size
    android:width="48dp"
    android:height="48dp" />

当您没有收到任何查看(可点击)的点击时,可以使用此选项。当我们检测到点击时,应用第二个文件。

    xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">

<solid android:color="#e91e63" />
<size
    android:width="53dp"
    android:height="53dp" />
<stroke
    android:width="5dp"
    android:color="#d2d1d2" />

现在,在活动中,需要将背景可绘制设置为视图(无论是图像按钮还是图像视图)。操作如下(只是一个示例):

public class MainActivity extends AppCompatActivity {
private ImageButton img;
private boolean isSelected = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    img = (ImageButton) findViewById(R.id.img);
    img.setClickable(true);
    img.setBackground(getDrawable(R.drawable.unselected_circle));
    img.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            img.startAnimation(AnimationUtils.loadAnimation(getBaseContext(), android.R.anim.fade_in));
            if (isSelected) {
                isSelected = false;
                img.setBackground(getDrawable(R.drawable.unselected_circle));
            } else {
                isSelected = true;
                img.setBackground(getDrawable(R.drawable.selected_circle));
            }
        }
    });
}

您好,以下是内容翻译:

}

activity_main布局大致如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/viewGroup"
tools:context="com.android.empty.MainActivity">

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:layout_margin="20dp"
    android:clickable="true"
    android:id="@+id/img"/>

然而,使用这种方法会为不同颜色创建多个drawable。为了避免这种情况,我们可以通过编程方式创建drawable,只需编写一次代码,并使用setColor(int color)方法将其用于不同的颜色:

public class MainActivity extends AppCompatActivity {
private ImageButton img;
private boolean isSelected = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final GradientDrawable unselected = new GradientDrawable();
    unselected.setShape(GradientDrawable.OVAL);
    unselected.setColor(Color.parseColor("#e91e63"));
    unselected.setSize(144, 144);

    final GradientDrawable selected = new GradientDrawable();
    selected.setShape(GradientDrawable.OVAL);
    selected.setColor(Color.parseColor("#E91E63"));
    selected.setSize(159, 159);
    selected.setStroke(15, Color.parseColor("#D2D1D2"));

    img = (ImageButton) findViewById(R.id.img);
    img.setBackground(unselected);
    img.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            img.startAnimation(AnimationUtils.loadAnimation(getBaseContext(), android.R.anim.fade_in));
            if (isSelected) {
                isSelected = false;
                img.setBackground(unselected);
            } else {
                isSelected = true;
                img.setBackground(selected);
            }
        }
    });
}

}

结果大致如此

注意: 此示例仅介绍实现类似于问题中提到的选择器的方法。要创建多个选择器,需要使用LayoutInflater类填充视图(图像按钮)。


1
非常感谢您提供如此详细的答案。这需要我花费很长时间将这么多概念组合在一起……我学到了很多。 - rbasniak

1

我曾经遇到同样的问题,想使用单选按钮,但后来我自己动手创建了[CustomRadioShapes]1库。

简单实现方法如下:

  1. 从CustomRadioAndShapes/library文件夹中下载发布的aar文件
  2. 在Android Studio中选择文件->新建->新模块->导入.aar或.jar文件
  3. 选择aar文件和子项目名称为CustomRadioAndShapes。完成。

enter image description here

enter image description here


1

在RadioButton中更改Drawable

我发现了一种使用本地的 RadioButton 的方法。您需要创建自己的 Drawable 和 Style,然后就可以使用它了。花了我整个下午才弄明白,所以亲爱的读者,请相信这篇文章会帮到你的。

以下是实现此操作所需的所有资源列表:

示例颜色选择器

  • 基于Android 13(API级别33)构建
  • 经测试也适用于Android 7.0(API级别24)

drawable/colour_picker.xml

(如果您不关心在选择选项时出现水波纹效果,请从selector元素开始)

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@android:color/white" android:radius="50dp">
    <item>
        <selector>
            <item android:drawable="@drawable/colour_picker_checked" android:state_checked="true" />
            <item android:drawable="@drawable/colour_picker_unchecked" android:state_checked="false" />
        </selector>
    </item>
</ripple>

drawable/colour_picker_checked.xml

(请确保这里的形状仅使用tint而不是color,否则它们将在以后被破坏)

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="oval" android:tint="#FFFFFF">
            <stroke android:width="5dp" />
            <solid android:color="@android:color/transparent" />
            <size android:width="50dp" android:height="50dp"/>
        </shape>
    </item>
    <item android:top="10dp" android:bottom="10dp" android:left="10dp" android:right="10dp">
        <shape android:shape="oval" android:tint="#FFFFFF">
            <solid android:width="1dp" />
        </shape>
    </item>
</layer-list>

drawable/colour_picker_unchecked.xml

(这个文件的尺寸需要与colour_picker_checked.xml完全匹配,否则选择选项会导致布局移动)

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="oval" android:tint="#FFFFFF">
            <solid android:color="@android:color/transparent" />
            <size android:width="50dp" android:height="50dp"/>
        </shape>
    </item>
    <item android:top="10dp" android:bottom="10dp" android:left="10dp" android:right="10dp">
        <shape android:shape="oval" android:tint="#FFFFFF">
            <solid android:width="1dp" />
        </shape>
    </item>
</layer-list>

values/styles.xml

(这些设置将使按钮水平分布和对齐)

    <style name="colour_picker"
        parent="Base.Widget.AppCompat.CompoundButton.RadioButton">
        <item name="android:button">@drawable/colour_picker</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">false</item>
        <item name="android:backgroundDimEnabled">true</item>
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">0dp</item>
        <item name="android:gravity">center</item>
        <item name="android:layout_weight">1</item>
    </style>

layout/colour_picker.xml

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:layout_gravity="center"
    android:orientation="vertical"
    android:theme="@style/RippleStyle">

    <RadioGroup
        android:id="@+id/colour_choice"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingBottom="10dp">

        <RadioButton name="" style="@style/colour_picker" android:buttonTint="#FFFFFF"/>
        <RadioButton style="@style/colour_picker" android:buttonTint="#FF00FF"/>
    </RadioGroup>
</LinearLayout>

如何使用

此时唯一的困难是识别选择了哪个选项。如果您的颜色列表是固定的,并且不介意硬编码,请考虑在XML中直接为每个RadioButton赋予一个android:id

在我的情况下,我选择通过编程方式创建RadioButton对象,这使我可以从string-array资源中交叉引用颜色。

String[] colourPalette = getResources().getStringArray(R.array.colour_options);
RadioGroup colourPicker = findViewById(R.id.YOUR_LAYOUT_WHERE_THIS_SHOULD_END_UP);
LayoutInflater inflater = LayoutInflater.from(this);
for (int i = 0; i < colourPalette.length; i++) {
    RadioButton colourOption = (RadioButton) inflater.inflate(R.layout.colour_picker_item,null).getRootView();
    colourOption.setId(i);
    colourOption.setButtonTintList(ColorStateList.valueOf(Color.parseColor(colourPalette[i])));
    colourPicker.addView(colourOption);
}

为了使它起作用,您需要两个额外的资源:layout/colour_picker_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RadioButton style="@style/colour_picker" />

values/colors.xml

<string-array name="colour_options">
    <item name="#FFFF00">#FFFF00</item>
    <item name="#FF0000">#FF0000</item>
</string-array>

然后在你的代码中,只需要这样:

colourPicker.setOnCheckedChangeListener((group, checkedId) -> {
    RadioButton colourOption = colourPicker.findViewById(checkedId);
    int colour = Color.parseColor(colourPalette[colourOption.getId()]);
    // do whatever you need to do with your picked colour
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接