私は何をしていますか?
Androidx Navigation Drawer(<com.google.Android.material.navigation.NavigationView>
)を使用しようとしています。ドキュメンテーション Here を読みました。これは、アイテムの選択を処理するためにsetNavigationItemSelectedListener
を使用できることを示しています。
注:JetPackのナビゲーションコンポーネントも使用しています。
以下は:main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/drawer_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="@color/colorPrimary"
Android:theme="@style/ThemeOverlay.AppCompat.Dark" />
<fragment
Android:id="@+id/nav_Host_fragment"
Android:name="androidx.navigation.fragment.NavHostFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</LinearLayout>
<com.google.Android.material.navigation.NavigationView
Android:id="@+id/navigationView"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_gravity="start"
Android:fitsSystemWindows="true"
app:menu="@menu/drawer_menu" />
</androidx.drawerlayout.widget.DrawerLayout>
ここに:MainActivity.Java
import Android.os.Bundle;
import Android.view.MenuItem;
import Android.widget.Toast;
import com.google.Android.material.navigation.NavigationView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;
public class MainActivity extends AppCompatActivity {
public Toolbar toolbar;
public DrawerLayout drawerLayout;
public NavController navController;
public NavigationView navigationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupNavigation();
}
// Setting Up One Time Navigation
private void setupNavigation() {
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
drawerLayout = findViewById(R.id.drawer_layout);
navigationView = findViewById(R.id.navigationView);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();
return false;
}
});
navController = Navigation.findNavController(this, R.id.nav_Host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout);
NavigationUI.setupWithNavController(navigationView, navController);
}
@Override
public boolean onSupportNavigateUp() {
return NavigationUI.navigateUp(drawerLayout, Navigation.findNavController(this, R.id.nav_Host_fragment));
}
@Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
}
状況:
すべてが正常に表示され、実行時にDrawer
を取得し、Hamburger
も取得します。メニュー項目でNavigationView
を表示すると正常に動作します。
以下は:drawer_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
<group Android:checkableBehavior="single">
<item
Android:id="@+id/first"
Android:icon="@mipmap/ic_launcher"
Android:title="First" />
<item
Android:id="@+id/second"
Android:icon="@mipmap/ic_launcher"
Android:title="Second" />
<item
Android:id="@+id/third"
Android:icon="@mipmap/ic_launcher"
Android:title="Third" />
</group>
</menu>
問題:
メニュー項目をタップすると、クリックイベントa.k.a onNavigationItemSelected
に応答しません。 MainActivity.Java
を見るとわかるように、Toast
は表示されず、スイッチ内で機能するメニューIDもありません。
これを実現するために、多くの例と異なる方法を試してきました。
選択したイベントにメニュー項目を応答させる方法はありますか?
これに関する詳細が必要な場合は、以下のコメントを入力してください。
ヘルプありがとうございます。
私はそれを考え出しました。
誰かがそれを必要とする場合に備えて、ここに投稿しています。
これの代わりに:
navigationView = findViewById(R.id.navigationView);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();
return false;
}
});
navController = Navigation.findNavController(this, R.id.nav_Host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout);
NavigationUI.setupWithNavController(navigationView, navController);
変更後:
navigationView = findViewById(R.id.navigationView);
navController = Navigation.findNavController(this, R.id.nav_Host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout);
NavigationUI.setupWithNavController(navigationView, navController);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();
return false;
}
});
onNavigationSelector
をアタッチする前にすべてを構成する必要があるかもしれません。
順序を切り替えることの完全な副作用を理解していないかもしれません。
NavigationUI.setupWithNavController(navigationView, navController); // Line 1
navigationView.setNavigationItemSelectedListener({...}) // Line 2
NavigationUI
は、NavigationView.OnNavigationItemSelectedListener
をLine1
でNavigationView
に内部的に接続します。 Line 2
のカスタムリスナーでそのリスナーをオーバーライドしています。
つまり、navController
は機能せず、カスタムリスナーですべてのナビゲーションアクションを手動で処理する必要があります。したがって、完全なソリューションは次のようなものになります。
NavigationUI.setupWithNavController(navigationView, navController);
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
// TODO: do stuff
Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();
// You need this line to handle the navigation
boolean handled = NavigationUI.onNavDestinationSelected(menuItem, navController);
if (handled) {
ViewParent parent = navigationView.getParent();
if (parent instanceof DrawerLayout) {
((DrawerLayout) parent).closeDrawer(navigationView);
}
}
return handled;
}
});
注:ナビゲーションアイテムのクリックリスナーをアタッチする以外のことを行うため、カスタムリスナーをアタッチする前にsetupWithNavController
を呼び出すこともできます。
まだ誰かが答えを探している場合、NavigationViewアイテムを処理するためにNavigationControllerだけでなく、NavigationView内で特定のアクションを行うための両方の方法があります。
通常のmenu.xmlファイルのセットアップメニュー項目:
<menu>
<item
Android:id="@+id/fragment_settings"
Android:icon="@drawable/ic_settings"
Android:orderInCategory="3"
Android:title="@string/settings" />
<item
Android:id="@+id/share_app"
Android:icon="@drawable/ic_share"
Android:orderInCategory="4"
Android:onClick="shareApp"
Android:title="@string/share_to_friends" />
<item
Android:id="@+id/fragment_about"
Android:icon="@drawable/ic_info"
Android:orderInCategory="5"
Android:title="@string/about" />
</menu>
最初にonClickメソッド"shareApp"を"share_app"メニュー項目に定義します。次に、アクティビティで次のようなメソッドを作成します。
fun shareApp(item:MenuItem) {
logD("share app clicked!")
val intent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_TEXT, "some text to send...")
type = "text/*"
}
startActivity(Intent.createChooser(intent, "Share app..."))
}
アクティビティのオーバーライドfun onCreate(savedInstanceState:Bundle?)メソッドで、ツールバー、NavigationView、およびDrawerLayoutをNavControllerにアタッチすることを忘れないでください(または必要に応じて)
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupActionBarWithNavController(navController, drawer_layout)
setupWithNavController(nav_view, navController)
setupWithNavController(toolbar, navController, drawer_layout)
}