自定义组件的简单使用—View
来源:互联网 发布:微信弹幕软件 编辑:程序博客网 时间:2024/05/02 01:44
自定义组件的简单使用—View
1、 控件是怎么来的?
每一个控件都是使用绘图的方式绘制出来的
2、开发自定义组件的几种方法
A、从0开始开发自定义组件,从View或ViewGroup类继承,难度最大
B、从已有组件继承,比如定义ImageView、ListView继承,为已有组件添加新的功能
C、将多个已有的组件组合成一个新的组件
3、View类
A、构造方法
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
如果给组件定义了样式和主题,则会调用该方法。
public MyView(Context context, AttributeSet attrs) { super(context, attrs); } 在layout文件中使用组件,则调用该方法。会自动将组件的属性传递给attrs参数,从该参数中可以获取定义在xml的属性。 <com.trkj.dept12_customer1.MyView android:layout_width="wrap_content" android:layout_height="wrap_content" /> public MyView(Context context) { super(context); } 直接代码创建组件,一般会调用该方法,所以属性都使用默认值 Button btn = new Button(this);
B、onDraw()方法
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
用于组件的绘制
C、onMeasure()方法
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
该方法用于确定组件的大小
A、参数:
widthMeasureSpec:保存了宽度的模式(match_parent、wrap_content、具体值)和大小
heightMeasureSpec:保存了高度的模式(match_parent、wrap_content、具体值)和大小
绝大部分情况下,我们只需要计算wrap_content(跟随内容)的情况
B、关于测量模式,一共有三种:
MeasureSpec.AT_MOST:是最大尺寸,当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。该模式必须要通过编程计算。
MeasureSpec.EXACTLY:是精确尺寸,当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width="50dip",或者为match_parent是,都是控件大小已经确定的情况,都是精确尺寸。 MeasureSpec.UNSPECIFIED:是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。
C、如何获取组件的测量模式和大小?
//获取宽度使用的模式
int wmode = MeasureSpec.getMode(widthMeasureSpec);
//获取宽度大小
int wsize = MeasureSpec.getSize(widthMeasureSpec);
//获取高度使用的模式 int hmode = MeasureSpec.getMode(heightMeasureSpec); //获取高度大小 int hsize = MeasureSpec.getSize(heightMeasureSpec);
D、测量出组件的宽度和高度之后,如果应用该大小?
//下面的方法一定要调用,用于应用计算出来的宽度和高度
setMeasuredDimension(wsize, hsize);
E、onMeasure()的完整写法:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//获取宽度使用的模式
int wmode = MeasureSpec.getMode(widthMeasureSpec);
//获取宽度大小
int wsize = MeasureSpec.getSize(widthMeasureSpec);
//组件的实际宽度 int width = 0; if(wmode == MeasureSpec.AT_MOST){ //计算宽度 }else{ //wsize就是父容器的大小,在EXACTLY模式下,父窗口的大小的组件的大小 width = wsize; } //获取高度使用的模式 int hmode = MeasureSpec.getMode(heightMeasureSpec); //获取高度大小 int hsize = MeasureSpec.getSize(heightMeasureSpec); int height = 0; if(hmode == MeasureSpec.AT_MOST){ //计算高度 }else{ height = hsize; } //下面的方法一定要调用,用于应用计算出来的宽度和高度 setMeasuredDimension(width, height); }
4、案例:模拟TextView,角为圆角
/** * qq:2286502415 * @time:2016-1-16 * @author Administrator * */public class MyView extends View { private String text = "中华文艺复兴"; private Paint paint; public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.WHITE); paint.setTextSize(40); } public MyView(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getMeasuredWidth(); int height = getMeasuredHeight(); Log.e("tag: ", "onDraw"); // 画填充的圆角矩形 Paint p = new Paint(); p.setColor(Color.RED); canvas.drawRoundRect(new RectF(1, 1, width - 1, height - 1), 15, 15, p); // 画文字 // 计算出文字所占的大小 Rect bounds = new Rect(); paint.getTextBounds(text, 0, text.length(), bounds);//从第一个到最后一个文字的距离 int left = (width - bounds.width()) / 2;//居中 int top = (height - bounds.height()) / 2; Log.i("MyView", "top:" + top); Log.i("MyView", "height:" + bounds.height()); canvas.drawText(text, left, top + bounds.height(), paint); //各参数意义(文本,字符串的左边在屏幕的位置,字符串下边线距离屏幕顶端的距离,画笔。参考:http://blog.csdn.net/sirnuo/article/details/21165665) } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 计算出文字所占的大小 Rect bounds = new Rect(); paint.getTextBounds(text, 0, text.length(), bounds); Log.e("tag: ", "onMeasure"); // 获取宽度使用的模式 int wmode = MeasureSpec.getMode(widthMeasureSpec); // 获取宽度大小 int wsize = MeasureSpec.getSize(widthMeasureSpec); // 组件的实际宽度 int width = 0; if (wmode == MeasureSpec.AT_MOST) { // 计算宽度 width = bounds.width(); } else { // wsize就是父容器的大小,在EXACTLY模式下,父窗口的大小的组件的大小 width = wsize; } // 获取高度使用的模式 int hmode = MeasureSpec.getMode(heightMeasureSpec); // 获取高度大小 int hsize = MeasureSpec.getSize(heightMeasureSpec); int height = 0; if (hmode == MeasureSpec.AT_MOST) { // 计算高度 height = bounds.height(); } else { height = hsize; } // 下面的方法一定要调用,用于应用计算出来的宽度和高度 setMeasuredDimension(width, height); }}
效果图:
- 自定义组件的简单使用—View
- 自定义view的简单使用
- 简单代码使用nib自定义的view
- 简单的view 自定义
- 简单的自定义View
- 简单的自定义view
- 【android 开发知识积累】——属性(Attribute)资源的使用和自定义View组件
- reactNative中View组件的简单使用(六)
- iOS——简单的自定义view
- 自定义View的使用
- 自定义view的使用
- 自定义View的简单尝试——自定义日历视图
- Android自定义简单的View
- Android自定义简单的View
- Android自定义简单的View
- 简单的学习自定义view
- 简单易懂的自定义view
- 简单的自定义view制作
- Github删除fork项目
- Linux常用命令大全
- 2015年总结
- UI01_UIView
- 《巴伦周刊》:纳德拉带领微软中兴
- 自定义组件的简单使用—View
- Android Support V4, V7, V13的作用与用法
- VC++对话框程序不响应OnChar 和 OnKeyDown事件处理函数
- SQLite指南(2) -- 帮助及编译SQLite
- Error:Execution failed for task ':app:dexDebug'. > com.android.ide.common.process.ProcessException
- linux相关的书籍
- Ubuntu环境下SSH的安装及使用
- 自动补全联系人姓名
- Hive Hbase Integration(hive和habse的集成)