Android BottomNavigationView में चयनित आइटम सेट करें


123

मैं android.support.design.widget.BottomNavigationViewसमर्थन पुस्तकालय से नए का उपयोग कर रहा हूं । मैं वर्तमान चयन को कोड से कैसे सेट कर सकता हूं? मुझे एहसास हुआ, कि स्क्रीन को घुमाने के बाद चयन को पहले आइटम पर वापस बदल दिया जाता है। बेशक यह भी मदद मिलेगी कोई मुझे बता सकते हैं अगर, कैसे करने के लिए की वर्तमान स्थिति "सहेजें" BottomNavigationViewमें onPauseसमारोह और कैसे में बहाल करने onResume

धन्यवाद!


1
मेरे पास स्रोत पर एक नज़र है और मेरे पास एक ही सवाल है .. ऐसा नहीं लगता है कि चयनित आइटम को सेट करने के लिए एक विधि है, और BottomNavigationViewराज्य की कोई आंतरिक बचत नहीं करता है। संभवतः भविष्य के अपडेट में इसे शामिल किए जाने की उम्मीद है। डुप्लीकेट (कुछ और जानकारी के साथ): stackoverflow.com/questions/40236786/…
टिम मालसीड

जवाबों:


171

एपीआई 25.3.0 से यह विधि पेश की गई setSelectedItemId(int id)जो आपको एक आइटम को चिह्नित करने की अनुमति देती है जैसे कि इसे टैप किया गया था।

डॉक्स से:

चयनित मेनू आइटम आईडी सेट करें। यह एक आइटम पर टैपिंग के समान व्यवहार करता है।

कोड उदाहरण:

BottomNavigationView bottomNavigationView;
bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottomNavigationView);
bottomNavigationView.setOnNavigationItemSelectedListener(myNavigationItemListener);
bottomNavigationView.setSelectedItemId(R.id.my_menu_item_id);

जरूरी

आप चाहिए पहले से ही मेनू में सभी वस्तुओं को शामिल किया है (मामले में आप इस प्रोग्राम के रूप में करते हैं) और setSelectedItemId बुला (मेरा मानना है कि आप को चलाने के लिए जब आप इस विधि कॉल आपके श्रोता में कोड चाहते हैं) से पहले श्रोता निर्धारित किया है। यदि आप मेनू आइटम जोड़ने और श्रोता सेट करने से पहले setSelectedItemId कॉल करते हैं तो कुछ नहीं होगा।


3
यह काम नहीं करता है, यह केवल टैब को ही अपडेट करता है, यह एक setOnNavigationItemSelectedListener ईवेंट ट्रिगर नहीं करता है
TjerkW

1
यदि आपने व्यवहार को onTabSelectedस्पष्ट रूप से परिभाषित नहीं किया है तो यह कुछ भी नहीं करेगा। डॉक्स पढ़ें -> चयनित मेनू आइटम आईडी सेट करें। यह एक आइटम पर टैपिंग के समान व्यवहार करता है। यह एंड्रॉइड डेवलपर्स से है
रिकार्डो

1
मैं आपको अत्यधिक सलाह देता हूं कि आप जो गलत कर रहे हैं उसे डिबग करें और समीक्षा करें। मैंने पहले ही तीन बॉटम नेशनव्यू व्यू एप्लिकेशन लागू कर दिए हैं और इस पद्धति से कभी कोई समस्या नहीं हुई।
रिकार्डो

@ रिकार्डो जब मैं इसे अपने टुकड़े में जोड़ता हूं, तो उस टुकड़े में प्रवेश करते समय आवेदन लटका हुआ मिलता है
सुबिन बाबू

1
मेरे मामले में काम नहीं कर रहा था, क्योंकि मैं नेवीगेशन प्रोग्राम बना रहा था। निर्माण के दौरान क्लिक ने काम नहीं किया। सभी आइटम मेनू में जोड़े जाने के बाद, कॉलिंग सेटसेलेटीमैम () काम किया।
पेड्रो रोमियो

53

नीचे दिए गए न्यूनतम आइटम पर प्रोग्रामेटिकली क्लिक करें:

View view = bottomNavigationView.findViewById(R.id.menu_action_item);
view.performClick();

यह सभी आइटम को उनके लेबल के साथ सही ढंग से व्यवस्थित करता है।


4
यह समस्या के बारे में एक हैक है। आपके पास पुस्तकालय से ही विधियां हैं जो आपको वह कार्य करने की आवश्यकता है जो आपको चाहिए। यदि आप तब ऐसा नहीं कर सकते हैं क्योंकि आप इसे गलत कर रहे हैं
रिकार्डो

47

उन लोगों के लिए, जो अभी भी SupportLibrary <25.3.0 का उपयोग करते हैं

मुझे यकीन नहीं है कि यह इस प्रश्न का पूर्ण उत्तर है, लेकिन मेरी समस्या बहुत समान थी - मुझे backबटन प्रेस को संसाधित करना था और उपयोगकर्ता को पिछले टैब पर लाना था जहां वह था। तो, शायद मेरा समाधान किसी के लिए उपयोगी होगा:

private void updateNavigationBarState(int actionId){
    Menu menu = bottomNavigationView.getMenu();

    for (int i = 0, size = menu.size(); i < size; i++) {
        MenuItem item = menu.getItem(i);
        item.setChecked(item.getItemId() == actionId);
    }
}

कृपया, ध्यान रखें कि यदि उपयोगकर्ता अन्य नेविगेशन टैब BottomNavigationViewको दबाता है , तो वर्तमान में चयनित आइटम स्पष्ट नहीं होगा, इसलिए आपको onNavigationItemSelectedनेविगेशन विधि के प्रसंस्करण के बाद इस पद्धति को कॉल करने की आवश्यकता है :

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    switch (item.getItemId()) {
        case R.id.some_id_1:
            // process action
            break;
        case R.id.some_id_2:
            // process action
            break;
        ...
        default:
            return false;
    }

    updateNavigationBarState(item.getItemId());

    return true;
}

उदाहरण के राज्य की बचत के बारे में मुझे लगता है कि आप action idनेविगेशन दृश्य के साथ खेल सकते हैं और उपयुक्त समाधान पा सकते हैं।


Menu menu = bottomNavigationView.getMenu();मेनू की एक प्रति वापस नहीं आती है , तो bottomNavigationViewवस्तु प्रभावित नहीं होती है?
最白目

1
@dan स्रोत के अनुसार यह रिटर्न वर्ग विशेषता mMenu, नहीं प्रतिलिपि android.googlesource.com/platform/frameworks/support/+/master/...
Viacheslav

6
आपको अन्य वस्तुओं को अनचेक करने की आवश्यकता नहीं है, कम से कम 26.1.0 / 27.1.0 पर
Jemshit Iskenderov

अनचेक न करें, यह उन्हें उजागर करेगा
djdance


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

   bottomNavigationView.setOnNavigationItemSelectedListener(this);
   Menu menu = bottomNavigationView.getMenu();
   this.onNavigationItemSelected(menu.findItem(R.id.action_favorites));
}

7

अब यह संभव है के बाद से 25.3.0 संस्करण कॉल करने के लिए setSelectedItemId()\ o /


5

android:enabled="true"निचलाअनुशमनमेनू आइटम में जोड़ें ।

और फिर सेट bottomNavigationView.setOnNavigationItemSelectedListener(mListener)करके सेट करें जैसा कि आप कर रहे हैंbottomNavigationView.selectedItemId = R.id.your_menu_id


3

यह संभवतः आने वाले अपडेट में जोड़ा जाएगा। लेकिन इस बीच, इसे पूरा करने के लिए आप प्रतिबिंब का उपयोग कर सकते हैं।

नीचे दिए गए कस्टम व्यू को नीचे की ओर देखें और उसके कुछ क्षेत्रों तक पहुँचें।

public class SelectableBottomNavigationView extends BottomNavigationView {

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

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

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

    public void setSelected(int index) {
        try {
            Field f = BottomNavigationView.class.getDeclaredField("mMenuView");
            f.setAccessible(true);
            BottomNavigationMenuView menuView = (BottomNavigationMenuView) f.get(this);

            try {
                Method method = menuView.getClass().getDeclaredMethod("activateNewButton", Integer.TYPE);
                method.setAccessible(true);
                method.invoke(menuView, index);
            } catch (SecurityException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

}

और फिर अपने xml लेआउट फ़ाइल में इसका उपयोग करें।

<com.your.app.SelectableBottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:itemBackground="@color/primary"
        app:itemIconTint="@drawable/nav_item_color_state"
        app:itemTextColor="@drawable/nav_item_color_state"
        app:menu="@menu/bottom_navigation_menu"/>

3
प्रतिबिंब एक बुरा विचार है!
ब्रिटो

PerformClick इस मामले में प्रतिबिंब, इमो से बेहतर है।
लस्सी किन्नुनेन

3

प्रोग्राम के अनुसार चयन करने के लिए बस एक और तरीका जोड़ना - यह शायद वही है जो पहले स्थान पर था या शायद बाद में इसे जोड़ा गया था।

Menu bottomNavigationMenu = myBottomNavigationMenu.getMenu();
bottomNavigationMenu.performIdentifierAction(selected_menu_item_id, 0);

performIdentifierActionएक लेता Menuआइटम आईडी और एक झंडा।

अधिक जानकारी के लिए दस्तावेज़ देखें ।


यह मेनू आइटम से संबंधित कार्रवाई करने के लिए लगता है, लेकिन मेनू आइटम को चयनित होने का कारण नहीं बनता है। मैंने सोचा था कि बाद में ओपी चाहता था, लेकिन मैं सकारात्मक नहीं हूं।
लारश डिक

3

SupportLibrary में तय किए गए 25.1.0 :) संपादित करें: यह तय हो गया है, कि स्क्रीन को घुमाते समय चयन की स्थिति बच गई है।


1
मैंने अभी 25.1.1 को अपडेट किया है। समस्या अब भी वहीं है।
शी वी

3

API 25 से ऊपर आप setSelectedItemId (menu_item_id) का उपयोग कर सकते हैं, लेकिन API 25 के तहत आपको हैंडल प्राप्त करने के लिए उपयोगकर्ता मेनू अलग से करना चाहिए, और फिर चेक किए गए विशिष्ट आइटम पर सेट किया जाना चाहिए


3

मेनू आईडी द्वारा चयनित निचला नेविगेशन मेनू आइटम सेट करने के लिए इसका उपयोग करें

MenuItem item = mBottomNavView.getMenu().findItem(menu_id);
item.setChecked(true);

2

मैं आपको अपना कोड संशोधित नहीं करना चाहता। यदि हां, तो मैंने आपको नीचे दिए गए प्रयास करने की सिफारिश की है

तुम सिर्फ एक विधि कॉल की जगह की जरूरत है setCurrentItem(index);और getCurrentItem()

छवि देखने के लिए यहां क्लिक करें



1

मैंने इस तथ्य के बारे में Google को एक बग बना दिया कि नीचे दिए गए पृष्ठ पर चयन करने का कोई विश्वसनीय तरीका नहीं है: https://code.google.com/p/android/issues/detail?id=233697

नेवीगेशन व्यू में स्पष्ट रूप से एक समान मुद्दा था, जिसे उन्होंने एक नया सेटचेकटिडेम () विधि जोड़कर तय किया था।



0
private void setSelectedItem(int actionId) {
    Menu menu = viewBottom.getMenu();
    for (int i = 0, size = menu.size(); i < size; i++) {
        MenuItem menuItem = menu.getItem(i);
        ((MenuItemImpl) menuItem).setExclusiveCheckable(false);
        menuItem.setChecked(menuItem.getItemId() == actionId);
        ((MenuItemImpl) menuItem).setExclusiveCheckable(true);
    }
}

समाधान का एकमात्र the माइनस ’उपयोग कर रहा है MenuItemImpl, जो पुस्तकालय (हालांकि सार्वजनिक) के लिए to आंतरिक’ है।


0

अगर आपको डायनामिकली के लिए जरूरी है तो घर्षण की जरूरत है

यहाँ बहुत सारे (अधिकतर बार-बार या पुराने) उत्तर दिए गए हैं, लेकिन उनमें से कोई भी एक बहुत ही सामान्य आवश्यकता को नहीं संभालता है: एक टैब में लोड किए गए फ्रेग्मेंट को गतिशील रूप से अलग-अलग तर्क दे रहा है

आप गतिशील रूप से लोड किए गए फ़्रैगमेंट में विभिन्न तर्कों का उपयोग करके पास नहीं कर सकते setSelectedItemId(R.id.second_tab) , जो स्थिर कॉलिंग को समाप्त करता है OnNavigationItemSelectedListener। इस सीमा को समाप्त करने के लिए मैंने अपने MainActivityटैब में यह करना समाप्त कर दिया है :

fun loadArticleTab(articleId: String) {
    bottomNavigationView.menu.findItem(R.id.tab_article).isChecked = true // use setChecked() in Java
    supportFragmentManager
        .beginTransaction()
        .replace(R.id.main_fragment_container, ArticleFragment.newInstance(articleId))
        .commit()
}

ArticleFragment.newInstance()विधि हमेशा की तरह लागू किया गया है:

private const val ARG_ARTICLE_ID = "ARG_ARTICLE_ID"

class ArticleFragment : Fragment() {

    companion object {
        /**
         * @return An [ArticleFragment] that shows the article with the given ID.
         */
        fun newInstance(articleId: String): ArticleFragment {
            val args = Bundle()
            args.putString(ARG_ARTICLE_ID, day)
            val fragment = ArticleFragment()
            fragment.arguments = args
            return fragment
        }
    }

}

0

आशा है कि ये आपकी मदद करेगा

//Setting default selected menu item and fragment
        bottomNavigationView.setSelectedItemId(R.id.action_home);
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.fragment_container, new HomeFragment()).commit();

यह एक ही समय में संगत नीचे नेविगेशन मेनू आइटम के साथ लोड किए गए डिफ़ॉल्ट टुकड़े को निर्धारित करने से अधिक है। आप अपने OnResume कॉलबैक में इसे शामिल कर सकते हैं


0

यह विधि मेरे लिए काम करती है।

private fun selectBottomNavigationViewMenuItem(bottomNavigationView : BottomNavigationView,@IdRes menuItemId: Int) {
            bottomNavigationView.setOnNavigationItemSelectedListener(null)
            bottomNavigationView.selectedItemId = menuItemId
            bottomNavigationView.setOnNavigationItemSelectedListener(this)
        }

उदाहरण

