Android自定义View基本使用
https://www.jianshu.com/p/705a6cb6bfee
https://zhuanlan.zhihu.com/p/162945366
自定义view步骤:
1、自定义View的属性
2、在View的构造方法中获得我们自定义的属性:引入 xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"我们的命名空间
3、重写onMesure
4、重写onDraw
https://blog.csdn.net/guolin_blog/article/details/16330267
自定义控件的实现有三种方式
(一)组合控件
组合控件,顾名思义就是将一些小的控件组合起来形成一个新的控件,这些小的控件多是系统自带的控件。
(二)自绘控件
自绘控件的内容都是自己绘制出来的,在View的onDraw方法中完成绘制。
(三)继承控件
就是继承已有的控件,创建新控件,保留继承的父控件的特性,并且还可以引入新特性。下面就以支持横向滑动删除列表项的自定义ListView的实现来介绍。
实例:关于自定义录音声音分贝波纹
1.自定义View的属性 :vaules/attrs.xml,在自定义View的初始化使用此值
<declare-styleable name="LineWaveVoiceView"><attr name="voiceLineColor" format="color" /><attr name="voiceLineWidth" format="color" /><attr name="voiceTextSize" format="dimension" /><attr name="voiceTextColor" format="dimension" /><attr name="updateSpeed" format="color" /></declare-styleable>
2.自定义LineWaveVoiceView集成自View,重写onDraw方法
package com.example.demo.view;/*** 语音录制的动画效果*/
public class LineWaveVoiceView extends View {private static final String DEFAULT_TEXT = " 请录音 ";private static final int LINE_WIDTH = 9;//默认矩形波纹的宽度,9像素, 原则上从layout的attr获得private Paint paint = new Paint();private Runnable task;private ExecutorService executorService = Executors.newCachedThreadPool();private RectF rectRight = new RectF();//右边波纹矩形的数据,10个矩形复用一个rectFprivate RectF rectLeft = new RectF();//左边波纹矩形的数据private String text = DEFAULT_TEXT;private int updateSpeed;private int lineColor;private int textColor;private float lineWidth;private float textSize;public LineWaveVoiceView(Context context) {super(context);}public LineWaveVoiceView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public LineWaveVoiceView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initView(attrs, context);resetView(mWaveList, DEFAULT_WAVE_HEIGHT);task = new LineJitterTask();}private void initView(AttributeSet attrs, Context context) {//获取布局属性里的值TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.LineWaveVoiceView);lineColor = mTypedArray.getColor(R.styleable.LineWaveVoiceView_voiceLineColor, context.getColor(R.color.color_accent));lineWidth = mTypedArray.getDimension(R.styleable.LineWaveVoiceView_voiceLineWidth, LINE_WIDTH);textSize = mTypedArray.getDimension(R.styleable.LineWaveVoiceView_voiceTextSize, 42);textColor = mTypedArray.getColor(R.styleable.LineWaveVoiceView_voiceTextColor, context.getColor(R.color.color_accent));updateSpeed = mTypedArray.getColor(R.styleable.LineWaveVoiceView_updateSpeed, UPDATE_INTERVAL_TIME);mTypedArray.recycle();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//获取实际宽高的一半int widthCentre = getWidth() / 2;int heightCentre = getHeight() / 2;paint.setStrokeWidth(0);paint.setColor(textColor);paint.setTextSize(textSize);float textWidth = paint.measureText(text);canvas.drawText(text, widthCentre - textWidth / 2, heightCentre - (paint.ascent() + paint.descent()) / 2, paint);//设置颜色paint.setColor(lineColor);//填充内部paint.setStyle(Paint.Style.FILL);//设置抗锯齿paint.setAntiAlias(true);for (int i = 0; i < 10; i++) {rectRight.left = widthCentre + textWidth / 2 + (1 + 2 * i) * lineWidth;rectRight.top = heightCentre - lineWidth * mWaveList.get(i) / 2;rectRight.right = widthCentre + textWidth / 2 + (2 + 2 * i) * lineWidth;rectRight.bottom = heightCentre + lineWidth * mWaveList.get(i) / 2;//左边矩形rectLeft.left = widthCentre - textWidth / 2 - (2 + 2 * i) * lineWidth;rectLeft.top = heightCentre - mWaveList.get(i) * lineWidth / 2;rectLeft.right = widthCentre - textWidth / 2 - (1 + 2 * i) * lineWidth;rectLeft.bottom = heightCentre + mWaveList.get(i) * lineWidth / 2;canvas.drawRoundRect(rectRight, 6, 6, paint);canvas.drawRoundRect(rectLeft, 6, 6, paint);}}private static final int MIN_WAVE_HEIGHT = 2;//矩形线最小高private static final int MAX_WAVE_HEIGHT = 12;//矩形线最大高private static final int[] DEFAULT_WAVE_HEIGHT = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2};private static final int UPDATE_INTERVAL_TIME = 100;//100ms更新一次private LinkedList<Integer> mWaveList = new LinkedList<>();private float maxDb;private void resetView(List<Integer> list, int[] array) {list.clear();for (int anArray : array) {list.add(anArray);}}private synchronized void refreshElement() {Random random = new Random();maxDb = random.nextInt(5) + 2;int waveH = MIN_WAVE_HEIGHT + Math.round(maxDb * (MAX_WAVE_HEIGHT - MIN_WAVE_HEIGHT));mWaveList.add(0, waveH);mWaveList.removeLast();}public boolean isStart = false;private class LineJitterTask implements Runnable {@Overridepublic void run() {while (isStart) {refreshElement();try {Thread.sleep(updateSpeed);} catch (Exception e) {e.printStackTrace();}postInvalidate();}}}public synchronized void startRecord() {isStart = true;executorService.execute(task);}public synchronized void stopRecord() {isStart = false;mWaveList.clear();resetView(mWaveList, DEFAULT_WAVE_HEIGHT);postInvalidate();}public synchronized void setText(String text) {this.text = text;postInvalidate();}public void setUpdateSpeed(int updateSpeed) {this.updateSpeed = updateSpeed;}
}
3.在layout中引入该自定义View的控件:该控件名为自定义View类路径
<com.example.demo.view.LineWaveVoiceViewandroid:layout_width="300dp"android:layout_height="100dp"android:layout_gravity="center"android:layout_margin="8dp" />
若要引用自定义View的属性,需要根布局添加命名空间
xmlns:custom_android="http://schemas.android.com/apk/res-auto"
然后才可以添加自定义控件的属性:custom_android:voiceLineColor="@color/color_accent"
<com.example.demo.view.LineWaveVoiceViewandroid:layout_width="300dp"android:layout_height="100dp"android:layout_gravity="center"android:layout_margin="8dp"custom_android:voiceLineColor="@color/color_accent" />
附加
如果我们自定义属性,这个属性应该去我们的应用程序包中找,所以要引入我们应用包的命名空间
xmlns:openxu="http://schemas.android.com/apk/res-auto”
,res-auto表示自动查找属性值的类型format
format支持的类型一共有11种:
(1). reference:参考某一资源ID
属性定义:
<declare-styleable name = "名称"><attr name = "background" format = "reference" />
</declare-styleable>
属性使用:
<ImageView android:background = "@drawable/图片ID"/>(2). color:颜色值
属性定义:
<attr name = "textColor" format = "color" />
属性使用:
<TextView android:textColor = "#00FF00" />(3). boolean:布尔值
属性定义:
<attr name = "focusable" format = "boolean" />
属性使用:
<Button android:focusable = "true"/>(4). dimension:尺寸值**
属性定义:
<attr name = "layout_width" format = "dimension" />
属性使用:
<Button android:layout_width = "42dip"/>(5). float:浮点值
属性定义:
<attr name = "fromAlpha" format = "float" />
属性使用:
<alpha android:fromAlpha = "1.0"/>(6). integer:整型值**
属性定义:
<attr name = "framesCount" format="integer" />
属性使用:
<animated-rotate android:framesCount = "12"/>(7). string:字符串
属性定义:
<attr name = "text" format = "string" />
属性使用:
<TextView android:text = "我是文本"/>(8). fraction:百分数**
属性定义:
<attr name = "pivotX" format = "fraction" />
属性使用:
<rotate android:pivotX = "200%"/>(9). enum:枚举值
属性定义:
<declare-styleable name="名称"> <attr name="orientation"> <enum name="horizontal" value="0" /><enum name="vertical" value="1" /></attr>
</declare-styleable>
属性使用:
<LinearLayout android:orientation = "vertical"></LinearLayout>
注意:枚举类型的属性在使用的过程中只能同时使用其中一个,不能 android:orientation = “horizontal|vertical"(10). flag:位或运算
属性定义:
<declare-styleable name="名称"> <attr name="gravity"> <flag name="top" value="0x30" /> <flag name="bottom" value="0x50" /><flag name="left" value="0x03" /> <flag name="right" value="0x05" /> <flag name="center_vertical" value="0x10" /></attr>
</declare-styleable>
属性使用:
<TextView android:gravity="bottom|left"/>
注意:位运算类型的属性在使用的过程中可以使用多个值(11). 混合类型:属性定义时可以指定多种类型值
属性定义:
<declare-styleable name = "名称"> <attr name = "background" format = "reference|color" />
</declare-styleable>
属性使用:
<ImageViewandroid:background = "@drawable/图片ID" />
或者:
<ImageViewandroid:background = "#00FF00" />
我们写好布局文件之后,要在控件中使用这些属性还需要将它解析出来。
Android自定义View基本使用相关推荐
- Android自定义View —— TypedArray
在上一篇中Android 自定义View Canvas -- Bitmap写到了TypedArray 这个属性 下面也简单的说一下TypedArray的使用 TypedArray 的作用: 用于从该结 ...
- Android 自定义View —— Canvas
上一篇在android 自定义view Paint 里面 说了几种常见的Point 属性 绘制图形的时候下面总有一个canvas ,Canvas 是是画布 上面可以绘制点,线,正方形,圆,等等,需要和 ...
- android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...
转载:http://blog.csdn.net/xiabing082/article/details/48781489 1. 大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...
- Android自定义View:ViewGroup(三)
自定义ViewGroup本质是什么? 自定义ViewGroup本质上就干一件事--layout. layout 我们知道ViewGroup是一个组合View,它与普通的基本View(只要不是ViewG ...
- android 自定义图形,Android自定义View之图形图像(模仿360的刷新球自定
概述: 360安全卫士的那个刷新球(姑且叫它刷新球,因为真的不知道叫什么好,不是dota里的刷新球!!),里面像住了水一样,生动可爱,看似简单,写起来不太简单,本例程只是实现了它的部分功能而已,说实话 ...
- android代码实现手机加速功能,Android自定义View实现内存清理加速球效果
Android自定义View实现内存清理加速球效果 发布时间:2020-09-21 22:21:57 来源:脚本之家 阅读:105 作者:程序员的自我反思 前言 用过猎豹清理大师或者相类似的安全软件, ...
- android中仿qq最新版抽屉,Android 自定义View实现抽屉效果
Android 自定义View实现抽屉效果 说明 这个自定义View,没有处理好多点触摸问题 View跟着手指移动,没有采用传统的scrollBy方法,而是通过不停地重新布局子View的方式,来使得子 ...
- Android 自定义 圆环,Android自定义view实现圆环效果实例代码
先上效果图,如果大家感觉不错,请参考实现代码. 重要的是如何实现自定义的view效果 (1)创建类,继承view,重写onDraw和onMesure方法 public class CirclePerc ...
- android自定义抽奖,Android自定义view制作抽奖转盘
本文实例为大家分享了Android自定义view制作抽奖转盘的具体代码,供大家参考,具体内容如下 效果图 TurntableActivity package com.bawei.myapplicati ...
- android view 渐变动画,Android自定义view渐变圆形动画
本文实例为大家分享了Android自定义view渐变圆形动画的具体代码,供大家参考,具体内容如下 直接上效果图 自定义属性 attrs.xml文件 创建一个类 ProgressRing继承自 view ...
最新文章
- java接口如何定义常量 c_在Java接口中怎样访问定义的常量呢?
- php模拟getua_php实现进行远程抓取百度网页内容,并伪装服务器端ip
- Long类型转json时前端js丢失精度解决方案
- IPFS Series -- Bitswap Protocol
- hdu4763 KMP
- 判断网络是否为真正的公网IP
- 交换机入门配置:IP和远程登录功能
- 人工操作阶段计算机是如何工作的,管理信息系统作业参考答案
- linux mysql 备份脚本_linux下mysql备份脚本
- 荷兰 转专业申请计算机,荷兰留学转专业申请须知
- VS中使用码云gitee建立源代码管理
- scanf和getch函数的区别
- 关于swiftUI和UIKit混用
- java小数位数保留
- sqlserver中计算日期差
- 深度学习( Deep Learning )软件资源列表
- 汽车覆盖件冲压模具铸造工艺研究
- 武汉轻工大学计算机学院宿舍,武汉轻工大学有几个校区及校区地址 哪个校区最好...
- iOS开发苹果支持中文字体,和使用字体
- 完美的正方形分割(二)
热门文章
- MyApplication
- 田野调查手记·浮山摩崖石刻(四)
- 如何通过学习开源项目来提高自己
- 进制转换python_进的解释|进的意思|汉典“进”字的基本解释
- 创业必读:没钱没技术,如何开发App?
- N1变砖有救N1 eMMC 镜像,理论用于TTL救砖 ,使用ddbr恢复官改系统救砖方法
- mysql 8 my.cnf 配置文件_mysql之my.cnf配置文件详解
- javascripts再进
- 17.03.05校内训练: 万圣节服饰
- 3.4 命令模式(5.2)