在 BottomNavigationView 中设置最初选择的项目 index/id
Set initially selected item index/id in BottomNavigationView
我已经实现了 BottomNavigationView 但不知道如何设置选择索引或 MenuItem
id(在我的例子中,默认情况下应该选择中间项)。
恐怕目前还没有这种可能性,因为它还太原始了,但无论如何,我们将不胜感激。谢谢!
唯一对我有用的解决方案是:
View view = bottomNavigationView.findViewById(R.id.menu_action_dashboard);
view.performClick();
只需执行点击即可。希望我们能在未来的版本中获得额外的 methods/properties。
UPD:
作为user5968678 ,自Android支持库v25.3.0以来添加了一个新方法:
bottomNavigationView.setSelectedItemId(R.id.item_id);
所以改用这个:)
您可以扩展 BottomNavigationView 并使用反射来调用私有方法。
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 {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) getField(BottomNavigationView.class, "mMenuView");
OnNavigationItemSelectedListener listener = (OnNavigationItemSelectedListener) getField(BottomNavigationView.class, "mListener");
try {
Method method = menuView.getClass().getDeclaredMethod("activateNewButton", Integer.TYPE);
method.setAccessible(true);
// activate item.
method.invoke(menuView, index);
if (listener != null) {
// trigger item select event.
listener.onNavigationItemSelected(getMenu().getItem(index));
}
} catch (SecurityException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
private Object getField(Class clazz, String fieldName) throws NoSuchFieldException, IllegalAccessException {
Field f = clazz.getDeclaredField(fieldName);
f.setAccessible(true);
return f.get(this);
}
}
停止使用反射!坏了!
好吧,虽然支持库没有让我们选择 select BottomNavigationView 中的项目在可见时第一次显示,但我们有两种可能性:
First, using loop:
private void setupBottomNavigationView() {
// Get the menu from our navigationBottomView.
Menu bottomNavigationViewMenu = bottomNavigationView.getMenu();
// Uncheck the first menu item (the default item which is always checked by the support library is at position 0).
bottomNavigationMenu.findItem(R.id.action_one).setChecked(false);
// Check the wished first menu item to be shown to the user.
bottomNavigationMenu.findItem(R.id.action_two).setChecked(true);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Menu bottomNavigationMenu = bottomNavigationView.getMenu();
for (int i = 0; i < bottomNavigationMenu.size(); i++) {
if (item.getItemId() != bottomNavigationMenu.getItem(i).getItemId()) {
bottomNavigationMenu.getItem(i).setChecked(false);
}
}
switch (item.getItemId()) {
case R.id.action_one :
replaceFragment(new OneFragment());
break;
case R.id.action_two :
replaceFragment(new TwoFragment());
break;
case R.id.action_three :
replaceFragment(new ThreeFragment());
break;
}
return false;
}
});
}
Second, without loop but with a class variable (because the logic is done from within inner class) :
private void setupBottomNavigationView() {
// Get the menu from our navigationBottomView.
Menu bottomNavigationViewMenu = bottomNavigationView.getMenu();
// Uncheck the first menu item (the default item which is always checked by the support library is at position 0).
bottomNavigationViewMenu.findItem(R.id.action_one).setChecked(false);
// Check the wished first menu item to be shown to the user. Also store that menu item on a variable to control when a menu item must be unchecked.
mActiveBottomNavigationViewMenuItem = bottomNavigationViewMenu.findItem(R.id.action_two).setChecked(true);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem selectedMenuItem) {
switch (selectedMenuItem.getItemId()) {
case R.id.action_one :
replaceFragment(new OneFragment());
break;
case R.id.action_two :
replaceFragment(new TwoFragment());
break;
case R.id.action_three :
replaceFragment(new ThreeFragment());
break;
}
if (selectedMenuItem != mActiveBottomNavigationViewMenuItem){
mActiveBottomNavigationViewMenuItem.setChecked(false);
mActiveBottomNavigationViewMenuItem = selectedMenuItem;
}
return false;
}
});
}
private MenuItem mActiveBottomNavigationViewMenuItem;
什么时候执行setupBottomNavigationView()方法?在Activity onCreate() 方法中,看一下:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ...
setupBottomNavigationView();
}
简单且没有大量代码。
希望对您有所帮助!
我认为这个解决方案比公认的答案稍微优雅一些:
bottomNavigationView.getMenu().getItem(menuItemIndex).setChecked(true)
其中 menuItemIndex 是所选元素的索引。
the documentation 是这样说的:
Menu items can also be used for programmatically selecting which destination is currently active. It can be done using MenuItem#setChecked(true)
作为 Jan 发布内容的替代方案,您还可以通过 ID 查找该项目:
Menu menu = findViewById(R.id.navigation).getMenu();
menu.findItem(R.id.navigation_home).setChecked(true);
此外,一般来说,我可以建议调用 .callOnClick()
instead of .performClick()
。
使用setSelectedItemId
设置所选菜单项ID:
bottomNavigationView.setSelectedItemId(R.id.item_id);
此方法从 Android 支持库 25.3.0 开始可用。
如果您正在使用侦听器,例如 android studio 中的默认实现,请尝试以下操作:
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
Integer indexItem = 4;
navigation.getMenu().getItem(indexItem).setChecked(true);
mOnNavigationItemSelectedListener.onNavigationItemSelected(navigation.getMenu().getItem(indexItem));
我相信根据此处的答案,可以在不同的上下文中查看此上下文中的问题。
根据评估,需要的是专注于特定 BottomNavigationView
项目的能力(肯定是在新的 class 中持有不同的片段)。
现在,您可以使用 BottomNavigationView 或按钮或任何可点击的内容来启动新的 activity:-
即
Intent intent = new Intent(getActivity(), New_Activity.class);
intent.putExtra("EXTRA_PAGE, 1);
startActivityForResult(intent, 30);
然后
-在我们的New_Activity中,我们收到了意图-
Intent 意图 = getIntent();
int page = intent.getExtras().getInt("EXTRA_PAGE);
然后我们遍历页面变量以找到当前 BottomNavigationView 反映的 number/Index,然后 我们设置焦点菜单项(假设您的 BottomNavigationView 有用于显示的菜单项)
if(page == 1) {
currentselect = new Pending();
bottomNavigationView.getMenu().getItem(0).setChecked(true);
}
这回答了上面的问题。通过调用 :
上面的帖子数量可以很好地处理其余的 Fragment 开关
bottomNavigationView.setOnNavigationItemSelectedListener(navListener);
然后像这样:
private BottomNavigationView.OnNavigationItemSelectedListener navListener =
new BottomNavigationView.OnNavigationItemSelectedListener(){
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment selectedFrag = null;
switch (item.getItemId()) {
case R.id.pending:
selectedFrag = new Pending();
break;
case R.id.onTransmit:
selectedFrag = new inTransmit();
break;
case R.id.complete:
selectedFrag = new Complete();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.select_field, selectedFrag).commit();
return true;
}
};
注意:
使用 BottomNavigationView 和 ContentFrameLayout 非常经济,与使用 ViewPager 和 Tablayout
bottomnavigation.BottomNavigationView 中初始选定项的 Kotlin 代码:
bottom_navigation_view.selectedItemId = R.id.navigation_item_messages
执行BottomNavigationView.OnNavigationItemSelectedListener
并在初始化时设置selectedItemId
。
this.bottomNavigationView.setOnNavigationItemSelectedListener {
val targetFragment = when (menuItem.itemId) {
R.id.action_home -> {
HomeFragment()
}
R.id.action_post -> {
PostFragment()
}
R.id.action_settings -> {
SettingsFragment()
}
else -> null
}
targetFragment?.let {
this.activity?.supportFragmentManager?.transaction {
replace(R.id.containerLayout, it, it.javaClass.simpleName)
}
}
true
}
this.bottomNavigationView.selectedItemId = R.id.action_home
您可以通过添加虚拟菜单项来实现此效果
作为分配给 BottomNavigationView 的菜单中的第一项
并将此项设置为不可见。然后在
您的重新选择处理程序,将 setSelectedItem(dummy) 调用到虚拟
物品。因此,可见的菜单项将表现为
“虚拟”切换。我花了比应该做的更多的工作
弄清楚这个。你必须这样做才能
重新选择完成后调用 setSelectItem:
@Override
public void onNavigationItemReselected(@NonNull MenuItem item) {
anyView.post(new Runnable() {
@Override
public void run() {
navigationView.setSelectedItemId(R.id.action_dummy);
}
}
});
在导航中设置初始页面 - Jetpack Navigation
在导航图中设置属性“startDestination”,值应该是给片段的id。
<navigation
app:startDestination="@+id/navigation_movies"
...
>
<!-- default page -->
<fragment
android:id="@+id/navigation_movies"
...`enter code here`
/>
<fragment
android:id="@+id/navigation_tv_shows"
...
/>
</fragment>
我已经实现了 BottomNavigationView 但不知道如何设置选择索引或 MenuItem
id(在我的例子中,默认情况下应该选择中间项)。
恐怕目前还没有这种可能性,因为它还太原始了,但无论如何,我们将不胜感激。谢谢!
唯一对我有用的解决方案是:
View view = bottomNavigationView.findViewById(R.id.menu_action_dashboard);
view.performClick();
只需执行点击即可。希望我们能在未来的版本中获得额外的 methods/properties。
UPD:
作为user5968678
bottomNavigationView.setSelectedItemId(R.id.item_id);
所以改用这个:)
您可以扩展 BottomNavigationView 并使用反射来调用私有方法。
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 {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) getField(BottomNavigationView.class, "mMenuView");
OnNavigationItemSelectedListener listener = (OnNavigationItemSelectedListener) getField(BottomNavigationView.class, "mListener");
try {
Method method = menuView.getClass().getDeclaredMethod("activateNewButton", Integer.TYPE);
method.setAccessible(true);
// activate item.
method.invoke(menuView, index);
if (listener != null) {
// trigger item select event.
listener.onNavigationItemSelected(getMenu().getItem(index));
}
} catch (SecurityException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
private Object getField(Class clazz, String fieldName) throws NoSuchFieldException, IllegalAccessException {
Field f = clazz.getDeclaredField(fieldName);
f.setAccessible(true);
return f.get(this);
}
}
停止使用反射!坏了!
好吧,虽然支持库没有让我们选择 select BottomNavigationView 中的项目在可见时第一次显示,但我们有两种可能性:
First, using loop:
private void setupBottomNavigationView() {
// Get the menu from our navigationBottomView.
Menu bottomNavigationViewMenu = bottomNavigationView.getMenu();
// Uncheck the first menu item (the default item which is always checked by the support library is at position 0).
bottomNavigationMenu.findItem(R.id.action_one).setChecked(false);
// Check the wished first menu item to be shown to the user.
bottomNavigationMenu.findItem(R.id.action_two).setChecked(true);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Menu bottomNavigationMenu = bottomNavigationView.getMenu();
for (int i = 0; i < bottomNavigationMenu.size(); i++) {
if (item.getItemId() != bottomNavigationMenu.getItem(i).getItemId()) {
bottomNavigationMenu.getItem(i).setChecked(false);
}
}
switch (item.getItemId()) {
case R.id.action_one :
replaceFragment(new OneFragment());
break;
case R.id.action_two :
replaceFragment(new TwoFragment());
break;
case R.id.action_three :
replaceFragment(new ThreeFragment());
break;
}
return false;
}
});
}
Second, without loop but with a class variable (because the logic is done from within inner class) :
private void setupBottomNavigationView() {
// Get the menu from our navigationBottomView.
Menu bottomNavigationViewMenu = bottomNavigationView.getMenu();
// Uncheck the first menu item (the default item which is always checked by the support library is at position 0).
bottomNavigationViewMenu.findItem(R.id.action_one).setChecked(false);
// Check the wished first menu item to be shown to the user. Also store that menu item on a variable to control when a menu item must be unchecked.
mActiveBottomNavigationViewMenuItem = bottomNavigationViewMenu.findItem(R.id.action_two).setChecked(true);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem selectedMenuItem) {
switch (selectedMenuItem.getItemId()) {
case R.id.action_one :
replaceFragment(new OneFragment());
break;
case R.id.action_two :
replaceFragment(new TwoFragment());
break;
case R.id.action_three :
replaceFragment(new ThreeFragment());
break;
}
if (selectedMenuItem != mActiveBottomNavigationViewMenuItem){
mActiveBottomNavigationViewMenuItem.setChecked(false);
mActiveBottomNavigationViewMenuItem = selectedMenuItem;
}
return false;
}
});
}
private MenuItem mActiveBottomNavigationViewMenuItem;
什么时候执行setupBottomNavigationView()方法?在Activity onCreate() 方法中,看一下:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ...
setupBottomNavigationView();
}
简单且没有大量代码。
希望对您有所帮助!
我认为这个解决方案比公认的答案稍微优雅一些:
bottomNavigationView.getMenu().getItem(menuItemIndex).setChecked(true)
其中 menuItemIndex 是所选元素的索引。
the documentation 是这样说的:
Menu items can also be used for programmatically selecting which destination is currently active. It can be done using
MenuItem#setChecked(true)
作为 Jan 发布内容的替代方案,您还可以通过 ID 查找该项目:
Menu menu = findViewById(R.id.navigation).getMenu();
menu.findItem(R.id.navigation_home).setChecked(true);
此外,一般来说,我可以建议调用 .callOnClick()
instead of .performClick()
。
使用setSelectedItemId
设置所选菜单项ID:
bottomNavigationView.setSelectedItemId(R.id.item_id);
此方法从 Android 支持库 25.3.0 开始可用。
如果您正在使用侦听器,例如 android studio 中的默认实现,请尝试以下操作:
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
Integer indexItem = 4;
navigation.getMenu().getItem(indexItem).setChecked(true);
mOnNavigationItemSelectedListener.onNavigationItemSelected(navigation.getMenu().getItem(indexItem));
我相信根据此处的答案,可以在不同的上下文中查看此上下文中的问题。
根据评估,需要的是专注于特定 BottomNavigationView
项目的能力(肯定是在新的 class 中持有不同的片段)。
现在,您可以使用 BottomNavigationView 或按钮或任何可点击的内容来启动新的 activity:- 即
Intent intent = new Intent(getActivity(), New_Activity.class);
intent.putExtra("EXTRA_PAGE, 1);
startActivityForResult(intent, 30);
然后 -在我们的New_Activity中,我们收到了意图-
Intent 意图 = getIntent(); int page = intent.getExtras().getInt("EXTRA_PAGE);
然后我们遍历页面变量以找到当前 BottomNavigationView 反映的 number/Index,然后 我们设置焦点菜单项(假设您的 BottomNavigationView 有用于显示的菜单项)
if(page == 1) {
currentselect = new Pending();
bottomNavigationView.getMenu().getItem(0).setChecked(true);
}
这回答了上面的问题。通过调用 :
上面的帖子数量可以很好地处理其余的 Fragment 开关
bottomNavigationView.setOnNavigationItemSelectedListener(navListener);
然后像这样:
private BottomNavigationView.OnNavigationItemSelectedListener navListener =
new BottomNavigationView.OnNavigationItemSelectedListener(){
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment selectedFrag = null;
switch (item.getItemId()) {
case R.id.pending:
selectedFrag = new Pending();
break;
case R.id.onTransmit:
selectedFrag = new inTransmit();
break;
case R.id.complete:
selectedFrag = new Complete();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.select_field, selectedFrag).commit();
return true;
}
};
注意: 使用 BottomNavigationView 和 ContentFrameLayout 非常经济,与使用 ViewPager 和 Tablayout
bottomnavigation.BottomNavigationView 中初始选定项的 Kotlin 代码:
bottom_navigation_view.selectedItemId = R.id.navigation_item_messages
执行BottomNavigationView.OnNavigationItemSelectedListener
并在初始化时设置selectedItemId
。
this.bottomNavigationView.setOnNavigationItemSelectedListener {
val targetFragment = when (menuItem.itemId) {
R.id.action_home -> {
HomeFragment()
}
R.id.action_post -> {
PostFragment()
}
R.id.action_settings -> {
SettingsFragment()
}
else -> null
}
targetFragment?.let {
this.activity?.supportFragmentManager?.transaction {
replace(R.id.containerLayout, it, it.javaClass.simpleName)
}
}
true
}
this.bottomNavigationView.selectedItemId = R.id.action_home
您可以通过添加虚拟菜单项来实现此效果 作为分配给 BottomNavigationView 的菜单中的第一项 并将此项设置为不可见。然后在 您的重新选择处理程序,将 setSelectedItem(dummy) 调用到虚拟 物品。因此,可见的菜单项将表现为 “虚拟”切换。我花了比应该做的更多的工作 弄清楚这个。你必须这样做才能 重新选择完成后调用 setSelectItem:
@Override
public void onNavigationItemReselected(@NonNull MenuItem item) {
anyView.post(new Runnable() {
@Override
public void run() {
navigationView.setSelectedItemId(R.id.action_dummy);
}
}
});
在导航中设置初始页面 - Jetpack Navigation
在导航图中设置属性“startDestination”,值应该是给片段的id。
<navigation
app:startDestination="@+id/navigation_movies"
...
>
<!-- default page -->
<fragment
android:id="@+id/navigation_movies"
...`enter code here`
/>
<fragment
android:id="@+id/navigation_tv_shows"
...
/>
</fragment>