Android 에 서 는 사용자 정의 ViewGroup 의 총 결 을 사용 합 니 다.

분류 하 다.
사용자 정의 Layout 는 두 가지 상황 으로 나 눌 수 있 습 니 다.
  • ViewGroup 을 사용자 정의 하여 LinearLayout,RelativeLayout 등 과 다른 ViewGroup 을 만 들 었 습 니 다.예 를 들 어 API 14 이후 추 가 된 GridLayout,design support library 의 Coordinator Layout 등 이다
  • 4.567917.이미 있 는 Layout 를 사용자 정의 한 다음 에 특수 한 기능 을 추가 합 니 다.예 를 들 어 TableLayout 와 percent support library 의 Percent FrameLayout 등 이다흐름
    사용자 정의 View 프로 세 스 는:onMeasure()->onLayout()->onDraw()입 니 다.View Group 을 사용자 정의 할 때 일반적으로 onDraw 를 실현 하지 않 습 니 다.물론 특별한 수요 도 있 을 수 있 습 니 다.예 를 들 어 Coordinator Layout.
    그래서 onMeasure 와 onLayout 는 대부분 우리 가 접촉 하 는 View Group 을 할 수 있 습 니 다.그러나 onMeasure 에서 View Group 의 크기 를 측정 하고 onLayout 에서 Child View 의 위 치 를 계산 하 는 것 만 으로 는 부족 하 다.
    예 를 들 어 View Group 의 Child View 에 속성 을 설정 하면 어떻게 합 니까?
    하나의 예.
    사용자 정의 ViewGroup 을 쓰 고 Child View 의 크기(길이)를 ViewGroup 에서 차지 하 는 속성 을 추가 합 니 다.
    LinearLayout 라 고 가정 하면 먼저 Custom LinearLayout 를 정의 합 니 다.
    
    public class CustomLinearLayout extends LinearLayout {
      public CustomLinearLayout(Context context) {
        super(context);
      }
    
      public CustomLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
      }
    
      public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
      }
    
      @TargetApi(Build.VERSION_CODES.LOLLIPOP)
      public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
      }
    }
    
    
    다른 것 은 말 하지 않 고 Child View 의 크기 를 조절 하기 위해 속성 을 늘 려 야 합 니 다.그러면 value/attr.xml 에서 그 속성 을 정의 합 니 다(CustomLinearLayout 사용Layout 는 Custom LinearLayout 와 구분 합 니 다.물론 이 이름 은 자 유 롭 습 니 다.)
    
    <declare-styleable name="CustomLinearLayout_Layout">
      <!--      -->
      <attr name="inner_percent" format="float"/>
    </declare-styleable>
    ViewGroup 이 addView()를 호출 할 때 최종 적 으로 이 방법 으로 호출 됩 니 다.
    
    public void addView(View child, int index, LayoutParams params)
    이 params 는 View 의 설정 을 대표 합 니 다.ViewGroup.LayoutParams 에는 width,height,LinearLayout.LayoutParams 가 weight 속성 을 증가 시 켰 습 니 다.그럼 우 리 는 Layout Params 를 실현 해 야 한다.그럼 이제 이렇게 된 거 야?
    
    public class CustomLinearLayout extends LinearLayout {
      public CustomLinearLayout(Context context) {
        super(context);
      }
    
      public CustomLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
      }
    
      public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
      }
    
      @TargetApi(Build.VERSION_CODES.LOLLIPOP)
      public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
      }
      public static class LayoutParams extends LinearLayout.LayoutParams {
    
        private float innerPercent;
    
        private static final int DEFAULT_WIDTH = WRAP_CONTENT;
        private static final int DEFAULT_HEIGHT = WRAP_CONTENT;
    
        public LayoutParams() {
          super(DEFAULT_WIDTH, DEFAULT_HEIGHT);
          innerPercent = -1.0f;
        }
    
        public LayoutParams(float innerPercent) {
          super(DEFAULT_WIDTH, DEFAULT_HEIGHT);
          this.innerPercent = innerPercent;
        }
    
        public LayoutParams(ViewGroup.LayoutParams p) {
          super(p);
        }
    
        @TargetApi(Build.VERSION_CODES.KITKAT)
        public LayoutParams(LinearLayout.LayoutParams source) {
          super(source);
        }
    
        @TargetApi(Build.VERSION_CODES.KITKAT)
        public LayoutParams(LayoutParams source) {
          super(source);
          this.innerPercent = source.innerPercent;
        }
    
        public LayoutParams(Context c, AttributeSet attrs) {
          super(c, attrs);
          init(c, attrs);
        }
    
        private void init(Context context, AttributeSet attrs) {
          TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomLinearLayout_Layout);
          innerPercent = a.getFloat(R.styleable.CustomLinearLayout_Layout_inner_percent, -1.0f);
          a.recycle();
        }
      }
    }
    
    
    이제 xml 에서 우리 의 속성 을 사용 할 수 있 습 니 다.
    
    <?xml version="1.0" encoding="utf-8"?>
    <com.egos.samples.custom_layout.CustomLinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:layout_width="200dp"
      android:layout_height="200dp"
      android:id="@+id/test_layout"
      android:background="#ffff0000"
      android:gravity="center"
      android:orientation="vertical">
      <ImageView
        android:text="Egos"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:onClick="add"
        android:background="#ff00ff00"
        app:inner_percent="0.8"/>
    </com.egos.samples.custom_layout.CustomLinearLayout>
    
    
    다만 부 드 러 울 뿐 소 용이 없다.
    그렇다면 Child View 의 크기 를 어떻게 조절 하 는 것 일 까?당연히 onMeasure 에서 제어 하 죠.addView 는 아래 코드 를 실행 합 니 다.
    
    requestLayout();
    invalidate(true);
    이렇게 되면 onMeasure(),onLayout()를 다시 한 번 걸 을 수 있 습 니 다.onMeasure()를 실현 하 는 방법 은 나중에 Child View 의 크기 를 직접 처리 합 니 다.저 는 LinearLayout 를 물 려 받 았 기 때문에 사실은 measure Child BeforeLayout()를 처리 합 니 다.결국 Child BeforeLayout 를 측정 할 때 Child View 의 크기 를 처리 합 니 다.
    
    @Override 
    protected void measureChildWithMargins(View child, int parentWidthMeasureSpec,
                        int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
      //  xml    match_parent,          
      if (child != null && child.getLayoutParams() instanceof LayoutParams &&
          ((LayoutParams) child.getLayoutParams()).innerPercent != -1.0f) {
        parentWidthMeasureSpec = MeasureSpec.makeMeasureSpec((int) (MeasureSpec.getSize(parentWidthMeasureSpec) *
            ((LayoutParams) child.getLayoutParams()).innerPercent), MeasureSpec.getMode(parentWidthMeasureSpec));
        parentHeightMeasureSpec = MeasureSpec.makeMeasureSpec((int) (MeasureSpec.getSize(parentHeightMeasureSpec) *
            ((LayoutParams) child.getLayoutParams()).innerPercent), MeasureSpec.getMode(parentHeightMeasureSpec));
        super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed,
          parentHeightMeasureSpec, heightUsed);
      } else {
        super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed,
            parentHeightMeasureSpec, heightUsed);
      }
    }
    
    
    이렇게 하면 최초의 수 요 를 실현 할 수 있다.

    사실 처리 해 야 할 세부 사항 도 있 습 니 다.아래 코드 는 바로...
    
    /**
     *  checkLayoutParams  false           generateLayoutParams
     */
     @Override
    protected LinearLayout.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
      return super.generateLayoutParams(lp);
    }
    
    /**
     *  addView       LayoutParams           generateDefaultLayoutParams
     */
    @Override
    protected LayoutParams generateDefaultLayoutParams() {
      return new LayoutParams();
    }
    
    /**
     *   xml             generateLayoutParams
     */
    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
      return new LayoutParams(getContext(), attrs);
    }
    
    
    총괄 하 다
  • 사용자 정의 View 와 View Group 이 주의해 야 할 것 은 모두 onMeasure,onLayout,onDraw 입 니 다
  • ViewGroup 자체 의 속성 과 Child View 의 속성 을 구분 합 니 다
  • 4.567917.슈퍼 port 가방 의 코드 를 많이 참고 할 수 있 고 디 버 깅 도 매우 편리 합 니 다안 드 로 이 드 개발 을 하려 면 자체 적 으로 View 를 사용자 정의 해 야 하 는 곳 이 많 지만 대부분 해당 하 는 오픈 소스 라 이브 러 리 가 있 습 니 다.하지만 뷰 그룹 을 어떻게 정의 해 야 하 는 지 능숙 하 게 알 아야 합 니 다.
    자신 은 비교적 건망증 이 심 한 사람 이 므 로 좀 상세 하 게 써 라.
    완전한 코드 스탬프 여기 있 습 니 다.
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기