用最简单且兼容性最好的方式去实现dialog的有序列表
来源:互联网 发布:知乎qq不能登陆了 编辑:程序博客网 时间:2024/06/03 12:42
用最简单且兼容性最好的方式去实现dialog的有序列表
最近项目开发,遇到这样一个dialog的需求,请看图:
这里有一个细节,如 2. 那条,如果文字长度超过一行,下一行文字是从序号后边对齐的。
要实现这种dialog,也厚很多种实现方式
- 自定义 dialog 布局,把内容写死在里边
- 用 html 标签来完成这种布局
- 自定义 LeadingMarginSpan ,用 SpannableStringBuilder 拼接字符串来实现(本篇的主要内容)
第一种方式(自定义 dialog 布局)
应该大多数人都会的,就是麻烦一点。
第二种方式(html 标签)
相比第一种简单了很多,直接用 Html.fromHtml()
来包裹 html标签的内容就可以了。起初我用的是这种方式,测试后也没问题,但在魅族手机上发现, html 标签有的不识别(文字前边的序号没有出来),对开发者来说 android 的开源有时候也会带来麻烦。。只好重新研究实现方式了。
第三种方式(自定义 LeadingMarginSpan)
/** * A paragraph style affecting the leading margin. There can be multiple leading * margin spans on a single paragraph; they will be rendered in order, each * adding its margin to the ones before it. The leading margin is on the right * for lines in a right-to-left paragraph. * <p> * LeadingMarginSpans should be attached from the first character to the last * character of a single paragraph. */
这是 LeadingMarginSpan 的官方注释,大致意思就是 它可以影响一个段落的文字的起始 margin 值(原谅我的英语渣水平。。。)
ok,重点来了,下面就是自定义这货来实现 dialog 的有序列表了,好上代码:
public class NumberIndentSpan implements LeadingMarginSpan { private int gapWidth; private final int index; public NumberIndentSpan(int index) { this.index = index; } public int getLeadingMargin(boolean first) { return gapWidth; } public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout l) { if (first) { Paint.Style orgStyle = p.getStyle(); p.setStyle(Paint.Style.FILL); String text1 = index + ". "; float width = p.measureText(text1); gapWidth = (int) width; com.orhanobut.logger.Logger.d(dir + ""); com.orhanobut.logger.Logger.d(width + ""); com.orhanobut.logger.Logger.d(x + ""); c.drawText(text1, x, baseline, p); p.setStyle(orgStyle); } }}
使用姿势
项目的设计是,api 成功后,返回一个 string 类型的集合,本地通过 dialog 去显示有序文本内容:
private void showSuccessTip(List<String> completeStrs) { SpannableStringBuilder completeStr = new SpannableStringBuilder(); completeStr.append("请留意:\n"); for (int i = 0; i < completeStrs.size(); i++) { int contentStart = completeStr.length(); completeStr.append(completeStrs.get(i)).append("\n"); NumberIndentSpan numberIndentSpan = new NumberIndentSpan(i + 1); completeStr.setSpan(numberIndentSpan, contentStart, completeStr.length(), 0); }
这种方式我认为应该是最简单兼容性最好的方式了吧,
ok,今天就到这里了,如有不同意见欢迎拍砖~
更正一下一个内容
第三种自定义 LeadingMarginSpan,这种方法虽然实现了,但是发现控件测量字符串的宽度不准确了,靠近右边缘的字体有的被遮住半个,如图:
又研究了一下 LeadingMarginSpan 这个类,发现了一种神奇的东西 LeadingMarginSpan.Standard
第四种方式(LeadingMarginSpan.Standard)
Standard 类是 LeadingMarginSpan 的一个内部类,它有三个构造方法,如下:
/** * Constructor taking separate indents for the first and subsequent * lines. * * @param first the indent for the first line of the paragraph 段落第一行距离左边的间距 * @param rest the indent for the remaining lines of the paragraph 段落除第一行外剩下所有行距离左边的间距 */ public Standard(int first, int rest) { mFirst = first; mRest = rest; } /** * Constructor taking an indent for all lines. * @param every the indent of each line */ public Standard(int every) { this(every, every); } public Standard(Parcel src) { mFirst = src.readInt(); mRest = src.readInt(); }
ok,我们用到的就是 Standard(int first, int rest)
,下边贴出使用方法:
private void showSuccessTip(List<String> completeStrs) { SpannableStringBuilder completeStr = new SpannableStringBuilder(); completeStr.append("请留意:\n"); for (int i = 0; i < completeStrs.size(); i++) { int contentStart = completeStr.length(); String leadStr = (i + 1) + ". "; completeStr.append(leadStr); completeStr.append(completeStrs.get(i)); completeStr.append("\n"); int contentEnd = completeStr.length(); completeStr.setSpan(new LeadingMarginSpan.Standard(0, (int) mRightMenu.getPaint().measureText(leadStr)) , contentStart, contentEnd, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } MaterialDialogUtil.showSendSuccessTip(_mActivity, "提问成功", completeStr , new MaterialDialog.SingleButtonCallback() { @Override public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { pop(); } }); }
这里不需要自定义什么类就完成了,无疑是最省事的,可见如果对 android 本身了解的不多,是要做多少无用功。。
以此自勉,继续奋进吧
- 用最简单且兼容性最好的方式去实现dialog的有序列表
- 实现两有序数组的合并仍为新有序数组,且不对新数组排序的最简单方法
- 最简单的数组去重方式
- 最简单的Dialog
- 最简单最好用的天气预报接口
- 最简单最好用的天气预报接口
- 用最简单的数组去实现队列
- 最简单的Dialog程序
- QTreeWidget Qt最常用最好用的树状列表窗体
- 最简单的对Java List列表按中文拼音排序的实现方式
- android中最简单的去Title方式
- 用最简单的办法,实现最好的打印(用BCB调用WORD的打印功能)
- 用最简单的办法,实现最好的打印(用BCB调用记事本的打印功能)
- 【简单向】用最简单易懂的方式实现FFT
- 最简Dialog的实现
- 解决el-dialog弹框多重嵌套,实现最好用的el-dialog
- 最简单的方式实现文件下载
- 最简单的截屏实现方式
- Swift: 消除警告-Scene is unreachable due to lack of entry points and does not have an identifier for
- 汇编之寄存器
- 【备忘】2017最新传智播客黑马java 32期基础就业班视频教程
- filterModel自动搜索机制
- VM中的Ubuntu配置置固定IP(NAT方式)
- 用最简单且兼容性最好的方式去实现dialog的有序列表
- SOA开发-001应用基本规范
- ZooKeeper的安装与部署
- 图像处理之特殊灰度算法技巧
- 第三章 授权——跟我学习springmvc shiro mybatis
- 【深入理解反向传播BP】Calculus on Computational Graphs: Backpropagation
- 阅读清单
- 模仿OKhttp框架Builder初始化数据,如何优雅地装逼
- Linux启动Tomcat服务器命令行