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 ...
随机推荐
- CC2540 USB DONGLE 使用 BTool 调试BLE 说明
一.Btool软件界面介绍 首先您要将USBDONGLE插入电脑的USB口,然后打开双击打开Btool软件,打开后如下图所示: 在安装驱动的教程中,我们已经记住了我们的USB DONGLE的串口号,在 ...
- 注册、启动、停止windows服务
找到本机InstallUtil.exe命令 命令行下注册服务InstallUtil.exe D:\XXXXService.exe 启动服务 net start XXXXService 停止服务net ...
- 1058 N的阶乘的长度
1058 N的阶乘的长度 基准时间限制:1 秒 空间限制:131072 KB 输入N求N的阶乘的10进制表示的长度.例如6! = 720,长度为3. Input 输入N(1 <= N <= ...
- [LeetCode]题解(python):045-Jump game II
题目来源 https://leetcode.com/problems/jump-game-ii/ Given an array of non-negative integers, you are in ...
- Android笔记:Select at least one project解决办法
导入项目的时候发现无法导入,最上方提示“Select at least one projec” 百度了一下,原来是和上一个项目名称相同了,直接把重名项目重命名后再导入即可.
- Emmet(之前叫Zencoding)插件安装
按 ctr+shift+P,输入 install Package,找到emmet,确认安装 Package Control Messages======================== Emmet ...
- 免费真机调试 -- Xcode7以上版本
刚新安装了Xcode7 , 据说这个版本可以免费真机调试,于是用了一个新的AppID测试了,发现真的可以免费真机调试了呢!新的appId账号(随便一个苹果手机账号就行),没有支付每年的99美刀,也没有 ...
- iOS Node Conflict svn冲突
当出现这个冲突时,应该是我add的文件,和同事处理的方法有冲突导致的. 这个的解决办法是:先revert这个文件,然后再update.
- Interview Sort Function
QuickSort Java Code: import java.util.*; public class quickSort{ public static void main(String [] a ...
- SET Statements (Transact-SQL)
The Transact-SQL programming language provides several SET statements that change the current sessio ...