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. Windows下 使用CodeBlocks配置OpenGL开发环境

    CodeBlocks版本:13.12 下载OpenGL配置文件 1.glut.dll glut32.dll放入系统盘Windows\System32文件夹 2.glut.h放入CodeBlocks安装 ...

  2. JS懒加载

    4.如何使用js懒加载图片       a.懒加载图片是基于jquery.js的,所以: <script src="jquery.js" type="text/ja ...

  3. Average Cost (AVCO) Method

    http://accountingexplained.com/financial/inventories/avco-method   Average Cost (AVCO) Method   Aver ...

  4. LightOj1007 - Mathematically Hard(欧拉函数)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1007 题意:给你两个数a和b,求他们之间所有数的欧拉值得平方和; a and b (2 ...

  5. HTML-003-模拟IDE代码展开收起功能简单示例

    当先我们在日常的编程开发工作中使用编程工具(例如 Eclipse.Sublime 等等)都有相应的代码折叠展开功能,如下图所示,极大的方便了我们的编码工作.

  6. 用css实现云状提示框

    经常会用到云状提示框,如图: 基本框架是这样,以三角在左侧为例: <div class="container"> <div class="content ...

  7. Eclipse代码风格

    1.代码对齐风格:project...properties...Java Code Style...Formatter...Brance

  8. 输出Java的GC信息

    -verbose:gc -XX:+printGC 可以打印GC的简要信息 [GC 4790K->374K(15872K), 0.0001606 secs] [GC 4790K->374K( ...

  9. webstorm注册

    选择“license server” 输入:http://114.215.133.70:41017(适用ws2016.2.2) 2.3选择activation code注册 43B4A73YYJ-ey ...

  10. 30天,App创业从0到1【7.12西安站】

    活动概况 时间:2015年07月12日13:30-16:30 地点:汇天使咖啡(高新路36号智空间二楼) 主办:APICloud.UPYUN.万紫网络 网址:www.apicloud.com 费用:免 ...