ลิ้นชักการนำทาง: ฉันจะตั้งค่ารายการที่เลือกเมื่อเริ่มต้นได้อย่างไร


229

รหัสของฉันทำงานได้อย่างสมบูรณ์: ทุกครั้งที่มีการคลิกรายการในลิ้นชักการนำทางรายการจะถูกเลือก

แน่นอนว่าฉันต้องการเริ่มแอพด้วยแฟรกเมนต์เริ่มต้น (โฮม) แต่ลิ้นชักการนำทางไม่มีรายการที่เลือก ฉันจะเลือกรายการนั้นโดยทางโปรแกรมได้อย่างไร

public class BaseApp extends AppCompatActivity {

    //Defining Variables
    protected String LOGTAG = "LOGDEBUG";
    protected Toolbar toolbar;
    protected NavigationView navigationView;
    protected DrawerLayout drawerLayout;

    private DateManager db = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.base_layout);

        navigationView = (NavigationView) findViewById(R.id.navigation_view);


        // set the home/dashboard at startup

        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.frame, new DashboardFragment());
        fragmentTransaction.commit();

        setNavDrawer();
    }

    private void setNavDrawer(){

        // Initializing Toolbar and setting it as the actionbar
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //Initializing NavigationView

        //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            // This method will trigger on item Click of navigation menu
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {


                //Checking if the item is in checked state or not, if not make it in checked state

                // I THINK THAT I NEED EDIT HERE...

                if (menuItem.isChecked()) menuItem.setChecked(false);
                else menuItem.setChecked(true);

                //Closing drawer on item click
                drawerLayout.closeDrawers();


                //Check to see which item was being clicked and perform appropriate action
                switch (menuItem.getItemId()) {    

                    //Replacing the main content with ContentFragment 

                    case R.id.home:

                        DashboardFragment dashboardFragment = new DashboardFragment();
                        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction.replace(R.id.frame, dashboardFragment,"DASHBOARD_FRAGMENT");
                        fragmentTransaction.commit();
                        return true;
[...]

ฉันคิดว่าฉันต้องแก้ไขที่นี่:

if (menuItem.isChecked()) menuItem.setChecked(false);
                    else menuItem.setChecked(true);

หรือในonCreateตอนเริ่มต้นแอพด้วย FragmentTransaction

ขอบคุณสำหรับการสนับสนุนของคุณ.


คำตอบใด ๆ กระตุ้นonNavigationItemSelectedการทำงานสำหรับรหัสที่เลือกหรือไม่
Prabs

คำตอบ:


478

ใช้รหัสด้านล่าง:

navigationView.getMenu().getItem(0).setChecked(true);

เรียกวิธีนี้หลังจากที่คุณโทร setNavDrawer();

getItem(int index)วิธีการได้รับMenuItemแล้วคุณสามารถเรียกsetChecked(true);ว่าMenuItemสิ่งที่คุณจะต้องทำคือการหาที่ดัชนีองค์ประกอบไม่เริ่มต้นมีและแทนที่ 0 มีค่าดัชนีที่

คุณสามารถเลือก (ไฮไลท์) รายการโดยการโทร

onNavigationItemSelected(navigationView.getMenu().getItem(0));

นี่คือลิงค์อ้างอิง: http://thegeekyland.blogspot.com/2015/11/navigation-drawer-how-set-selected-item.html

แก้ไข ไม่ทำงานบน Nexus 4 สนับสนุนการแก้ไขไลบรารี 24.0.0 ฉันแนะนำให้ใช้

navigationView.setCheckedItem(R.id.nav_item);

ตอบโดย @kingston ด้านล่าง


65
เพิ่มห้องสมุดสนับสนุน Android v23 setCheckedItem (int id)แล้ว
Markus Rubey

1
@MarkusRubey แม้หลังจากการตั้งค่า setCheckedItem ฉันไม่สามารถเน้นรายการที่เลือกได้ คุณสามารถบอกเหตุผลที่เป็นไปได้หรือไม่
Dexto

3
ไม่ได้ผลสำหรับฉัน! เมื่อเมธอดonNavigationItemSelected ถูกเรียกใช้สำหรับตัวเลือกอื่น ๆ ในลิ้นชักเมนูนำทางรายการเริ่มต้นที่เรียกว่า "ตรวจสอบ" จะคงสถานะไว้เสมอ เมื่อฉันใช้ 'navigationView.setCheckedItem (id);' ทำงานได้อย่างสมบูรณ์แบบ! หลังจากนั้นจะต้องเรียกใช้เมธอด 'navigationView.getMenu () performIdentifierAction (R.id.nav_market, 0);' เพื่อทำการเลือกรายการที่ต้องการ
GFPF

3
วิธีการดังกล่าวไม่ได้ผลสำหรับฉันด้วยเหตุผลบางอย่าง แต่ทำnavigationView.post(new Runnable() { navigationView.setCheckedItem(...) })- ทำงาน
dimsuz

1
คุณอาจจะพยายามที่จะเปลี่ยนรายการการตรวจสอบจากหัวข้อที่แตกต่างกว่าหัวข้อหลัก :)
Arlind

105

นอกจากนี้คุณยังสามารถโทร:

navigationView.setCheckedItem(id);

วิธีนี้ถูกนำมาใช้ใน API 23.0.0

ตัวอย่าง

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      tools:ignore="UnusedIds">

    <group
        android:id="@+id/group"
        android:checkableBehavior="single">
        <item
            android:id="@+id/menu_nav_home"
            android:icon="@drawable/ic_home_black_24dp"
            android:title="@string/menu_nav_home" />
    </group>
</menu>

บันทึก: android:checkableBehavior="single"

ดูสิ่งนี้ด้วย


1
แม้หลังจากการตั้งค่า setCheckedItem ฉันไม่สามารถเน้นรายการที่เลือกได้ คุณสามารถบอกเหตุผลที่เป็นไปได้หรือไม่
Dexto

3
@DeepeshDoshi โปรดตรวจสอบให้แน่ใจว่าคุณมีพฤติกรรมที่ตรวจสอบได้
Jared Burrows

1
มันควรที่เขานำทางView.setCheckedItem (R.id.menu_nav_home) เพื่อเลือกเมนูโฮม
jaga

สำหรับแต่ละรายการเพียงเพิ่มรายการandroid:checkable="true"อื่นมันจะไม่ถูกตรวจสอบด้วยตนเอง
sud007

นอกจากนี้ตรวจสอบให้แน่ใจว่าคุณไม่ได้เรียกวิธีนี้จากด้วยnavItemSelecteListenerเป็นรายการที่ถูกเลือกหลังจากที่วิธีนี้กลับมา
mallaudin

47

สำหรับฉันทั้งสองวิธีนี้ใช้ไม่ได้:

  • navigationView.getMenu().getItem(0).setChecked(true);
  • navigationView.setCheckedItem(id);

ลองอันนี้มันใช้งานได้สำหรับฉัน

onNavigationItemSelected(navigationView.getMenu().findItem(R.id.nav_profile));


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

2
onNavigationItemSelected (navView.getMenu () GetItem (0).); หรือ onNavigationItemSelected (navView.getMenu (). getItem (R.id.nav_profile)); ทั้งสองทำงานให้ฉันแทน getitem แทน finditem
Harsh Dalwadi

30

ตัวอย่าง ( NavigationView.OnNavigationItemSelectedListener ):

private void setFirstItemNavigationView() {
        navigationView.setCheckedItem(R.id.custom_id);
        navigationView.getMenu().performIdentifierAction(R.id.custom_id, 0);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setFirstItemNavigationView();
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    FragmentManager fragmentManager = getFragmentManager();

    switch (item.getItemId()) {
        case R.id.custom_id:
            Fragment frag = new CustomFragment();

            // update the main content by replacing fragments
            fragmentManager.beginTransaction()
                    .replace(R.id.viewholder_container, frag)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .addToBackStack(null)
                    .commit();
            break;
    }

Tks


2
นี่เป็นวิธีหนึ่งที่ฉันชอบ แม้ว่าคำตอบของรหัสเท่านั้นมักจะหมดกำลังใจ ฉันจะแก้ไขคำตอบของคุณที่จะอธิบายรหัสนิด ๆ หน่อย ๆ เช่นทำไมคุณใช้และสิ่งที่เกิดขึ้นในperformIdentifierAction onNavigationItemSelectedสำหรับคุณอาจดูเหมือนตรงไปตรงมา แต่นักพัฒนาซอฟต์แวร์รุ่นใหม่อาจมีปัญหาในการทำความเข้าใจโค้ดของคุณ
AdamMc331

@ McAdam331 แน่นอนว่ารู้สึกฟรีมันหายไปครึ่งแล้วที่นี่ในวันนี้และไม่มีเวลาที่จะเขียนรายละเอียดเพิ่มเติม
GFPF

25

มักจะมีปัญหากับ libs สนับสนุน "โอ้ยอดเยี่ยมมาก" ของ Googles อยู่เสมอ หากคุณต้องการตรวจสอบรายการโดยไม่ลดระดับรุ่น libs สนับสนุนของคุณเพียงแค่ตั้งค่าตรวจสอบได้ก่อนที่จะตั้งค่าสถานะการตรวจสอบ

MenuItem item = drawer.getMenu().findItem(R.id.action_something);
item.setCheckable(true);
item.setChecked(true);

อาจใช้งานได้หากคุณตั้งค่าที่ตรวจสอบได้ในไฟล์เมนู xml



9

API 23 มีวิธีการดังต่อไปนี้:

navigationView.setCheckedItem(R.id.nav_item_id);

อย่างไรก็ตามด้วยเหตุผลบางประการฟังก์ชั่นนี้ไม่ได้ทำให้รหัสที่อยู่เบื้องหลังรายการการนำทางทำงาน วิธีการเน้นรายการในลิ้นชักการนำทางหรือ 'ตรวจสอบ' แต่ดูเหมือนจะไม่เรียกOnNavigationItemSelectedListenerผลลัพธ์ในหน้าจอว่างเมื่อเริ่มต้นหากหน้าจอเริ่มต้นของคุณขึ้นอยู่กับการเลือกลิ้นชักการนำทาง เป็นไปได้ที่จะเรียกผู้ฟังด้วยตนเอง แต่ดูเหมือนว่าจะเป็นแฮ็ค:

if (savedInstanceState == null) this.onNavigationItemSelected(navigationView.getMenu().getItem(0));

รหัสข้างต้นถือว่า:

  1. คุณได้ดำเนินการ NavigationView.OnNavigationItemSelectedListenerในกิจกรรมของคุณ
  2. คุณได้โทรแล้ว:
    navigationView.setNavigationItemSelectedListener(this);
  3. รายการที่คุณต้องการเลือกอยู่ในตำแหน่ง 0

6

คุณต้องเรียกใช้ 2 ฟังก์ชันสำหรับสิ่งนี้:

ข้อแรก:สำหรับการเรียกคำสั่งที่คุณนำไปใช้ในการonNavigationItemSelectedฟัง:

onNavigationItemSelected(navigationView.getMenu().getItem(R.id.nav_camera));

ที่สอง:สำหรับการเปลี่ยนสถานะของรายการเมนูลิ้นชักการนำทางเป็นที่เลือก (หรือทำเครื่องหมายไว้):

navigationView.setCheckedItem(R.id.nav_camera);

ฉันเรียกทั้งสองฟังก์ชั่นและมันก็ใช้ได้ผลสำหรับฉัน


5

รหัสต่อไปนี้จะทำให้เลือกรายการเมนูเท่านั้น:

navigationView.setCheckedItem(id);

ในการเลือกและเปิดรายการเมนูให้เพิ่มรหัสต่อไปนี้หลังจากบรรทัดด้านบน

onNavigationItemSelected(navigationView.getMenu().getItem(0));


4

นี่คือทางออกของฉันง่ายมาก

นี่คือไฟล์ menu.xml ของฉัน:

<group
    android:id="@+id/grp1"
    android:checkableBehavior="single">
    <item
        android:id="@+id/nav_all_deals"
        android:checked="true"
        android:icon="@drawable/ic_all_deals"
        android:title="@string/all_deals" />
    <item
        android:id="@+id/nav_news_and_events"
        android:icon="@drawable/ic_news"
        android:title="@string/news_and_events" />
    <item
        android:id="@+id/nav_histories"
        android:icon="@drawable/ic_histories"
        android:title="@string/histories" />
</group>

เมนูด้านบนจะเน้นรายการเมนูแรก บรรทัดด้านล่างจะทำบางสิ่ง (เช่น: แสดงแฟรกเมนต์แรกเป็นต้น) หมายเหตุ: เขียนหลังจาก 'กำหนดค่ารหัสลิ้นชักของคุณ'

onNavigationItemSelected(mNavigationView.getMenu().getItem(0));

4

วิธีที่ง่ายที่สุดคือเลือกจาก xml ดังนี้

<menu>
   <group android:checkableBehavior="single">
         <item
              android:checked="true"
              android:id="@+id/nav_home"
              android:icon="@drawable/nav_home"
              android:title="@string/main_screen_title_home" />

จดบันทึกบรรทัด android:checked="true"


1
ในความเห็นของฉันคำตอบที่ดีที่สุดทำให้เกิดการใช้ตรรกะเริ่มต้นให้ Android โหวตให้ดีที่สุดเท่านั้นจะดีกว่าถ้าเมนูใช้โครงร่างและสร้างโดยอะแด็ปเตอร์ไม่ใช่ไฟล์เมนู xml
Andris

1
นี่คือคำตอบที่ดีที่สุด
Ganesh Chowdhary Sadanala

2

ก่อนอื่นสร้างสีสำหรับรายการที่เลือก นี่คือตัวอย่างที่ดีhttps://stackoverflow.com/a/30594875/1462969 ช่วยให้คุณเปลี่ยนสีของไอคอน สำหรับการเปลี่ยนพื้นหลังของรายการที่เลือกทั้งหมดจะเพิ่มในไฟล์ values ​​\ style.xml ของคุณ

  <item name="selectableItemBackground">@drawable/selectable_item_background</item>

โดยที่ selectable_item_background ควรประกาศใน drawable / selectable_item_background.xml

  <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/accent_translucent"
      android:state_pressed="true" />
    <item android:drawable="@android:color/transparent" />
   </selector>

ตำแหน่งที่สามารถประกาศสีใน style.xml

 <color name="accent_translucent">#80FFEB3B</color>

และหลังจากนี้

   // The main navigation menu with user-specific actions
        mainNavigationMenu_ = (NavigationView) findViewById(R.id.main_drawer);
        mainNavigationMenu_.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                mainNavigationMenu_.getMenu().findItem(itemId).setChecked(true);
                return true;
            }
        });

