自定义View

自定义控件的三种实现方法

  1. 对现有控件进行拓展
  2. 通过组合来实现新的控件:将系统原生控件组合起来,加上动画效果,形成一种特殊的UI效果
  3. 继承View来实现全新的控件

通过组合来实现新的控件

优酷菜单

对于消失动画

  • 角度:逆时针旋转,0 ~ -180
  • 旋转中心:底部中心点

轮播大图

ViewPager是Android 3.0之后才出现的,之前版本使用v4包里面的

ViewPager预加载机制:最多保存3个page,即当前显示的page以及位于其左右的page,超过的page要被销毁掉


下拉选择

如果Listview的item中有Button、ImageButton、CheckBox等会强制获取焦点的子控件,整个item将无法获取焦点,也就无法被点击

解决方法:给item的根布局增加以下属性

android:descendantFocusability="blocksDescendants"

重写View来实现全新的控件

滑动开关

  • 自定义控件步骤

    • 测量:onMeasure() 设置控件的原始测量宽高,如果不需要支持wrap_content属性,则无需重写该方法
    • 布局:onLayout() 设置控件显示在屏幕上的位置(只有在自定义ViewGroup时才需要重写,手动设置其子View的位置)
    • 绘制:onDraw() 绘制View显示在屏幕上的样子(只有在自定义View时才用到)
  • View和ViewGroup的相同点和不同点

    • 他们都需要进行测量操作
    • ViewGroup主要是控制子View如何摆放,所以自定义ViewGroup必须实现onLayout()
    • 自定义View必须实现onDraw()

下拉刷新

  • ListView的addHeaderView()必须在setAdapter()之前调用

  • 将headerView的paddingTop设置为其高度的负值可以隐藏它

  • getHeight()和getMeasuredHeight()的区别

    • getMeasuredHeight():获取原始测量高度,必须在onMeasure()之后执行

    • getHeight():获得最终显示高度,必须在onLayout()之后执行

  • 获取View宽高的两种方式

    1. 先使用view.measure(0,0)主动通知系统去测量View,然后再使用view.getMeasuredWidth()view.getMeasuredHeight()就可以成功获取原始测量宽高

    2. 为View注册一个监听器OnGlobalLayoutListener,当View的onLayout()执行完就会回调onGlobalLayout(),在回调方法中使用view.getWidth()view.getHeight()就可以成功获取宽高

       view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
           @Override
           public void onGlobalLayout() {  // onLayout()执行完
               view.getViewTreeObserver().removeOnGlobalLayoutListener(this); // 及时解除OnGlobalLayoutListener
               int viewHeight = view.getHeight(); // 直接可以获取宽高
           }
       });
      
  • setSelection(position)将position位置的item放置到屏幕顶端

侧滑菜单

  • 在自定义ViewGroup中一般不需要我们去重写onMeasure(),我们可以继承系统已有的ViewGroup,比如继承FrameLayout,它在onMeasure()中已经实现了对所有子View的测量,不需要我们再重写onMeasure()就已支持wrap_content属性
  • 在ViewGroup中,让内容移动有以下几个方法:

    • view.layout(l,t,r,b)

    • offsetLeftAndRight(offsetX)offsetTopAndBottom(offsetY)

    • 通过View的LayoutParams改变View的Margin

    • scrollTo(x, y)scrollBy(x, y),移动的是View的内容,而不是View本身,所以不会影响View的背景

  • 上面的方法都是瞬间移动,没有过渡效果(弹性滑动),下列方法可以让View在一段时间内移动到某个位置

    • 使用Scroller,模拟一个执行过程

    • 使用自定义动画,本质是让View在一段时间内做某件事

  • Touch事件分发机制的三个相关方法

    1. dispatchTouchEvent():用来分发触摸事件,如果接下来被拦截则交给onTouchEvent()处理,否则传递给子View

    2. onInterceptTouchEvent():返回true表示拦截,false表示不拦截

    3. onTouchEvent():处理触摸事件

你可能感兴趣的:(自定义View)