NavigationView รับ / ค้นหาเค้าโครงส่วนหัว


171

ใน NavigationView ของฉันฉันมีเค้าโครงส่วนหัวพร้อมรหัส 'viewId' พร้อมปุ่มที่ใช้งาน ในการตั้งค่าปุ่มเหล่านั้นฉันจะทำสิ่งต่อไปนี้ในกิจกรรมonPostCreate:

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

ด้วยไลบรารีการสนับสนุน android เวอร์ชันใหม่ ( 23.1.0 ) ไม่พบมุมมองจะส่งคืน null กับรุ่นก่อนหน้ามันทำงานได้ดี เป็นข้อบกพร่องหรือฉันใช้คุณสมบัตินี้ผิดหรือเปล่า? ถ้าเป็นเช่นนั้นจะเข้าถึงเค้าโครงส่วนหัวและเพิ่มลักษณะการทำงานได้อย่างไร

คำตอบ:


429

เวอร์ชัน 23.1.0 เปลี่ยนNavigationViewเป็นการใช้RecyclerView(แทนที่จะเป็นก่อนหน้าListView) และส่วนหัวจะถูกเพิ่มเป็นหนึ่งในองค์ประกอบเหล่านั้น ซึ่งหมายความว่ามันเป็นสิ่งที่ไม่สามารถใช้งานได้ทันทีที่จะเรียกfindViewById()- NavigationViewผ่านรูปแบบเป็นสิ่งจำเป็นก่อนที่มันจะถูกแนบไปกับ

สำหรับเวอร์ชัน 23.1.1ของ Support Library ตอนนี้คุณสามารถรับการอ้างอิงถึงมุมมองส่วนหัวโดยใช้getHeaderView():

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

นี่คือข้อดีของการทำงานกับส่วนหัวที่เพิ่มผ่าน XML และรหัส

หากคุณยังคงใช้ 23.1.0 ตามข้อบกพร่องที่เกี่ยวข้องคุณสามารถขยายส่วนหัวในรหัสและใช้findViewById()กับที่:

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

จนกว่าคุณจะย้ายไปที่ 23.1.1


1
ขอขอบคุณสำหรับความช่วยเหลือที่รวดเร็วจะใช้วิธีแก้ปัญหา การมีวิธีการเฉพาะดูเหมือนว่าจะเป็นไปได้หวังว่าจะมีในอนาคต
khusrav

2
@AlexanderFarber - รหัสที่ฉันโพสต์ใช้งานได้กลับไปที่ API 7
ianhanniballake

4
ฉันชอบที่จะลดระดับ libs การแนะนำข้อบกพร่องเป็นเหมือนลายเซ็นจาก Google หากเวอร์ชันใหม่มีข้อผิดพลาด Google จะเปิดตัวเวอร์ชันใหม่นั้น
BamsBamx

1
@GFPF - เมื่อคุณเรียกinflateHeaderViewมันยึดติดกับมุมมองสำหรับคุณในชั้นที่ถูกต้องในRecyclerViewกับผู้ปกครองที่ถูกต้อง - NavigationViewบางสิ่งบางอย่างที่คุณไม่สามารถทำภายนอก
ianhanniballake

1
@RmK - ขอบคุณฉันได้อัปเดตเพื่อให้สะท้อนถึง API ใหม่ที่เพิ่มใน 23.1.1 เพื่อดึงข้อมูลส่วนหัวที่เพิ่มผ่าน XML (เนื่องจากวิธีแก้ไขปัญหาก่อนหน้านี้ทำงานเฉพาะกับส่วนหัวที่เพิ่มผ่านรหัส)
ianhanniballake

142

ขณะนี้ด้วยไลบรารีการสนับสนุนการออกแบบรุ่น 23.1.1 คุณสามารถใช้

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

คุณสามารถใช้navigationView.getHeaderCount()ในกรณีที่คุณมีส่วนหัวมากกว่า 1 ด้วยเหตุผลใดก็ตาม
Francois Dermu

13

นี่คือวิธีที่ฉันใช้ButterKnifeและใช้งานได้สำหรับฉัน

protected static class HeaderViewHolder {

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

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

แล้วใช้ตัวยึดมุมมองนี้ดังนี้:

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

2
สิ่งนี้สมบูรณ์แบบเมื่อคุณต้องการลบดูตรรกะที่เกี่ยวข้องจากกิจกรรมของคุณ ความคิดที่ดี!
amouly

2
มันทำงานได้อย่างสมบูรณ์กับ ButterKnife ขอบคุณพี่ชาย
Rajesh Naddy

8

สำหรับฉันที่เป็นสถานการณ์เดียวกันกับ 23.1.0 หลังจากการปรับปรุงข้อยกเว้นตัวชี้โมฆะกลายเป็น ในกรณีนี้NavigatorViewดูเหมือนว่า:

<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"/>

ฉันลองข้อเสนอการแก้ปัญหาโดย ianhanniballake แต่มันไม่ทำงาน จากนั้นฉันก็พองไปตามประโยค:

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

หลังจากนั้นฉันสามารถค้นหาด้วย id ทุกมุมมองที่กำหนดในnav_heardโครงร่าง


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 ");

สวัสดีและยินดีต้อนรับสู่ Stack Overflow! โปรดเพิ่มข้อความอธิบายวิธีการแก้คำถามที่ถามข้างต้น ขอบคุณ!
Jonathan

0

ใน Kotlin @Francois Dermu รหัสเป็นเช่น

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

0

รุ่น 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"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.