精华内容
下载资源
问答
  • Android自定义控件三部曲文章索引

    万次阅读 多人点赞 2016-11-25 17:39:06
    前言:在我从C++转到Android时,就被Android里炫彩斑斓的自定义控件深深折服,想知道如果想利用C++实现这些功能,那是相当困难的。从那时候起,我就想,等我学会了自定义控件,一定要写一篇系列出来,方便后来者能更...

    前言:在我从C++转到Android时,就被Android里炫彩斑斓的自定义控件深深折服,想知道如果想利用C++实现这些功能,那是相当困难的。从那时候起,我就想,等我学会了自定义控件,一定要写一篇系列出来,方便后来者能更系统完善地掌握它。今天,这个系列就这样默默地诞生了,希望它能够完成它的使命,在你读完这系列博客时,发现定自义控件也不过如此!如果,顺便能给个评论,加个关注,我将不胜感激——启舰

     

    我的新书《Android自定义控件入门与实战》出版啦:https://blog.csdn.net/harvic880925/article/details/81455073

     

    一、自定义控件三部曲之动画篇

    1、《自定义控件三部曲之动画篇(一)——alpha、scale、translate、rotate、set的xml属性及用法》
    2、《自定义控件三部曲之动画篇(二)——Interpolator插值器》
    3、《自定义控件三部曲之动画篇(三)—— 代码生成alpha、scale、translate、rotate、set及插值器动画》
    4、《自定义控件三部曲之动画篇(四)——ValueAnimator基本使用》

    • 初识ValueAnimator:ofInt,ofFloat以及监听器用法

    5、《自定义控件三部曲之动画篇(五)——ValueAnimator高级进阶(一)》

    • 这一节非常重要,讲解了插值器与Evaluator的使用与如何自定义知识
    • 这节中有如何做到背景色渐变的特效

    6、《自定义控件三部曲之动画篇(六)——ValueAnimator高级进阶(二)》

    • 这节着重讲解了ValueAnimator的ofObject函数用法
    • 可以看到自定义弹性圆的伸缩特效
    • 如何给A-Z字母变化添加上插值器效果

    7、《自定义控件三部曲之动画篇(七)——ObjectAnimator基本使用》

    • 这节讲了ObjectAnimator的用法及如何利用ObjectAnimator来实现前几节的效果

    8、《自定义控件三部曲之动画篇(八)——PropertyValuesHolder与Keyframe》

    • 这节主要讲了如何自定义关键帧的知识
    • 使用关键帧实现电话振铃效果

    9、《自定义控件三部曲之动画篇(九)——联合动画的代码实现》

    • 这节讲解了如何实现组合动画的知识包括顺序播放、同时播放和自由定义顺序播放以及动画监听器相关的知识

    10、《自定义控件三部曲之动画篇(十)——联合动画的XML实现与使用示例》

    • 利用XML来实现组合动画的知识
    • 实现了路径菜单动画

    11、《 自定义控件三部曲之动画篇(十一)——layoutAnimation与gridLayoutAnimation》

    • 讲解了容器类中控件的进入动画的实现方式

    12、《自定义控件三部曲之动画篇(十二)——animateLayoutChanges与LayoutTransition》

    • 自定义容器类中控件进入、退出等相关动画的实现方式


    13、《自定义控件三部曲之动画篇(十三)——实现ListView Item进入动画》

    • 讲解了一个实例:如何实现listview中各个item进场时的动画

     

    在动画篇中,从一到十篇是必须要掌握的,11-13篇不是必须掌握的,有个印象就行

     

    二、自定义控件三部曲之绘图篇

    1、《自定义控件三部曲之绘图篇(一):概述及基本几何图形绘制》
    2、《自定义控件三部曲之绘图篇(二):路径及文字》
    3、《自定义控件三部曲之绘图篇(三):区域(Range)》
    4、《自定义控件三部曲之绘图篇(四):canvas变换与操作》
    5、《自定义控件三部曲之绘图篇( 五):drawText()详解》
    6、《 自定义控件三部曲之绘图篇(六)——Path之贝赛尔曲线和手势轨迹、水波纹效果》

    • 本篇将讲述手势轨迹捕捉、波浪纹效果实现的几种方法

    7、《 自定义控件三部曲之绘图篇(七)——Paint之函数大汇总》

    • 本篇将讲述路径的各种效果,比如铁锈路径、自定义图形路径、虚线路径等

    8、《自定义控件三部曲之绘图篇(八)——Paint之ColorMatrix与滤镜效果》

    • 本篇将讲述各种滤镜效果的实现方法:包括黑白滤镜、反古滤镜、色彩增强滤镜、色彩替换等

    9、《自定义控件三部曲之绘图篇(九)——Paint之setColorFilter》

    • 按钮点击时,动态加深图片色彩(简易方法)
    • 可以学到针对不同主题动态设置不同色彩图片的方法(setTint())

    10、《自定义控件三部曲之绘图篇(十)——Paint之setXfermode(一)》

    • 硬件加速的原理与禁用方法
    • 选区颜色替换、溶合图片、反向选区颜色替换

    11、《自定义控件三部曲之绘图篇(十一)——Paint之setXfermode(二)》

    • 书架中书本选中灯光效果
    • Twiter标识中空效果实现
    • 图片圆角实现
    • 图片倒影实现
    • 橡皮擦效果实现
    • 刮刮卡效果实现

    12、《自定义控件三部曲之绘图篇(十二)——Paint之setXfermode(三)》

    • 区域波纹动画效果
    • 心电图动画
    • 不规则波纹
    • 刷刷卡、图片倒影等另种实现方式

    13、《自定义控件三部曲之绘图篇(十三)——Canvas与图层(一)》

    • 这篇文章中没有任何特效,但这是绘图篇中非常重要的一篇,对于理解Canvas绘图起着重要作用

    14、《自定义控件三部曲之绘图篇(十四)——Canvas与图层(二)》

    • 上一篇的续篇,讲解了save、saveLayer、saveLayerAlpha中所使用的FLAG的具体意义

    15、《自定义控件三部曲之绘图篇(十五)——QQ红点拖动删除效果实现(基本原理篇)》

    • 对以往知识点进行总结复习,涉及有Canvas绘图、SaveLayer图层、贝赛尔曲线、手势监听和逐帧动画等
    • 初步实现了QQ红点拖动效果

    16、《自定义控件三部曲之绘图篇(十六)——给控件添加阴影效果与发光效果》

    • 传统地给按钮添加阴影的方法
    • 如何给已有控件添加阴影
    • 如何给控件添加发光效果

    17、《自定义控件三部曲之绘图篇(十七)——为Bitmap添加阴影并封装控件》

    • 如何给图片添加阴影
    • 如何自定义控件属性
    • 控件如何自测量
    • 如何最终封装成控件

    18、《自定义控件三部曲之绘图篇(十八)——BitmapShader与望远镜效果》

    • 实现望远镜效果
    • 封装不规则头像控件

    19、《自定义控件三部曲之绘图篇(十九)——LinearGradient与闪动文字效果》

    • 讲解了LinearGradient的意义
    • 实现了闪动文字效果控件

    20、《自定义控件三部曲之绘图篇(二十)——RadialGradient与水波纹按钮效果》

    • 讲解了RradialGradient知识
    • 实现了按钮水波纹效果

     

    三、自定义控件三部曲之视图篇

    1、《自定义控件三部曲视图篇(一)——测量与布局》

    • 讲解onMeasure、onLayout的区别与用法
    • 讲解margin的计算方法

    2、《自定义控件三部曲视图篇(二)——FlowLayout自适应容器实现》

    • 实现了自适应的派生自ViewGroup的容器FlowLayout

    3、《自定义控件三部曲视图篇(三)——瀑布流容器WaterFallLayout实现》

    • 讲解了自定义LayoutParams并使用的方法
    • 能够了解派生自ViewGroup的控件如何定义与使用的方法

    4、《自定义控件三部曲视图篇(四)——RecyclerView系列之一简单使用》

    • 讲解了RecyclerView的基本使用方法,为下篇深入讲解做准备

    5、《自定义控件三部曲视图篇(五)——RecyclerView系列之二ItemDecoration》

    • 讲解了ItemDecoration与Item的关系
    • ItemDecoration的用法
    • 自定义ItemDecoration与蒙版效果

    6、《自定义控件三部曲视图篇(六)——RecyclerView系列之三自定义LayoutManager》

    • 讲解了自定义LayoutManager的方法
    • 讲解了如何初始化Item布局,如何实现Item的滚动

    7、《自定义控件三部曲视图篇(七)——RecyclerView系列之四实现回收复用》

    • 讲解了RecyclerView的回收复用原理
    • 讲解了为自定义LayoutManager添加回收复用的实现方法

    8、《自定义控件三部曲视图篇(八)——RecyclerView系统之五回收复用实现方式二》

    • 讲解了另一种实现回收复用的方法
    • 实现了针对每个Item布局,同时在布局后更改每个Item的属性的方法

    9、《自定义控件三部曲视图篇(九)——RecycerView系列之六实现滚动画廊控件》

    • 实现2D画廊
    • 实现fling校正的方法
    • 实现3D画廊的方法

     

    如果你喜欢我的文章,你可能更喜欢我的公众号

    启舰杂谈

     

     

     

    展开全文
  • 用户自定义控件,用户自定义控件,用户自定义控件,用户自定义控件,用户自定义控件,用户自定义控件,用户自定义控件,用户自定义控件,用户自定义控件用户自定义控件,用户自定义控件,用户自定义控件,用户自定义...
  • 自定义控件

    2016-03-26 15:14:34
    自定义控件

    实际上的自定义控件很多种类型,但现在基本上非原生控件都叫做自定义控件,那么今天就来研究研究自定义控件到底是个啥。

    自定义控件分类

    这里的分类是依照实现方式进行的。自定义控件可以分为以下几种类型:
    一、继承原生控件的View

    1. 简单重写其中方法
    2. 改变控件布局

    二、继承原生布局的ViewGroup

    1. 修改其中的方法
    2. 修改控件布局
    3. 设置指定子View

    自定义控件实现

    自定义控件种类繁多,实现方式也是各种各样,也正是因为多样化的设计才让Android的控件永远不乏新意。(只有你想不到,没有我做的到( ̄ε(# ̄)☆╰╮( ̄▽ ̄///))

    关于自定义控件最重要的就是三个方法,也就是传说中的onMeashure()、onLayout()、onDraw()

    别的不扯,自定义控件所需要的基本设置有哪些,具体研究一下,这一点很重要:

    1.继承View它的子类(包括ViewGroup)

    说要自定义控件,总归来说做的还是一个控件,所以还是要做继承,只是做个自定义View,总不至于连View都自己写。

    完成继承以后,根据所要做的自定义View不同,那么要进行的工作也就不一样了,一般来说,尽量继承与自定义控件结构相似的已有控件,这也是为了减少工作量。举个例子,想要做一个很酷炫的文本输入框,那直接继承EditText就好,要什么效果再做具体修改。没必要从继承View开始,那样会毁灭世界的。(没那么夸张,当时真的没那个必要)

    2.做自定义内容设置

    这一步就要分为两种种情况了,分开两种讲:

    • 第一种:继承View
      继承View的做法,表示当前没有存在哪些能够满足或是靠近你要求的控件存在,此时我们就要自己创造一个,一般的步骤如下:

    1.复写构造方法

    //这个是用来初始化控件的
    
    /**打个比方**/
    public class CustomerView extends View{
        public CustomerView (Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public CustomerView (Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomerView (Context context) {
            super(context);
        }
    }

    2.重写onMeasure()方法
    这个方法是用来控制控件的宽高值的

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    //参数widthMeasureSpec和heightMeasureSpec分别指代行准确测量值以及高准确测量值,根据父类的onMeasure(),它们是存在自己的默认值的,根据父控件以及本身的宽高属性(wrap_content之类)来确定值。
    
    //而在这个方法中,也可以由程序设定时自行制定
    
    //注意这个方法,这是最终设置控件的宽高值
            setMeasuredDimension(widthMeasureSpec,heightMeasureSpec);
        }

    3.重写onDraw()方法
    我知道onLayout()方法不见了,但是我真的没吃它,事实上,View是不存在onLayout()方法的,原因是onLayout()用来控制控件中的布局,但是View中是不存在子View的(单身控(#‵′)凸),因此直接完成onDraw()方法基本就能搞定这个自定义控件了。

    protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            //看到了Canvas以后,一切都明了了,这个控件现在是个画板了,想在上面画什么,全凭大家的需求和想象力了。
        }

    4.完善工作
    自定义控件毕竟不是只用来看的,不然请UI切份图给我们就好了,还写一大块的代码干嘛,需要声明控件中的各种各样七七八八的功能都能在里面完成,提供给应用使用,还能在里面添加观察者,说到观察者,有兴趣可以移步http://blog.csdn.net/baidu_20596139/article/details/50930716,也是我写的,可以交流一下


    • 第二种:继承已有控件
      同样是自定义的View,这一种自定义控件相对来说就简单了很多。首先,这个控件的基本结构已经存在了,那么做这一种继承一般是为了修改控件中的一些方法或是某些显示方式,那么要做的就是:1.继承 2. 复写
      需要对哪修改就复写哪个方法,简单快捷,赞一个(^o^)/YES!

    但是!! 不得不说,当需要高个性化的控件,这种方法真的就没什么用处了,还是需要使用第一种方式。


    说完了继承View的情况,还有一种继承ViewGroup的情况

    1.继承ViewGroup
    选择一个与需求最为匹配的布局作为父类,能够帮助快速方便的完成自定义控件的设计。

    2.根据需求选择完成方式:

    • 有指定的布局样式
    • 修改原布局部分功能
    • 指定内部布局方式或绘制内容

    首先是有指定布局样式

    //通过这句代码将指定的布局添加到ViewGroup中,这里的viewGroup就应该是this
    View.inflate(context,layout,viewGroup);

    完成了这个步骤,接下来有其他的需要就可以编写其他的方法进行控件的操作。

    另一个是修改原布局功能
    这其实是一个小部分的方法重写,实现也很简单,一般我用来处理事件传递方法。

    再一个就是有自行绘制需求
    这一点中onMeasure()和onDraw()参考View的继承就行,基本上是一样的,这里讲一下onLayout()。
    这个方法是用来设置子View的摆放的,也就是说ViewGroup中放置View的位置可以由这个方法完成。

    protected abstract void onLayout(boolean changed,int l,int t,int r,int b){
    //在该方法中能够设定各个子View的位置
        //可以使用获取子View
        getChild()
    }

    基本简单的自定义控件完成方法都介绍完了,事实上还有很多详细的实现方法以及其他的实现方式,在这片文章里就不做介绍了。

    展开全文
  • C#自定义控件

    千次下载 热门讨论 2013-01-22 23:17:46
    C#自定义控件
  • C#实现自定义控件、在项目工具箱中加入控件、调用控件。
    1. 新建一个windows自定义控件的项目
      在这里插入图片描述
    2. 在界面上拖入:一个picturebox1 , 6个label,1个button
      picturebox1命名为picBox,左边三个label的text改为:文件名称、文件大小、文件尺寸;右边的三个label的name改为lblName、lblLength、lblSize
      button的name属性改为btnOpen.
      在这里插入图片描述
      代码如下:
    namespace 自定义控件
    {
        public partial class UserControl1: UserControl
        {
            public UserControl1()
            {
                InitializeComponent();
            }
    
            private void btnOpen_Click(object sender, EventArgs e)
            {
                OpenFileDialog ofdPic = new OpenFileDialog();
                ofdPic.Filter = "JPG(*.JPG;*.JPEG);gif文件(*.GIF)|*.jpg;*.jpeg;*.gif";
                ofdPic.FilterIndex = 1;
                ofdPic.RestoreDirectory = true;
                ofdPic.FileName = "";
                if (ofdPic.ShowDialog() == DialogResult.OK)
                {
                    string sPicPaht = ofdPic.FileName.ToString();
                    System.IO.FileInfo fiPicInfo = new System.IO.FileInfo(sPicPaht);
                    long lPicLong = fiPicInfo.Length / 1024;
                    string sPicName = fiPicInfo.Name;
                    string sPicDirectory = fiPicInfo.Directory.ToString();
                    string sPicDirectoryPath = fiPicInfo.DirectoryName;
                    Bitmap bmPic = new Bitmap(sPicPaht);
                    if (lPicLong > 400)
                    {
                        MessageBox.Show("此文件大小為" + lPicLong + "K;已超過最大限制的K范圍!");
                    }
                    else
                    {
                        Point ptLoction = new Point(bmPic.Size);
                        if (ptLoction.X > picBox.Size.Width || ptLoction.Y > picBox.Size.Height)
                        {
                            picBox.SizeMode = PictureBoxSizeMode.Zoom;
                        }
                        else
                        {
                            picBox.SizeMode = PictureBoxSizeMode.CenterImage;
                        }
                    }
                    picBox.LoadAsync(sPicPaht);
                    lblName.Text = sPicName;
                    lblLength.Text = lPicLong.ToString() + " KB";
                    lblSize.Text = bmPic.Size.Width.ToString() + "×" + bmPic.Size.Height.ToString();
                }
              
            }
        }
    }
    
    

    3、鼠标右键点击项目名,重新生成下
    在这里插入图片描述
    4、新建一个常规winform界面项目,打开自定义控件的文件,找到控件项目想的Debug里面的dll文件,拖进当前项目的工具箱中

    在这里插入图片描述
    5、在当前的界面中就可以调用这个控件了
    在这里插入图片描述
    参考链接:https://blog.csdn.net/xiongxuanwen/article/details/2605109

    展开全文
  • 目录 1 开关需求整体介绍 2 画开关的背景和滑块 ...前面总结到自定义控件分为 ...上一篇写了自定义控件的自定义属性深入理解点击链接查看,是自定控件比较难以理解的地方,但是是很重要滴,是基础。...

    前面总结到自定义控件分为

    • 组合控件
    • 继承已有控件 比如自定义SmartImageView继承ImageView
    • 完全自定义控件

    上一篇写了自定义控件的自定义属性深入理解点击链接查看,是自定控件比较难以理解的地方,但是是很重要滴,是基础。这一篇是完全自定义控件就是继承基类View,实现一个开关控件的功能,会用到以下几个知识点:
    - 自定义属性
    - View的绘制流程
    - View的事件处理
    - 回调函数

    最后实现的开关效果如下:
    这里写图片描述


    目录

    1 开关需求整体介绍

        开关是一个单纯的控件view,不是已有控件的组合即组合控件,他实际上就是根据两张图绘制而成,下层是开关背景,上层是滑块,绘制成view控件后动态的控制滑块的位置就能实现开关打开、关闭的效果,比如本文例子的材料就是2张图,通过图绘制而成的开关控件,图一:
    这里写图片描述
    图二:
    这里写图片描述

    布局中引用控件MyToggleButton:

    <com.yezhu.myapplication.togglebutton.MyToggleButton
                android:id="@+id/mtb"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                yezhu:slideBackGround="@drawable/slide_background"
                yezhu:slideIcon="@drawable/slide_icon" />

    自定义属性attrs:

     <!--自定义开关按钮-->
        <declare-styleable name="MyToggleButton">
            <attr name="slideBackGround" format="reference" />
            <attr name="slideIcon" format="reference" />
            <attr name="state" format="boolean" />
        </declare-styleable>

    拿到控件的属性:

      public MyToggleButton(Context context) {
            this(context, null);
        }
    
        public MyToggleButton(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public MyToggleButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initView(context, attrs);
        }
    
        private void initView(Context context, AttributeSet attrs) {
            //1.拿到控件的引用值
            TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.MyToggleButton);
            int resSlideBack = attributes.getResourceId(R.styleable.MyToggleButton_slideBackGround, 0);
            int resSlideIcon = attributes.getResourceId(R.styleable.MyToggleButton_slideIcon, 0);
    
            //2.根据引用值
            bitmapSlideBack = BitmapFactory.decodeResource(getResources(), resSlideBack);
            bitmapSlideIcon = BitmapFactory.decodeResource(getResources(), resSlideIcon);
    
            //3.拿到图之后  根据图绘制控件 调用onMeasure 测量 排版 绘制
    
            //4.走完onDraw后界面上已经能显示控件 后设置控件的事件onTouchEvent
        }

    拿到图之后就要开始绘制控件,view的绘制流程是

    1. 测量onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法
    2. 排版
    3. 绘制 onDraw(Canvas canvas) 方法

    似乎每一个过程展开讲都能说繁多,view的绘制渲染过程很复杂还有诸多如view过度渲染的原因等面试题,本例子只是简单的说明其流程。

    2 画开关的背景和滑块

       想要绘制view首先要测量,我们拿到背景图和滑块图2个bitmap,那开关的大小肯定是背景图的大小,所以有:

      @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            //根据值设定控件的大小
            setMeasuredDimension(bitmapSlideBack.getWidth(), bitmapSlideBack.getHeight());
    
        }
    

    setMeasuredDimension()就指定了你要绘制的view控件的宽高。

       其次是排版,由于我们的基类是View,所以不需要排版。继承ViewGroup时需要根据要求进行排版的,之后会有例子。

       再者是绘制,绘制是根据canvas画布来实现的,当代码走完这一步的时候我们在界面上就能看到真实的控件了,当然还没有设置具体的事件监听。

        @Override
        protected void onDraw(Canvas canvas) {
    
            canvas.drawBitmap(bitmapSlideBack, 0, 0, null);
    
            canvas.drawBitmap(bitmapSlideIcon, 30, 0, null);
        }

    canvas.drawBitmap(bitmapSlideIcon, 30, 0, null);方法中有四个参数,参数1是根据哪个图片绘制、参数2 距离左侧的距离、参数3 距离顶部的距离、参数4 Paint画笔是否需要。

       这里我们把left写死30,效果如下:显然上层滑块距初始位置右移30,也为我们动态控制开关提供了思路,只要在控件onTouchEvent(MotionEvent event)方法中根据手指的按下、移动、抬起动态的改变left值,再重新调用onDraw(Canvas canvas)就能实现开关的切换效果。
    这里写图片描述

    3 实现开关的功能

       如上所述只要在控件onTouchEvent(MotionEvent event)方法中根据手指的按下、移动、抬起时动态的改变left值,再重新调onDraw(Canvas canvas)就能实现开关的切换效果。
       代码:

     @Override
        public boolean onTouchEvent(MotionEvent event) {
    
            int action = event.getAction();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    //手指按下 上层icon距离左侧的位置 最左侧代表是关 最右侧代表开
                    //iconLeft 距离左侧的距离 画图体会
                    iconLeft = (int) event.getX() - bitmapSlideIcon.getWidth() / 2;
    
                    break;
    
                case MotionEvent.ACTION_MOVE:
                    //手指移动
                    iconLeft = (int) event.getX() - bitmapSlideIcon.getWidth() / 2;
    
                    break;
    
                case MotionEvent.ACTION_UP:
                    //手指抬起 要是当前的手指抬起时的位置 已经是超过了背景的一半 松开手就是打开开关
                    // 要是手指抬起时(离开控件)的位置 尚不足背景的一半  松开手默认关闭开关
    
                    if ((int) event.getX() > (int) bitmapSlideBack.getWidth() / 2) {
                        iconLeft = bitmapSlideBack.getWidth() - bitmapSlideIcon.getWidth();
    
                    } else {
                        iconLeft = 0;
                    }
    
    
                    break;
            }
    
            invalidate();//调用这个方法 内部默认走一遍onDraw()方法
    
            // 设置成true 是指当前监听自己消费此事件
            return true;
        }
    

    需要解释的是:

    event.getX()可以获取当前你点击的位置相对按钮横坐标,还有一个getRowX()方法时获取触摸点相对于屏幕的坐标;

    在手指按下和移动时滑块距离左侧的位置都是event.getX()-背景宽度的一半,单纯的说特别难以理解,画图佐证一下:
    这里写图片描述

    再者当抬起时要根据当前滑块的位置判断一下到底是关闭还是打开,画图佐证:
    这里写图片描述
    当抬起时位置超过了背景的一半就默认打开,否则执行关闭。

    invalidate();必须要调用,内部调用的是onDraw()方法。
    返回值是true意味着此次事件由当前监听自己消费掉。

    4 开关回调

       在初学button时总是写点击事件setOnClickListener(new OnOnClickListener ..),那么我们这里也可以模仿点击事件写一个回调函数,当控件打开是toast提示或者做一些保存开关标志的操作。

    关于回调我自己的解释是假设你写一个函数是为了显示当前控件的状态, 当控件有了事件触发的时候, 你写的那个函数就会显示改变之后的,就是回调。这样一想有没有感觉好多了,再者有没有感觉回调好像只有一个观察者的观察者模式,当被观察者发生变化时通知注册了的观察者做对应操作。

       那么在onTouchEvent()方法中手指抬起时就可以这样操作:

     case MotionEvent.ACTION_UP:
                    //手指抬起 要是当前的手指抬起时的位置 已经是超过了背景的一半 松开手就是打开开关
                    // 要是手指抬起时(离开控件)的位置 尚不足背景的一半  松开手默认关闭开关
    
                    if ((int) event.getX() > (int) bitmapSlideBack.getWidth() / 2) {
                        iconLeft = bitmapSlideBack.getWidth() - bitmapSlideIcon.getWidth();
    
                        isOpen = true;
                    } else {
                        iconLeft = 0;
    
                        isOpen = false;
                    }
    
                    //手指抬起 开关打开 界面toast 开关如何操作 ? 回调 界面引用开关处 多一个监听
                    if (mListener != null) {
                        mListener.onToggleState(isOpen);
                    }
    
                    break;

       对于控件使用时:

      MyToggleButton myToggleButton = (MyToggleButton) findViewById(R.id.mtb);
    
            //做开关状态监听 回调 开关打开 吐司
            myToggleButton.setOnToggleStateListener(new MyToggleButton.OnToggleStateListener() {
                @SuppressLint("WrongConstant")
                @Override
                public void onToggleState(boolean state) {
                    if (state) {
                        Toast.makeText(MainActivity.this, "打开", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(MainActivity.this, "关闭", Toast.LENGTH_SHORT).show();
                    }
    
                }
            });

       以上就是全部的实现,希望能对大家对自定义控件时view绘制流程有一个大概认识。文章中如有叙述错误或不明确的地方请大家私信或留言指出。烦劳点个赞可好?

    展开全文
  • 首先,自定义控件分为三类: 自定义的组合控件 继承View的自定义控件 继承ViewGroup的自定义控件 在这里,我要写的是第二种,也就是继承自View的自定义控件,第一种自定义的组合控件,我已经写过了,可以在我的...
  • QT 自定义控件自定义控件设置QSS无效 解决办法: 重载需要重载其paintEvent函数即可 具体: void QMyToolButton::paintEvent(QPaintEvent*) { QStyleOption opt; opt.init(this); QPainter p(this); ...
  • 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一)、自定义属性Android自定义控件之自定义属性(二)。今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发成本,以及维护成本。 ...
  • 1.开发环境 Qt版本:Qt 4.8.7 编译器:MinGw 系统:Windows 2.创建Qt4自定义控件 ...此时编译出来Release版本的自定义控件放进Designer目录下仅能在Designer中拖动,在使用该控件的工程中编译将会报错,所...
  • 在这篇博客中主要讲解给Android自定义控件添加点击事件,实现可以按住百分比圆圈在屏幕上进行拖动圆圈的功能。分两部分讲,第一部分是获取自定义控件的坐标,第二部分是重新绘制控件。 没有看过自定义控件的可以先...
  • 一步一步详细介绍自定义控件的开发流程。 这边介绍一个最为原始的自定义控件demo------多个activity公用某个自定义控件。 主要步骤如下: 1.编写自定义控件的layout文件; 2.实现自定义控件的动作; 3.在需要添加...
  • 在安卓开发中,谷歌已经为我们提供了许多原生控件,基本上能够满足我们日常的开发需求,但是某些项目中原生控件可能达不到产品所要求的各式各样的酷炫效果或功能效果,这个时候我们只能自己自定义控件来满足项目需求...
  • 一、代码 1. 在自定义控件的时候分为自定义控件和子控件,自定义固定控件的时候直接在
  • android自助餐之自定义控件(一)从layout自定义控件android自助餐之自定义控件一从layout自定义控件 从layout自定义控件 从layout自定义控件 layout中新建一个layout ...
  • CSharp开发自定义控件类库并测试的简单例子 最近想研究一下怎么编写CSharp的自定义控件,在此记录一下学习过程: 首先讲一下我的解决方案工程的组成: 首先打开VS(我的是VS2015)新建一个Windows窗体应用程序,...
  • 自定义控件之 - 自定义LinearLayout控件 1.1 引入布局include 1.2 自定义LinearLayout控件 自定义控件之 - 自定义LinearLayout控件 1.1 引入布局include 最终效果 要创建这样的标题栏只需在界面中...
  • 决定由浅入深的来学习与Android自定义控件有关的知识。首先先从如何设置自定义控件的属性开始吧。 实现的效果:  像系统控件一样,可以在布局文件中设置控件的属性。 实现步奏: 一、在res/values中添加 二...
  • 原文:WPF 自定义控件的坑(蠢的:自定义控件内容不显示) 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/koloumi/article/details/73915903 ...
  • 简单的理解了自定义控件后,才发现,当使用自定义控件的时候,一个很大的问题,里面的控件不会随着自定义控件的改变而改变(包括Size,Font和Location)。上网查了一下,发现这个问题的解决不尽人意。用dock和Anchor...
  • 编写Qt Designer自定义控件(四)——使用自定义控件 分类: Qt2013-10-11 19:47 4190人阅读 评论(10) 收藏 举报 接上文:编写Qt Designer自定义控件(三)——给自定义控件添加属性  控件编写...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 64,963
精华内容 25,985
关键字:

自定义控件