安卓Swipemenulistview侧滑删除 源码分析

今天分析一下 安卓侧滑删除 的 源码, 源码来自github,名称: SwipeMenuListView。 需要源码的童鞋可以自己去github 搜索下载。

要看懂这篇文章 一定要 先把 github 上 SwipMenuListView 的 源码 下载 下来先 分析 一遍, 分析不透彻 或者 理解不了 的 时候 再来看这篇 文章, 否则 这篇 文章 会看的 不知 所云.

目的:

分析源码的实现 和 代码结构, 学习源码中的设计模式。 并发现源码中的不足,, 提出解决方法。

1 、思考:

要实现 ListView 滑动删除,那一定是在 ListView 的 Item 的 布局上 做文章, 手指在 item(下称之为 item 根布局,包括显示层和菜单) 上向左滑动时 , 底部出现 删除 等菜单, 那么 item 的布局 涉及到 两方面的 内容,第一是 item 本身需要显示的内容(下称之为 item内容显示层), 第二是 滑动后底部的菜单布局(item菜单布局)。 这两个部分 分离出来 单独设计。

2、继续分析

从面向对象的角度来思考, 应该 是 item 根布局 同时包含 内容显示层 和 菜单布局, 但是 内容显示层 是需要用户调用的时候决定的,所以这个布局 的代码应该是写在 用户的 adapter 的 getView 里, 菜单布局 需要抽象分离出来 , 暂且命名为 SwipMenuView 。把 item 根布局命名为 SwipItemLayout 。 然而 这两者的关系 应该 是 SwipItemLayout 包含 SwipMenuView , 就是说 SwipItemLayout类 应该有一个SwipMenuView 类型的成员变量 。

结论:SwipItemLayout 类 应该有一个SwipMenuView 类型的成员变量

3、继续分析

SwipMenuView的菜单会有自己的一些属性,比如 菜单名称、 菜单图标的 资源id、 菜单的背景颜色、菜单文字大小、菜单文字颜色、菜单文字和菜单图标的排版方式左右还是上下等, 所以需要有一个 SwipeMenuItem 类 来描述 这些 信息。 有同学会问, 为什么不把这些信息 当作 成员变量 直接 放在SwipMenuView类里,按功能来说这样做确实也可以, 但是违背了类的单一职责原则,也不便于扩展。

单一职责原则怎么理解呢? SwipMenuView本来应该是 继承自 某Layout 的一个 布局类完成生成View的功能, 而现在 却把 布局里的View的属性如菜单名称图标等 工作也完成了, 使得SwipMenuView的内部逻辑过于复杂。

不便于扩展怎么理解呢? 假设日后有一个需要 滑动后出现多个菜单,那不是要把 菜单名称、图标、文字大小 等属性全部 换成 ArrayList 成员变量 来保存? 到时候再改 这 代码量 就会非常 庞大,不便于扩展。

怎么解决呢? 再新建一个类 SwipeMenuItem , 把 菜单名称、图标、颜色、文字大小这些属性 保存在这个 类里,让SwipMenuView类有一个成员变量 SwipeMenuItem

结论:SwipMenuView 类有一个成员变量 SwipeMenuItem

4、继续分析

之前说的不便于扩展怎么解决呢? 假设以后要支持多个菜单怎么办? 方法 就是 让 SwipMenuView有一个成员变量SwipeMenuItem的 List数组。 这样SwipMenuView生成布局的时候 根据 SwipeMenuItem的 List 数组 把 所有的 菜单 都 add到 自己 Layout 里 。

结论:SwipMenuView 类有一个成员变量SwipeMenuItem 的 List 数组

5、继续分析

菜单布局的 设计 已经完成, 但是 item内容显示层 和 菜单布局 还是 耦合 在一起的, 怎么解决? item内容显示层 的 布局生成 的代码 应该是 用户的 adapter 里, 这一块是我们的 侧滑删除 不能去修改的。 用户上层 只会调用一个 setAdapter 方法, 传进来用户自己的 Adapter , 我们能做文章的 就只有 用户这一个 adapter 了。 所以 需要 思考 对 用户的 adapter 如何进行 处理 来 分离 item内容显示层 和 菜单布局 的代码。

解决方法 就是 , 重写 ListView 的 SetAdapter 方法, 将用户的adapter 包装成 我们的 adapter, 这就需要 再定义一个类SwipeMenuAdapter 继承自 ListAdapter , 同时 一个成员变量 ListAdapter 类型, 保存的就是 用户的 adapter 。

@Override public void setAdapter(ListAdapter userAdapter) { super.setAdapter(new SwipeMenuAdapter(getContext(), userAdapter) ;

}

那我们的 SwipeMenuAdapter 里面 就有了 用户的 userAdapter , 这样我们就有了 处理 用户 adapter 里getView 生成的 View 的能力了。

6、继续分析

游手好闲会使人心智生锈

安卓Swipemenulistview侧滑删除 源码分析

相关文章:

你感兴趣的文章:

标签云: