CoordinatorLayout messing up setError popup position - android

I'm facing an issue with EditText setError popup position.
I'm using the following code in to create the layout:
activity_profile.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=".ProfileActivity"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout android:layout_height="wrap_content"
android:layout_width="match_parent" android:theme="#style/AppTheme.AppBarOverlay">
<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/profile" />
</android.support.design.widget.CoordinatorLayout>
profile.xml
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".ProfileActivity"
tools:showIn="#layout/activity_profile">
<EditText
android:id="#+id/etProfileName"
android:layout_width="match_parent"
android:layout_height="50dp"
android:capitalize="words"
android:hint="#string/et_hint_profile_name"
android:textAlignment="center" />
</RelativeLayout>
What I have tried
If I change the android.support.design.widget.CoordinatorLayout with LinearLayout the setError issue won't happen, but that will change the status bar color to white one and my UI is looking odd.
I'm new to Android programming and not sure what's going on, please help me.

What worked for me is an extra LinearLayout in activity_main.xml (yes, there):
<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:id="#+id/activityRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.biptest.MainActivity">
<!-- *** THIS ONE *** -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/appbar"
android:theme="#style/AppTheme.AppBarOverlay">
<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" /> <!-- FRAGMENT(S) INSIDE -->
</LinearLayout>
<!-- *** BUT LEAVE THE FAB ALONE *** -->
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_dialog_email"
android:visibility="gone"
/>
</android.support.design.widget.CoordinatorLayout>
This also works around the layout bug that shows when you toggle visibility of a view in a fragment.
And the next problem is white-on-white error messages in the popup on Android 2.x (link)

I had the same problem. Testing a little bit the UI, I found that the problem appeared when the EditText widget gets the focus programatically to show the error, in my case calling .requestFocus(), but when focusing on the widget again manually the popup appeared correctly.
So my workaround was to delay the call to .requestFocus() in a Runnable (simulating a user clicking on the EditText widget).
Here is the code:
if (mFocusView != null) mFocusView.clearFocus(); // clear current focus. Needed to simulate a new "manual" focus
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
final Handler handler = new Handler();
final boolean b = handler.postDelayed(new Runnable() {
#Override
public void run() {
mFocusView.requestFocus(); // request focus
}
}, 1); // only delay 1 milisecond
}
});
mFocusView is the current EditText view to show an error.
Depending on your use case you may need to handle the focus when the keyboard is dismissed, as it makes the popup appear in the wrong position again.
Don't know if this will solve your problem. Hope it helps while Google solves this problem.

This was an Android bug and it is now fixed.
Reference : https://code.google.com/p/android/issues/detail?id=193793

Actually, the problem is not the CoordinatorLayout, but AppBarLayout.ScrollingViewBehavior. As a simple workaround you can remove the line app:layout_behavior="#string/appbar_scrolling_view_behavior" and add android:layout_marginBottom="?attr/actionBarSize" to your nested view if you don't need nested scroll.

Related

SearchView shifting AppBar permanently upwards?

I am adding a SearchView to the current view at Runtime, like so:
View searchpage = inflater.inflate(R.layout.search_ui, (ViewGroup) view.getParent(), false);
SearchView searchbar = (SearchView) searchpage.findViewById(R.id.searchbar);
//ViewGroup of current layout
parent.addView(searchbar);
This code is executed when a button is pressed.
This code works, however if the SearchView is entered and exited, the animation that shifts the AppBar upwards works however upon exiting the AppBar is not reset. The SearchView is not embedded in the AppBar, and I am not attempting to do this. I would like the SearchView to be below the AppBar as it is.
The AppBar is defined in a separate xml file. I am switching between multiple views using a ViewPager.
Here are some screenshots:
Before SearchView is Tapped
After SearchView is Tapped/Entered and Exited
The SearchBar is defined in xml like so:
<android.support.v7.widget.SearchView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/searchbar"
android:layout_below="#+id/view"
android:iconifiedByDefault="false"
android:queryHint="Search"
android:layout_centerHorizontal="true">
</android.support.v7.widget.SearchView>
The AppBar is defined like so:
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
Any help would be appreciated, I am at a loss as to why the AppBar won't slide back down automatically.
EDIT: I was concurrently having issues with a set of buttons not appearing at the bottom of the screen. I figured out that they were being drawn underneath the nav bar. I believe that when the SearchView was being entered, the toolbar was being pushed upwards to accommodate for the set of buttons at the absolute bottom of the screen. I added padding to the layout and I believe that was the solution to the issue.
Thanks,
-n.parker
Try something like this;
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorWhite"
android:orientation="vertical"
tools:context="Your-Activity-name-like-com.xyz.MainActivity">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<android.support.v7.widget.SearchView
android:id="#+id/action_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:clickable="true"
android:title="#string/action_search">
</android.support.v7.widget.SearchView>
And inside the "layout" folder, create a toolbar.xml that looks like this;
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:minHeight="?attr/actionBarSize"/>
Now you can reuse this toolbar in other activities too, id needed.

