AlertDialog.Builder+SpannableStringBuilder自定义单选框
Posted 碎格子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AlertDialog.Builder+SpannableStringBuilder自定义单选框相关的知识,希望对你有一定的参考价值。
在项目开发的时候,产品汪希望我们做出这种样式的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转px
textView.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自定义按钮颜色,不知道大家有没有更好的建议和办法,如果有的话可以在下面评论留言,不胜感激 :)
以上是关于AlertDialog.Builder+SpannableStringBuilder自定义单选框的主要内容,如果未能解决你的问题,请参考以下文章
带有Edittext setView的Android AlertDialog Builder在底部显示?
Android运用Builder来创建Alertdialog
AlertDialog.Builder+SpannableStringBuilder自定义单选框
AlertDialog.Builder#show 上的“android.view.WindowManager$BadTokenException”即使有保护措施