2015-07-21 25 views
4

是否可以在設計支持庫NavigationView中使標題變得粘稠?如何製作NavigationView標題sticky

<android.support.design.widget.NavigationView 
    android:id="@+id/nav_drawer" 
    android:layout_width="wrap_content" 
    android:layout_height="match_parent" 
    android:layout_gravity="start" 
    app:headerLayout="@layout/nav_header" 
    app:menu="@menu/nav_drawer" 
    style="@style/navigation_view_drawer" 
    /> 

編輯:

我嘗試迄今已導致該

重寫NavigationView部件和添加新的方法:

public class CustomNavigationView extends NavigationView { 

public CustomNavigationView(Context context) { 
    super(context); 
} 


public CustomNavigationView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 


public CustomNavigationView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
} 


// Inflates header as a child of NavigationView, on top of the normal menu 
public void createHeader(int res) { 
    LayoutInflater inflater = LayoutInflater.from(getContext());; 
    View view = inflater.inflate(res, this, false); 
    addView(view); 
} 

}

然後 加入到這個活動的OnCreate:

CustomNavigationView navigationView = (CustomNavigationView) findViewById(R.id.your_navigation_view); 
navigationView.createHeader(R.layout.your_header); 

這實現了預期的效果(如果有點hackily),但是當菜單項的標題下,你仍然可以點擊他們,任何想法解決這一問題?

回答

2

經過大量的實驗後,我得到了一些有用的東西......這是非常哈克,我很樂意聽到任何建議,你必須改善它!

的overrided NavigationView

public class CustomNavigationView extends NavigationView { 

public CustomNavigationView(Context context) { 
    super(context); 
} 


public CustomNavigationView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 


public CustomNavigationView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
} 


// Consumes touch in the NavigationView so it doesn't propagate to views below 
public boolean onTouchEvent (MotionEvent me) { 
    return true; 
} 


// Inflates header as a child of NavigationView 
public void createHeader(int res) { 
    LayoutInflater inflater = LayoutInflater.from(getContext()); 
    View view = inflater.inflate(res, this, false); 

    // Consumes touch in the header so it doesn't propagate to menu items below 
    view.setOnTouchListener(new OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event){ 
      return true; 
     } 
    }); 

    addView(view); 
} 


// Positions and sizes the menu view 
public void sizeMenu(View view) { 
    // Height of header 
    int header_height = (int) getResources().getDimension(R.dimen.nav_header_height); 

    // Gets required display metrics 
    DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); 
    float screen_height = displayMetrics.heightPixels; 

    // Height of menu 
    int menu_height = (int) (screen_height - header_height); 

    // Layout params for menu 
    LayoutParams params = new LayoutParams(
      LayoutParams.MATCH_PARENT, 
      LayoutParams.WRAP_CONTENT); 
    params.gravity = Gravity.BOTTOM; 
    params.height = menu_height; 
    view.setLayoutParams(params); 
} 

}

而這主要活動

// Inflates the nav drawer 
    CustomNavigationView navigationView = (CustomNavigationView) findViewById(R.id.your_nav_view); 
    navigationView.createHeader(R.layout.your_nav_header); 

    // sizes nav drawer menu so it appears under header 
    ViewGroup parent = (ViewGroup) navigationView; 
    View view = parent.getChildAt(0); 
    navigationView.sizeMenu(view); 
1

的OnCreate我知道這個問題是舊的,但也許我可以幫助別人。

<android.support.design.widget.NavigationView 
    android:id="@+id/nav_drawer" 
    style="@style/navigation_view_drawer" 
    android:layout_width="wrap_content" 
    android:layout_height="match_parent" 
    android:layout_gravity="start" 
    app:headerLayout="@layout/nav_header" 
    app:menu="@menu/nav_drawer"> 

    <include layout="@layout/nav_header" /> 
</android.support.design.widget.NavigationView> 

應用程式:headerLayout是多餘的,但是必需的。

+0

這很簡單,謝謝。 – Sucipto

+0

這很簡單,但觸摸事件對NavigationView中的粘性標題有一些問題 – OnJohn

0

編輯自enyciaa的回答。
這是簡化,更穩定,並支持Android數據綁定。
此外,增加了一個API來獲取粘頭視圖(數據綁定的情況下,以頭佈局)