BottomNavigationView hides when scrolling up instead of down

The new BottomNavigationView from support library v25.0.0 is supposed to hide when scrolling down, in order to see all the items from a list. However, in my testing scenario, the view hides when scrolling up. Any ideas what can cause this reverse behavior?
The inner_fragment is set up as a Fragment inserted inside the activity_main_framelayout_content Framelayout. XML layouts below:
main_activity.xml:
<android.support.design.widget.CoordinatorLayout
android:id="#+id/activity_main_coordinatorlayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/activity_main_appbarlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/activity_main_toolbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
android:background="?attr/colorPrimary"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways">
<include layout="#layout/activity_main_spinner_layout"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/activity_main_framelayout_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:fitsSystemWindows="true"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/activity_main_framelayout_navigation_drawer"
android:layout_width="#dimen/drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:background="#color/color_black_700"/>
inner_fragment.xml:
<FrameLayout 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">
<FrameLayout
android:id="#+id/inner_fragment_framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/inner_fragment_bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:menu="#menu/inner_fragment"
app:itemBackground="#drawable/bg_bottom_navigation"
app:itemIconTint="#color/ic_bottom_navigation"
app:itemTextColor="#color/ic_bottom_navigation"/>
</FrameLayout>
A simple solution is to just add an offset listener to appbarlayout. Works perfectly for me.
So something like this:
((AppBarLayout)toolbar.getParent()).addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
mNavigationBar.setTranslationY(verticalOffset*-1);
}
});
This release of BottomNavigationView is missing scrolling behavior to work out of the box as specified in the guidelines.
I wrote an article on what's missing and how you can fix it. This includes implementing scrolling behavior of the BottomNavigationView in CoordinatorLayout.
My solution was to replace the FrameLayout with a NestedCoordinatorLayout from here https://stackoverflow.com/a/37660246/2233621 and then add the BottomNavigationBehavior from Nikola's blog post https://medium.com/#nullthemall/bottomnavigationview-missing-pearls-eaa950f9ad4e#.p1i01wwui that way your bottom navigation behaviour can listen for nested scrolling of the fragment inside the NestedCoordinatorLayout
I believe you could use another view that implements NestedScrollParent + NestedScrollChild for the same behaviour.

FloatingActionButton, layout_anchor and layout_gravity

A bit of a newbie here. I'm about two months into Android development, but I have years of development experience in other environments.
Okay. I have a FloatingActionButton which was not showing up where I expected it or wanted it. It's inside a CoordinatorLayout, along with an AppBarLayout/Toolbar, and following a ListView.
Here is the layout:
<?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:id="#+id/fragment_coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".ViewVehicleList">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:title="Vehicle List"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
</android.support.design.widget.AppBarLayout>
<ListView
android:id="#+id/Vehicle_ListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:background="#FFFFFF"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</ListView>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_AddVehicle"
style="#style/FloatingAddButton"
android:src="#drawable/ic_green_add"
android:layout_gravity="bottom|end"
app:layout_anchor="#id/Vehicle_ListView"
android:onClick="addVehicle"/>
</android.support.design.widget.CoordinatorLayout>
With this layout, the screen looks like this:
My layout_gravity says "bottom|end". I changed it to "bottom|right", but still I got the same result. I've read many tutorials, and researched through Stack Overflow, and have had no luck.
I managed to solve it by removing the anchor listed in the FAB element app:layout_anchor="#id/Vehicle_ListView", which seems to run a counter to what I've read: to use a FAB and position it properly you need to use layout_anchor and layout_gravity. Without the anchor tag, it looks like this:
So here's my question: Why is my anchor screwing up the positioning of my FloatingActionButton? What am I doing wrong?
You just need to add layout_anchorGravity.
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_AddVehicle"
style="#style/FloatingAddButton"
android:src="#drawable/ic_green_add"
android:onClick="addVehicle"
app:layout_anchor="#id/Vehicle_ListView"
app:layout_anchorGravity="bottom|end" />
if you use constraint layout, you should set fab's top and bottom constraint to your desired layout edge like this. for example I have a cardview witch I want to anchor fab to it
<androidx.cardview.widget.CardView
android:id="#+id/mix_video_cardView/>
<com.google.android.material.floatingactionbutton.FloatingActionButto
app:layout_constraintTop_toBottomOf="#+id/mix_video_cardView"
app:layout_constraintBottom_toBottomOf="#+id/mix_video_cardView"
app:layout_constraintStart_toStartOf="#+id/mix_video_cardView"
app:layout_constraintEnd_toEndOf="#+id/mix_video_cardView"
/>

View jumps and blinks instantly, though animateLayoutChanges="true"

