Szuflada nawigacji: Jak ustawić wybrany element podczas uruchamiania?


229

Mój kod działa idealnie: za każdym razem, gdy kliknięty zostanie element w Szufladzie nawigacji, zostaje on wybrany.

Oczywiście chcę uruchomić aplikację z domyślnym fragmentem (domowym), ale w Szufladzie nawigacji nie ma zaznaczonego elementu. Jak mogę wybrać ten element programowo?

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;
[...]

Myślę, że muszę edytować tutaj:

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

Lub onCreatepodczas uruchamiania aplikacji za pomocą FragmentTransaction.

Dziękuję za Twoje wsparcie.


Czy którakolwiek z odpowiedzi wyzwala onNavigationItemSelectedakcję dla wybranego identyfikatora?
Prabs

Odpowiedzi:


478

Użyj poniższego kodu:

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

Zadzwoń po tej metodzie setNavDrawer();

getItem(int index)Metoda dostaje MenuItemwtedy można wywołać setChecked(true);na tym MenuItem, wszystko co pozostało do zrobienia jest, aby dowiedzieć się, które indeks elementu robi domyślnych i wymień 0 z tego indeksu.

Możesz wybrać (podświetlić) element, dzwoniąc

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

Oto link referencyjny: http://thegeekyland.blogspot.com/2015/11/navigation-drawer-how-set-selected-item.html

EDYCJA Nie działała na Nexusie 4, obsługa wersji biblioteki 24.0.0. Polecam użyć

navigationView.setCheckedItem(R.id.nav_item);

odpowiedział @kingston poniżej.


65
Dodano biblioteki obsługi Androida v23 setCheckedItem (int id).
Markus Rubey,

1
@MarkusRubey nawet po ustawieniu setCheckedItem Nie mogę podświetlić wybranego elementu. Czy możesz podać możliwy powód?
Dexto

3
Nie działało dla mnie! Po wywołaniu metody onNavigationItemSelected dla innych opcji w szufladzie menu nawigacyjnego, element początkowy określany jako „zaznaczony” zawsze zachowuje swój stan. Kiedy używam „navigationView.setCheckedItem (id);” działało idealnie! Następnie musi wywołać metodę „navigationView.getMenu () performIdentifierAction (R.id.nav_market, 0);” aby dokonać wyboru żądanego elementu.
GFPF

3
Żadna z wymienionych metod nie działała dla mnie z jakiegoś powodu. Ale robienie navigationView.post(new Runnable() { navigationView.setCheckedItem(...) })- działało.
dimsuz

1
Prawdopodobnie próbujesz zmienić zaznaczony element z innego wątku niż główny wątek :)
Arlind

105

Możesz także zadzwonić:

navigationView.setCheckedItem(id);

Ta metoda została wprowadzona w API 23.0.0

Przykład

<?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>

Uwaga: android:checkableBehavior="single"

Zobacz także to


1
nawet po ustawieniu setCheckedItem Nie mogę podświetlić wybranego elementu. Czy możesz podać możliwy powód?
Dexto

3
@DeepeshDoshi Upewnij się, że masz sprawdzalne zachowanie.
Jared Burrows,

1
powinien on navigationView.setCheckedItem (R.id.menu_nav_home), aby wybrać menu główne
Jaga

dla pojedynczego przedmiotu wystarczy dodać android:checkable="true"inaczej, że nie będzie sprawdzany samodzielnie.
sud007

Upewnij się także, że nie wywołujesz tej metody za pomocą, navItemSelecteListenerponieważ element jest wybierany po powrocie tej metody.
mallaudin

47

Dla mnie obie te metody nie działały:

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

Wypróbuj ten, działa dla mnie.

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


2
Dzięki za tę wskazówkę. Powyższe metody są w rzeczywistości OK, ale problem jest inny: jeśli ich użyjesz, onNavigationItemSelected nie zostanie wywołany, tylko pozycja menu zostanie sprawdzona. Musimy więc wywołać obie metody.
user1209216,

2
onNavigationItemSelected (navView.getMenu (). getItem (0)); lub onNavigationItemSelected (navView.getMenu (). getItem (R.id.nav_profile)); oba działały dla mnie, getitem zamiast finditem.
Harsh Dalwadi

30

