27 自定义View 和案例
来源:互联网 发布:开挂一样的人生知乎 编辑:程序博客网 时间:2024/06/08 03:17
有时安卓提供的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>
0 0
- 27 自定义View 和案例
- 自定义view进度条案例
- android自定义view的案例。
- 自定义view 绘制太极案例
- 自定义View做的一个Clock案例
- 自定义View做的一个Clock案例
- 安卓自定义view动画案例
- 自定义View(详解)多案例模块
- Android入门教程 自定义View详解 真实案例
- 自定义View的简单案例(1)
- 自定义View的简单案例(2)
- Android自定义view案例一气泡框
- 自定义view拖动远点案例
- 自定义view 开关的实现案例
- 自定义View简单案例-自绘控件
- 自定义View和自定义Button
- 自定义View和控件
- 自定义View和ViewGroup
- odata初探01
- 基于Opencv2.4.11+OpenGL(Qt5.6.0)实现增强现实(一)
- 第五周【项目二-建立链栈算法库】
- uva11134贪心加优先队列
- Codeforces 706C Hard problem
- 27 自定义View 和案例
- Android视频学习(四):网络编程2
- 洛谷 1373
- 中文分词的python实现-基于FMM算法
- 数据库与表的操作之编辑表结构(ALTER TABLE)
- Socket通信c++实现
- POJ2965
- 空格替换
- LeetCode-----34. Search for a Range(查找范围)