 override fun onBackPressed() {
        replaceFragment(HomeFragment())
        selectBottomNavigationViewMenuItem(navView, R.id.navigation_home)
    }



private fun replaceFragment(fragment: Fragment) {
        val transaction: FragmentTransaction = supportFragmentManager.beginTransaction()
        transaction.replace(R.id.frame_container, fragment)
        transaction.commit()
    }

-1

प्रतिबिंब बुरा विचार है।

इस सिर के बल । एक तरीका है जो चयन करता है लेकिन कॉलबैक को भी आमंत्रित करता है:

  @CallSuper
    public void setSelectedItem(int position) {
        if (position >= getMenu().size() || position < 0) return;

        View menuItemView = getMenuItemView(position);
        if (menuItemView == null) return;
        MenuItemImpl itemData = ((MenuView.ItemView) menuItemView).getItemData();


        itemData.setChecked(true);

        boolean previousHapticFeedbackEnabled = menuItemView.isHapticFeedbackEnabled();
        menuItemView.setSoundEffectsEnabled(false);
        menuItemView.setHapticFeedbackEnabled(false); //avoid hearing click sounds, disable haptic and restore settings later of that view
        menuItemView.performClick();
        menuItemView.setHapticFeedbackEnabled(previousHapticFeedbackEnabled);
        menuItemView.setSoundEffectsEnabled(true);


        mLastSelection = position;

    }

मैं callOnClick()इसके बजाय का उपयोग करता हूं performClick(), इस तरह मुझे ध्वनि को अक्षम करने की आवश्यकता नहीं है, जो performClick()वैसे भी काम नहीं करता था ।
इस्कॉलेक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.