I am making my TabLayout animated by using android:animateLayoutChanges="true" in AppBarLayout. But when I set TabLayout.setVisibility(View.GONE), container for my fragment goes up to ActionBar instantly for a few milliseconds. And then it returns to the end of TabLayout and goes up with it to the ActionBar. I explained this on following gif.
The buttons Theory and Practice are behind the TabLayout for some reason but when hiding TabLayout animation starts FrameContainer that holds my view sticks to the bottom of TabLayout.
I have recorded a video that demostrates this behavior. Dropbox video player skip some frames and animation seems nice. Thats why, to notice the bug, you can load video on computer and watch 5 and 11 second in high quality. Video
My LayoutXML:
<android.support.design.widget.CoordinatorLayout
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:orientation="vertical">
<SurfaceView
android:layout_width="0px"
android:layout_height="0px"/>
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:visibility="gone"
app:tabGravity="fill"
app:tabIndicatorColor="#android:color/white"
app:tabMode="fixed"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<!--
This FrameLayout holds my fragments.
-->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/outer_background">
<ProgressBar
android:id="#+id/main_load_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true"/>
</FrameLayout>
<include
android:id="#+id/left_drawer_full"
layout="#layout/navigation_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"/>
</android.support.v4.widget.DrawerLayout>
</android.support.design.widget.CoordinatorLayout>
In addition I am using 23.2.1 support libraries.
How can I fix this blinks and jumps?
Try adding android:animateLayoutChanges="true" to your view with
app:layout_behavior="#string/appbar_scrolling_view_behavior
so that would be your DrawerLayout. Then enable Transition Type LayoutTransition.CHANGING on it like so:
ViewGroup layout = (ViewGroup) findViewById(R.id. drawer_layout);
LayoutTransition layoutTransition = layout.getLayoutTransition();
layoutTransition.enableTransitionType(LayoutTransition.CHANGING);
related: https://stackoverflow.com/a/22573099/1363742
I wasted all day to investigate this problem.
And I have found one possible solution for this problem.
Now i change visibility by this code
mTabLayout.postDelayed(new Runnable() {
#Override
public void run() {
switch (newMode) {
case MODE_CONTENTS:
mTabLayout.setVisibility(mContents.isTheoryAvailable() ? View.VISIBLE : View.GONE);
break;
default:
findViewById(R.id.content_frame).setVisibility(View.INVISIBLE);
mTabLayout.setVisibility(View.GONE);
findViewById(R.id.content_frame).setVisibility(View.VISIBLE);
}
}
}, 200);
It works well and views are not blinking now. But on old androids the bug is still presents.

Android: visibility:gone element is shortly visible

Hy,
I have the problem that a FloatingActionButton with visibility set to GONE shows up very short when opening the activity and then disappears as it should.
The button is used at a later point, that's why it must be invisible. At the moment though if somebody is fast enough (mainly on older devices/android versions), he can click the button before he should be allowed to.
My layout is pretty much the same as it was created by android studio, only that I set the visibility to gone:
<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.fallenritemonk.ludus.game.GameActivity">
<android.support.design.widget.AppBarLayout android:layout_height="wrap_content"
android:layout_width="match_parent" android:theme="#style/AppTheme.AppBarOverlay">
<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_game" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/add_fields_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/ic_add"
android:visibility="gone" />
</android.support.design.widget.CoordinatorLayout>
content_game.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.fallenritemonk.ludus.game.GameActivity">
<GridView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fieldGrid"
android:numColumns="9"
android:verticalSpacing="5dp"
android:horizontalSpacing="5dp" />
</RelativeLayout>
I have no clue where the problem could be. I tried also setting it INVISIBLE instead of GONE. Since I cannot determine if the user was fast enough to press the button before he should have been able to, the only possibility to prevent him from doing so is to remove this "flashing up of the FAB"-bug.
If any more information needed feel free to ask!!!
Thanks for your help
Just add fab.hide() to your onCreate() method (or onCreateView() if using Fragment). You can remove visibility tag from xml as it will no longer be needed. If you want to show your FAB, use fab.show();
Have no reputation enough to comment, so I answer here
Try to place tag android.support.design.widget.FloatingActionButton before include. If it does not help, please, provide content of content_game
Try disabling the anchor id and after that set the visibility. It should work.
Try the following:
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
CoordinatorLayout.LayoutParams param = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
param.setBehavior(null);
param.setAnchorId(View.NO_ID);
fab.setLayoutParams(param);
fab.setVisibility(View.GONE);
// TO show again
param.setBehavior(new FloatingActionButton.Behavior());
param.setAnchorId(R.id.appbar);
fab.setVisibility(View.VISIBLE);
The problem seems to have been solved by simply updating the android support design library. I now have updated it from 23.0.1 to 23.1.1!

Categories

Resources