国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義ViewGroup的實現方法

2019-12-12 06:20:12
字體:
來源:轉載
供稿:網友

     在android中提供了常見的幾種ViewGroup的實現,包括LinearLayout、Relativeayout、FrameLayout等。這些ViewGroup可以滿足我們一般的開發需求,但是對于界面要求復雜的,這幾個布局就顯得捉襟見肘了。所以自定義的ViewGroup在我們接觸過的應用中比比皆是。

     要想實現一個自定義的ViewGroup,第一步是學會自定義屬性,這些自定義的屬性將讓我們配置布局文件的時候更加的靈活。自定義屬性是在value目錄下聲明一個attrs.xml文件。

<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="CascadeViewGroup">  <attr name="verticalspacing" format="dimension"/>  <attr name="horizontalspacing" format="dimension"/> </declare-styleable> <declare-styleable name="CascadeViewGroup_LayoutParams">  <attr name="layout_paddingleft" format="dimension"/>  <attr name="layout_paddinTop" format="dimension"/> </declare-styleable></resources>

      在這里我們聲明了兩個自定義屬性集,CascadeViewGroup中的屬性是針對我們自定義的CascadeViewGroup組件設置的,也就是可以在布局文件中<CascadeViewGroup>標簽中可以使用的屬性。另外一個CascadeViewGroup_LayoutParams則是針對于CascadeViewGroup中的子View設置的屬性。

    在編寫代碼前,我們還設置了一個默認的寬度和高度供CascadeLayout使用。這兩個屬性在dimens.xml定義。

<?xml version="1.0" encoding="utf-8"?><resources>  <dimen name="default_horizontal_spacing">10dp</dimen> <dimen name="default_vertical_spacing">10dp</dimen></resources>

下面開始編寫自定義的組件CascadeLayout了。

package com.app.CustomViewMotion;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;/** * Created by charles on 2015/8/13. */public class CascadeViewGroup extends ViewGroup { //自定義布局中設置的寬度和高度 private int mHoriztonalSpacing; private int mVerticalSpacing; public CascadeViewGroup(Context context) {  this(context, null); } public CascadeViewGroup(Context context, AttributeSet attrs) {  this(context, attrs, 0); } public CascadeViewGroup(Context context, AttributeSet attrs, int defStyle) {  super(context, attrs, defStyle);  TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CascadeViewGroup);  try {   //獲取設置的寬度   mHoriztonalSpacing = a.getDimensionPixelSize(R.styleable.CascadeViewGroup_horizontalspacing,     this.getResources().getDimensionPixelSize(R.dimen.default_horizontal_spacing));   //獲取設置的高度   mVerticalSpacing = a.getDimensionPixelSize(R.styleable.CascadeViewGroup_verticalspacing,     this.getResources().getDimensionPixelSize(R.dimen.default_vertical_spacing));  } catch (Exception e) {   e.printStackTrace();  } finally {   a.recycle();  } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  final int count = this.getChildCount();  int width = this.getPaddingLeft();  int height = this.getPaddingTop();  for (int i = 0; i < count; i++) {   final View currentView = this.getChildAt(i);   this.measureChild(currentView, widthMeasureSpec, heightMeasureSpec);   CascadeViewGroup.LayoutParams lp = (CascadeViewGroup.LayoutParams) currentView.getLayoutParams();   if(lp.mSettingPaddingLeft != 0){    width +=lp.mSettingPaddingLeft;   }   if(lp.mSettingPaddingTop != 0){    height +=lp.mSettingPaddingTop;   }   lp.x = width;   lp.y = height;   width += mHoriztonalSpacing;   height += mVerticalSpacing;  }  width +=getChildAt(this.getChildCount() - 1).getMeasuredWidth() + this.getPaddingRight();  height += getChildAt(this.getChildCount() - 1).getMeasuredHeight() + this.getPaddingBottom();  this.setMeasuredDimension(resolveSize(width, widthMeasureSpec), resolveSize(height, heightMeasureSpec)); } @Override protected void onLayout(boolean b, int l, int i1, int i2, int i3) {  final int count = this.getChildCount();  for (int i = 0; i < count; i++) {   final View currentView = this.getChildAt(i);   CascadeViewGroup.LayoutParams lp = (CascadeViewGroup.LayoutParams) currentView.getLayoutParams();   currentView.layout(lp.x, lp.y, lp.x + currentView.getMeasuredWidth(),     lp.y + currentView.getMeasuredHeight());  } } public static class LayoutParams extends ViewGroup.LayoutParams {  int x;  int y;  int mSettingPaddingLeft;  int mSettingPaddingTop;  public LayoutParams(Context c, AttributeSet attrs) {   super(c, attrs);   TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.CascadeViewGroup_LayoutParams);   mSettingPaddingLeft = a.getDimensionPixelSize(R.styleable.CascadeViewGroup_LayoutParams_layout_paddingleft, 0);   mSettingPaddingTop = a.getDimensionPixelSize(R.styleable.CascadeViewGroup_LayoutParams_layout_paddinTop, 0);   a.recycle();  }  public LayoutParams(int width, int height) {   super(width, height);  }  public LayoutParams(ViewGroup.LayoutParams source) {   super(source);  } } @Override protected ViewGroup.LayoutParams generateDefaultLayoutParams() {  return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); } @Override protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {  return new LayoutParams(p); } @Override public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {  return new LayoutParams(this.getContext(), attrs); }}

代碼稍微優點長,但是結構還是很清晰的。

1)構造方法中或者XML文件中配置屬性的值。通過TypedArray中的方法獲取我們在layout布局中設置的屬性,并且將他們保存在成員變量中。