ตามที่เห็นฉันใช้ mainNavigationMenu_.getMenu (). findItem (itemId) .setChecked (จริง); เพื่อตั้งค่ารายการที่เลือก ที่นี่นำทางดู

 <android.support.design.widget.NavigationView
        android:id="@+id/main_drawer"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/header_main_navigation_menu"
        app:itemIconTint="@color/state_list"
        app:itemTextColor="@color/primary"
        app:menu="@menu/main_menu_drawer"/>

ฉันชอบวิธีนี้ฉันใช้มันในโครงการของตัวเอง มันอาจช่วยให้รวม@color/state_listรหัสในคำตอบของคุณ จากความอยากรู้คุณได้รับแบบแผนการตั้งชื่อเพื่อใส่เครื่องหมายขีดล่างที่ท้ายชื่อตัวแปรหรือไม่ ฉันไม่เคยเห็นวิธีการนั้น
AdamMc331

ฉันคิดว่าบางทีคุณอาจต้องการmenuItem.getItemId()แทนitemId
เครกรัสเซลล์

2

เมื่อใช้BottomNavigationViewคำตอบอื่น ๆ เช่นnavigationView.getMenu().getItem(0).setChecked(true);และ navigationView.setCheckedItem(id);จะไม่ทำงานการโทรsetSelectedItemIdทำงาน:

    BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation_view);

    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
            // TODO: 10-Aug-19 your code here 
        }
    });

    bottomNavigationView.setSelectedItemId(R.id.myitem);

