Android使用DialogFragment实现段落缩进对话框

Android使用DialogFragment实现段落缩进对话框

一、目标

二、体验地址

神马笔记最新版本下载:【神马笔记 版本1.7.0——辅助编辑功能.apk

三、功能设计

段落缩进有2种实现方式。

  1. 在段落开始位置插入空白字符
  2. 使用LeadingMarginSpan
实现方式 优点 缺点
空白字符 保存为纯文本,依然保持缩进 删除时,需要删除空白字符
LeadingMarginSpan 删除时,不用额外删除 纯文本时,丢失格式

考虑到LeadingMarginSpan保持时,还必须额外保存Span信息,开发难度较大。

因此采用插入空白字符的段落缩进方式。

这样一来,必须让用户决定缩进的字符数以及空白字符类型(全角或者半角)。

段落缩进的参数。

  • 字符个数——[0, 12],默认为2,缩进2个字符。
  • 字符类型——{全角, 半角},默认为全角即中文。

四、实现过程

1. 类定义

代码类 Summary
IndentDialogFragment 缩进对话框类,负责管理Fragment跳转
IndentFragment 段落缩进界面(左侧图片)
ListOptionFragment 字符类型选单(右侧图片)

2. IndentFragment

IndentFragment包含2个设置项

  • 缩进个数——通过点击列表项右侧的“-”,“+”按钮,调整个数
  • 缩进类型——垫脚列表项跳转到ListOptionFragment选择类型

3. ListOptionFragment

可选项列表Fragment,由外部传入ArrayList<CharSequence>构建列表内容。

段落缩进传入{中文, 英文}2个项目。

4. IndentDialogFragment

负责管理IndentFragmentListOptionFragment的显示,并负责与调用者进行交互。

五、Fragment消息传递问题

段落缩进的3个Fragment实现非常简单,但Fragment之前的消息传递确是一个麻烦的事情。

1. 消息传递过程

Sender/Receiver IndentDialog Indent ListOption 调用者
IndentDialog / 1. 创建Indent作为初始显示的Fragment
2. 接收ListOption结果,并传递给Indent
接收Indent请求,初始化ListOption参数 告知用户操作结果
Indent 通知用户取消或者完成,及具体参数 / / /
ListOption 告知选项结果 / / /
调用者 创建并显示IndentDialog / / /

剔除IndentDialogFragment与调用者的交互,内部有4次消息传递。

IndentFragmentListOptionFragment之前不能进行直接进行消息传递,否则ListOptionFragment将无法复用,因此IndentDialogFragment需要来回传递二者的消息。在加上各自的一次消息传递,共4次消息传递。

1个DialogFragment内有n个子Fragment时,消息传递个数大约为n + 2 * (n - 1)

2. 消息传递的几种方式

1. 通用接口方式

1
2
3
4
5
public interface OnFragmentInteractionListener {

void onInteraction(Uri uri);

}

这是Android Studio创建Fragment子类可选的消息传递接口类。

2. 专用的接口方式

每个Fragment定义自身相关的消息接口类,类似于View的各种Listener。

具体实现方式,可参考以下文章。

3. EventBus

由greenrobot 组织贡献(该组织还贡献了greenDAO)的一个Android事件发布/订阅轻量级框架。

功能:通过解耦发布者和订阅者简化Android事件传递。

EventBus可以代替Android传统的Intent, Handler, Broadcast或接口函数, 在Fragment, Activity, Service线程之间传递数据,执行方法。

特点:代码简洁,是一种发布订阅设计模式(观察者设计模式)。

具体使用方式,可参考以下文章。

神马笔记当前使用的是第一种方案,虽然实现了需求功能。但重复了非常多的代码,并且使用了非常多的switch…case…if…else…语句,代码可读性和管理性非常之糟糕。

因为目前只有4次消息传递,勉强不进行修改。

未来版本设置富文本样式时,将会使用到非常多的设置选项,必须依循Donot Repeat Yourself原则实现一个技术方案。

TODO:留待未来的某一天来实现。

六、Finally

~深院静,小庭空~断续寒砧断续风~