的overrided NavigationView

// Add this annotation if databinding is enabled 
@BindingMethods({ 
    @BindingMethod(type = StickyHeaderNavigationView.class, attribute = "app:stickyHeader", method = "setStickyHeader") 
}) 
public class StickyHeaderNavigationView extends NavigationView { 

@Nullable 
View mStickyHeaderView; 

public StickyHeaderNavigationView(Context context) { 
    super(context); 
} 

public StickyHeaderNavigationView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

public StickyHeaderNavigationView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
} 

// Consumes touch in the NavigationView so it doesn't propagate to views below 
@Override 
public boolean onTouchEvent(MotionEvent me) { 
    return true; 
} 

@Nullable 
public View getStickyHeaderView() { 
    return mStickyHeaderView; 
} 

// Set a header layout as a child of NavigationView 
public void setStickyHeader(@LayoutRes int res) { 

    if (mStickyHeaderView != null) { 
     removeView(mStickyHeaderView); 
    } 

    LayoutInflater inflater = LayoutInflater.from(getContext()); 
    View view = mStickyHeaderView = inflater.inflate(res, this, false); 

    // Consumes touch in the header so it doesn't propagate to menu items below 
    view.setOnTouchListener(new OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      return true; 
     } 
    }); 

    addView(view); 

    // Listen to layout update. When ready, we can do #sizeMenu 
    getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener(this, view)); 
} 

// Positions and sizes the menu view 
private void sizeMenu(@NonNull View view, View headerView) { 

    // Height of header 
    int headerHeight = headerView.getHeight(); 

    // Gets required display metrics 
    DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); 
    float screenHeight = displayMetrics.heightPixels; 

    // Height of menu 
    int menuHeight = (int) (screenHeight - headerHeight); 

    // Layout params for menu 
    LayoutParams params = new LayoutParams(
      LayoutParams.MATCH_PARENT, 
      LayoutParams.WRAP_CONTENT); 
    params.gravity = Gravity.BOTTOM; 
    params.height = menuHeight; 
    view.setLayoutParams(params); 
} 


// To listen for layout update, that means header height was calculated 
private static class OnGlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener { 

    final WeakReference<StickyHeaderNavigationView> mViewRef; 
    final WeakReference<View> mHeaderView; 

    OnGlobalLayoutListener(@NonNull StickyHeaderNavigationView view, 
          @NonNull View headerView) { 
     mViewRef = new WeakReference<>(view); 
     mHeaderView = new WeakReference<>(headerView); 
    } 

    @Override 
    public void onGlobalLayout() { 

     StickyHeaderNavigationView view = mViewRef.get(); 
     if (view == null) { 
      return; 
     } 

     // Update once only as the header should be fixed size 
     view.getViewTreeObserver().removeOnGlobalLayoutListener(this); 

     View headerView = mHeaderView.get(); 
     if (headerView == null) { 
      return; 
     } 

     // childAt(0) is the navigation menu 
     view.sizeMenu(view.getChildAt(0), headerView); 
    } 
} 
} 

數據綁定啓用
在佈局XML應用此

<StickyHeaderNavigationView 
    ... 
    android:stickyHeader="@{@layout/your_nav_header}" /> 

數據綁定不牛逼啓用
在爲什麼你重新發明輪子主要活動

// Inflates the nav drawer 
CustomNavigationView navigationView = (CustomNavigationView) findViewById(R.id.your_nav_view); 
navigationView.setStickyHeader(R.layout.your_nav_header); 
0

的OnCreate應用此,谷歌已經加入你的NavigatoinView屬性應用:headerLayout =「你的願望在這裏佈局」 如果你仍然這裏不瞭解代碼。

<android.support.design.widget.NavigationView 
    android:id="@+id/navigationview" 
    android:layout_gravity="start" 
    android:layout_width="wrap_content" 
    android:layout_height="match_parent" 
    app:headerLayout="@layout/nav_header_layout" <!-This your header layout wihch is not sticky--> 
    app:menu="@menu/nav_menu_drawer"/> 

如果你想使你的粘頭的佈局,請參閱本github source here。總之我可以說,你會RecyclerVIew實現這個不NavigationView.If您有任何問題隨時問我。