AlertDialog.Builder+SpannableStringBuilder自定义单选框

原创 2016年09月06日 00:29:07

这里写图片描述
在项目开发的时候,产品汪希望我们做出这种样式的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创建单选列表对话框

说到AlertDialog.Builder就不得不提下这个安卓中典型的一个构造者模式,那Buidler模式就是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.Builder模...

单选框的用法即几种常见对话框

一、单选框 RadioGroup的组事件,可以将各自不同的RadioButton,设定与同一个RadioGroup组里的按钮,做出单一选择。 RadioGroup中使用类组单选按钮。如果我们选中一...

Android之在Dialog中添加单选按钮【自定义Dialog】

XML 文件: 创建一个点击按钮并添加点击方法:

Android中AlertDialog内含单选框或者复选框

主要代码如下: 创建代码: /*** * 显示提示对话框 * * @param ctx * @param Title * 标题 * @p...

AlertDialog.Builder对话框(2)之单选框,多选框,列表框和进度框

由于都是比较常见的,且容易懂,代码量较少: 1,带进度条的对话框ProgressDialog:可以想象一下应用场景,当我们登录扣扣账号后,点击“确定”,将跳转到登录等待界面 其代码实现为: Pro...
  • willba
  • willba
  • 2016年11月18日 21:34
  • 126

自定义对话框初级之改变单选框颜色

一个小小单选框

自定义单选框复选框样式

  • 2017年08月20日 15:11
  • 2KB
  • 下载

5分钟DIY一个自定义单选框单选按钮

转眼间2017年了,在这里祝大家2017都能 展翅高飞、心想事成! 上次写博已经是两个月前了,这两个月七搞八搞学了不少黑科技日后必会分享给大家~下面咱们就开门见山了由于浏览器本身自带的单选按钮且不说...

android 自定义ListView 使其带单选框按钮,并解决item点击不响应的问题

android 自定义ListView 使其带单选框按钮,并解决item点击不响应的问题 自己定义ListView就要自己写个LIstviewAdapter继承BaseAdapter这个类然后通过其中...

ios自定义控件复选框和单选框的实现

我们先实现单个按钮,为了复用,不管单选还是复选按钮都是使用同一个类来实现,为了区别单选还是复选,我们用一个自定义枚举类型CheckButtonStyle属性style来区别,当其值设置为CheckBu...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AlertDialog.Builder+SpannableStringBuilder自定义单选框
举报原因:
原因补充:

(最多只允许输入30个字)