অ্যান্ড্রয়েড নীচে নেভিগেশনভিউতে নির্বাচিত আইটেমটি সেট করুন


122

আমি android.support.design.widget.BottomNavigationViewসমর্থন লাইব্রেরি থেকে নতুন ব্যবহার করছি । আমি কোড থেকে বর্তমান নির্বাচনটি কীভাবে সেট করতে পারি? আমি বুঝতে পেরেছি যে স্ক্রিনটি ঘোরানোর পরে বাছাইটি প্রথম আইটেমে ফিরে এসেছে। অবশ্যই এটি সাহায্য করবে, যদি কেউ আমাকে বলতে পারে, কীভাবে ফাংশনটির বর্তমান অবস্থা "সংরক্ষণ" BottomNavigationViewকরতে onPauseহয় এবং কীভাবে এটি পুনরুদ্ধার করা যায় onResume

ধন্যবাদ!


1
আমি কেবল উত্সটি দেখেছি এবং আমারও একই প্রশ্ন রয়েছে .. এটি দেখে মনে হচ্ছে না যে নির্বাচিত আইটেমটি সেট করার কোনও পদ্ধতি আছে, এবং BottomNavigationViewকোনও রাজ্যের অভ্যন্তরীণ সঞ্চয় করে না। সম্ভবত এটি ভবিষ্যতের আপডেটে অন্তর্ভুক্ত হবে আশা করি। এখানে অনুলিপি (আরও কিছু তথ্যের সাথে): stackoverflow.com/questions/40236786/…
টিম মালসিড

উত্তর:


170

এপিআই 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);

গুরুত্বপূর্ণ

আপনি অবশ্যই মেনুতে সমস্ত আইটেম যুক্ত করে রেখেছেন (আপনি যদি এই প্রোগ্রামটিমেটিভ করেন তবে) সেটলেস্টড আইটেম আইডি কল করার আগে শ্রোতাকে সেট করে (আমি বিশ্বাস করি যে আপনি যখন এই পদ্ধতিটি কল করবেন তখন আপনার শ্রোতার কোডটি চলবে)। আপনি যদি মেনু আইটেমগুলি যুক্ত করার আগে এবং শ্রোতাকে সেট করার আগে সেটসিলেক্টড আইটেম আইড কল করেন তবে কিছুই হবে না।


3
এটি কাজ করে না, এটি কেবল ট্যাবটি নিজেই আপডেট করে, এটি কোনও সেট-ও-নেভিগেশন আইটেমসিলেক্টডলাইজন ইভেন্টকে ট্রিগার করে না
TjerkW

1
আপনি যদি আচরণটি onTabSelectedস্পষ্টত সংজ্ঞায়িত না করেন তবে এটি কিছু করবে না। দস্তাবেজগুলি পড়ুন -> নির্বাচিত মেনু আইটেম আইডি সেট করুন। এটি কোনও আইটেমটিতে আলতো চাপানোর মতো আচরণ করে। এটি অ্যান্ড্রয়েড বিকাশকারীদের থেকে
রিকার্ডো

1
আমি আপনাকে ডিবাগ করতে এবং আপনি কী ভুল করছেন তা পর্যালোচনা করার জন্য অত্যন্ত পরামর্শ দিচ্ছি। আমি ইতিমধ্যে তিনটি বটমনাভিশনভিউ অ্যাপ্লিকেশনগুলি প্রয়োগ করেছি এবং এই পদ্ধতিতে কখনও সমস্যা হয়নি a
রিকার্ডো

@ রিকার্ডো যখন আমি এটি আমার খণ্ডে যুক্ত করি তখন সেই টুকরোটিতে প্রবেশের সময় অ্যাপ্লিকেশনটি স্তব্ধ হয়ে যায়
সুবিন বাবু

1
আমার ক্ষেত্রে কাজ করা হয়নি, কারণ আমি নেভিগেশনমেনুকে প্রোগ্রামক্রমে তৈরি করছিলাম। নির্মাণের সময় ক্লিকটি কার্যকর হয়নি। সমস্ত আইটেম মেনুতে যুক্ত হওয়ার পরে, কল করে সেটলেক্ট আইটেম আইডি () কাজ করেছে।
পেড্রো রোমো

53

প্রোগ্রাম্যাটিকভাবে নীচে নেভিগেশনবার আইটেমটি ক্লিক করতে আপনার ব্যবহারের প্রয়োজন:

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

এটি সমস্ত আইটেমকে তাদের লেবেলগুলি সঠিকভাবে সাজিয়েছে।


