Include Menu and ListView in NavigationDrawer at the same time - java

I want to include a Menu with 2-3 fixed items, that will never change and below the menu I want to include a ListView that I can manage dynamically.
I want to do something like the following picture.
When I start the application, I always get the following error:
Process: com.pigmalionstudios.todolist, PID: 7055
java.lang.RuntimeException: Unable to start activity ComponentInfo{...}: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class menu
The corresponding error line in MainActivity.java is:
setContentView(R.layout.activity_main);
Here's the activity_main.xml layout.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="#layout/nav_header_main" />
<include layout="#menu/drawer_menu"/>
<ListView
android:id="#+id/list_slidermenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:dividerHeight="1dp"
android:textColor="#424242"/>
</LinearLayout>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
And the drawer_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view"
android:id="#+id/activity_main_drawer"
android:layout_width="match_parent"
android:layout_height="#dimen/nav_header_height"
android:background="#drawable/side_nav_bar"
android:orientation="vertical">
<group android:checkableBehavior="single">
<item
android:id="#+id/add"
android:icon="#drawable/add"
android:title="#string/add" />
<item
android:id="#+id/ToDo"
android:icon="#drawable/pending"
android:title="To Dos" />
<item
android:id="#+id/settings"
android:icon="#drawable/settings"
android:title="Settings" />
</group>
</menu>

You do not really have to get a Menu in your navigation drawer for the desired layout. Just simply add a header view along with your ListView in the navigation drawer.
In my case, I just had to create a custom header for the ListView, then added the header along with the ListView in the navigation drawer. The process might look something like this.
LinearLayout nDrawerListHeader = (LinearLayout) inflater.inflate(R.layout.header_navigation_drawer, container, false);
mDrawerListView.addHeaderView(nDrawerListHeader);
The header_navigation_drawer.xml looked something like this.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/navigation_header_color_white">
<!-- Some other layouts to get the precise view -->
</RelativeLayout>
</LinearLayout>
Then implement the action click by finding the right view inside the header view like this.
Button menuButton = nDrawerListHeader.findViewById(R.id.menu_button_1);
menuButton.setOnClickListener(...);
Hope that helps!

Related

How to access a switch in a menu using ViewBinding?

How to access a switch in a menu using ViewBinding ?
menu/drawer_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:showIn="navigation_view"
>
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_read"
android:title="#string/read"
android:icon="#drawable/ic_read"
/>
<item
android:id="#+id/nav_write"
android:icon="#drawable/ic_write"
android:title="#string/write"
/>
<item
android:id="#+id/nav_theme"
android:icon="#drawable/ic_theme"
android:title="Dark Theme"
app:actionLayout="#layout/theme_switch"
/>
</group>
<item android:title="#string/about">
<menu>
<item
android:id="#+id/nav_source_code"
android:icon="#drawable/ic_source_code"
android:title="#string/source_code"/>
</menu>
</item>
</menu>
theme_switch.xml:
<androidx.appcompat.widget.SwitchCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toggleSwitch"
android:layout_width="fill_parent"
android:layout_height="match_parent" />
activity_home.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".HomeActivity"
android:id="#+id/drawer_layout"
android:fitsSystemWindows="true"
tools:openDrawer="start"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
android:id="#+id/toolBar"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
/>
<FrameLayout
android:id="#+id/fl_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:id="#+id/nav_view"
app:headerLayout="#layout/nav_header"
app:menu="#menu/drawer_menu"
/>
</androidx.drawerlayout.widget.DrawerLayout>
These are my layout files.
In brief, I've created a DrawerLayout inside which I've implemented my menu using NavigationView. One of the menu item is a switch and I want to add a .setOnCheckedChangeListener to this switch.
I've tried accessing the switch like this inside the onCreate() function of my activity:
val switch = binding.navView.menu.findItem(R.id.nav_theme) as SwitchCompat
switch.setOnCheckedChangeListener { _, isChecked ->
}
However, it is throwing an exception that MenuItem cannot be cast into a SwitchCompat.
I don't see any otherway to access this switch.
If you want a switch on your item, use actionViewClass to define the component.
And if a not mistaken you can remove app:actionLayout="#layout/theme_switch"
app:actionViewClass="androidx.appcompat.widget.SwitchCompat"

How to draw a line in menu item atctive

I want to put this little green line in the menu item that is active ... already has to create a shape and a custom style but no success ...
My activity_main_drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_ordem"
android:checked="true"
android:title="Home"/>
<item
android:id="#+id/nav_auto_infracao"
android:title="Payment Profile" />
<item
android:id="#+id/nav_apreensao_deposito"
android:title="Payment history" />
<item
android:id="#+id/nav_doacao"
android:title="My card" />
<item
android:id="#+id/nav_sincronia"
android:title="Frinds" />
</group>
</menu>
Try to use View to draw line.
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#android:color/black" />
One way to solve this is you can highlight the item by calling the following method to detect when to change the visibility and position the view:
onNavigationItemSelected(navigationView.getMenu().getItem(0));
Since you've mentioned you already have a shape and a custom style, put the view (here in this code below, selectedItemBottomView) inside the NavigationView in activity_main or the XML layout file where you've used the activity_main_drawer like this:
activity_main
<?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"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<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"
app:menu="#menu/activity_main_drawer" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="#+id/selectedItemBottomView"
android:layout_width="match_parent"
android:layout_height="10dp"
android:background="#color/green" />
</LinearLayout>
</RelativeLayout>
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
On selected, change the visibility or position as per your requirement:
selectedItemBottomView.setVisibility(View.VISIBLE);
Hope this helps.

