Reputation: 126
I'm actually working on an app which includes navigation view and the app is running on androidx, I tried all the possible solutions from my point of view. Actual problem is onNavigationItemSelected is not calling even though I implemented NavigationView.OnNavigationItemSelectedListener to my base class.
My HomeActivity class which implements NavigationView.OnNavigationItemSelectedListener is
public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private static final String TAG = "checkDate";
ActivityHomeBinding binding;
Context context;
LinearLayoutManager layoutManager;
HomeAdapter adapter;
ActionBarDrawerToggle drawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
context = this;
binding = DataBindingUtil.setContentView(this, R.layout.activity_home);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
drawerToggle = new ActionBarDrawerToggle(this, binding.drawer, R.string.open, R.string.close);
binding.drawer.addDrawerListener(drawerToggle);
drawerToggle.syncState();
drawerToggle.setDrawerIndicatorEnabled(false);
drawerToggle.setHomeAsUpIndicator(R.drawable.ic_menu_black_24dp);
List<EventDay> events = new ArrayList<>();
Calendar calendar = Calendar.getInstance();
events.add(new EventDay(calendar, R.drawable.ic_event_black_24dp));
binding.homeLayout.calendarView.setEvents(events);
binding.homeLayout.calendarView.setOnDayClickListener(eventDay -> {
Toast.makeText(context, eventDay.getCalendar().getTime().toString(), Toast.LENGTH_SHORT).show();
Log.d(TAG, "onDayClick: "+Calendar.DAY_OF_MONTH);
});
layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(RecyclerView.VERTICAL);
adapter = new HomeAdapter(context);
binding.homeLayout.rvEvents.setNestedScrollingEnabled(true);
binding.homeLayout.rvEvents.setHasFixedSize(true);
binding.homeLayout.rvEvents.setAdapter(adapter);
binding.homeLayout.rvEvents.setLayoutManager(layoutManager);
binding.navView.setNavigationItemSelectedListener(this);
ItemClickSupport.addTo(binding.homeLayout.rvEvents).setOnItemClickListener((recyclerView, position, v) -> {
Intent intent = new Intent(context, SiteReachActivity.class);
startActivity(intent);
});
}
@Override
public void onBackPressed() {
if (binding.drawer.isDrawerOpen(GravityCompat.START)){
binding.drawer.closeDrawer(GravityCompat.START);
return;
}
super.onBackPressed();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home){
binding.drawer.openDrawer(GravityCompat.START);
}
return true;
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
int id = menuItem.getItemId();
Intent intent;
switch (id){
case R.id.menu_profile:
intent = new Intent(context, ProfileActivity.class);
startActivity(intent);
break;
case R.id.menu_dashboard:
break;
case R.id.menu_history:
intent = new Intent(context, HistoryActivity.class);
startActivity(intent);
break;
case R.id.menu_TADA:
break;
case R.id.menu_logOut:
break;
}
return true;
}
}
And the layout file is
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<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"
android:background="@color/white"
app:headerLayout="@layout/nav_header_main"
app:itemIconTint="@color/colorPrimary"
app:menu="@menu/activity_main_drawer"/>
<include
android:id="@+id/home_layout"
layout="@layout/home_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.drawerlayout.widget.DrawerLayout>
</layout>
And the layout file for activity_main_drawer is
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_profile"
android:icon="@drawable/user"
android:title="@string/user"/>
<item android:id="@+id/menu_dashboard"
android:icon="@drawable/home"
android:title="Dashboard"/>
<item android:id="@+id/menu_history"
android:icon="@drawable/history"
android:title="History"/>
<item android:id="@+id/menu_TADA"
android:icon="@drawable/wallet"
android:title="TADA"/>
<item
android:id="@+id/menu_logOut"
android:icon="@drawable/ic_power_settings_new_black_24dp"
android:title="Logout"/>
</menu>
In case anything more needed plese do comment. TIA
Upvotes: 2
Views: 1433
Reputation: 1112
If you are using androidX then you have to use the NavController for navigation through fragments.
I will post the code I have tried
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
NavController mNavController;
Navigation mNavigation;
BottomNavigationView mBottomNavigationView;
NavigationView mNavigationView;
DrawerLayout mDrawerLayout;
Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
mDrawerLayout = findViewById(R.id.drawer_layout);
mBottomNavigationView = findViewById(R.id.bottom_navigation_view);
mNavigationView = findViewById(R.id.navigation_view);
//mNavController = Navigation.findNavController(this,R.id.host_fragment);
mNavController = Navigation.findNavController(this,R.id.host_fragment);
NavigationUI.setupWithNavController(mBottomNavigationView,Navigation.findNavController(this,R.id.host_fragment));
NavigationUI.setupActionBarWithNavController(this, mNavController, mDrawerLayout);
NavigationUI.setupWithNavController(mNavigationView,mNavController);
mNavigationView.setNavigationItemSelectedListener(this);
//NavigationUI.setupActionBarWithNavController(this,Navigation.findNavController(this,R.id.host_fragment));
}
@Override
public boolean onSupportNavigateUp() {
/*return mNavController.popBackStack(R.id.host_fragment,false);*/
return NavigationUI.navigateUp(Navigation.findNavController(this, R.id.host_fragment), mDrawerLayout);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onBackPressed() {
NavController navController = Navigation.findNavController(this, R.id.host_fragment);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.nav_first) {
finishAffinity();
} else {
mNavController.popBackStack(R.id.nav_first, false);
}
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.home:
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
mDrawerLayout.closeDrawers();
int id = menuItem.getItemId();
switch (id){
//Nav drawer items
case R.id.profile:
mNavController.navigate(R.id.profile);
break;
case R.id.features:
mNavController.navigate(R.id.features);
break;
case R.id.signOut:
finishAffinity();
break;
}
return true;
}
}
You need to have the host fragment where you need to implement the fragments in the activity layout where you are implementing the Navigation
activity_main.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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/white"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="10">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/toolbar_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="8"
android:gravity="center"
android:padding="10dp"
android:text="@string/jetpack_example"
android:textColor="#000"
android:textSize="15sp" />
<ImageView
android:id="@+id/search_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="2"
android:padding="10dp"
android:src="@drawable/about_icon" />
</LinearLayout>
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:itemBackground="@android:color/white"
app:labelVisibilityMode="selected"
app:layout_constraintBottom_toBottomOf="@+id/host_fragment"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/menu_drawer" />
<fragment
android:id="@+id/host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_graph"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/navigation_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/nav_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
Next you need to have navigation graph for the navigation and using the arguments.You can also implement actions.Create a navigation folder and implement the below implementing the fragment when you click on the particular item.
navigation_graph.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/navigation_graph"
app:startDestination="@id/nav_first">
<fragment
android:id="@+id/nav_first"
android:name="com.escapadetechnologies.jetpacknavigationexample.Fragments.FirstFragment"
android:label="@string/first"
tools:layout="@layout/fragment_first" />
<fragment
android:id="@+id/nav_second"
android:name="com.escapadetechnologies.jetpacknavigationexample.Fragments.SecondFragment"
android:label="@string/second"
tools:layout="@layout/fragment_second" />
<fragment
android:id="@+id/nav_third"
android:name="com.escapadetechnologies.jetpacknavigationexample.Fragments.ThirdFragment"
android:label="@string/third"
tools:layout="@layout/fragment_third" />
<fragment
android:id="@+id/nav_fourth"
android:name="com.escapadetechnologies.jetpacknavigationexample.Fragments.FourthFragment"
android:label="@string/fourth"
tools:layout="@layout/fragment_fourth" />
<fragment
android:id="@+id/profile"
android:name="com.escapadetechnologies.jetpacknavigationexample.Fragments.ProfileFragment"
android:label="@string/profile"
tools:layout="@layout/fragment_profile" />
<fragment
android:id="@+id/features"
android:name="com.escapadetechnologies.jetpacknavigationexample.Fragments.FeaturesFragment"
android:label="@string/features"
tools:layout="@layout/fragment_features" />
It is very handy and with the androidx lot of boilerplate code can be avoided. If you have any doubts you can comment on my answer.
Upvotes: 3