[英]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
。 据我了解,这意味着每次我从一个活动导航到另一个活动时,都会再次执行MenuActivity
的OnCreate
。 我在该方法中从 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.