zoukankan      html  css  js  c++  java
  • 27 自定义View 和案例

    • 有时安卓提供的View不满足我们的需求时可以创建一个类继承View或其子类重写方法

      package com.qf.sxy.day28_customview.view;
      
      import android.content.Context;
      import android.graphics.Canvas;
      import android.graphics.Color;
      import android.graphics.Paint;
      import android.util.AttributeSet;
      import android.view.View;
      
      /**
       * Created by sxy on 2016/9/28.
       */
      public class MyTextView extends View {
          /**
           * 在逻辑代码中使用
           * @param context
           */
          public MyTextView(Context context) {
              super(context);
          }
      
          /**
           * 布局文件中使用    note:布局中使用必须有俩个参数
           * @param context
           * @param attrs   布局中设置的属性
           */
          public MyTextView(Context context, AttributeSet attrs) {
              super(context, attrs);
          }
      
          /**
           * @param context
           * @param attrs 布局中设置的属性
           * @param defStyleAttr 指定样式资源
           */
          public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
              super(context, attrs, defStyleAttr);
          }
      
      
          /**
           * 绘制的方法
           * @param canvas   画布
           */
          @Override
          protected void onDraw(Canvas canvas) {
              super.onDraw(canvas);
      
              //创建画笔对象
              Paint paint =  new Paint();
              paint.setColor(Color.BLUE);
      //        paint.setColor(0xff00);//0x 红  绿 蓝
              paint.setStrokeWidth(3);//设置画笔粗细
              paint.setAntiAlias(true);//抗锯齿 边缘柔和
              paint.setTextSize(30);//设置文字大小
              paint.setStyle(Paint.Style.STROKE);//设置样式  空心
              /**
               * 画直线
               * 参数1:x轴起始位置
               * 参数2:y轴起始位置
               * 参数3:x轴终止位置
               * 参数4:y轴终止位置
               * 参数5:画笔对象
               */
              canvas.drawLine(0,0,getWidth(),getHeight(),paint);
      
              /**
               * 画圆
               * 参数1,2:圆心
               * 参数3:半径
               * 参数4:画笔
               */
              canvas.drawCircle(200,200,100,paint);
      
              /**
               * 画文字
               * 参数1:内容
               * 参数2,3:起始位置
               * 参数4:画笔
               */
              canvas.drawText("国庆快乐",0,100,paint);
      
              /**
               * 画图片
               */
             // canvas.drawBitmap();
              /**
               * 画矩阵
               */
             // canvas.clipRect()
      
              //....
          }
      }
      
    • 在使用此自定义View的时候在布局文件 写完整的包名类名

      •   <!--
            使用自定义View   包名+类名
            -->
            <com.qf.sxy.day28_customview.view.MyTextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />
    • 如果我们想在布局文件中设置属性的话 那么可以按一下步骤

      • 在valus文件夹新建一个resources文件
      • <?xml version="1.0" encoding="utf-8"?>
        <resources>
            <!--
            circleColor  圆的颜色
            sweepColor   扫描的颜色
            startAngle 起始角度
            sweepAngle 扫描角度
            sweepStep 每次扫描的步数
            -->
            <declare-styleable name="ProgressView">
                <attr name="circleColor" format="color|reference"></attr>
                <attr name="sweepColor" format="color|reference"></attr>
                <attr name="startAngle" format="integer|reference"></attr>
                <attr name="sweepAngle" format="integer|reference"></attr>
                <attr name="sweepStep" format="integer|reference"></attr>
            </declare-styleable>
        </resources>
      • 赋值方法

        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:orientation="vertical"
            tools:context="com.qf.sxy.customview3.MainActivity">
        
            <com.qf.sxy.customview3.widget.ProgressView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:circleColor="#00ff00"
                app:sweepColor="#0000ff"
                app:sweepStep="10"
                app:sweepAngle="0"
                app:startAngle="0"
                 />
            <com.qf.sxy.customview3.widget.ProgressView
                android:layout_width="200dp"
                android:layout_height="200dp"
                app:circleColor="#0000ff"
                app:sweepColor="#ff00ff"
                app:sweepStep="2"
                app:startAngle="-90"
                 />
            <com.qf.sxy.customview3.widget.ProgressView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:circleColor="#00ffff"
                app:sweepColor="#005644"
                app:sweepStep="20"
                app:startAngle="180"
                 />
        </LinearLayout>
        
      • 获取属性值

          public ProgressView(Context context) {
                        this(context,null);
                    }
        
                    public ProgressView(Context context, AttributeSet attrs) {
                        super(context, attrs);
                        //获取布局中属性
                        TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.ProgressView);
                        if(array!=null){
                            circleColor = array.getColor(R.styleable.ProgressView_circleColor,Color.BLUE);
                            sweepColor = array.getColor(R.styleable.ProgressView_sweepColor,Color.RED);
                            startAngle = array.getInteger(R.styleable.ProgressView_startAngle,-90);
                            sweepStep = array.getInteger(R.styleable.ProgressView_sweepStep,1);
                        }
        
                    }

    具体案例一

    一个最基础的案例 继承一个View画一个圆等
    这里写图片描述

    • 重写View文件MyTextView.java
    package com.qf.sxy.day28_customview.view;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.view.View;
    
    /**
     * Created by sxy on 2016/9/28.
     */
    public class MyTextView extends View {
        /**
         * 在逻辑代码中使用
         * @param context
         */
        public MyTextView(Context context) {
            super(context);
        }
    
        /**
         * 布局文件中使用    note:布局中使用必须有俩个参数
         * @param context
         * @param attrs   布局中设置的属性
         */
        public MyTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        /**
         * @param context
         * @param attrs 布局中设置的属性
         * @param defStyleAttr 指定样式资源
         */
        public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
    
        /**
         * 绘制的方法
         * @param canvas   画布
         */
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            //创建画笔对象
            Paint paint =  new Paint();
            paint.setColor(Color.BLUE);
    //        paint.setColor(0xff00);//0x 红  绿 蓝
            paint.setStrokeWidth(3);//设置画笔粗细
            paint.setAntiAlias(true);//抗锯齿 边缘柔和
            paint.setTextSize(30);//设置文字大小
            paint.setStyle(Paint.Style.STROKE);//设置样式  空心
            /**
             * 画直线
             * 参数1:x轴起始位置
             * 参数2:y轴起始位置
             * 参数3:x轴终止位置
             * 参数4:y轴终止位置
             * 参数5:画笔对象
             */
            canvas.drawLine(0,0,getWidth(),getHeight(),paint);
    
            /**
             * 画圆
             * 参数1,2:圆心
             * 参数3:半径
             * 参数4:画笔
             */
            canvas.drawCircle(200,200,100,paint);
    
            /**
             * 画文字
             * 参数1:内容
             * 参数2,3:起始位置
             * 参数4:画笔
             */
            canvas.drawText("国庆快乐",0,100,paint);
    
            /**
             * 画图片
             */
           // canvas.drawBitmap();
            /**
             * 画矩阵
             */
           // canvas.clipRect()
    
            //....
        }
    }
    

    布局文件activity_main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.qf.sxy.day28_customview.MainActivity">
    
    <!--
    使用自定义View   包名+类名
    -->
    <com.qf.sxy.day28_customview.view.MyTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
    </RelativeLayout>
    

    具体案例二

    说明
    展示如何设置属性 然后在布局文件里面赋值 和在重写类获取对应属性值

    这里写图片描述

    (重写View方法的类)MyTextView.java

    package com.qf.sxy.customview02.widget;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.view.View;
    import android.widget.TextView;
    
    import com.qf.sxy.customview02.R;
    
    /**
     * Created by sxy on 2016/9/28.
     */
    public class MyTextView extends View {
    
        TextView tv;
    
        private Paint mPaint;
    
        private String mText="哈哈";
        public MyTextView(Context context) {
            super(context);
            initPain();
        }
    
        public MyTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initPain();
    
            //获取布局资源中的属性
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyTextView);
    
            //获取文本内容
            CharSequence ch = array.getText(R.styleable.MyTextView_text);
            if(ch!=null&&!"".equals(ch)){
                setText(ch.toString());
            }
            //获取文本颜色
            int textColor = array.getColor(R.styleable.MyTextView_textColor,Color.BLACK);
            settextColor(textColor);
    
            //获取字体大小
            int textSize = (int)(array.getDimension(R.styleable.MyTextView_textSize,30));
            setTextSize(textSize);
    
    
        }
    
    
        //设置字体大小
        private void setTextSize(int textSize) {
            mPaint.setTextSize(textSize);
            requestLayout();//重新绘制画布 会
            invalidate();//进行刷新(重新获取数据)
        }
    
    
        //设置文本颜色
        public void settextColor(int textColor) {
            mPaint.setColor(textColor);
            requestLayout();//重新绘制画布
            invalidate();//进行刷新(重新获取数据)
        }
        //给文本设置内容
        private void setText(String str) {
            mText = str;
            //onMeasure只会重新调用次方
            requestLayout();//重新绘制画布
            //重新调用ondraw方法 和上诉方法正好相反
            invalidate();//进行刷新(重新获取数据)
        }
    
        public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initPain();
        }
    
    
        //初始化画笔对象
        public void initPain() {
            mPaint = new Paint();
            mPaint.setColor(Color.RED);
            mPaint.setAntiAlias(true);
            mPaint.setTextSize(30);
            //设置文字的内边距
            setPadding(10,10,10,10);
        }
    
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            //给画布设置颜色
            canvas.drawColor(Color.GREEN);
    
            canvas.drawText(mText,getPaddingLeft(),getPaddingTop()-mPaint.ascent(),mPaint);
        }
    
        /**
         * 测量控件大小
         * @param widthMeasureSpec
         * @param heightMeasureSpec
         */
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
    //        //得到设置的模式
    //        int wMode = MeasureSpec.getMode(widthMeasureSpec);
    //        //获取父布局的宽高/50dp
    //        int wSize = MeasureSpec.getSize(widthMeasureSpec);
    //
    //        /**
    //         * MeasureSpec.UNSPECIFIED:Adapter View用到  未设定尺寸
    //         * MeasureSpec.AT_MOST:wrap_content  根据里面内容变化而变化
    //         * MeasureSpec.EXACTLY:match_parent/50dp   精准的值
    //         */
    //
    //        if(wMode == MeasureSpec.AT_MOST){//wrap_content  根据里面内容变化而变化
    //            //获取宽  计算
    //
    //        }else if(wMode == MeasureSpec.EXACTLY){ //match_parent/50dp   精准的值
    //            //wSize
    //        }
    
            //设定最终的宽和高
           setMeasuredDimension(Measure(widthMeasureSpec,1),Measure(heightMeasureSpec,2));
        }
    
    
        //进行测量
        public int Measure(int Spec ,int type){
    
            int result=0;//返回的值
    
            int mode = MeasureSpec.getMode(Spec);
            int size = MeasureSpec.getSize(Spec);
    
            if(mode == MeasureSpec.AT_MOST){//wrap_content  根据里面内容变化而变化
                //计算
                if(type==1){//获取宽     左右内边距+文字宽
                    result = (int)(getPaddingLeft()+getPaddingRight()+mPaint.measureText(mText));
                }else if(type==2){//获取高
                    result = (int)(getPaddingTop()+getPaddingBottom()+mPaint.descent()-mPaint.ascent());
                }
    
            }else if(mode == MeasureSpec.EXACTLY){ //match_parent/50dp   精准的值
                //wSize
                result = size;
            }
    
            return result;
        }
    
    
    
    }
    

    设置属性文件attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <!--
          <declare-styleable name="样式名称">
          name ="名称" format="类型"
          string  字符串
          reference  引用的类型  R.string.xxx
          dimension 尺寸
          color 颜色
            <attr name="text" format="string|reference"></attr>
        </declare-styleable>
    
        -->
        <declare-styleable name="MyTextView">
            <attr name="text" format="string|reference"></attr>
            <!--dimension可以在此属性写 XXXDP或者XXXDIP-->
            <attr name="textSize" format="dimension|reference"></attr>
            <attr name="textColor" format="color|reference"></attr>
        </declare-styleable>
    </resources>

    activity_main.xml布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.qf.sxy.customview02.MainActivity">
    
        <!--
        命名空间  引用资源的
         xmlns:app="http://schemas.android.com/apk/res-auto"
    
          xmlns:app="http://schemas.android.com/apk/包名"
        -->
    
        <com.qf.sxy.customview02.widget.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:text="国庆快乐"
            app:textSize="20sp"
            app:textColor="#ff00ff"
           />
    </RelativeLayout>
    

    案例三

    说明 在界面画一个圆 然后让其一直旋转 360APP的雷达效果

    这里写图片描述

    ProgressView.java(重写View方法)

    package com.qf.sxy.customview3.widget;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.RectF;
    import android.util.AttributeSet;
    import android.view.View;
    
    import com.qf.sxy.customview3.R;
    
    /**
     * Created by sxy on 2016/9/28.
     */
    public class ProgressView extends View {
    
        private int circleColor = Color.BLUE;//设置颜色
    
        private int startAngle = -90;//开始的角度
        private int sweepAngle = 0;//扫描的角度
        private int sweepStep = 5;//每次扫描走多少
        private int sweepColor = Color.RED;
    
        //wrap_content  设定宽高  100
        int sweepWith =100;
        int sweepHeight =100;
    
        public ProgressView(Context context) {
            this(context,null);
        }
    
        public ProgressView(Context context, AttributeSet attrs) {
            super(context, attrs);
            //获取布局中属性
            TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.ProgressView);
            if(array!=null){
                circleColor = array.getColor(R.styleable.ProgressView_circleColor,Color.BLUE);
                sweepColor = array.getColor(R.styleable.ProgressView_sweepColor,Color.RED);
                startAngle = array.getInteger(R.styleable.ProgressView_startAngle,-90);
                sweepStep = array.getInteger(R.styleable.ProgressView_sweepStep,1);
            }
    
        }
    
    
        /**
         * 绘制
         * @param canvas
         */
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            Paint paint = new Paint();
            paint.setColor(circleColor);
            paint.setAntiAlias(true);
    
            //绘制圆  控件的一半
            canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/2,paint);
    
            //重新设置画笔颜色
            paint.setColor(sweepColor);
            //绘制的扇形
            canvas.drawArc(new RectF(0,0,getWidth(),getHeight()),startAngle,sweepAngle,true,paint);
            sweepAngle += sweepStep;//扫描角度等于 走的和
            sweepAngle= sweepAngle>360?0:sweepAngle;//是否跑了一圈
            invalidate();//刷新数据
        }
    
        /**
         * 测量
         * @param widthMeasureSpec
         * @param heightMeasureSpec
         */
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
    
            int wMode = MeasureSpec.getMode(widthMeasureSpec);
            int hMode = MeasureSpec.getMode(heightMeasureSpec);
    
            int wSize = MeasureSpec.getSize(widthMeasureSpec);
            int hSize = MeasureSpec.getSize(heightMeasureSpec);
    
    
            switch (wMode){
                case MeasureSpec.AT_MOST:
                   // wSize = sweepWith;
                    wSize = hSize = sweepHeight;
    
                    break;
                case MeasureSpec.EXACTLY:
                    wSize = hSize = Math.min(wSize,hSize);
                    break;
            }
            //设置最终的宽高
            setMeasuredDimension(wSize,hSize);
    
        }
    }
    

    属性文件attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!--
        circleColor  圆的颜色
        sweepColor   扫描的颜色
        startAngle 起始角度
        sweepAngle 扫描角度
        sweepStep 每次扫描的步数
        -->
        <declare-styleable name="ProgressView">
            <attr name="circleColor" format="color|reference"></attr>
            <attr name="sweepColor" format="color|reference"></attr>
            <attr name="startAngle" format="integer|reference"></attr>
            <attr name="sweepAngle" format="integer|reference"></attr>
            <attr name="sweepStep" format="integer|reference"></attr>
        </declare-styleable>
    </resources>

    布局文件activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        tools:context="com.qf.sxy.customview3.MainActivity">
    
        <com.qf.sxy.customview3.widget.ProgressView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:circleColor="#00ff00"
            app:sweepColor="#0000ff"
            app:sweepStep="10"
            app:sweepAngle="0"
            app:startAngle="0"
             />
        <com.qf.sxy.customview3.widget.ProgressView
            android:layout_width="200dp"
            android:layout_height="200dp"
            app:circleColor="#0000ff"
            app:sweepColor="#ff00ff"
            app:sweepStep="2"
            app:startAngle="-90"
             />
        <com.qf.sxy.customview3.widget.ProgressView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:circleColor="#00ffff"
            app:sweepColor="#005644"
            app:sweepStep="20"
            app:startAngle="180"
             />
    </LinearLayout>
    

    案例四

    继承View 并实现监听方法 当用户点击时View中的数字+1
    这里写图片描述

    重写View的类CountView.java

    package com.qf.sxy.customview04;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.util.AttributeSet;
    import android.view.View;
    
    /**
     * Created by sxy on 2016/9/28.
     */
    public class CountView extends View implements View.OnClickListener{
    
        private Paint mPaint;
        private int count =0;
    
        public CountView(Context context) {
            this(context,null);
        }
    
        public CountView(Context context, AttributeSet attrs) {
            this(context, attrs,0);
        }
    
        public CountView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            //初始化化画笔对象
            initPaint();
            //监听事件
            setOnClickListener(this);
        }
    
        private void initPaint(){
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setColor(Color.RED);
            mPaint.setTextSize(300);
        }
    
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            //获取当前的数字字符串
            String countStr =String.valueOf(count);
            Rect rect = new Rect();
            //获取文字区域
            mPaint.getTextBounds(countStr,0,countStr.length(),rect);
            int strWith =  rect.width();
            int strHeight = rect.height();
    
            canvas.drawText(countStr,getWidth()/2-strWith/2,getHeight()/2+strHeight/2,mPaint);
        }
    
    
        //点击事件的监听
        @Override
        public void onClick(View v) {
            count++;
            invalidate();//刷新
        }
    }
    

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.qf.sxy.customview04.MainActivity">
    
        <com.qf.sxy.customview04.CountView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </RelativeLayout>
    

    案例五

    说明 View上有一个点 当用户点击或者移动时小点变色并且跟随移动

    这里写图片描述

    重写View的类BallView.java

    package com.qf.sxy.customview05.widget;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    
    import java.util.Random;
    
    /**
     * Created by sxy on 2016/9/28.
     */
    public class BallView extends View {
    
        private Paint mPaint;
        private int cx = 50,cy=50,radius = 20;//圆心x  圆心y  半径
    
        //小球颜色随机改变
        private int[] colors = {Color.BLACK,Color.BLUE,Color.DKGRAY,Color.GREEN,Color.RED,Color.YELLOW};
    
    
        private int pWith = 100,pHeight =100;
        public BallView(Context context) {
            this(context,null);
        }
    
        public BallView(Context context, AttributeSet attrs) {
            this(context, attrs,0);
        }
    
        public BallView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            //初始化画笔对象
            initPaint();
        }
    
        private void initPaint(){
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setColor(Color.RED);
        }
    
        //绘制  小球
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            //是否出界
            isOutSide();
    
            //随机获取颜色
            getBallColor();
    
            //绘制一个小球
            canvas.drawCircle(cx,cy,radius,mPaint);
        }
    
        private void isOutSide() {
    
            if(cx<radius){//左
                cx = radius;
            }
            if(cx>pWith-radius){//右
                cx = pWith-radius;
            }
            if(cy<radius){//上
                cy = radius;
            }
            if(cy>pHeight-radius){//下
                cy = pHeight-radius;
            }
    
        }
    
    
        private void getBallColor() {
            Random r = new Random();
            int color = r.nextInt(colors.length);
            mPaint.setColor(colors[color]);
    
        }
    
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN://按下事件
                    cx = (int)event.getX();
                    cy = (int)event.getY();
                    invalidate();//刷新
                    break;
                case MotionEvent.ACTION_MOVE://移动事件
                    cx = (int)event.getX();
                    cy = (int)event.getY();
                    invalidate();//刷新
                    break;
                case MotionEvent.ACTION_UP://抬起的事件
                    cx = (int)event.getX();
                    cy = (int)event.getY();
                    invalidate();//刷新
                    break;
            }
            //消费事件 不然会有问题
            return true;
        }
    
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            pWith = MeasureSpec.getSize(widthMeasureSpec);
            pHeight = MeasureSpec.getSize(heightMeasureSpec);
        }
    }
    

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    
        tools:context="com.qf.sxy.customview05.MainActivity">
    
        <com.qf.sxy.customview05.widget.BallView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
    </RelativeLayout>
    

    案例6

    说明 重写EditText 并监听文本改变事件 如果有字就在文本框右侧改变图片

    这里写图片描述

    MyEditText.java

    package com.qf.sxy.customview06.widget;
    
    import android.content.Context;
    import android.graphics.drawable.Drawable;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.util.AttributeSet;
    import android.widget.EditText;
    
    import com.qf.sxy.customview06.R;
    
    /**
     * Created by sxy on 2016/9/28.
     */
    public class MyEditText extends EditText {
    
        Drawable drawable1;
        Drawable drawable2;
        public MyEditText(Context context) {
            this(context,null);
        }
    
        public MyEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
            changeBitmap();
        }
    
        public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            //根据文本输入 修改图片
           // changeBitmap();
        }
    
    
        public void changeBitmap(){
    
    
            addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
                }
    
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    //修改图片
                    setBitmap();
                }
    
                @Override
                public void afterTextChanged(Editable s) {
    
                }
            });
    
    
            setBitmap();
        }
    
        //设置图片
        public void setBitmap(){
             drawable1 =getResources().getDrawable(R.mipmap.ic_launcher);
             drawable2 =getResources().getDrawable(R.mipmap.qq);
    
            if(length()>0){//设置一种图片
    //            setFocusable(true);
                //左上右下
                setCompoundDrawablesWithIntrinsicBounds(null,null,drawable1,null);
    
            }else{//设置另一种图片
               // setFocusable(true);
    //左上右下
                setCompoundDrawablesWithIntrinsicBounds(null,null,drawable2,null);
            }
    
        }
    
    
    }
    

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.qf.sxy.customview06.MainActivity">
    
        <com.qf.sxy.customview06.widget.MyEditText
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:enabled="true"
    
            android:hint="请输入姓名" />
        <com.qf.sxy.customview06.widget.MyEditText
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:hint="请输入密码"
           />
    </LinearLayout>
    

    案例7

    说明 继承EditText 设置一张背景图 并且划线 让其想一个笔记本

    这里写图片描述

    MyNoteView.java

    package com.qf.sxy.customview07.widget;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.view.Gravity;
    import android.widget.EditText;
    
    import com.qf.sxy.customview07.R;
    
    /**
     * Created by sxy on 2016/9/28.
     */
    public class MyNoteView extends EditText {
    
    
        private int lineSpace = 50;//行间距
        private Paint mPaint ;
        private int linePadding = 60;//设置内边距
        private int lineColor = Color.RED;
    
        public MyNoteView(Context context) {
            super(context);
        }
    
        public MyNoteView(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            //初始化画笔对象
            initPaint();
    
    
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyNoteView);
            if(array!=null){
                lineColor = array.getColor(R.styleable.MyNoteView_lineColor,Color.RED);
                linePadding = array.getInteger(R.styleable.MyNoteView_linePadding,60);
                lineSpace = array.getInteger(R.styleable.MyNoteView_lineSpace,60);
            }
    
            mPaint.setColor(lineColor);
    
            //设置行间距  参数1:间距  参数2:倍数
            setLineSpacing(lineSpace,1);
            //设置整个的内边距
            setPadding(linePadding,0,linePadding,0);
            //文字从顶部开始
            setGravity(Gravity.TOP);
        }
    
    
        public void initPaint(){
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setColor(Color.RED);
        }
    
        //绘制线
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            //获取View的高度
            int height = getHeight();
            //获取每一行的高度
            int lineHeight = getLineHeight();
            //得到总的线的数量
            int lineNum = height/lineHeight;
    
            for(int i=0;i<lineNum;i++){
                canvas.drawLine(linePadding,(i+1)*lineHeight,getWidth()-linePadding,(i+1)*lineHeight,mPaint);
            }
    
            //获取文本行数
            int linesCount = getLineCount();
            //画多余的部分
            for(int i = lineNum;i<linesCount;i++ ){
                canvas.drawLine(linePadding,i*lineHeight,getWidth()-linePadding,i*lineHeight,mPaint);
            }
    
        }
    }
    

    属性文件

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="MyNoteView">
            <attr name="lineSpace" format="integer|reference"></attr>
            <attr name="linePadding" format="integer|reference"></attr>
            <attr name="lineColor" format="color|reference"></attr>
        </declare-styleable>
    </resources>

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        tools:context="com.qf.sxy.customview07.MainActivity">
    
        <com.qf.sxy.customview07.widget.MyNoteView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@mipmap/background"
            app:lineColor="#0000ff"
            app:linePadding="100"
            app:lineSpace="30"
            />
    </RelativeLayout>
    
  • 相关阅读:
    缓存
    mybatis(ibatis)理解
    hibernate理解
    linux vi 命令
    Activity中ConfigChanges属性的用法
    sendStickyBroadcast和sendStickyOrderedBroadcast
    广播 BroadCastReceiver
    Android四大基本组件介绍与生命周期
    ubuntu14.04 开机自动运行应用程序
    Android中BindService方式使用的理解
  • 原文地址:https://www.cnblogs.com/muyuge/p/6152169.html
Copyright © 2011-2022 走看看