Can't control Android SearchView focus

I have an activity with SearchView the problem I am having is
1- I can't get focus when activity starts. I solved this by using searchView.requestFocusFromTouch(); from onCreateOptionsMenu(). I thought this would be default because there is nothing else in this activity? Is this the right way to solve the problem?
2- The real problem is I am using zxing IntentIntegrator and I want to hide the #+id/coordinator_layout when I return from scanner and search is in progress.
I start scanner with this code and onActivityResult() I start the AsyncTask
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setCaptureActivity(BarcodeScannerActivity.class);
integrator.initiateScan();
But when I set R.id.coordinator_layout visibility to GONE or INVISIBLE inside AsyncTask, immediately SearchView gets focus. This happens only after returning from a barcode scanner activity and running AsyncTask with following code in onPreExecute()
CoordinatorLayout coordinatorLayout = activity.findViewById(R.id.coordinator_layout);
coordinatorLayout.setVisibility(View.GONE);
then focus goes to SearchView and softkeyboard pops up. Why is this happening?
Below are the layouts I use.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/toolbar_main"
layout="#layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?android:attr/actionBarSize">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbarLayout"
android:layout_width="match_parent"
android:layout_height="24dp"
android:theme="#style/Theme.Design.Light"
android:visibility="gone">
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
I am inflating this at onCreateOptionsMenu() pretty standard SearchView
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/search"
android:title="#string/app_name"
android:icon="#drawable/ic_search_tint_control_normal_24"
android:showAsAction="always"
android:actionViewClass="android.widget.SearchView" />
</menu>
toolbar_main :
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:elevation="4dp" />
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
Update:
For now I solved the problem by using this in onPreExecute(). I am not sure why and how, but I can still get focus on SearchView by touching on it even after this... strange...
if (searchView != null) {
searchView.clearFocus();
searchView.setFocusable(false);
}

Trying to add a menu to ToolBar

Trying to add a menu to my toolbar, however the code supposedly required to do that is showing errors:
Here's my other code:
res/menu/home_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/settings"
android:title="#string/settings" />
<item
android:id="#+id/dark_theme"
android:title="#string/dark_theme" />
</menu>
Here's the layout with the Toolbar I want to add the menu to:
res/layout/activity_home.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorVeryDark"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar" />
</LinearLayout>
Any idea how I can add my menu to the toolbar?

Left space in Toolbar with SearchView android studio

I'm trying to add a simple SearchView to the toolbar in my app. Everything it's working fine expect for the layout.
There is this "space" between the NavigationDrawer icon and the SearchView.
If I set a title the space is filled with that string, otherwise is empty.
Empty string:
With a string in title:
How do I remove that annoying empty space?
Edit:
I'm using as base code the NavigationDrawer example from Android Studio
main.xml
<menu 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"
tools:context=".MainActivity"
>
<item
android:id="#+id/action_search"
android:icon="#android:drawable/ic_menu_search"
android:title="Search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always" />
</menu>
app_bar_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="ga.musicforyou.musicforyou.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
app:contentInsetEnd="0dp"
app:contentInsetStart="0dp"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
/>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
app:theme="#style/ThemeOverlay.AppCompat.Dark"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:itemTextColor="#FFF"
app:itemIconTint="#FFF"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
Toolbar extends from FrameLayout and you can put views inside it. Like this:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toolbar"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/primary_color">
<SearchView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.v7.widget.Toolbar>
Edit: You put it inside the layout as a menu. It always will be on the right side of the toolbar, because it is a menu. If you want to have a more direct control over views inside a toolbar, just put it there as I did show you.
I have set actionBar.setDisplayHomeAsUpEnabled(true) in code. So only adding SearchView in the toolbar didn't work for me and there is some extra space between Navigation Back and SearchView. I don't have Title in Toolbar. So I customized whole toolbar like this:
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentTop="true" // If parent layout is RelativeLayout
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:contentInsetLeft="0dp" // This is important,
app:contentInsetStart="0dp" // Otherwise there will be extra space on Left Side
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="#+id/ivNavBack"
android:layout_width="56dp"
android:layout_height="56dp"
android:background="#drawable/your_drawable" // Custom background (optional), if you want to have a press effect
android:padding="16dp"
android:src="#drawable/ic_nav_back" /> // You can set icon of your choice here
<android.support.v7.widget.SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="#string/search_view_hint"
app:queryHint="#string/search_view_hint" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
...& in your Activity:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
SearchView searchView = (SearchView) toolbar.findViewById(R.id.searchView);
searchView.onActionViewExpanded(); // Expands searchView by default
// If this is not set, then you will see default search icon and you have to click it to expand SearchView.
Now no need to set actionBar.setDisplayHomeAsUpEnabled(true) in code. Just handle click event of ivNavBack for it.

Categories