4
এটি সমস্যা সম্পর্কিত একটি হ্যাক। আপনার কাছে লাইব্রেরি থেকেই এমন পদ্ধতি রয়েছে যা আপনাকে যা প্রয়োজন তা সম্পাদন করতে দেয়। যদি আপনি তা না করতে পারেন তবে আপনি এটি ভুল করছেন কারণ
রিকার্ডো

47

তাদের জন্য, যারা এখনও সমর্থন লাইব্রেরি <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 এ
জেমশিট ইস্কেন্দ্রভ

চেক করবেন না, এটি তাদের হাইলাইট করবে
djdance 10'19

19
bottomNavigationView.setSelectedItemId(R.id.action_item1);

যেখানে action_item1মেনু আইটেম আইডি নয়।


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"BottomNavigationMenu আইটেম।

এবং তারপরে সেট 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();
        }
    }

}

এবং তারপরে এটি আপনার এক্সএমএল লেআউট ফাইলটিতে ব্যবহার করুন।

<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
প্রতিবিম্ব একটি খারাপ ধারণা!
ফিলিপ ব্রিটো

এই ক্ষেত্রে প্রতিস্থাপনের চেয়ে পারফরম্যান্স ক্লিক ভাল।
লাসি কিনুনুনেন

3

অগ্রগতিমূলকভাবে একটি নির্বাচন সঞ্চালনের জন্য কেবল অন্য উপায় যুক্ত করা - সম্ভবত এটিই প্রথম স্থানে ছিল বা সম্ভবত এটি পরে যুক্ত করা হয়েছিল।

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

আইটেম আইডি এবং একটি পতাকা performIdentifierActionনেয় TheMenu

আরও তথ্যের জন্য ডকুমেন্টেশন দেখুন ।


এটি মেনু আইটেমের সাথে সম্পর্কিত ক্রিয়াটি সম্পাদন করে বলে মনে হচ্ছে, তবে মেনু আইটেমটি নির্বাচিত প্রদর্শিত হবে না। আমি ভেবেছিলাম দ্বিতীয়টি ওপি যা চেয়েছিল তা কিন্তু আমি ইতিবাচক নই।
LarsH

3

সমর্থন লাইব্রেরি 25.1.0 এ সংশোধন করা হয়েছে বলে মনে হয় :) সম্পাদনা: এটি ঠিক হয়ে গেছে বলে মনে হচ্ছে, স্ক্রিনটি ঘোরানোর সময় নির্বাচনের অবস্থাটি সংরক্ষণ করা হয়।


1
আমি সবেমাত্র 25.1.1 এ আপডেট করেছি। সমস্যা এখনও আছে।
Xi ওয়েই

3

এপিআই 25 এর উপরে আপনি সেটলেক্ট আইটেমআইডি (মেনু_ইটেম_আইডি) ব্যবহার করতে পারেন তবে এপিআই 25 এর অধীনে আপনাকে আলাদাভাবে করতে হবে, হ্যান্ডেলটি পেতে ব্যবহারকারী মেনু এবং তারপরে নির্দিষ্ট আইটেমটিতে চেক করা হয়েছে


3

মেনু আইডি দ্বারা নির্বাচিত নীচের নেভিগেশন মেনু আইটেম সেট করতে এটি ব্যবহার করুন

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

2

আমি আপনার কোডটি পরিবর্তন করতে চাই না। যদি তা হয় তবে আমি আপনাকে নীচ নেভিগেশনভিউএক্স try চেষ্টা করার পরামর্শ দিয়েছি

আপনার কেবল কল করতে হবে একটি পদ্ধতি setCurrentItem(index);এবং getCurrentItem()

ছবিটি দেখতে এখানে ক্লিক করুন


1

: আমি আসলে একটা BottomNavigationView পৃষ্ঠার নির্বাচন করতে কোন নির্ভরযোগ্য উপায় যে সম্পর্কে 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);
    }
}

সমাধানটির একমাত্র 'বিয়োগ' ব্যবহার করা হচ্ছে MenuItemImpl, এটি লাইব্রেরির (অভ্যন্তরীণ) যদিও (প্রকাশ্য)।


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

এটি একই সাথে নীচের নেভিগেশন নেভিগেশন মেনু আইটেমের সাথে লোড হওয়া ডিফল্ট খণ্ডটি নির্ধারণ করার বেশি। আপনি নিজের অনারুমিউম কলব্যাকগুলিতে এটি অন্তর্ভুক্ত করতে পারেন


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()কোনওভাবেই কাজ করে না।
arekolek
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.