2)構造自定義的內部類LayoutParams。構造這個內部類,可以方便我們在測量我們的子View的時候保存他們的屬性值,以便在Layout階段布局。

3)generateLayoutParams()、generateDefaultParams()等方法。在這些方法中返回我們自定義的layoutParams。至于為什么要重寫這些方法,可以查看ViewGroup類的addView()方法就很清楚了。

4)measure階段。在measure階段,我們會測量自己的大小,同時也要測量子View的大小,并且將子View的信息保存在LayoutParams中。

5)layout階段。根據各個子View的信息,布局他們的位置。

最后加上布局文件。

<?xml version="1.0" encoding="utf-8"?><!--添加自定義屬性給viewGroup--><!--新添加的命名空間的后綴必須保持和.xml中聲明的包名一致--><com.app.CustomViewMotion.CascadeViewGroup  xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:ts="http://schemas.android.com/apk/res/com.app.CustomViewMotion"  android:layout_width="match_parent"  android:layout_height="match_parent"  ts:horizontalspacing="15dp"  ts:verticalspacing="15dp"> <TextView android:layout_width="100dp"    android:layout_height="100dp"    android:gravity="center"    android:text="text1"    android:background="#668B8B"/> <TextView android:layout_width="100dp"    android:layout_height="100dp"    android:gravity="center"    android:text="text2"    android:background="#FFDAB9"/> <TextView android:layout_width="100dp"    android:layout_height="100dp"    android:gravity="center"    android:text="text3"    android:background="#43CD80"/><!--這個子view中添加自定義子view屬性--> <TextView android:layout_width="100dp"    android:layout_height="100dp"    android:gravity="center"    android:text="text4"    ts:layout_paddingleft="100dp"    ts:layout_paddinTop="100dp"    android:background="#00CED1"/></com.app.CustomViewMotion.CascadeViewGroup>

實現的效果如下:

以上就是的全部內容,希望能給大家一個參考,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 务川| 阿巴嘎旗| 黄浦区| 奉贤区| 庆元县| 吉水县| 霍城县| 镇雄县| 武宁县| 凭祥市| 台前县| 犍为县| 和田县| 兴安县| 烟台市| 海安县| 乌鲁木齐市| 宜兰县| 龙山县| 长葛市| 巫溪县| 中牟县| 赤水市| 万荣县| 禹城市| 蕉岭县| 沾益县| 中宁县| 鲁甸县| 普定县| 黑龙江省| 莆田市| 渑池县| 辉南县| 五寨县| 平江县| 乌兰县| 呼图壁县| 二手房| 伊春市| 萍乡市|