Android -- 自定义View(一)
1,引言:刚从国庆长假的放荡中醒过来,已经有将近十天没碰电脑了,上午写写代码感觉手还是挺生的,想把自定义view好好的系统的学学,在网上看了看别人出的教程 ,stay4it的自定义view感觉还是挺好的,就打算按照这个课程好好学习学习。并打算用blog记录下来(主要怕自己忘记嘛)
2, 今天这个简单的自定义view是在网上看的,就是实现其内所有的view放置在上下左右的顺序进行排列,然后简单的跟着别人的思路写了些,效果图如下:

不多说了 直接上代码 ,主要是重写了OnMeasure()和OnDraw()方法
MyFourTextViewGroup.Class
package com.wangjitao.myview.view; import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup; /**
* Created by wangjitao on 2016/10/8 0008.
* 当内部传入TextView的时候依次显示在上下左右的四个角
*/
public class MyFourTextViewGroup extends ViewGroup { public MyFourTextViewGroup(Context context) {
super(context);
} public MyFourTextViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
} public MyFourTextViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
} /**
* 1,重写generateLayoutParams是view支持margin
*
* @param attrs
* @return
*/
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
} /**
* 计算所有子view的宽度和高度,根据ChildView的计算解雇,设置自己的宽和高
*
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
/**
* 获得此viewGroup上级容器为其推荐的高和宽,以及计算的方式
*/
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec); //计算出所有的childView的设置的宽和高
measureChildren(widthMeasureSpec, heightMeasureSpec);
/**
* 记录如果是wrap_content设置的宽和高
*/
int width = 0;
int height = 0; int childCount = getChildCount(); int childWidth = 0;
int childHeight = 0;
MarginLayoutParams childParams = null; //用于计算左边两个childView的高度
int leftHeight = 0; //用于计算右边两个childView的高度,最终高度取二者之间的最大值
int rightHeight = 0; //用于取上面两个childView的宽度
int topWidth = 0; //计算下面两个chideView的宽高,取二者之间的最大值
int bottomWidth = 0; /**
* 根据childView计算出来的宽度和高度,以及设置的margin计算容器的宽和高,主要用于容器的wrap_content
*/
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
childWidth = childView.getMeasuredWidth();
childHeight = childView.getMeasuredHeight();
childParams = (MarginLayoutParams) childView.getLayoutParams(); //上面的两个Childview比较的是宽度
if (i == 0 || i == 1) {
topWidth += childWidth + childParams.leftMargin + childParams.rightMargin;
}
if (i == 2 || i == 3) {
bottomWidth += childWidth + childParams.leftMargin + childParams.rightMargin;
} //左边的两个childView比较的是高度
if (i == 0 || i == 2) {
leftHeight += childHeight + childParams.topMargin + childParams.bottomMargin;
}
if (i == 0 || i == 2) {
rightHeight += childHeight + childParams.topMargin + childParams.bottomMargin;
} } width = Math.max(topWidth, bottomWidth);
height = Math.max(leftHeight, rightHeight); //如果是wrap_content则设置为我们计算的值,否的话则设置为父容器计算的值 setMeasuredDimension((widthMode == MeasureSpec.EXACTLY) ? widthSize : width,
(heightMode == MeasureSpec.EXACTLY) ? heightSize : height); } /**
* 用来给所有的childView进行定位
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int childCount = getChildCount();
int childWidth = 0;
int childHeight = 0;
MarginLayoutParams childParams = null;
/**
* 遍历所有childView根据其高和宽,以及margin进行布局
*/
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
childWidth = childView.getMeasuredWidth();
childHeight = childView.getMeasuredHeight();
childParams = (MarginLayoutParams) childView.getLayoutParams(); int childLeft = 0;
int childTop = 0;
int childRight = 0;
int childBottom = 0; switch (i) {
case 0:
childLeft = childParams.leftMargin;
childTop = childParams.topMargin;
break;
case 1:
Log.i("wangjitao", "getWidth():" + getWidth() + ",childWidth :" + childWidth
+ ",childParams.leftMargin:" + childParams.leftMargin);
childLeft = getWidth() - childWidth -
childParams.leftMargin - childParams.rightMargin;
childTop = childParams.topMargin; break;
case 2:
childLeft = childParams.leftMargin; childTop = getHeight() - childHeight - childParams.bottomMargin; break;
case 3:
childLeft = getWidth() - childWidth -
childParams.leftMargin - childParams.rightMargin;
childTop = getHeight() - childHeight - childParams.bottomMargin;
break; }
childRight = childLeft + childWidth;
childBottom = childHeight + childTop; childView.layout(childLeft, childTop, childRight, childBottom); }
}
}
Android -- 自定义View(一)的更多相关文章
- Android自定义View 画弧形,文字,并增加动画效果
一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类 B ...
- (转)[原] Android 自定义View 密码框 例子
遵从准则 暴露您view中所有影响可见外观的属性或者行为. 通过XML添加和设置样式 通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 ...
- Android 自定义View合集
自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...
- Android 自定义View (五)——实践
前言: 前面已经介绍了<Android 自定义 view(四)-- onMeasure 方法理解>,那么这次我们就来小实践下吧 任务: 公司现有两个任务需要我完成 (1)监测液化天然气液压 ...
- Android 自定义 view(四)—— onMeasure 方法理解
前言: 前面我们已经学过<Android 自定义 view(三)-- onDraw 方法理解>,那么接下我们还需要继续去理解自定义view里面的onMeasure 方法 推荐文章: htt ...
- Android 自定义 view(三)—— onDraw 方法理解
前言: 上一篇已经介绍了用自己定义的属性怎么简单定义一个view<Android 自定义view(二) -- attr 使用>,那么接下来我们继续深究自定义view,下一步将要去简单理解自 ...
- Android 自定义view(二) —— attr 使用
前言: attr 在前一篇文章<Android 自定义view -- attr理解>已经简单的进行了介绍和创建,那么这篇文章就来一步步说说attr的简单使用吧 自定义view简单实现步骤 ...
- Android 自定义View
Android 自定义View流程中的几个方法解析: onFinishInflate():从布局文件.xml加载完组件后回调 onMeasure() :调用该方法负责测量组件大小 onSizeChan ...
- Android自定义View之CircleView
Android自定义View之CircleView 版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请表明出处:http://www.cnblogs.com/cavalier-/p/5999 ...
- Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程
转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...
随机推荐
- Qt调用dll中的功能函数
声明: 事先我已经自己动手写了一个简单的dll文件(myDLL.dll),C版接口的.并且用我前两篇有关DLL文章里面的方法,从dll中导出了导入库(.lib)文件,dll中有两个函数,原型如下: ...
- Qt编写自定义控件大全(liudianwu)
http://www.cnblogs.com/feiyangqingyun/p/6128288.html http://www.qtcn.org/bbs/read-htm-tid-62279.html
- 正则表达式lastIndex属性浅析
有这样一段代码: var newDateStr = " 11 13:48:18"; var reg = new RegExp("[0-9]+","g& ...
- JavaScript操作数组
数组被描述为一个存储元素的线性集合,元素可以通过索引来任意存取. 几乎所有的编程语言都有类似的数据结构,但是Javascript中的数组却略有不同. Javascript中的数组是一种特殊的对象,所以 ...
- new和delete malloc和free
程序中动态分配的对象存放在自由存储区(free store)或堆(heap). C语言程序使用一对标准库函数malloc和free在自由存储区中分配存储空间,而C++语言则使用new和delete表达 ...
- [LeetCode]题解(python):046-Permutations
题目来源 https://leetcode.com/problems/permutations/ Given a collection of distinct numbers, return all ...
- 【Algorithm】堆排,C++实现
对一个数组中的元素按照顺序构建二叉树,就形成了一个(二叉)堆.(二叉树是虚拟的,并不是真的建立二叉树) 表示堆的数组A有两个重要属性:A.heapSize,表示堆里面有多少元素,数组里有多少元素在堆里 ...
- Java: Difference between ArrayList and LinkedList
Basically, they are just two different implementations of List interface. LinkedList is implemented ...
- [BS-11] 关于RGB/ARGB颜色相关知识
关于RGB/ARGB颜色相关知识 众所周知,自然界的颜色都是由红色R.绿色G.蓝色B三元色按不同比例混合而成,每种元色取值范围是0-255.iOS中图片的颜色分为2种:24位和32位. 1. 24位( ...
- Perl Debug error: SetConsoleMode failed, LastError=|6|
Windows Strawberry Perl. 解决办法: 1. 设置环境变量 TERM = dumb 2. 重启 CMD 参考资料: http://padre.perlide.org/trac/t ...