【问题标题】:BottomNavigationView with fragments in MVVM way以 MVVM 方式带有片段的 BottomNavigationView
【发布时间】:2017-08-25 09:42:25
【问题描述】:

我们有底部导航标签(4),每个标签都有片段。任何人都可以帮助(给出想法)如何以 MVVM 方式设计结构并保持每个选项卡的片段状态。我知道这不是提出糟糕问题的地方,但我正在寻找概念性建议。以最好的方式完成它。

【问题讨论】:

  • 寻找相同的信息,你是怎么做到的?
  • @ateebahmed 我认为这个特别的repo 可能是你的好例子。
  • 我用这个解决了我的问题。我希望它对你有用stackoverflow.com/questions/68395330/…

标签: java android mvvm deeplink


【解决方案1】:

使用最新的拱形组件,生活变得如此轻松。 现在,只要我在 ViewModel 中实现业务逻辑(状态),我就不必关心让我的片段保持活力,我很好。它在配置更改后仍然存在。 如果你问我什么时候系统会杀死你的应用程序以获取内存, 使用最新的 ViewModel feature,您可以在 ViewModel 中管理它。因此,您可以消除 View 和 ViewModel 之间的额外样板代码/通信代码以传递 saveState(例如 id、url 等)。这将是真正的关注点分离。

【讨论】:

    【解决方案2】:

    Google(通过Nick Butcher‏)宣布发布Android Design Support Library v25,其中包括新的BottomNavigationView。

    menu.xml

    在菜单资源文件中定义导航项(Fragments项)

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

    activity_main.xml

    将实际的BottomNavigationView 添加到布局中。

      <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:local="http://schemas.android.com/apk/res-auto"
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize"
            android:background="@color/colorPrimary"
            local:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            local:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    
    
        <FrameLayout
            android:id="@+id/frame_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/navigation"
            android:layout_below="@id/toolbar"
            android:animateLayoutChanges="true">
    
        </FrameLayout>
    
        <android.support.design.widget.BottomNavigationView
            android:id="@+id/navigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:background="@drawable/rbtn_selector"
            android:paddingTop="@dimen/_2sdp"
            app:itemIconTint="@drawable/selector_bottom"
            app:itemTextColor="@drawable/selector_bottom"
            app:elevation="@dimen/_8sdp"
            app:menu="@menu/menu"/>
    
    
    </RelativeLayout>
    

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

    这个用于移除移动动画的 Helper 类

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

    每个片段作为一个菜单项 **Fragmen1.java**

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

    【讨论】:

    • 感谢 Harsh 的努力,但是保持片段的状态呢。
    • 你能指定片段状态吗?你到底想要什么。
    • 我想在创建后将所有 4 个片段保留在内存中,以避免每次用户在选项卡之间切换时重新创建片段
    • 这甚至不是 MVVM。
    • 这只是实现底部导航的一种方式,但与我提出的问题无关。这些问题更具架构性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2022-10-12
    • 1970-01-01
    • 2020-03-31
    • 1970-01-01
    相关资源
    最近更新 更多