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的串口号,在 ...
- iOS开发之Objective-c的MD5/SHA1加密算法的实现
Objective-c实现MD5和SHA1算法相对还是比较简单的,可以直接调用系统的C/C++共享库来实现调用 MD5即Message Digest Algorithm 5(信息-摘要算法 5),用于 ...
- 利用堆排序找出数组中前n大的元素
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <time.h> ...
- node.js使用util实现简单继承
/** * Created by zzq on 2015/5/15. */ var util = require('util'); var Person = function(){ var myD=' ...
- gcc工具链简述
工具链软件包括BINUTILS.GCC.GLIBC.GDB等. BINUTILS是二进制程序处理工具,包括链接器.汇编器等目标程序处理的工具. GCC(GNU Compiler Collection) ...
- android framework浅析_转
Android系统从底向上一共分了4层,每一层都把底层实现封装,并暴露调用接口给上一层. 1. Linux内核(Linux Kernel) 1)Android运行在linux kernel 2.6之上 ...
- Enum 绑定到 RadioButton
参考 这篇文章. 和 http://www.cnblogs.com/626498301/archive/2012/05/22/2512958.html
- Nuget程序包 使用log4net
Nuget程序包不用细介绍,网上资源很多,有个项目使用了log4net,为项目打log,功能很多,足够一般使用. 使用时候需要在配置文件中对其进行相关配置,我自己的配置文件放在App.config文件 ...
- osgEarth编译的一些问题
这两天借着osg培训的机会捯饬了下64位osgearth的编译.遇到了一些问题: 首先我没有编译osg,用的提供的osg3.2.1编译好的64位包. 编译osgearth先后编译了2个版本,先是2.7 ...
- 获取git的最后一次提交的commit id
git log --pretty=format:"%h" | head -1 | awk '{print $1}' 可以放到xcode build setting post ...