簡體   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