繁体   English   中英

如何在不每次加载的情况下使用导航抽屉菜单?

[英]How to use the navigation drawer menu without loading it each time?

这更像是一个 Java 问题(在理解如何设置 inheritance 时遇到了一些麻烦)。 我正在尝试向我的应用程序添加一个侧面菜单(可以正常工作)。 我的菜单活动的 class 签名是:

public class MenuActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener

用户登录后,他看到的第一个 window 就是主仪表板。 仪表板活动扩展了菜单活动以获得侧边菜单:

public class DashboardActivity extends MenuActivity 

为了导航到其他活动,我实现了onNavigationItemSelected方法来 select 加载intent (该方法位于MenuActivity中):

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    if (toggle.onOptionsItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        Intent intent = null;
        switch (item.getItemId()) {
            case R.id.lay_dashboard:
                intent = new Intent(this, DashboardActivity.class);
                //intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                break;
            case R.id.lay_settings:
                intent = new Intent(this, SettingsActivity.class);
                //intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                break;
            case R.id.lay_contacts:
                startActivity(new Intent(this, ContactsActivity.class));
                break;
            case R.id.lay_about:
                startActivity(new Intent(this, AboutActivity.class));
                break;
            case R.id.lay_logout:
                mAuth.signOut();
                intent = new Intent(this, MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                break;
        }
        if (intent != null) {
            startActivity(intent);
        }
        drawerLayout.closeDrawer(GravityCompat.START);
        return true;
    }

如您所见,我评论了intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); 作为调试问题的一部分。 我希望导航过程不要开始一个新屏幕,而是移动到它。

MenuActivity中的OnCreate方法也如下所示:


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_menu);

    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeButtonEnabled(true);
    }

    drawerLayout = findViewById(R.id.drawer_layout);
    navigationView = findViewById(R.id.lay_nav_view);

    toggle = new ActionBarDrawerToggle(this, drawerLayout,
            R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawerLayout.addDrawerListener(toggle);
    toggle.syncState();
    navigationView.setNavigationItemSelectedListener(this);

    mAuth = FirebaseAuth.getInstance();
    logged_user = mAuth.getCurrentUser();

    if (logged_user != null) {
        // Get data from firebase in order to set the avatar
        // and user name in the menu
    }
}

protected void setLayoutView(int layout) {
    LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (inflater != null) {
        View contentView = inflater.inflate(layout, null, false);
        drawerLayout.addView(contentView, 0);
    }
}

每个活动都扩展了MenuActivity并在其onCreate方法中执行以下操作:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setLayoutView(R.layout.activity_about); // My method which loads UI
        // other code
    }

因此,如您所见,每个活动都在扩展MenuActivity 据我了解,这意味着每次我从一个活动导航到另一个活动时,都会再次执行MenuActivityOnCreate 我在该方法中从 Firebase 获取数据,以便在菜单顶部设置用户名和头像。 所以每次我从一个活动导航到另一个活动时,它都会一次又一次地获取。 如何使菜单在记录模式下仅加载一次? 另外,感谢所有阅读过这个主题的人(我知道它很长)。

编辑:为了更清楚,我添加了代码的层次结构:

在此处输入图像描述

也许这个问题的解决方案是让MenuActivity成为 singleton class?

我只想在每个活动上都有一个菜单,并且只获取一次数据。

您好,您可以将 NavigationDrawer 与片段一起使用。 这将是最优化且简单的解决方案,您还可以使用 Jetpack 的导航组件来更改目的地。

你可以使用这样的东西,以下布局使用带有两个子视图的 DrawerLayout:一个 NavHostFragment 包含主要内容,一个 NavigationView 用于导航抽屉的内容。

<?xml version="1.0" encoding="utf-8"?>
<!-- Use DrawerLayout as root container for activity -->
<androidx.drawerlayout.widget.DrawerLayout       xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<!-- Layout to contain contents of main body of screen (drawer will slide over this) -->
<fragment
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:id="@+id/nav_host_fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:defaultNavHost="true"
    app:navGraph="@navigation/nav_graph" />

<!-- Container for contents of drawer - use NavigationView to make configuration easier -->
<com.google.android.material.navigation.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true" />

接下来,通过将 DrawerLayout 传递给 AppBarConfiguration 将其连接到导航图,如下例所示:

val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)

接下来,在您的主要活动 class 中,从您的主要活动的 onCreate() 方法调用 setupWithNavController(),如下所示:

override fun onCreate(savedInstanceState: Bundle?) {
setContentView(R.layout.activity_main)

...

val navController = findNavController(R.id.nav_host_fragment)
findViewById<NavigationView>(R.id.nav_view)
    .setupWithNavController(navController)

}

就是这样,然后您可以使用 navContoller 导航到任何片段,并且您需要的 rest 是导航图和在目的地上设置的操作,以便通过这种方式在片段之间导航:

navController.navigate(R.id.actionSettingFragment_to_ContactsFrament)

希望这有点帮助。 我有一个关于此的博客,所以请检查它是否对您有用。

解决您的问题的方法不止一种。 我将为解决方案提供不同的方法。

存储库

要重用您从Firebase获取的数据,需要将其持久化或缓存在您的应用程序中。 通常,您会围绕Firebase实现存储库抽象 该存储库可以是 singleton 并直接将数据缓存在 memory 中。 您只需确保在必要时清理缓存。 MenuActivity不能是单例

意图附加功能

您可以将其作为Intent extras提供,而不是将数据存储在 memory 中。 只要数据存在,只需跳过加载并重用提供的数据。

碎片

您可以使用片段而不是一堆活动。 因此,您将有一个活动,只需替换其中的片段。 使用这种方法,您只需定义一个抽屉布局,您将自动与每个片段一起使用。 这种方法也使您能够使用导航组件

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM