main.xml

  1. <?xml version="1.0" encoding="utf-8"?
  2.  
  3. >
  4. <com.example.SimpleLayout.MyLinLayout xmlns:android="http://schemas.android.com/apk/res/android"
  5. xmlns:tools="http://schemas.android.com/tools"
  6. android:layout_width="match_parent"
  7. android:layout_height="wrap_content"
  8. android:background="#ff00ff"
  9. tools:context=".MainActivity" >
  10. <!-- XML中加入上layout_margin參数 -->
  11. <TextView
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"
  14. android:layout_marginTop="10dp"
  15. android:background="#ff0000"
  16. android:text="第一个VIEW" />
  17.  
  18. <TextView
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:layout_marginTop="20dp"
  22. android:background="#00ff00"
  23. android:text="第二个VIEW" />
  24.  
  25. <TextView
  26. android:layout_width="wrap_content"
  27. android:layout_height="wrap_content"
  28. android:layout_marginTop="30dp"
  29. android:background="#0000ff"
  30. android:text="第三个VIEW" />
  31.  
  32. </com.example.SimpleLayout.MyLinLayout>

MainActivity

  1. package com.example.SimpleLayout;
  2.  
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5.  
  6. public class MainActivity extends Activity {
  7. @Override
  8. public void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.main);
  11. }
  12. }

MyLinLayout

  1. package com.example.SimpleLayout;
  2.  
  3. import android.content.Context;
  4. import android.util.AttributeSet;
  5. import android.view.View;
  6. import android.view.ViewGroup;
  7.  
  8. /**
  9. * /** onMeasure():測量自己的大小。自己的大小,为正式布局提供建议。(注意,仅仅是建议。至于用不用,要看onLayout);
  10. * onLayout():使用layout()函数对全部子控件布局; onDraw():依据布局的位置画图;
  11. *
  12. */
  13. public class MyLinLayout extends ViewGroup {
  14. /**
  15. * 构造函数--二话不说,直接写出三个来
  16. *
  17. * @param context
  18. */
  19. public MyLinLayout(Context context) {
  20. super(context);
  21. }
  22.  
  23. public MyLinLayout(Context context, AttributeSet attrs) {
  24. super(context, attrs);
  25. }
  26.  
  27. public MyLinLayout(Context context, AttributeSet attrs, int defStyleAttr) {
  28. super(context, attrs, defStyleAttr);
  29. }
  30.  
  31. /**
  32. * 假设要自己定义ViewGroup支持子控件的layout_margin參数。
  33. * 则自己定义的ViewGroup类必须重载generateLayoutParams
  34. * ()函数,而且在该函数中返回一个ViewGroup.MarginLayoutParams派生类对象,这样才干使用margin參数。
  35. */
  36. @Override
  37. protected LayoutParams generateLayoutParams(LayoutParams p) {
  38. return new MarginLayoutParams(p);
  39. }
  40.  
  41. /**
  42. * 从指定的XML中获取相应的layout_width和layout_height值
  43. */
  44. // 假设我们还须要margin相关的參数就仅仅能重写generateLayoutParams()函数了:
  45. @Override
  46. public LayoutParams generateLayoutParams(AttributeSet attrs) {
  47. return new MarginLayoutParams(getContext(), attrs);
  48. }
  49.  
  50. /**
  51. * generateDefaultLayoutParams()函数。 直接返回相应的MarginLayoutParams()的实例
  52. */
  53. /**
  54. * 假设要使用默认的构造方法,就生成layout_width="wrap_content"、layout_height="wrap_content"
  55. * 相应的參数
  56. */
  57. /**
  58. * 为什么非要重写generateLayoutParams()函数了。就是由于默认的generateLayoutParams()
  59. * 函数仅仅会提取layout_width
  60. * 、layout_height的值,仅仅有MarginLayoutParams()才具有提取margin间距的功能!
  61.  
  62. !!
  63.  

  64. */
  65. @Override
  66. protected LayoutParams generateDefaultLayoutParams() {
  67. return new MarginLayoutParams(LayoutParams.WRAP_CONTENT,
  68. LayoutParams.WRAP_CONTENT);
  69. }
  70.  
  71. /**
  72. * 此ViewGroup的宽高属性 android:layout_width="match_parent"--EXACTLY(确定)
  73. * android:layout_height="wrap_content"--AT_MOST(不确定)
  74. *
  75. * 他们是父类传递过来给当前view的一个建议值,建议值,即想把当前view的尺寸设置为宽widthMeasureSpec,
  76. * 高heightMeasureSpec
  77. *
  78. * ②、EXACTLY(全然),父元素决定自元素的确切大小。子元素将被限定在给定的边界里而忽略它本身大小。
  79. * ③、AT_MOST(至多),子元素至多达到指定大小的值。
  80. */
  81. @Override
  82. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  83. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  84. // 宽度、高度
  85. int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
  86. int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
  87. // 測量模式
  88. int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);
  89. int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec);
  90. // 初始化ViewGroup宽、高
  91. int viewGroupHeight = 0;
  92. int viewGroupWidth = 0;
  93. // 获取viewGroup中的每一个孩子View,进行遍历
  94. int count = getChildCount();
  95. for (int i = 0; i < count; i++) {
  96. // 依次获取每一个孩子View对象
  97. View child = getChildAt(i);
  98. // 測量每一个孩子View,将父类的模式传进去--点开看源代码
  99. measureChild(child, widthMeasureSpec, heightMeasureSpec);
  100.  
  101. // 获取MarginLayoutParams布局參数!!!。!。!
  102.  
  103. !!!
  104.  
  105.  
  106. !!
  107.  
  108. 。!!。!
  109.  
  110.  
  111. !。!
  112.  

  113. /**
  114. * 由于generateLayoutParams()的返回值是LayoutParams实例,
  115. * 而MarginLayoutParams是派生自LayoutParam的
  116. * ;所以依据类的多态的特性,能够直接将此时的LayoutParams实例直接强转成MarginLayoutParams实例。
  117. * 所以以下这句在这里是不会报错的:
  118. */
  119. MarginLayoutParams lp = (MarginLayoutParams) child
  120. .getLayoutParams();
  121. int childHeight = child.getMeasuredHeight() + lp.topMargin
  122. + lp.bottomMargin;
  123. int childWidth = child.getMeasuredWidth() + lp.leftMargin
  124. + lp.rightMargin;
  125.  
  126. // ViewGroup高度递增
  127. viewGroupHeight += childHeight;
  128. // ViewGroup宽度取最大值
  129. viewGroupWidth = Math.max(childWidth, viewGroupWidth);
  130. }
  131.  
  132. // ViewGroup的宽不须要測量直接"match_parent"--EXACTLY
  133. // 高是"wrap_content"--AT_MOST。须要累加得到高度
  134. /**
  135. * ②、EXACTLY(全然)。父元素决定自元素的确切大小,子元素将被限定在给定的边界里而忽略它本身大小。
  136. * ③、AT_MOST(至多),子元素至多达到指定大小的值。
  137.  
  138. */
  139. setMeasuredDimension(
  140. (measureWidthMode == MeasureSpec.EXACTLY) ?
  141.  
  142. measureWidth
  143. : viewGroupWidth,
  144. (measureHeightMode == MeasureSpec.EXACTLY) ?
  145.  
  146. measureHeight
  147. : viewGroupHeight);
  148. }
  149.  
  150. @Override
  151. protected void onLayout(boolean changed, int l, int t, int r, int b) {
  152. int top = 0;
  153. int count = getChildCount();
  154. for (int i = 0; i < count; i++) {
  155.  
  156. View child = getChildAt(i);
  157. // 获取MarginLayoutParams布局參数!。!
  158.  
  159.  
  160.  
  161.  
  162.  
  163. !!
  164.  
  165.  
  166.  
  167. !!!
  168.  
  169.  
  170. !。。!!
  171. MarginLayoutParams lp = (MarginLayoutParams) child
  172. .getLayoutParams();
  173. int childHeight = child.getMeasuredHeight() + lp.topMargin
  174. + lp.bottomMargin;
  175. int childWidth = child.getMeasuredWidth() + lp.leftMargin
  176. + lp.rightMargin;
  177.  
  178. child.layout(0, top, childWidth, top + childHeight);
  179. top += childHeight;
  180. }
  181. }
  182. }

自己定义ViewGroup控件(二)-----&gt;流式布局进阶(二)的更多相关文章

  1. 自己定义ViewGroup控件(一)-----&gt;流式布局进阶(一)

    main.xml <? xml version="1.0" encoding="utf-8"?> <com.example.SimpleLay ...

  2. 05-移动web之流式布局

    一.视口 1.常见屏幕知识 设备 解释 描述 宽 屏幕的宽度 - (单位:英寸) 屏幕的宽度 高 屏幕的高度 -(单位:英寸) 屏幕的高度 对角线 屏幕的对角线的长度 英寸 一般说手机尺寸 是指以屏幕 ...

  3. Android控件进阶-自定义流式布局和热门标签控件

    技术:Android+java   概述 在日常的app使用中,我们会在android 的app中看见 热门标签等自动换行的流式布局,今天,我们就来看看如何 自定义一个类似热门标签那样的流式布局吧,类 ...

  4. android 自己定义组合控件

    自己定义控件是一些android程序猿感觉非常难攻破的难点,起码对我来说是这种,可是我们能够在网上找一些好的博客关于自己定义控件好好拿过来学习研究下,多练,多写点也能找到感觉,把一些原理弄懂,今天就讲 ...

  5. Quartz2D-二维画图引擎 、自己定义UI控件

    // // MyDraw.m // 绘图 #import "MyDraw.h" @implementation MyDraw //Quartz2D 是一个二维绘图引擎 //自己定义 ...

  6. android:自己定义组合控件Weight(高仿猫眼底部菜单条)

    在我们实际开发其中.会碰见一些布局结构类似或者同样的界面.比如应用的设置界面.tabbutton界面等. 这时候.对于刚開始学习的人来说,xml里面一个个绘制出来也许是最初的想法.可能随着经验的积累, ...

  7. Android 使用shape定义不同控件的的颜色、背景色、边框色

    Android 使用shape定义不同控件的的颜色.背景色.边框色 设置按钮的右边框和底边框颜色为红色,边框大小为3dp: 在drawable新建一个 buttonstyle.xml的文件,内容如下: ...

  8. MUI框架-03-自定义MUI控件样式

    MUI框架-03-自定义MUI控件样式 开发请查阅:官方文档:http://dev.dcloud.net.cn/mui/ui/ 如何自定义MUI控件样式 mui 以 iOS 7的 UI 为基础,补充了 ...

  9. android自己定义开关控件

    近日在android项目要使用开关控件.可是android中自带的开关控件不太惬意,所以就打算通过自己定义View写一个开关控件 ios的开关控件当然就是我要仿照的目标. 先上图:   waterma ...

随机推荐

  1. StringBuilder与StringBuffer

    转:http://www.cnblogs.com/pepcod/archive/2013/02/16/2913557.html JAVA中用于处理字符串常用的有三个类: java.lang.Strin ...

  2. 自定义JQuery扩展方法

    ; (function ($, window, document, undefined) { $.getUrlParam = function (name) { var reg = new RegEx ...

  3. js 数组知识复习

    2.Array类型 2.1 创建数组 两种方式: 1.new Array(); //创建一个空数组 var arr1 = new Array(); //创建一个长度为10的空数组, var arr2 ...

  4. Program "D:\AndroidDevelopment\android-ndk-r9\ndk-build.cmd" not found in PATH

    1.问题描述 2.解决方法:修改ndk-build.cmd的配置路径, 修改成本地ndk-build.cmd所在路径,如下

  5. DNS解析过程详解【转】

    转自:http://blog.chinaunix.net/uid-28216282-id-3757849.html 先说一下DNS的几个基本概念: 一. 根域 就是所谓的“.”,其实我们的网址www. ...

  6. python - break和continue

    break 终止整个循环:当循环或判断执行到break语句时,即使判断条件为True或者序列尚未完全被历遍,都会跳出循环或判断 for i in xrange(10): print(i) if i = ...

  7. hdu 2363(枚举+最短路好题)

    Cycling Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  8. UITextView只能显示两行问题

    需求:UITextView只能显示两行 UITextView * textView = [[UITextView alloc]init]; textView.frame = CGRectMake(20 ...

  9. 爬虫学习笔记(五) Beautiful Soup使用

    上篇博客说了正则表达式,但是正则学起来比较费劲,写的时候也不好写,这次说下Beautiful Soup怎么用,这个模块是用来解析html的,它操作很简单,用起来比较方便,比正则学习起来简单多了. 这是 ...

  10. Network| ICMP

    Internet Control Message Protocol,ICMP是网路协议族的核心协议之一.它用于TCP/IP网络中发送控制消息,提供可能发生在通信环境中的各种问题反馈,通过这些信息,令管 ...