• 有时安卓提供的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>

最新文章

  1. UIView
  2. ASP.NET中cookie与Fiter实现简单登陆,AllowAnonymous匿名登陆
  3. 配置Chrome Driver
  4. android 高效加载大图
  5. 微信第一个“小程序”亮相:不是APP胜似APP!
  6. MS SQL SERVER 锁研究记录
  7. android studio添加三方jar包
  8. html添加keyword,description帮助百度收录处理方法,jsp去除空白行方法
  9. C# 常用控件及单击事件
  10. mvc5 + ef6 + autofac搭建项目(repository+uow)(二)
  11. Codeforces Round #216 (Div. 2) E. Valera and Queries 树状数组 离线处理
  12. Weblogic10 集群配置
  13. 关于std::cin阻塞事件循环以及控制台命令输入功能的方案;
  14. .NetCore部署至IIS
  15. tensorflow中moving average的用法
  16. linux正则
  17. Laravel框架中实现supervisor执行异步进程
  18. nodejs 接收上传的图片
  19. 如何成为技术大牛——阿里CodeLife
  20. Http请求之基于HttpUrlConnection,支持Header,Body传值,支持Multipart上传文件:

热门文章

  1. [LeetCode] Strange Printer 奇怪的打印机
  2. centOS7配置DNS服务器
  3. Linux的基本命令(CentOS)
  4. [USACO 13DEC]Vacation Planning(gold)
  5. 【数据结构】【平衡树】无旋转treap
  6. bzoj 4974: 字符串大师
  7. Python入门之装饰器九步学习入门
  8. urllib,request 设置代理
  9. KMP算法小结
  10. SpringBoot学习之启动探究