AlertDialog.Builder+SpannableStringBuilder自定义单选框

来源:互联网 发布:软件测试行业好吗 编辑:程序博客网 时间:2024/06/04 08:43

这里写图片描述
在项目开发的时候,产品汪希望我们做出这种样式的dialog,要做出单选Dialog很简单,网上例子一搜一大把。而我们常用的AlertDialog.Builder也有实现这样的方法:

setSingleChoiceItems(ListAdapter adapter, int checkedItem, final OnClickListener)

我们就用这个方法弹一个单选框看看:

AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle("Please check out separately :");ArrayList<String> chooseTypeList = new ArrayList<>();chooseTypeList.add("Check out A (A post paid)");chooseTypeList.add("Check out B (B prepaid)");ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_single_choice, chooseTypeList);   builder.setSingleChoiceItems(adapter, 0, new DialogInterface.OnClickListener() {    @Override    public void onClick(DialogInterface dialog, int which) {        //do something    }});builder.show();

看看实际效果:
这里写图片描述
虽然大概样子出来了,但是产品汪表示多个细节不满意:

  • Dialog的title没跟下面的选项对齐
  • 单选项后面备注文案应该是灰色的
  • 单选项的按钮可不可以换个颜色?

那我们就按照产品汪的需要来改:
第一个很容易,AlertDialog.Builder有个自定义title的方法setCustomTitle(View view),将我们自定义的View设置进去就行了

TextView textView = new TextView(MainActivity.this);textView.setText("Please check out separately :");textView.setTextSize(16);textView.setTypeface(Typeface.DEFAULT_BOLD);textView.setTextColor(Color.BLACK);float dp_px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()); //dp转pxtextView.setPadding((int) (dp_px * 16), (int) (dp_px * 24), (int) (dp_px * 12), 0);builder.setCustomTitle(textView);

这里写图片描述

第二点似乎有点不大容易实现,前一段字黑色,后一段字灰色,如果是不用两个TextView的话,怎么实现呢?突然想到前段时间使用过SpannableStringBuilder来对文字进行分割设置,这里的话可不可以用这样的方法实现呢?看了一下SpannableString和SpannableStringBuilder都实现了CharSequence,那它的实现应该跟String大同小异的,既然Adapter里可以设置String的list,我们声明一个SpannableStringBuilder的list添加进Adapter里试试:

ArrayList<SpannableStringBuilder> chooseTypeList = new ArrayList<>();SpannableStringBuilder builder1 = new SpannableStringBuilder();SpannableString ss = new SpannableString("Check out A (A post paid)");ss.setSpan(new ForegroundColorSpan(Color.GRAY), "Check out A ".length(), ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);builder1.append(ss);SpannableStringBuilder builder2 = new SpannableStringBuilder();SpannableString ss2 = new SpannableString("Check out B (B prepaid)");ss2.setSpan(new ForegroundColorSpan(Color.GRAY), "Check out B ".length(), ss2.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);builder2.append(ss2);chooseTypeList.add(builder1);chooseTypeList.add(builder2);ArrayAdapter<SpannableStringBuilder> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_single_choice, android.R.id.text1, chooseTypeList);builder.setSingleChoiceItems(adapter, 0, new DialogInterface.OnClickListener() {    @Override    public void onClick(DialogInterface dialog, int which) {        //do something    }});

这里写图片描述

果然可以!接下来就是最后一个需求:换按钮。
其实不难发现,在创建adapter的时候,传入了一个android.R.layout.simple_list_item_single_choice的layout,从这一长串名字可以看出这是android的layout,打开这个布局文件可以看到:

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@android:id/text1"    android:layout_width="match_parent"    android:layout_height="?android:attr/listPreferredItemHeightSmall"    android:textAppearance="?android:attr/textAppearanceListItemSmall"    android:gravity="center_vertical"    android:checkMark="?android:attr/listChoiceIndicatorSingle"    android:paddingStart="?android:attr/listPreferredItemPaddingStart"    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" />

忽略其他的设置,直接看我们想要更改的按钮样式android:checkMark=”?android:attr/listChoiceIndicatorSingle”
这一句就是默认按钮的设置,如果我们要设置我们自定义的样式的话,需要新建一个布局文件,然后将android:checkMark的属性设置成为我们想要的:
select_dialog_singlechoice.xml

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/text1"    android:layout_width="match_parent"    android:layout_height="?android:attr/listPreferredItemHeightSmall"    android:textAppearance="?android:attr/textAppearanceListItemSmall"    android:gravity="center_vertical"    android:checkMark="@drawable/selector_register_cb"    android:paddingStart="?android:attr/listPreferredItemPaddingStart"    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" />

这里我将android:checkMark属性换成了我自己写的一个selector文件,然后java代码中改一下adapter的参数:

ArrayAdapter<SpannableStringBuilder> adapter = new ArrayAdapter<>(this, R.layout.select_dialog_singlechoice, R.id.text1, chooseTypeList);

这里写图片描述

大功告成,产品汪终于表示很满意 : )
tips:

  • SpannableStringBuilder这个类其实非常实用功能也非常大,不仅可以提供分段设置字体颜色,还可以设置字体大小,字体样式,前景色背景色等等,总之就是使用得当的话这个类对减少布局层级非常有帮助。
  • SpannableStringBuilder如果声明为成员变量的话,记得在每一次append之前先clear一下。

其实开发中的实际效果图是这样的,描述文案折行并且字体调小了,使用SpannableStringBuilder都可以实现。
这里写图片描述

我在这里有一个疑问,设计想让我们checkout 按钮变成橙色,以及将cancel按钮置灰,我能想到的粗暴一点的方式是重写Dialog自定义按钮颜色,不知道大家有没有更好的建议和办法,如果有的话可以在下面评论留言,不胜感激 :)

0 0
原创粉丝点击