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>