Heim > Java > javaLernprogramm > Implementierungsmethode der benutzerdefinierten ViewGroup für Android

Implementierungsmethode der benutzerdefinierten ViewGroup für Android

高洛峰
Freigeben: 2017-01-16 16:59:27
Original
1347 Leute haben es durchsucht

In Android werden mehrere gängige ViewGroup-Implementierungen bereitgestellt, darunter LinearLayout, Relativeayout, FrameLayout usw. Diese ViewGroups können unsere allgemeinen Entwicklungsanforderungen erfüllen, für komplexe Schnittstellenanforderungen reichen diese Layouts jedoch nicht aus. Daher gibt es in den Anwendungen, mit denen wir in Kontakt gekommen sind, zahlreiche benutzerdefinierte ViewGroups.

Um eine benutzerdefinierte ViewGroup zu implementieren, besteht der erste Schritt darin, benutzerdefinierte Attribute zu lernen. Diese benutzerdefinierten Attribute machen uns flexibler bei der Konfiguration der Layoutdatei. Benutzerdefinierte Attribute werden in einer attrs.xml-Datei im Werteverzeichnis deklariert.

<?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>
Nach dem Login kopieren

Hier deklarieren wir zwei benutzerdefinierte Eigenschaftssätze für unsere benutzerdefinierte CascadeViewGroup-Komponente, die im Tag zu verwenden ist. Ein weiterer CascadeViewGroup_LayoutParams ist ein Eigenschaftssatz für die Unteransicht in CascadeViewGroup.

Bevor wir den Code schreiben, legen wir außerdem eine Standardbreite und -höhe fest, die CascadeLayout verwenden soll. Diese beiden Eigenschaften sind in dimens.xml definiert.

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

Jetzt beginnen wir mit dem Schreiben der benutzerdefinierten Komponente 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);
 }
}
Nach dem Login kopieren

Der Code ist etwas länger, aber die Struktur ist immer noch sehr klar.

1) Der Wert des Konfigurationsattributs im Konstruktor oder in der XML-Datei. Rufen Sie die Eigenschaften, die wir im Layout festlegen, über die Methoden in TypedArray ab und speichern Sie sie in Mitgliedsvariablen.

2) Erstellen Sie eine benutzerdefinierte innere Klasse LayoutParams. Durch die Konstruktion dieser internen Klasse können wir ihre Attributwerte speichern, wenn wir unsere Unteransichten für das Layout in der Layoutphase messen.

3) GenerateLayoutParams(), GenerateDefaultParams() und andere Methoden. Geben Sie unsere benutzerdefinierten layoutParams in diesen Methoden zurück. Warum diese Methoden überschrieben werden müssen, wird durch einen Blick auf die addView()-Methode der ViewGroup-Klasse deutlich.

4) Messphase. In der Messphase messen wir unsere eigene Größe sowie die Größe der Unteransicht und speichern die Informationen der Unteransicht in LayoutParams.

5) Layoutphase. Legen Sie ihre Positionen basierend auf den Informationen jeder Unteransicht fest.

Fügen Sie abschließend die Layoutdatei hinzu.

<?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>
Nach dem Login kopieren

Der erzielte Effekt ist wie folgt:

Implementierungsmethode der benutzerdefinierten ViewGroup für Android

Das Obige ist der gesamte Inhalt. Ich hoffe, er kann jedem eine Referenz geben, und ich auch Ich hoffe, dass jeder die chinesische PHP-Website unterstützt.

Weitere Artikel zur Implementierungsmethode der benutzerdefinierten Android ViewGroup finden Sie auf der chinesischen PHP-Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage