Android-->自定义ViewGroup, 银行卡片布局

这里写图片描述

首先了解下, 自定义View的三部曲.

1:onMeasure方法

此方法主要目的, 就是根据xml的
android:layout_width="wrap_content"
android:layout_height="wrap_content"

wrap_content match_parent 这2个属性, 来确定测量自身的大小.
当然, 这2个值, 只是parent告诉你, 需要按照此规则来测量, 如果你是一个坏孩子, 那么可以无视测量规则, 任意设置一个宽度和高度, 比如: setMeasuredDimension(1万, 2万) 就是如此简单;

2:onLayout方法

如果你是自定义View, 此方法可以不必override
如果你是自定义的ViewGroup, 那么就必须override, 此方法的目的就是由你决定child view在界面上的位置.

3:onDraw方法

在这个方法里面, 你可以展开你天才般的做图功能, 想画啥就画啥. 美美的view, 就这样出来了.
友情提示:如果你是自定义的ViewGroup, 还需要调用setWillNotDraw(false)方法, 否则onDraw方法不会执行哦


本文由于是自定义的ViewGroup, 所以重点是在onLayout方法里面;

不着急, 分析一波:
此需求, 说难不难, 说易不易.
易: 因为只要重写onLayout方法就行.
难: 你需要有一套规则限制onLayout方法.(如果你的规则很简单, 那么相当容易. 反之…)

1: 在默认情况下, 所有卡片按照层级和一定的偏移距离进行布局(相当于FrameLayout+marginTop的组合)
2: 当手指往下滑动的时候, 最顶层的卡片优先滑动到一定距离, 然后倒数第二层的卡片再滑动.以此类推
3: 当手指快速滑动的时候, 根据滑动方向,进行fling操作, 卡片自动折叠或展开.

需求就这么点.


这里说一下我相当的思路, 如果你有更简洁的思路, 欢迎交流.

假设卡片的高度(cardHeight)一定, 宽度一定. 相邻之间卡片默认状态时偏移的高度(offsetTop);
这种情况下, onLayout之后, 卡片的布局就是默认看到的状态了.

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
     int top = 0;
     int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
               View childAt = getChildAt(i);
               int layoutTop = top + offsetTop;
               childAt.layout(getPaddingLeft(), layoutTop, getMeasuredWidth() - getPaddingRight(), layoutTop + childAt.getMeasuredHeight());
               top += offsetTop;
           }
}

这样就完成了第一阶段了.

当手指滑动的时候, 比如向下滑动了dy.
我这里的思路就是, 把dy平分给每一个卡片的top上. 并且显示每一个卡片允许分到的最大top值;
这样, 在onLayout的时候, 加上这个top就行了.

//翻译成代码, 就是
    /**
     * 默认状态是, 每个View之间的间隔
     */
    public final int DEFAULT_MIN_OFFSET = (int) (40 * density());
    /**
     * 每一个View, 最多可以消耗多少距离
     */
    public final int DEFAULT_MAX_OFFSET = (int) (80 * density());

 private void refreshLayout() {
      int top = getPaddingTop();
      int childCount = getChildCount();

      //计算每个item view,能够消耗的高度
      for (int i = 0; i < childCount; i++) {
          View childAt = getChildAt(i);
          int needOffset = (childCount - 1 - i) * DEFAULT_MAX_OFFSET;
          if (currentOffset > needOffset) {
              needOffset = Math.min(currentOffset - needOffset, DEFAULT_MAX_OFFSET);

              if (i == 0) {
                  //如果是第一个item, 限制能够消耗的高度
                  //needOffset = Math.min(DEFAULT_MIN_OFFSET, needOffset);
                  needOffset = 0;
              }
          } else {
              needOffset = 0;
          }
          childAt.setTag(needOffset);
      }

      //开始布局item 
      for (int i = 0; i < childCount; i++) {
          View childAt = getChildAt(i);
          int offsetTop = getViewTop(childAt);
          int layoutTop = top + offsetTop;
          childAt.layout(getPaddingLeft(), layoutTop, getMeasuredWidth() - getPaddingRight(), layoutTop + childAt.getMeasuredHeight());
          top += DEFAULT_MIN_OFFSET + offsetTop;
      }
  }

联系作者

请使用QQ扫码加群, 小伙伴们在等着你哦!

关注我的公众号, 每天都能一起玩耍哦!

已标记关键词 清除标记
课程简介: 历经半个多月的时间,Debug亲自撸的 “企业员工角色权限管理平台” 终于完成了。正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十几张数据库表。 其中的核心业务模块主要包括用户模块、部门模块、岗位模块、角色模块、菜单模块和系统日志模块;与此同时,Debug还亲自撸了额外的附属模块,包括字典管理模块、商品分类模块以及考勤管理模块等等,主要是为了更好地巩固相应的技术栈以及企业应用系统业务模块的开发流程! 核心技术栈列表: 值得介绍的是,本课程在技术栈层面涵盖了前端和后端的大部分常用技术,包括Spring Boot、Spring MVC、Mybatis、Mybatis-Plus、Shiro(身份认证与资源授权跟会话等等)、Spring AOP、防止XSS攻击、防止SQL注入攻击、过滤器Filter、验证码Kaptcha、热部署插件Devtools、POI、Vue、LayUI、ElementUI、JQuery、HTML、Bootstrap、Freemarker、一键打包部署运行工具Wagon等等,如下图所示: 课程内容与收益: 总的来说,本课程是一门具有很强实践性质的“项目实战”课程,即“企业应用员工角色权限管理平台”,主要介绍了当前企业级应用系统中员工、部门、岗位、角色、权限、菜单以及其他实体模块的管理;其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限的管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为项目整体的运行效果截图: 值得一提的是,在本课程中,Debug也向各位小伙伴介绍了如何在企业级应用系统业务模块的开发中,前端到后端再到数据库,最后再到服务器的上线部署运行等流程,如下图所示:
©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师:上身试试 返回首页