NavigationView nhận / tìm bố cục tiêu đề


171

Trong NavigationView của tôi, tôi có bố cục tiêu đề với id 'viewId' với các nút hoạt động. Để thiết lập các nút đó, tôi thực hiện như sau trong hoạt động onPostCreate:

final View panel = findViewById(R.id.viewId);
panel.setOnClickListener(new View.OnClickListener() {
... setup goes here ...
});

Với thư viện hỗ trợ Android phiên bản mới, ( 23.1.0 ), không thể tìm thấy chế độ xem, nó trả về null. Với các phiên bản trước, nó hoạt động tốt. Có phải là một lỗi hoặc tôi đang sử dụng tính năng này sai? Nếu vậy, làm thế nào để truy cập bố trí tiêu đề và thêm hành vi cho nó?

Câu trả lời:


429

Phiên bản 23.1.0 chuyển NavigationViewsang sử dụng một RecyclerView(chứ không phải trước đó ListView) và tiêu đề được thêm vào như một trong những yếu tố đó. Điều này có nghĩa là nó không có sẵn để gọi ngay lập tức findViewById()- cần có một bố cục vượt qua trước khi nó được gắn vào NavigationView.

Đối với phiên bản 23.1.1 của Thư viện hỗ trợ, giờ đây bạn có thể nhận được tham chiếu đến chế độ xem tiêu đề bằng cách sử dụng getHeaderView():

View headerLayout = navigationView.getHeaderView(0); // 0-index header

Điều này có lợi thế là làm việc trên các tiêu đề được thêm thông qua XML và qua mã.

Nếu bạn vẫn đang sử dụng 23.1.0, theo lỗi liên quan , bạn có thể tăng tiêu đề trong mã và sử dụng findViewById()theo đó:

View headerLayout = 
    navigationView.inflateHeaderView(R.layout.navigation_header);
panel = headerLayout.findViewById(R.id.viewId);
// panel won't be null

Cho đến khi bạn chuyển sang 23.1.1.


1
Cảm ơn sự giúp đỡ nhanh chóng, sẽ sử dụng cách giải quyết. Có phương pháp chuyên dụng dường như là con đường để đi, hy vọng sẽ có nó trong các phiên bản tương lai.
khusrav

2
@AlexanderFarber - mã tôi đã đăng hoạt động trở lại API 7
ianhanniballake

4
Tôi thích hạ cấp libs. Giới thiệu một lỗi giống như một chữ ký từ Google. Nếu phiên bản mới có lỗi, thì Google đã phát hành phiên bản mới đó
BamsBamx

1
@GFPF - khi bạn gọi inflateHeaderView, nó sẽ gắn Chế độ xem cho bạn trong lớp chính xác RecyclerViewvới cha mẹ chính xác - điều mà bạn không thể thực hiện bên ngoài NavigationView.
ianhanniballake

1
@RmK - cảm ơn, tôi đã cập nhật để trả lời để phản ánh các API mới được thêm vào 23.1.1 để truy xuất các tiêu đề được thêm qua XML (vì cách giải quyết trước đó chỉ hoạt động trên các tiêu đề được thêm qua mã).
ianhanniballake

142

Giờ đây với bản phát hành 23.1.1 của thư viện hỗ trợ thiết kế, bạn có thể sử dụng

NavigationView navigationView = (NavigationView) findViewById(R.id.your_nav_view_id);
View header = navigationView.getHeaderView(0)
TextView text = (TextView) header.findViewById(R.id.textView);

Bạn cũng có thể sử dụng navigationView.getHeaderCount()trong trường hợp bạn có nhiều hơn 1 tiêu đề vì bất kỳ lý do gì.
Francois Dermu

13

Đây là cách tôi đã làm nó bằng cách sử dụng ButterKnifevà nó hoạt động với tôi.

protected static class HeaderViewHolder {

    @BindView(R.id.button)
    Button button;

    HeaderViewHolder(View view) {
        ButterKnife.bind(this, view);
    }
}

và sau đó sử dụng chế độ xem này như thế này:

View header = navigationView.getHeaderView(0);
headerViewHolder = new HeaderViewHolder(header);

2
Điều này là hoàn hảo khi bạn muốn loại bỏ Xem logic liên quan khỏi Hoạt động của bạn. Ý tưởng tuyệt vời!
amouly

2
Nó hoạt động hoàn hảo với ButterKnife, cảm ơn anh trai.
Rajesh Naddy

8

Đối với tôi đó là tình huống tương tự với 23.1.0, sau khi cập nhật, ngoại lệ con trỏ null trở thành. Trong trường hợp này, NavigatorViewgiao diện như:

<android.support.design.widget.NavigationView
  android:id="@+id/navigation_view"
  android:layout_height="match_parent"
  android:layout_width="wrap_content"
  android:layout_gravity="start"
  android:fitsSystemWindows="true"
  app:headerLayout="@layout/nav_header"
  app:menu="@menu/menu_nav"/>

Tôi đã thử đề xuất giải pháp của ianhanniballake nhưng không được. Sau đó tôi thổi phồng câu:

LayoutInflater.from(getContext()).inflate(R.layout.nav_header, mNavigationView);

Sau đó, tôi có thể tìm thấy theo id tất cả các khung nhìn được xác định trong nav_heardbố cục.


3
NavigationView navigationView = findViewById(R.id.your_nav_view);
View header = navigationView.getHeaderView(0);
TextView textUsername = header.findViewById(R.id.textView);
textUsername.setText("you text here ");

Xin chào và chào mừng đến với Stack Overflow! Vui lòng thêm một số văn bản giải thích làm thế nào điều này giải quyết câu hỏi được hỏi ở trên. Cảm ơn!
Jonathan

0

Trong mã Kotlin @Francois Dermu giống như

val navigationView : NavigationView = findViewById(R.id.your_nav_view_id);
val header = navigationView.getHeaderView(0)
val textView = header.findViewById<TextView>(R.id.textView)

0

Phiên bản Kotlin.

val navView: NavigationView = findViewById(R.id.nav_view)       
// set User Name
val headerView: View = navView.getHeaderView(0)
headerView.txtUserName.text = "User Name Goes here"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.