Java 以MVVM方式使用片段的BottomNavigationView
我们有底部导航选项卡(4),每个选项卡中都有片段。任何人都可以帮助(给出想法)如何以MVVM的方式设计结构,并保持每个选项卡的片段状态。我知道这不是一个提出糟糕问题的地方,但我正在寻找概念性的建议。以最好的方式完成它 Google(通过)宣布发布Android设计支持库的v25,其中包括新的BottomNavigationView menu.xml 在菜单资源文件中定义导航项(片段项)Java 以MVVM方式使用片段的BottomNavigationView,java,android,mvvm,deeplink,Java,Android,Mvvm,Deeplink,我们有底部导航选项卡(4),每个选项卡中都有片段。任何人都可以帮助(给出想法)如何以MVVM的方式设计结构,并保持每个选项卡的片段状态。我知道这不是一个提出糟糕问题的地方,但我正在寻找概念性的建议。以最好的方式完成它 Google(通过)宣布发布Android设计支持库的v25,其中包括新的BottomNavigationView menu.xml 在菜单资源文件中定义导航项(片段项) <?xml version="1.0" encoding="utf-8"?> <menu x
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_item1"
android:icon="@drawable/icon1"
android:title="Menu1"
/>
<item
android:id="@+id/action_item2"
android:icon="@drawable/icon2"
android:title="Menu2"/>
<item
android:id="@+id/action_item3"
android:icon="@drawable/icon3"
android:title="Menu3" />
<item
android:id="@+id/action_item4"
android:icon="@drawable/icon4"
android:title="Menu4" />
</menu>
MainActivity.java
public class MainActivity extends AppCompatActivity {
bottomNavigationView = (BottomNavigationView)findViewById(R.id.navigation);
//If you want to remove slide animation of bottomview with Helper Class
BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);
Menu m = bottomNavigationView.getMenu();
bottomNavigationView.setOnNavigationItemSelectedListener
(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
if (getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setHomeButtonEnabled(false);
}
android.app.Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.action_item1:
selectedFragment = Fragment1.newInstance();
toolbar.setTitle("Fragment1");
break;
case R.id.action_item2:
selectedFragment = Fragment2.newInstance();
toolbar.setTitle("Fragment2");
break;
case R.id.action_item3:
selectedFragment = Fragment3.newInstance();
toolbar.setTitle("Fragment3");
break;
case R.id.action_item4:
selectedFragment = Fragment4.newInstance();
toolbar.setTitle("Fragment4");
break;
default:
selectedFragment = Fragment1.newInstance();
toolbar.setTitle("Fragment1");
break;
}
android.app.FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, selectedFragment);
transaction.commit();
return true;
}
});
//Manually displaying the first fragment - one time only
android.app.FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, Fragment1.newInstance());
transaction.commit();
}
此帮助器类用于删除移动动画
static class BottomNavigationViewHelper {
public static void removeShiftMode(BottomNavigationView view) {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
try {
Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
shiftingMode.setAccessible(true);
shiftingMode.setBoolean(menuView, false);
shiftingMode.setAccessible(false);
for (int i = 0; i < menuView.getChildCount(); i++) {
BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
item.setShiftingMode(false);
// set once again checked value, so view will be updated
item.setChecked(item.getItemData().isChecked());
}
} catch (NoSuchFieldException e) {
Log.e("ERROR NO SUCH FIELD", "Unable to get shift mode field");
} catch (IllegalAccessException e) {
Log.e("ERROR ILLEGAL ALG", "Unable to change value of shift mode");
}
}
}
使用最新的拱组件,生活变得轻松多了。 现在,只要我在ViewModel中实现业务逻辑(状态),我就不必关心如何保持我的片段存活,我很好。它在配置更改后仍然有效。 如果你问我,当系统为了获取内存而关闭你的应用程序时,
使用最新的ViewModel,您可以在ViewModel中管理此功能。因此,您可以消除视图和ViewModel之间的额外样板代码/通信代码,以传递savedState(例如id、url等)。这将是真正的关注分离。感谢您的努力,但是如何保持片段的状态。您可以指定片段状态吗?你到底想要什么。我想在创建后将所有4个片段保留在内存中,以避免每次用户在选项卡之间切换时都重新创建片段。这甚至不是MVVM。这只是实现底部导航的一种方法,但与我提出的问题无关。问题更多的是架构性的。寻找相同的信息,你是如何做到的?@ateebahmed我认为这一点可以为你树立一个很好的榜样。
static class BottomNavigationViewHelper {
public static void removeShiftMode(BottomNavigationView view) {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
try {
Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
shiftingMode.setAccessible(true);
shiftingMode.setBoolean(menuView, false);
shiftingMode.setAccessible(false);
for (int i = 0; i < menuView.getChildCount(); i++) {
BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
item.setShiftingMode(false);
// set once again checked value, so view will be updated
item.setChecked(item.getItemData().isChecked());
}
} catch (NoSuchFieldException e) {
Log.e("ERROR NO SUCH FIELD", "Unable to get shift mode field");
} catch (IllegalAccessException e) {
Log.e("ERROR ILLEGAL ALG", "Unable to change value of shift mode");
}
}
}
public class Fragmen1 extends android.app.Fragment {
public static Fragmen1 newInstance() {
Fragmen1 fragment = new Fragmen1();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
}