[英]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.