android自定义View之重写View来实现全新的控件
来源:互联网 发布:手机淘宝店铺怎么开 编辑:程序博客网 时间:2024/05/01 09:59
当android系统原生的控件无法满足我们的需要求时,我们完全可以新建一个自定义的View实现需要的功能。自定义控件通常要重写它的onDraw(),onMeasure()等方法来实现绘制逻辑。下面我就以一个例子来了解如何创建一个自定义View。
实现效果如图:
项目分析:图中的自定义View分为三个部分,分别只中间的圆形,中间的文字,外圈的弧形。我们设置View的绘制长度就是屏幕的宽度。
第一步:绘制三种图像—–创建类ArcImg,继承View
package com.wjc.drawview0504;import android.app.Application;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.RectF;import android.support.v4.content.ContextCompat;import android.util.AttributeSet;import android.util.Log;import android.view.View;/** * Created by admin on 2016/5/4. */public class ArcImg extends View { private int mWidth; private int mHeihgt; private Paint mCirclePaint,mArcPaint,mTextPaint; private float mCircleXY; private float mRadius; private RectF mArcRectF; private float mSweepValue=66; private float mSweepAngle; private String mShowText; private float mShowTextSie; public ArcImg(Context context, AttributeSet attrs) { super(context, attrs); } //对宽高重新进行定义 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { mWidth=MeasureSpec.getSize(widthMeasureSpec); mHeihgt=MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(mWidth,mHeihgt); initView(); } public void initView(){ //设置圆的参数 float length=0;//自定义View的宽度 if(mWidth>mHeihgt){ length=mHeihgt; }else{ length=mWidth; } mCircleXY=(float)(length/2);//圆心坐标 mRadius=mCircleXY/2;//设置圆的半径 mCirclePaint=new Paint();//画笔 mCirclePaint.setAntiAlias(true);//平滑 // mCirclePaint.setColor(getResources().getColor(android.R.color.holo_blue_bright));//过时了 mCirclePaint.setColor(ContextCompat.getColor(getContext(),android.R.color.holo_blue_bright)); //设置弧线 mArcRectF=new RectF( (float)(length*0.1), (float)(length*0.1), (float)(length*0.9), (float)(length*0.9)); mSweepAngle=(mSweepValue/100f)*360f;//扫过的角度 mArcPaint=new Paint(); mArcPaint.setAntiAlias(true); mArcPaint.setStrokeWidth((float) (length * 0.1)); mArcPaint.setStyle(Paint.Style.STROKE);//设置文字 mShowText=setShowText(); mShowTextSie=setShowTextSize(); mTextPaint=new Paint(); mTextPaint.setTextSize(mShowTextSie); mTextPaint.setTextAlign(Paint.Align.CENTER); }//绘制图像 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //绘制圆 canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint); //绘制弧线 /** * mArcRectF :指定圆弧的外轮廓矩形区域。 startAngle: 圆弧起始角度,单位为度。 sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度。 useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。 paint: 绘制圆弧的画板属性,如颜色,是否填充等。 */ canvas.drawArc(mArcRectF, 270, mSweepAngle, false, mArcPaint); //绘制文字 canvas.drawText(mShowText,0,mShowText.length(),mCircleXY,mCircleXY,mTextPaint); } private float setShowTextSize(){ this.invalidate();//刷新View,在UI线程中进行 return 30; } private String setShowText(){ this.invalidate(); return "Android Skill"; } //设置不同弧度的状态值 public void setSweepValue(float sweepValue){ if(sweepValue!=0){ mSweepValue=sweepValue; }else{ mSweepValue=25; } }}
代码中,设置圆的颜色,在 API 23 之前使用a这种写法,但API 23 建议使用ContextCompat.getColor(context,id),如b,我使用了getContext()获取context,如果哪位有更好的方法,请告知!
a. mCirclePaint.setColor(getResources().getColor(android.R.color.holo_blue_bright));//过时了b. mCirclePaint.setColor(ContextCompat.getColor(getContext(),android.R.color.holo_blue_bright));
而在绘制文字中,我看了drawText()的源代码,实在不能理解源代码坐标(x,y)意思,我认为x,y是文字的中心,你觉得呢?
canvas.drawText(mShowText,0,mShowText.length(),mCircleXY,mCircleXY,mTextPaint);
drawText()的源代码:
/** * Draw the text, with origin at (x,y), using the specified paint. * The origin is interpreted based on the Align setting in the paint. * * @param text The text to be drawn * @param start The index of the first character in text to draw * @param end (end - 1) is the index of the last character in text to draw * @param x The x-coordinate of the origin of the text being drawn * @param y The y-coordinate of the baseline of the text being drawn * @param paint The paint used for the text (e.g. color, size, style) */ public void drawText(@NonNull String text, int start, int end, float x, float y, @NonNull Paint paint) { if ((start | end | (end - start) | (text.length() - end)) < 0) { throw new IndexOutOfBoundsException(); } native_drawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface); }
第二步:在布局xml中引用
<com.wjc.drawview0504.ArcImg android:id="@+id/circle" android:layout_width="match_parent" android:layout_height="match_parent" />
第三步:在activity中调用,检测自定义View是否成功
mArcImg=(ArcImg)findViewById(R.id.circle); mArcImg.setSweepValue(70);//指定弧度比例
好了,整个流程就这样了。现在我的案例基本是来自徐宜生的《android群英传》,如果哪位也在看这本书,欢迎一起讨论,学习。
0 0
- android自定义View之重写View来实现全新的控件
- 重写View来实现全新的控件------弧线展示图
- android群英传笔记——重写View来实现全新的控件(弧线展示图)
- Android-自定义View之重写控件(自定义Dialog)
- Android-自定义View之重写控件(自定义Dialog)
- Android进阶——自定义View之重写ViewGroup组合系统控件实现自定义ToolBar模板
- Android自定义view之环形等待控件的实现
- Android之自定义View实现随手势滑动的控件
- Android单独继承View类来实现自定义控件
- 【代码】Android 单独继承View类来实现自定义控件
- [Android开发] 自定义View之重写View非常简单实现开关按钮SwitchView
- Android之自定义view换行的实现
- Android自定义view之ProgressBar的实现
- Android自定义控件之自定义View(一)
- Android自定义控件之自定义View(二)
- Android自定义控件之自定义View(四)
- Android自定义View 之 View的测量
- Android 自定义View之View的绘制
- 推荐系统的误区
- Fragment切换页面思路整理
- Linux编码问题
- 关于 MotionEvent 的笔记
- 有用的机器学习链接(持续更新)
- android自定义View之重写View来实现全新的控件
- ReactNative 学习第二节 环境搭建
- bzoj 3242: [Noi2013]快餐店 dfs&递推
- 拦截导弹
- 选择排序和冒泡排序
- 二进制中1的个数----位运算
- 蓝桥杯 PREV-6-翻硬币
- String、StringBuffer与StringBuilder之间区别
- Spring IOC 深入分析