Android自定义控件

Android学习笔记,整理给自己复习的时候看的,谢谢!

  • Android自身带的控件不能满足需求, 需要根据自己的需求定义控件.

自定义控件可以分为三大类型

1. 组合已有的控件实现

  • 优酷菜单
    1. 在xml布局里摆放好
    2. 给指定控件添加点击事件
    3. 根据业务逻辑,执行动画(旋转动画: 补间动画)
    4. 菜单按钮的截获

  • 轮播图广告
    1. 让图片滑动起来(ViewPager)
    2. 让图片和文字,指示器对应起来
    3. 让轮播器无限循环

        向右无限循环  
            0 -> 4  newPosition = position % 5  
            5 -> 0  
            6 -> 1  
            7 -> 2  
            8 -> 3  
            9 -> 4  
           10 -> 0  
        向左无限循环  
            设置到中间某个位置.      
    4. 轮播器自动轮询, OK      
    
  • 下拉选择框

  • Button或ImageButton等自带按钮功能的控件会抢夺所在Layout的焦点.导致其他区域点击不生效.在所在layout声明一个属性

    android:descendantFocusability="blocksDescendants"
    
  • popupwindow获取焦点, 外部可点击

        // 设置点击外部区域, 自动隐藏
    popupWindow.setOutsideTouchable(true); // 外部可触摸
    popupWindow.setBackgroundDrawable(new BitmapDrawable()); // 设置空的背景, 响应点击事件
    
    popupWindow.setFocusable(true); //设置可获取焦点
    

2. 完全自定义控件.(继承View, ViewGroup)

1. 自定义开关
    1. 写个类继承View
    1. 拷贝包含包名的全路径到xml中
    1. 界面中找到该控件, 设置初始信息
    1. 根据需求绘制界面内容
    1. 响应用户的触摸事件
    1. 创建一个状态更新监听
    // 1. 声明接口对象
    public interface OnSwitchStateUpdateListener{
        // 状态回调, 把当前状态传出去
        void onStateUpdate(boolean state);
    }
    // 2. 添加设置接口对象的方法, 外部进行调用
    public void setOnSwitchStateUpdateListener(
            OnSwitchStateUpdateListener onSwitchStateUpdateListener) {
                this.onSwitchStateUpdateListener = onSwitchStateUpdateListener;
    }
    // 3. 在合适的位置.执行接口的方法    
    onSwitchStateUpdateListener.onStateUpdate(state);
    // 4. 界面/外部, 收到事件.
    1. 自定义属性
1. 在attrs.xml声明节点declare-styleable
<declare-styleable name="ToggleView">
            <attr name="switch_background" format="reference" />
            <attr name="slide_button" format="reference" />
            <attr name="switch_state" format="boolean" />
        </declare-styleable>
2. R会自动创建变量

    attr 3个变量
    styleable 一个int数组, 3个变量(保存位置)

3. 在xml配置声明的属性/ 注意添加命名空间
    xmlns:itheima="http://schemas.android.com/apk/res/com.itheima74.toggleview"

        itheima:switch_background="@drawable/switch_background"
        itheima:slide_button="@drawable/slide_button"
        itheima:switch_state="false"
4. 在构造函数中获取并使用
// 获取配置的自定义属性
        String namespace = "http://schemas.android.com/apk/res/com.itheima74.toggleview";
        int switchBackgroundResource = attrs.getAttributeResourceValue(namespace , "switch_background", -1);
  • Android 的界面绘制流程
  测量             摆放     绘制
  measure   ->  layout  ->  draw
      |           |          |
  onMeasure -> onLayout -> onDraw 重写这些方法, 实现自定义控件

  都在onResume()之后执行

  View流程
  onMeasure() (在这个方法里指定自己的宽高) -> onDraw() (绘制自己的内容)

  ViewGroup流程
  onMeasure() (指定自己的宽高, 所有子View的宽高)-> onLayout() (摆放所有子View) -> onDraw() (绘制内容)
2. 侧滑面板
  1. 在xml布局里摆放内容. include
    1. 在自定义ViewGroup里, 进行measure测量, layout布局
    2. 响应用户的触摸事件
    3. int scrollX = (int) (downX - moveX);
    4. getScrollX()获取当前滚动到的位置
    5. 平滑动画
//1. 开始模拟数据

        scroller.startScroll(startX, 0, dx, 0, duration);
        invalidate();// 重绘界面 -> drawChild() -> computeScroll();

    //2. 在computeScroll中不断获取模拟的数值

        @Override
        public void computeScroll() {
            super.computeScroll();
            if(scroller.computeScrollOffset()){
                // true, 动画还没有结束
                // 获取当前模拟的数据, 也就是要滚动到的位置
                int currX = scroller.getCurrX(); 
                scrollTo(currX, 0); // 滚过去

                invalidate(); // 重绘界面
            }
        }

3. 继承已有的控件实现(扩展已有的功能)

    1. 包含下拉刷新功能的ListView

    2. 添加了自定义的头布局

    3. 默认让头布局隐藏setPadding.设置 -自身的高度
    4. ListView下拉的时候, 修改paddingTop, 让头布局显示出来
    5. 触摸动态修改头布局, 根据paddingTop.

      • paddingTop = 0 完全显示
      • paddingTop < 不完全显示 -64(自身高度)完全隐藏
      • paddingTop > 0 顶部空白
    6. 松手之后根据当前的paddingTop决定是否执行刷新

      • paddingTop < 0 不完全显示, 恢复
      • paddingTop >= 0 完全显示, 执行正在刷新…
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值