0

เลือกเป็นตัวเลือกสำหรับรายการ Individaual ของ Nav Drawer

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/darkBlue" android:state_pressed="true"/>
    <item android:drawable="@color/darkBlue" android:state_checked="true"/>
    <item android:drawable="@color/textBlue" />
</selector>

ทำการเปลี่ยนแปลงเล็กน้อยใน NavigationView ของคุณ

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:itemBackground="@drawable/drawer_item"
        android:background="@color/textBlue"
        app:itemIconTint="@color/white"
        app:itemTextColor="@color/white"
        app:menu="@menu/activity_main_drawer"
        />

0

ในกิจกรรมของคุณ (หลังลิ้นชัก):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar,
               R.string.navigation_drawer_open,
               R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    navigationView.setCheckedItem(R.id.nav_portfolio);
    onNavigationItemSelected(navigationView.getMenu().getItem(0));
}

และ

@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    Fragment fragment = null;

    if (id == R.id.nav_test1) {
        fragment = new Test1Fragment();
        displaySelectedFragment(fragment);
    } else if (id == R.id.nav_test2) {
        fragment = new Test2Fragment();
        displaySelectedFragment(fragment);
    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

และในเมนูของคุณ:

<group android:checkableBehavior="single">

    <item
        android:id="@+id/nav_test1"
        android:title="@string/test1" />

    <item
        android:id="@+id/nav_test2"
        android:title="@string/test2" />

  </group>

ดังนั้นเมนูแรกคือไฮไลต์และแสดงเป็นเมนูเริ่มต้น


0

รหัสด้านล่างใช้สำหรับเลือกรายการแรกและไฮไลต์รายการแรกที่เลือกในเมนู

onNavigationItemSelected(mNavigationView.getMenu().getItem(0).setChecked(true));

คุณช่วยกรุณาบอกฉันได้อย่างไรและที่ใดบนสิ่งนี้เนวิเกชันไอเท็มที่เลือกจะสามารถเข้าถึงได้? โปรดระบุตัวอย่างรหัสแบบเต็ม
kilokahn


-1

ด้วยเหตุผลบางอย่างมันจะดีกว่าที่จะหา MenuItem โดยใช้ ID

drawer.getMenu().findItem(R.id.action_something).setChecked(true);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.