自定义控件<一>
来源:互联网 发布:淘宝联盟分享店铺 编辑:程序博客网 时间:2024/06/11 06:38
View的工作流主要是指measure、layout、draw,即测量、布局和绘制。
- measure确定View的测量宽/高
- layout确定View最终的宽高和四个顶点的位置。
- draw则将View绘制到屏幕上
案例:做一个圆形的控件
public class CircleView extends View { private int mColor = Color.RED; //设置画笔 private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); public CircleView(Context context) { super(context); initView(); } public CircleView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public CircleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } private void initView() { mPaint.setColor(mColor); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int paddingRight = getPaddingRight(); int paddingLeft = getPaddingLeft(); int paddingBottom = getPaddingBottom(); int paddingTop = getPaddingTop(); //获取控件的宽和高 int width = getWidth() - paddingRight - paddingLeft; int height = getHeight() - paddingBottom - paddingTop; //获取控件宽和高中最小值,然后除以2,得到控件的半径 int radiu = Math.min(width, height) / 2; //绘制View canvas.drawCircle(width / 2 + paddingLeft, height / 2 + paddingTop, radiu, mPaint); }}
上述代码是自定义的红色的圆形控件。但是有两个问题:
问题一:
<zx.demo.zx_circle_view.view.CircleView android:layout_width="match_parent" android:layout_height="match_parent" /><zx.demo.zx_circle_view.view.CircleView android:layout_width="wrap_content" android:layout_height="wrap_content" />
两种布局的效果一样,都是第一种的match_parent效果,那么怎样设定一个wrap_content效果?
解决方法:
想要解决这个问题,那么就需要引入MeasureSpec。
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) { setMeasuredDimension(500, 500); } else if (widthSpecMode == MeasureSpec.AT_MOST) { setMeasuredDimension(500, heightSpecSize); } else if (heightSpecMode == MeasureSpec.AT_MOST) { setMeasuredDimension(widthSpecSize, 500); }}
问题二:
怎样添加自定义属性,比如添加控件选择控件的颜色。
解决方法:
第一步、在values目录下创建自定义属性的XML。
第二步、在View的构造方法中解析自定义属性的值并做相应处理。
public CircleView(Context context, AttributeSet attrs) { super(context, attrs); //加载自定义属性集合CircleView TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleView); //解析CircleView中的circle_color属性,如果默认情况下为红色 mColor = typedArray.getColor(R.styleable.CircleView_circle_color, Color.RED); //释放资源 typedArray.recycle(); initView();}
第三步、在布局文件中使用自定义属性
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <zx.demo.zx_circle_view.view.CircleView android:layout_width="300dp" android:layout_height="300dp" app:circle_color="@color/colorPrimary" /></RelativeLayout>
注意:xmlns:app=”http://schemas.android.com/apk/res-auto”
app:自定义属性的前缀,可以换其他名字,但是CircleView中的自定义属性的前缀必须和它一致。
还有一种声明方式是:xmlns:app=”http://schemas.android.com/apk/res/zx.demo.zx_circle_view”,在apk/res/后面加上包名。
MeasureSpec理解:
第二个问题的解决很好理解,但是第一个问题解决方案中的MeasureSpec是什么东西呢?
MeasureSpec代表一个32位int值,其中最高的2位代表SpecMode,后面的30为代表SpecSize。
一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求,一个MeasureSpec由大小和模式组成,它有三种模式:
- UNSPECIFIED(未指定):父容器不对View有任何限制,要多大给多大,这种情况一般用于系统内部,表示一种测量状态。
- EXACTLY(完全):父容器已经检测到View所需要的精确大小,这个时候View的最终大小就是SpecSize所指定的值。它对应于LayoutParams中的match_parent和具体的数值这两种模式。
- AT_MOST(至多):父容器指定了一个可用大小即SpecSize,View的的大小不能大于这个值,具体是什么值要看不同View的具体实现。它对应于LayoutParams中的wrap_content。
0 0
- 自定义控件(一)
- 自定义控件(一)
- 自定义UIPageControl 控件(一)
- 自定义UIPageControl 控件(一)
- 自定义控件(一)
- 自定义控件一
- 自定义控件(一)
- Android自定义控件(一)
- 自定义控件(一)
- 自定义控件(一)
- 自定义控件(一)【Android】
- android自定义控件(一)
- 自定义控件一
- 自定义组合控件一
- 自定义控件(一)
- 自定义控件(一)
- 自定义控件(一)
- 自定义控件(一)
- c++作业4
- 开源的跨平台移动开发利器Xamarin Studio v6.3发布丨附下载
- @Configuration、@Bean
- 量化投资策略回测框架(一):胜率的估算
- netezza 数据库几个常用的日期处理函数
- 自定义控件<一>
- leetcode-215-Kth Largest Element in an Array
- Zookeeper入门学习(二)--Zookeeper环境搭建
- PHP static局部静态变量和全局静态变量总结
- java io操作之InputStream,OutputStream
- S4 1610 smartforms取消使用word编辑器
- 大数据|Spark技术在京东智能供应链预测的应用案例深度剖析
- C++第四次作业
- 关于《抑郁症》