Przykład ( 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
To jeden ze sposobów, aby to zrobić, podoba mi się. Jednak odpowiedzi tylko na kod są często odradzane. Zredagowałbym twoją odpowiedź, aby trochę wyjaśnić kod, na przykład dlaczego używasz performIdentifierActioni co się dzieje onNavigationItemSelected. Może ci się to wydawać proste, ale nowszy programista może mieć problemy ze zrozumieniem twojego kodu.
AdamMc331,

@ McAdam331 Oczywiście nie krępuj się, dziś już tu jest połowa i nie miałem czasu pisać bardziej szczegółowo.
GFPF,

25

Zawsze występują problemy z bibliotekami wsparcia „och, tak świetnie” obsługującymi biblioteki lib. Jeśli chcesz sprawdzić element bez obniżenia wersji libs wsparcia, po prostu ustaw checkable przed ustawieniem stanu sprawdzonego.

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

Może to również działać, jeśli ustawisz sprawdzalne w plikach xml menu



9

API 23 zapewnia następującą metodę:

navigationView.setCheckedItem(R.id.nav_item_id);

Jednak z jakiegoś powodu ta funkcja nie spowodowała uruchomienia kodu za elementem nawigacyjnym. Metoda z pewnością wyróżnia element w szufladzie nawigacji lub „sprawdza” go, ale wydaje się, że nie wywołuje OnNavigationItemSelectedListenerpustego ekranu podczas uruchamiania, jeśli ekran startowy zależy od wybranych szuflad nawigacji. Możliwe jest ręczne wywołanie nasłuchiwania, ale wydaje się to hacking:

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

Powyższy kod zakłada:

  1. Zaimplementowałeś NavigationView.OnNavigationItemSelectedListenerw swojej działalności
  2. Dzwoniłeś już:
    navigationView.setNavigationItemSelectedListener(this);
  3. Element, który chcesz wybrać, znajduje się w pozycji 0

6

W tym celu musisz wywołać 2 funkcje:

Po pierwsze: w celu wyceny poleceń zaimplementowanych w onNavigationItemSelectednasłuchiwaniu:

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

Po drugie: aby zmienić stan pozycji menu szuflady nawigacji na wybraną (lub zaznaczoną):

navigationView.setCheckedItem(R.id.nav_camera);

Wywołałem obie funkcje i zadziałało to dla mnie.


5

Poniższy kod spowoduje wybranie tylko pozycji menu:

navigationView.setCheckedItem(id);

Aby wybrać i otworzyć element menu, dodaj następujący kod po powyższym wierszu.

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


4

To jest moje rozwiązanie, bardzo proste.

Oto mój plik 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>

Powyższe menu podświetli pierwszą pozycję menu. Linia poniżej coś zrobi (np .: pokaż pierwszy fragment itp.). UWAGA: napisz po „skonfiguruj kod szuflady”

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

4

Najprostszym sposobem jest wybranie go z xml w następujący sposób,

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

Zwróć uwagę na linię android:checked="true"


1
Moim zdaniem najlepsza odpowiedź, bo używa domyślnej logiki dostarczonej z Androidem. Najlepiej ocenione tylko jako lepsze, jeśli menu używa układu i jest generowane przez adapter, a nie plik xml menu.
Andris

1
To najlepsza odpowiedź
Ganesh Chowdhary Sadanala

2

Najpierw utwórz kolory dla wybranego elementu. Tutaj https://stackoverflow.com/a/30594875/1462969 dobry przykład. Pomaga zmienić kolor ikony. Aby zmienić tło wszystkich wybranych elementów, dodaj w pliku wartości \ style.xml to

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

Gdzie selectable_item_background należy zadeklarować w 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>

Gdzie kolor można zadeklarować w style.xml

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

A potem

   // 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;
            }
        });

Jak widzisz użyłem tego mainNavigationMenu_.getMenu (). FindItem (itemId) .setChecked (true); ustawić wybrany element. Tutaj nawigacja Zobacz

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

Podoba mi się ta metoda, obecnie używam jej we własnym projekcie. Może to pomóc w dołączeniu @color/state_listkodu do odpowiedzi. Z ciekawości, skąd wzięła się konwencja nazewnictwa, która umieszcza znak podkreślenia na końcu nazwy zmiennej? Nigdy nie widziałem takiego podejścia.
AdamMc331,

Myślę, że może menuItem.getItemId()zamiast tegoitemId
Craig Russell

2

Podczas korzystania BottomNavigationViewz innych odpowiedzi, takich jak navigationView.getMenu().getItem(0).setChecked(true);i navigationView.setCheckedItem(id);nie działa, zadzwoń setSelectedItemIddziała:

    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

Zrób selektor dla Individaual elementu w 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>

Wprowadź kilka zmian w 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

na temat twojej aktywności (za szufladą):

@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));
}

i

@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;
}

i w twoim menu:

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

więc pierwsze menu jest podświetlone i wyświetlane jako menu domyślne.


0

Poniższy kod służy do wybrania pierwszego elementu i podświetlenia wybranego pierwszego elementu w menu.

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

Czy możesz mi powiedzieć, w jaki sposób i gdzie ten onNavigationItemSelected jest dostępny? Podaj pełniejszy przykład kodu.
kilokahn


-1

Z jakiegoś powodu lepiej jest znaleźć element menu za pomocą identyfikatora.

drawer.getMenu().findItem(R.id.action_something).setChecked(true);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.