安卓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、继续分析

        我们 的 SwipeMenuAdapter 里 应该 怎样 处理 userAdapter 的 getView 生成 的 View 和 菜单 布局 的逻辑。   按上面的分析过程, 只需要 将 用户adapter的getView 生成的View 和  SwipMenuView  一起放置到 SwipItemLayout  里,  返回给 SwipeMenuAdapter 的 getView 方法 , 

伪代码如下:

SwipeMenuAdapter.java


@override

getView(){

SwipItemLayout   swipItemLayout  = new SwipItemLayout   (  userAdapter.getView(),  createSwipMenu()  );

return swipItemLayout 

}


createSwipMenu()
{

};


7、继续分析

        上一步分析中 createSwipMenu()  方法 是 adapter 自己的方法,  用户是没有办法 调用的,  而与用户的 交接 的 是  SwipMenuListView ,用户可以拿到 SwipMenuListView ,  所以只需要考虑 SwipMenuListView 中 如何 将 用户生成 的 菜单View 放置到 SwipeMenuAdapter 中。    简单说 就是:

原本由 SwipeMenuAdapter createSwipMenu 方法 完成的 任务, 现在需要由 SwipMenuListView  来完成(因为用户只能操作SwipMenuListView ), 而SwipMenuListView  完成的 创建 菜单数据源 怎么传递给 SwipeMenuAdapter  进行生成View。

        解决方法, 就是 在 SwipMenuListView   里写一个 内部类 继承自 SwipeMenuAdapter  , 覆写  SwipeMenuAdapter   的 createSwipMenu 方法 。并在 SwipMenuListView    提供一个接口, 供用户 生成 菜单item数据源。

       涉及到一个 小技巧: 类的通信方法两种, 第一  覆写 父类 的 方法, 第二 类内部增加一个 接口 供外部 调用。


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





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值