Android 사용자 정의 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 구성 요 소 를 대상 으로 설정 한 것 입 니 다.즉,레이아웃 파일 에서코드 를 작성 하기 전에 캐 스 케 이 드 레이아웃 에 사용 할 기본 너비 와 높이 를 설정 합 니 다.이 두 속성 은 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 의 방법 을 통 해 레이아웃 레이아웃 에 설 정 된 속성 을 가 져 오고 구성원 변수 에 저장 합 니 다.
2)사용자 정의 내부 클래스 LayoutParams 를 구성 합 니 다.이 내부 클래스 를 구성 하면 Layout 단계 에서 배치 할 수 있 도록 하위 View 를 측정 할 때 속성 값 을 저장 할 수 있 습 니 다.
3)generateLayoutParams(),generateDefaultParams()등 방법.이 방법 들 에서 사용자 정의 layoutParams 를 되 돌려 줍 니 다.왜 이런 방법 을 다시 써 야 하 는 지 에 대해 서 는 View Group 류 의 addView()방법 을 보면 알 수 있 습 니 다.
4)measure 단계.measure 단계 에서 저 희 는 자신의 크기 를 측정 하 는 동시에 하위 View 의 크기 도 측정 하고 하위 View 의 정 보 를 Layout Params 에 저장 합 니 다.
5)layot 단계.각 키 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>
실현 효 과 는 다음 과 같다.이상 의 모든 내용 입 니 다.참고 해 주시 고 많은 응원 부 탁 드 리 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.