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(一)的更多相关文章

  1. Android自定义View 画弧形,文字,并增加动画效果

    一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类   B ...

  2. (转)[原] Android 自定义View 密码框 例子

    遵从准则 暴露您view中所有影响可见外观的属性或者行为. 通过XML添加和设置样式 通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 ...

  3. Android 自定义View合集

    自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...

  4. Android 自定义View (五)——实践

    前言: 前面已经介绍了<Android 自定义 view(四)-- onMeasure 方法理解>,那么这次我们就来小实践下吧 任务: 公司现有两个任务需要我完成 (1)监测液化天然气液压 ...

  5. Android 自定义 view(四)—— onMeasure 方法理解

    前言: 前面我们已经学过<Android 自定义 view(三)-- onDraw 方法理解>,那么接下我们还需要继续去理解自定义view里面的onMeasure 方法 推荐文章: htt ...

  6. Android 自定义 view(三)—— onDraw 方法理解

    前言: 上一篇已经介绍了用自己定义的属性怎么简单定义一个view<Android 自定义view(二) -- attr 使用>,那么接下来我们继续深究自定义view,下一步将要去简单理解自 ...

  7. Android 自定义view(二) —— attr 使用

    前言: attr 在前一篇文章<Android 自定义view -- attr理解>已经简单的进行了介绍和创建,那么这篇文章就来一步步说说attr的简单使用吧 自定义view简单实现步骤 ...

  8. Android 自定义View

    Android 自定义View流程中的几个方法解析: onFinishInflate():从布局文件.xml加载完组件后回调 onMeasure() :调用该方法负责测量组件大小 onSizeChan ...

  9. Android自定义View之CircleView

    Android自定义View之CircleView 版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请表明出处:http://www.cnblogs.com/cavalier-/p/5999 ...

  10. Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...

随机推荐

  1. Delphi Dll示例

    //MyInt.pas unit MyInt; interface {$IFNDEF MYLIB} function MyAdd(a,b:integer):integer ;stdcall; {$EN ...

  2. IIS是如何处理ASP.NET请求的

    每次服务器接受到请求,都要先经IIS处理.这不是一篇描述ASP.NE生命周期的文章,仅仅是关于IIS操作的.在我们开始之前,先了解这些会有助于对全文的理解,同时欢迎反馈和建议. 什么是Web Serv ...

  3. Android笔记:gson处理多层嵌套的复杂形式的json

    当一个Class的字段属性中包含另一个class时gson能正常处理吗? 最初看到网上有说使用static的说法 经验证是不需要的 直接当普通类来用就可以了. 直接使用gson.fromJson方法即 ...

  4. Xor Sum---hdu4825(01字典树模板)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4825 题意:有n个数m个查找,每个查找有一个数x, 从序列中找到一个数y,使得x异或y最大 ...

  5. Processes vs Threads

    A process is an executing instance of an application. What does that mean? Well, for example, when y ...

  6. SQL2000的Enterprise Edition和Developer Edition有什么区别

    1.SQL Server 2000 Enterprise Edition(企业版) 该版本具有强大的可伸缩性和可靠性,可作为大型WEB站点.企业联机事务处理(OLTP)以及数据仓库系统等数据库产品的服 ...

  7. iOS7上TableViewCell的button和UIImageView个别未显示的bug

    要做这个cell,用xib将cell做成之后,在iPhone6.6Plus.5s上运行良好,但是在iOS7的5s和iPad上,黄色的小星星和下载按钮均没有显示. 甚为惊奇. 在网上百度之,发现了解决办 ...

  8. 05-雷海林-mysql备份原理与在TDSQL中的实践

    05-雷海林-mysql备份原理与在TDSQL中的实践 下载地址: http://files.cnblogs.com/files/MYSQLZOUQI/05-%E9%9B%B7%E6%B5%B7%E6 ...

  9. 8款实用Sublime text 3插件推荐

    Sublime Text作为一个尽为人知的代码编辑器,其优点不用赘述.界面整洁美观.文本功能强大,且运行速度极快,非常适合编写代码,写文章做笔记.Sublime Text还支持Mac.Windows和 ...

  10. MongoDB Map Reduce

    介绍 Map-Reduce是一种计算模型,简单的说就是将大批量的工作分解(MAP)执行,然后再将结果合并成最终结果(REDUCE). MongoDB提供的Map-Reduce非常灵活,对于大规模数据分 ...