2016-12-11 7 views
1

화면 오른쪽 상단의 세로 LinearLayout에 3 Button의 주보기가 있습니다. 각 버튼은 DrawerLayout 안에 호스팅되는 Fragment을 표시합니다. 이처럼 : 이동 방법 DrawerLayout의 내용과 함께 동일한 내용을 볼 수 있습니다. Z

enter image description here

내가 어떤 버튼을 클릭

, 나는 DrawerLayout이 (가) 오른쪽에서 표시하고이 버튼이 함께 번역하고 싶습니다. 이처럼 :

enter image description here

나는 서랍과 Button 이동 관리해야하지만 내 문제는 서랍의 그림자뿐만 아니라 버튼에 영향을 미친다는 것이다. 서랍의 내용 (똑같은 높이)만큼 밝기를 원하지만 다른 버튼도 서랍 뒤에 남기를 원합니다.

이 내 activity_main.xml 파일입니다 DrawerLayout 내부의 버튼, 그 위의 서랍 이동하지만 어두워 번역되고있는 하나

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fitsSystemWindows="true"> 

    <android.support.v4.widget.DrawerLayout 
     android:id="@+id/drawer_layout" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <include layout="@layout/content_main"/> 

     <LinearLayout ... > 
      <ImageButton ... /> 
      <ImageButton ... /> 
      <ImageButton ... /> 
     </LinearLayout> 

     <FrameLayout 
      android:id="@+id/fragment_secondary_content" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_gravity="right" 
      tools:context="..."/> 

    </android.support.v4.widget.DrawerLayout> 

</android.support.design.widget.CoordinatorLayout> 

합니다.

반면에 DrawerLayout 외부에 단추를 배치하면 이동하는 단추는 괜찮아 보이지만 서랍은 다른 단추 아래에 있습니다. 마찬가지로 :

enter image description here

특정 뷰에 영향을 DrawerLayout의 그림자를 피할 수있는 방법이 있나요? 아니면 그것을 취소 하시겠습니까?

답변

1

DrawerLayout은 그 그림자를 자식 ViewdrawChild() 메서드에 적용합니다. 주어진 어린이가 서랍이 아닌지 확인하여 어느 어린이에게 적용 할 것인지를 결정합니다 View. 궁극적으로 이는 어린이의 LayoutParamsgravity을 확인하여 수행합니다. 이를 아는

, 우리는 drawChild()를 오버라이드 (override) 할 수있는 사용자 정의 DrawerLayout 서브 클래스를 만들 수 있으며, 일시적으로 우리는 스크림을 적용하지 않으려는 아이의 gravity을 변경합니다. 추첨 중에 레이아웃이 일어나지 않으므로 View의 실제 배치에는 영향을 미치지 않습니다. 은 "무 스크림"View이 레이아웃에서 지정된 수 없도록

public class CustomDrawerLayout extends DrawerLayout { 

    private int noScrimId; 

    public CustomDrawerLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     // Get the ID for the no-scrim View. 
     TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomDrawerLayout); 
     noScrimId = a.getResourceId(R.styleable.CustomDrawerLayout_noScrimView, View.NO_ID); 
     a.recycle(); 
    } 

    @Override 
    protected boolean drawChild(Canvas canvas, View child, long drawingTime) { 
     // Is this the child we want? 
     final boolean isNoScrimView = child.getId() == noScrimId; 

     // If yes, temporarily tag it as a drawer. 
     if (isNoScrimView) { 
      ((LayoutParams) child.getLayoutParams()).gravity = Gravity.LEFT; 
     } 

     // Let the super class do the draw, and save the return. 
     final boolean res = super.drawChild(canvas, child, drawingTime); 

     // Reset the gravity if we changed it. 
     if (isNoScrimView) { 
      ((LayoutParams) child.getLayoutParams()).gravity = Gravity.NO_GRAVITY; 
     } 

     return res; 
    } 
} 

이 예는 지정 특성을 이용한다. 해당 특성을 사용하지 않으려면 TypedArray 처리를 생성자에서 제거하고 ID를 하드 코드하면됩니다. 사용자 정의 속성을 사용하려면 프로젝트에서 정의해야합니다.이 파일은 values/ 폴더에 다음 파일을 붙여 넣거나 이미있을 수있는 파일에 추가하여 작성할 수 있습니다.

<resources> 
    <declare-styleable name="CustomDrawerLayout"> 
     <attr name="noScrimView" format="reference" /> 
    </declare-styleable> 
</resources> 

CustomDrawerLayout

attrs.xml

는 드롭 인 교체, 당신은 당신이하고자 일반 클래스처럼 레이아웃에서 사용할 수 있습니다.예를 들어, ImageButton의 ' LinearLayout는 ID button_menu가있는 경우 :

<com.mycompany.myapp.CustomDrawerLayout 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/drawer_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    app:noScrimView="@+id/button_menu"> 

당신이 noScrimView으로 서랍 View을 설정 일어나면, 당신은거야 나쁜 시간이 있습니다. 또한 noScrimView은 scrim 효과가 적용되는 경우에만 DrawerLayout의 직계 하위 항목이어야합니다.

간단히하기 위해 샘플에서 검사를 생략했지만 일부를 포함하려는 경우 onMeasure() 메서드에서 수행하면 DrawerLayout이 자체 검사를 처리하는 방법과 일치하게됩니다.

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

    final View v = findViewById(noScrimId); 
    if (v != null) { 
     if (!(v.getLayoutParams() instanceof LayoutParams)) { 
      throw new IllegalStateException("noScrimView must be a child of DrawerLayout"); 
     } 
     if (((LayoutParams) v.getLayoutParams()).gravity != Gravity.NO_GRAVITY) { 
      throw new IllegalStateException("noScrimView cannot be a drawer View"); 
     } 
    } 
    else { 
     if (noScrimId != View.NO_ID) { 
      Log.d(getClass().getSimpleName(), "noScrimView not found"); 
     } 
    } 
}