美文网首页
自定义控件笔记1

自定义控件笔记1

作者: 唐嘉娆 | 来源:发表于2018-06-07 16:22 被阅读0次

自定义控件:用系统自带控件重新组合或者自定义类继承View或者自定义类继承ViewGroup,实现特定的UI效果。

重点:
a.View和ViewGroup的区别
b.Android中事件的传递
c.View的原理

事例一:优酷菜单


youku1.png

由于这里是以中心为旋转点,所以pivotXValue就是view.getWidth()/2,pivotYValue就是view.getHeight()

class Tools {

    /**
     * 隐藏
     * @param view
     */
    public static void hideView(View view) {

       hideView(view,0);
    }

    /**
     * 显示
     * @param view
     */
    public static void showView(View view) {

       showView(view,0);
    }

    /**
     * 有延迟时间的隐藏
     * @param view
     * @param startOffset
     */
    public static void hideView(View view, int startOffset) {
        /**
         * fromDegrees 从哪个角度 toDegrees 到哪个角度  水平线为x轴
         * pivotXValue  pivotYValue 是相对于x y坐标的位置 控件的左上角的坐标为(0,0) 右下角为(1,1)
         * 由于这里是以中心为旋转点,所以pivotXValue就是view.getWidth()/2,pivotYValue就是view.getHeight()
         *
         */
        RotateAnimation animation = new RotateAnimation(0,180,view.getWidth()/2,view.getHeight());
        //设置动画的速度
        animation.setDuration(500);
        //设置动画结束后停留在改变后的位置
        animation.setFillAfter(true);
        //设置延迟动画时间
        animation.setStartOffset(startOffset);
        view.startAnimation(animation);
    }

    /**
     * 有延迟时间的显示
     * @param view
     * @param startOffset
     */
    public static void showView(View view, int startOffset) {

        RotateAnimation animation = new RotateAnimation(180,360,view.getWidth()/2,view.getHeight());
        //设置动画的速度
        animation.setDuration(500);
        //设置动画结束后停留在改变后的位置
        animation.setFillAfter(true);
        //设置延迟动画时间
        animation.setStartOffset(startOffset);
        view.startAnimation(animation);
    }
}

问题:如果此时隐藏掉所有的菜单,点击一级菜单会出现bug,因为即使这个视图已经旋转过去,但是它的属性还在,所以可以点击。


youku2.png

如果直接修改成以下代码会无效

 /**
     * 有延迟时间的隐藏
     * @param view
     * @param startOffset
     */
    public static void hideView(View view, int startOffset) {
        /**
         * fromDegrees 从哪个角度 toDegrees 到哪个角度  水平线为x轴
         * pivotXValue  pivotYValue 是相对于x y坐标的位置 控件的左上角的坐标为(0,0) 右下角为(1,1)
         * 由于这里是以中心为旋转点,所以pivotXValue就是view.getWidth()/2,pivotYValue就是view.getHeight()
         *
         */
        RotateAnimation animation = new RotateAnimation(0,180,view.getWidth()/2,view.getHeight());
        //设置动画的速度
        animation.setDuration(500);
        //设置动画结束后停留在改变后的位置
        animation.setFillAfter(true);
        //设置延迟动画时间
        animation.setStartOffset(startOffset);
        view.startAnimation(animation);
        view.setEnabled(false);
    }

    /**
     * 有延迟时间的显示
     * @param view
     * @param startOffset
     */
    public static void showView(View view, int startOffset) {

        RotateAnimation animation = new RotateAnimation(180,360,view.getWidth()/2,view.getHeight());
        //设置动画的速度
        animation.setDuration(500);
        //设置动画结束后停留在改变后的位置
        animation.setFillAfter(true);
        //设置延迟动画时间
        animation.setStartOffset(startOffset);
        view.startAnimation(animation);
        view.setEnabled(true);
    }

因为传进来的view是RelativeLayout,而RelativeLayout是继承ViewGroup的,即使其设置了Enabled,也只是对他自身有效,但是他里面的子view依然可以被点击。

解决办法:
1.将View改为ViewGroup,循环出其子View,并且对每个子View设置Enabled。
2.通过属性动画解决

方法1:

/**
     * 有延迟时间的隐藏
     * @param view
     * @param startOffset
     */
    public static void hideView(ViewGroup view, int startOffset) {
        /**
         * fromDegrees 从哪个角度 toDegrees 到哪个角度  水平线为x轴
         * pivotXValue  pivotYValue 是相对于x y坐标的位置 控件的左上角的坐标为(0,0) 右下角为(1,1)
         * 由于这里是以中心为旋转点,所以pivotXValue就是view.getWidth()/2,pivotYValue就是view.getHeight()
         *
         */
        RotateAnimation animation = new RotateAnimation(0,180,view.getWidth()/2,view.getHeight());
        //设置动画的速度
        animation.setDuration(500);
        //设置动画结束后停留在改变后的位置
        animation.setFillAfter(true);
        //设置延迟动画时间
        animation.setStartOffset(startOffset);
        view.startAnimation(animation);
        for (int i = 0;i<view.getChildCount();i++){
            View child = view.getChildAt(i);
            child.setEnabled(false);
        }

    }

    /**
     * 有延迟时间的显示
     * @param view
     * @param startOffset
     */
    public static void showView(ViewGroup view, int startOffset) {

        RotateAnimation animation = new RotateAnimation(180,360,view.getWidth()/2,view.getHeight());
        //设置动画的速度
        animation.setDuration(500);
        //设置动画结束后停留在改变后的位置
        animation.setFillAfter(true);
        //设置延迟动画时间
        animation.setStartOffset(startOffset);
        view.startAnimation(animation);
        for (int i = 0;i<view.getChildCount();i++){
            View child = view.getChildAt(i);
            child.setEnabled(true);
        }

    }

android包含三种动画:View Animation(补间)、Drawable Animation(帧动画)、property Animation(属性动画)

View Animation:
基于View的渐变动画,只改变了View的绘制效果,而实际属性未变,比如动画移动一个按钮的位置,但按钮的实际点击位置未变。在代码中定义动画,可以参考AnimationSet类和Animation子类,而如使用Xml,可以在res/anim/文件夹中定义Xml。(事例一则是View Animation)

Drawable Animation:加载一系列的Drawable资源来创建动画,这种传统动画某种程度上就是创建不同图片序列,顺序播放。在代码中定义使用AnimationDawable类;XMl文件更简单的组成动画帧,在res/drawable文件夹,使用<animation-list>采用<item>来定义不同的帧。

property Animation:动画的对象除了是view对象,还可以是Object对象,动画之后,Object对象的属性值被实实在在的改变。view属性改变,view能自动调用invalidate来刷新。

方法2:

/**
     * 有延迟时间的隐藏
     * @param view
     * @param startOffset
     */
    public static void hideView(ViewGroup view, int startOffset) {


        //使用属性动画
        //第一个参数是作用的对象,第二个参数是要改变的属性名,小写
        //例子 view.setRotation();
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view,"rotation",0,180);
        //设置动画的速度
        objectAnimator.setDuration(500);
        //设置延迟时间
        objectAnimator.setStartDelay(startOffset);
        //设置旋转中心
        view.setPivotX(view.getWidth()/2);
        view.setPivotY(view.getHeight());
        objectAnimator.start();

    }

    /**
     * 有延迟时间的显示
     * @param view
     * @param startOffset
     */
    public static void showView(ViewGroup view, int startOffset) {


        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view,"rotation",180,360);
        //设置动画的速度
        objectAnimator.setDuration(500);
        //设置延迟时间
        objectAnimator.setStartDelay(startOffset);
        //设置旋转中心
        view.setPivotX(view.getWidth()/2);
        view.setPivotY(view.getHeight());
        objectAnimator.start();

    }

更简单的写法:

/**
     * 有延迟时间的隐藏
     * @param view
     * @param startOffset
     */
    public static void hideView(ViewGroup view, int startOffset) {

        OtherFunction(view,startOffset);

    }

    /**
     * 有延迟时间的显示
     * @param view
     * @param startOffset
     */
    public static void showView(ViewGroup view, int startOffset) {

        OtherFunction(view,startOffset);
    }

    private static void OtherFunction(ViewGroup view, int startOffset) {
        //另一种写法
        view.setPivotX(view.getWidth()/2);
        view.setPivotY(view.getHeight());
        view.animate()
                .rotationBy(180)    //旋转角度
                .setDuration(500)
                .setStartDelay(startOffset)
                .start();
    }

相关文章

  • 自定义控件讲解(csdn爱哥)

    自定义控件其实很简单1/12 自定义控件其实很简单1/6 自定义控件其实很简单1/4 自定义控件其实很简单1/3 ...

  • Android面试准备

    一、简历准备 1、个人技能 (1)自定义控件、UI设计、常用动画特效 自定义控件 ①为什么要自定义控件? Andr...

  • 学习笔记—Android 控件架构与自定义控件

    《Android 群英传》第三章 “ Android 控件架构与自定义控件详解 ” 学习笔记 Android控件...

  • android2019-01-03

    1.View的绘制流程自定义控件:1、组合控件。这种自定义控件不需要我们自己绘制,而是使用原生控件组合成的新控件。...

  • 完全自绘控件示例

    参考:Android利用canvas画各种图形。 1. 自定义控件 (1) eg1: 自定义控件 MyMessag...

  • 自定义控件笔记1

    自定义控件:用系统自带控件重新组合或者自定义类继承View或者自定义类继承ViewGroup,实现特定的UI效果。...

  • 购物车加减器自定义组合控件

    一.案例效果 二.技术点描述: 1.自绘控件(完全自定义控件):继承的是RelativeLayout2.自定义控件...

  • Python 学习笔记 050

    续前节 tkinter学习笔记 6-8 6.Text控件文本控件,用于显示多行文本 Entry控件加强版 自定义插...

  • 组合控件2——海贼王选项菜单

    之前的自定义控件——初识自定义控件,我们了解到了自定义控件分为三种,自制控件,组合控件,拓展控件。而我们在自制控件...

  • 自定义控价的认识

    自定义控件 Android自身带的控件不能满足需求, 需要根据自己的需求定义控件. 自定义控件可以分为三大类型 1...

网友评论

      本文标题:自定义控件笔记1

      本文链接:https://www.haomeiwen.com/subject/mmlgsftx.html