Can't control Android SearchView focus - java

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);
}

Related

Include Menu and ListView in NavigationDrawer at the same time

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!

Default height of toolbar with menu icons

What is the default height of the android toolbar if it contains a menu with icons?
If I use
<android.support.v7.widget.Toolbar android:layout_height="?android:attr/actionBarSize" />
then it looks cut-off like this
If I use
<android.support.v7.widget.Toolbar android:layout_height="wrap_content" />
it works correctly. But it flickers for a moment when initializing the Activity, because it starts smaller and gets adjusted a few miliseconds later.
How to set the correct height right from the beginning?
Update
The full XML looks like this
<android.support.design.widget.CoordinatorLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true"
tools:context=".MyActivity" >
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="#style/AppTheme.AppBarOverlay"
android:fitsSystemWindows="true" >
<android.support.v7.widget.Toolbar
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/myToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay"
android:elevation="#dimen/elevation"
android:fitsSystemWindows="true" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
The menu file looks like this
<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=".MyActivity" >
<item
android:id="#+id/action_save"
android:orderInCategory="100"
android:icon="#drawable/ic_save"
app:showAsAction="always" />
</menu>
In my Activity onCreate() method I do this
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mine);
Toolbar toolbar = (Toolbar) findViewById(R.id.myToolbar);
setSupportActionBar(toolbar);
}
The actionBarSize is correct approach but it looks like your Toolbar is under StatusBar.
To avoid drawing under the Android StatusBar you should disable fitsSystemWindows for your root layout (CoordinatorLayout). If you want to read more, check out this article.
For others, if android:fitsSystemWindows="false" doesn't help you can check if the problem is connected with a transparency of status bar - look for android:windowTranslucentStatus, android:statusBarColor in the project.
Even if you didn't set any of these settings by yourself, these could come from default Android Studio template.

How to remove elevation under the toolbar on all activites

I'm trying to get rid of the elevation under the toolbar by using app:elevation="0dp" but it only works in the main activity xml. When I go to other activities I can still see the elevation, any ideas how to completely get rid of the elevation under my toolbar?
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="com.example.khalid.myapplication3.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
this is what I got after including toolbar in other activities layouts
I ran into this problem before, and it looks like you're using a theme that doesn't extend #style/Theme.AppCompat.NoActionBar. When you're using a Toolbar in your XML layout, you have to hide the default ActionBar so they don't conflict.
In your AndroidManifest.xml, make sure you set the theme for the activity you're having a problem with:
<application ...>
<activity ...
android:theme="#style/AppTheme.NoActionBar">
</activity>
</application>
In your activity XML, just add app:elevation="0dp" attribute to AppBarLayout. This will cause no elevation to all fragments under this activity. Here, I use a frame layout for the fragment containers.
<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.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.blog.BlogActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="#style/AppTheme.AppBarOverlay"
app:elevation="0dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:popupTheme="#style/AppTheme.PopupOverlay" />
// my code: remove for brevity
</RelativeLayout>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/gray"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

RelativeLayout dosen't get OnClick Events because of the DrawerLayout

If I set the order as seen in the picture --> Image
The DrawerLayout is drawn under the content_main
And the DrawerLayout dosen't get OnClickEvents
If I set The Order: first content_main then drawer_layout
The DrawerLayout is drawn over the content_main but the content_main doesn't get OnClick Events
Here my activity_main.xml
<?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">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/toolbar"
android:clickable="true">
<!--The main content view-->
<!--The navigation drawer-->
<ListView android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#fff"
android:visibility="visible"/>
</android.support.v4.widget.DrawerLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/toolbar"
android:id="#+id/content_main"
android:focusable="false">
</RelativeLayout>
</RelativeLayout>
The Problem is only one of the layouts get OnClickEvents.
How do i do that both Layouts get OnClickEvents.
Sorry for my English.
You should put the content_main into the DrawerLayout as seen in the picture.
Picture
I recently came across something for placeholderview onClick. You have to keep the XML file in the correct layout as well else the onClick on the items wont work.
For example in my faulty layout I had
DrawerLayout ->
FrameLayout (for the side menu) ->
LinearLayout (including my UI).
The correct layout was DrawerLayout then LinearLayout and FrameLayout.
I spent a lot of time on a silly mistake. If anyone knows why that would be the case please reply back. Thank you.

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