Snackbar expands when soft keyboard is showing - android

I'm seeing a problem where the snackbar expands itself to fit the size of a listview on the screen when the soft keyboard is up.
Snackbar with issue
Normal snackbar (keyboard not up)
I've been able to slightly remedy this by setting the height programatically, however then the text disappears from the snackbar and I have no idea how to add it back.
ViewGroup.LayoutParams lp = snackbarView.getLayoutParams();
lp.height = 150;
snackbarView.setLayoutParams(lp);
The snackbar is added as follows:
mConnectionLostSnackbar = Snackbar.make(view, mConnectionLostString, Snackbar.LENGTH_INDEFINITE);
final View snackbarView = mConnectionLostSnackbar.getView();
TextView textView = snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setLineSpacing(0, SNACKBAR_LINE_SPACING_MULTIPLIER);
snackbarView.getViewTreeObserver().addOnPreDrawListener(new NotDismissiblePreDrawListener(snackbarView));
mConnectionLostSnackbar.show();
I would appreciate any thoughts on not having the snackbar expand when the keyboard is up. Thanks in advance.

I have noticed that this only happens when the Snackbar is attached to a CoordinatorLayout that has ANOTHER CoordinatorLayout parent somewhere up the hierarchy. I guess the behaviour of <add as much bottom padding as needed to display the Snackbar above the keyboard> gets duplicated because of the multiple CoordinatorLayouts, and the Snackbar ends up taking the entire screen.
The solution is to attach the Snackbar to the topmost CoordinatorLayout. In my scenario I have an Activity with a CoordinatorLayout content view, that hosts a fragment that has a CoordinatorLayout as the root view. When the fragment needs to display a Snackbar, it attaches it to the Activity's CoordinatorLayout, and then it behaves correctly when the keyboard is displayed. Note that I am now using the AndroidX library instead of the support library, so the behaviour may be slightly different.

The same happened to me, but I could not find the reason of the problem.
To avoid expanding the snackbar, I decided keep it behind the keyboard. This was achieved by adding this line to the desired activity on the manifest
android:windowSoftInputMode="adjustNothing"
I would really like to know why it happens, because on this project I use snackbar a lot and it only breaks on one activity

Just put this property in your Manifest file to your proper activity.
<activity android:name=".YourActivity"
android:windowSoftInputMode="adjustResize"/>

Related

Get the height of the Snackbar in Xamarin.android

I have a ListView shown in the screen and there is a Snackbar which is shown indefinitely. The last element of the ListView is getting covered partially because of the Snackbar.
I am trying to get the height of the Snackbar and give it as a bottom margin programmatically to the ListView.
Snackbar snackbar =
Snackbar.Make(_refresher,"message",Snackbar.LengthIndefinite);
snackbar.Show();
View snackbarView = (Snackbar.SnackbarLayout)snackbar.View;
int h = snackbarView.MeasuredHeightAndState;
But the height of the Snackbar is always 0.
I also tried snackbarView.Height and snackbarView.MinimumHeight, but it always returns 0.
Can anybody help me solving this issue?
i am not familiar with xamarin but i work with snakbar many times so may this work like this
You need to use view.post because height property only becomes available after the view is inflated/run
Ref : https://developer.xamarin.com/api/type/Android.Views.View/
Ref : https://developer.xamarin.com/api/type/Java.Lang.IRunnable/
snackbar.View.Post(() =>
{
int h=snackbar.View.Height();
Log.Error ("Height", "Height"+h);
});
i hope it helps

Snackbar is not dismissing on swipe

i have a snackbar in my appcompat activity. It has a button OK which dismiss the snackbar.It is working perfact. but i can't dismiss the snackbar on swipe(left to right).
Following is my code for snackbar....
final Snackbar snackbar = Snackbar
.make(view, "Error Message", Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("OK", new View.OnClickListener() {
#Override
public void onClick(View view) {
snackbar.dismiss();
}
});
snackbar.show();
Edit 1
I have Relative layout as parent layout in my activity's XML layout.
Snackbar needs a CoordinatorLayout as its root layout or some where on top of it, to perform its various operations like swipe to dismiss. You need to have that some where in your layout hierarchy.
Further the view that we pass in the Snackbar.make() method is used to search a CoordinatorLayout some where in the view hierarchy. The method traverse from this view to the root view to find a CoordinatorLayout over which it can show the snackbar and perform its animations and operations.
So try replacing root layout to CoordinatorLayout and your problem will be solved.
As a reference to Ashwani Kumars answer.
I saw Intimate asked if there is a way to implement this with LinearLayout. Well simple wrap your original LinearLayout with a CoordinatorLayout with
match_parent in android:layout_height and android:layout_width attributes.
this will keep your original arrangement and still make sure the Snackbar is swipable.
Snackbar will now look like this:
For fragments -
Snackbar.make(getView(), "Error Message", Snackbar.LENGTH_INDEFINITE);
For activities -
Snackbar.make(this.findViewById(android.R.id.content), "Error Message", Snackbar.LENGTH_INDEFINITE);
Assuming you wraped your whole layout with CoordinatorLayout and this is the root layout.
I've written a library that supports swipe to dimiss behaviour even without providing CoordinatorLayout. Users can swipe both left or right to dismiss it (you can only swipe to right originally). It also includes progressBar and other stuff. Try it out https://github.com/tingyik90/snackprogressbar.
All you need to do is to create a SnackProgressBar and allow swipe to dismiss. Sample code:
SnackProgressBar messageType = new SnackProgressBar(
SnackProgressBar.TYPE_MESSAGE, "Your message")
.setSwipeToDismiss(true)
Snackbars in my GLSurfaceView game don't dismiss with a swipe, and users may not know to swipe anyway if they did. The following one line of code dismisses a Snackbar with any touch of the bar. Critically I found if the user does happen to hit the action button if it has one, whatever action it is set to do is still performed. The overall dismiss does not get in the way.
snackbar.getView().setOnClickListener(view -> snackbar.dismiss());

Making DialogFragment window scrollable

I'm having a problem where Dialogs don't scroll when their content is too large for the screen. I assume this is because Dialogs are not displayed within Scrollable containers.
Screenshot contains content wrapped in a ScrollView - You can see only the content is scrollable
Extra fields added to artificially increase dialog size for this example
You can see from the Android Developer Documentation that Dialogs should be wrapped within DialogFragments (This gives the benefit of having your dialogs survive an orientation change and response to lifecycle events) and this is the set up I'm trying to make work.
Much of the other answers I've found are all similar to one another and revolve around ensuring the window is set to "adjustResize". However, this would only make the parent view smaller on keyboard opening, it wouldn't make a View scrollable if it wasn't in a Scrollable container.
If someone could let me know if they have info to make a Dialog scrollable or to confirm that you cannot make a Dialog scrollable I'd appreciate it.
I have achieved scrolling in dialog fragment,
Dialog layout design
<LinearLayout>
<NestedScrollView>
<ConstrainLayout>
</ConstrainLayout>
</NestedScrollView>
</LinearLayout>
In DialogFrament class ,
override fun onStart() {
super.onStart()
dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZ)
}
This is possibly the dirtiest and most likely to break solution to this problem:
After creating the Dialog in onCreateDialog() but before returning it you can achieve scrolling by adding this code:
final ViewGroup content = (ViewGroup) dialog.findViewById(android.R.id.content);
content.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
content.getViewTreeObserver().removeGlobalOnLayoutListener(this);
View inner = content.getChildAt(0);
content.removeViewAt(0);
ScrollView scrollView = new ScrollView(getContext());
scrollView.addView(inner);
content.addView(scrollView);
}
});
I had the same problem with DialogFragment, but I changed:
<fragment android:layout_height="425dp"
...
to this:
<fragment android:layout_height="wrap_content"
...
And now it's scrolling when the keyboard is open, or when the screen is in landscape mode.
NOTE: I have ScrollView as a rootView in DialogFragment layout, of course.

Set NavigationDrawer's ListView margin programmatically

I am currently struggling to design my application the way i want to.
In my app i am using a NavigationDrawer and different fragments. By clicking on an item in the NavigationDrawer i swap out the fragment that is currently active.
There is one main fragment which shows a map and doesn't show a toolbar. When I switch to another fragment I want to show my toolbar and let the user interact with it.
Now when I show the toolbar I have to set the top margin of the NavigationDrawer to the size of the toolbar so it doesn't get overlapped.
When I am showing the toolbar I set the margin of the NavigationDrawer's listview like this:
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mDrawerListView.getLayoutParams();
params.setMargins(0, drawerMarginTop, 0, 0);
mDrawerListView.setLayoutParams(params);
mDrawerListView.requestLayout();
The outcome is like the complete opposite of what i expect. It seems like the margin is applied to the bottom of the view.
Screenshot:
Another thing that annoys me is that the toggle-arrow of the toolbar is not centered correctly. It's a little bit higher than it should be, so it overlaps the system bar in the top and doesn't fill the whole size of the toolbar. I tried to make this clear in the following picture:
If you need any xml or code just let me know and I will edit my question.
Thank you in advance!
EDIT 1+2:
My toolbar style:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar_navigation"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/my_color"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>
EDIT 3:
The Problem with the toggle-arrow not being centered is fixed now. Thanks to Alchete.
Unfortunately the NavigationDrawer is still buggy. I found out that if I open and close the NavigationDrawer many times it somehow changes its layout at one time and the margin is set correctly... Is there any way to force this top happen immediately?
After many times of opening and closing the drawer it looks like this: (Exactly what I want it to look like)
There must be a way to force this immediately, right?
Your alignment issue is most likely due to your toolbar height. You should be setting the toolbar height as follows:
<android.support.v7.widget.Toolbar
android:layout_height="?attr/actionBarSize">
Here's the same issue for reference: android.support.v7.widget.Toolbar icon alignment issue
I would also be using Google's IOSched app for reference on how to set these items up properly. You can find all the code on Github.
Here are their layout files. Scroll down to see their toolbar/navdrawer layouts: https://github.com/google/iosched/tree/dfaf8b83ad1b3e7c8d1af0b08d59caf4223e0b95/android/src/main/res/layout
And, also note that Google's reference design is to OVERLAP the toolbar with the navdrawer -- which is not how you have it. And, the right margin should be equivalent to the toolbar height.
See here: http://www.google.com/design/spec/patterns/navigation-drawer.html
I'm not 100% about this but it looks like you're setting the ViewGroup layout params to be of type MarginLayoutParams. Instead, set the margin on a 'normal' root ViewGroup type e.g. RelativeLayout and pass that to the View:
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT);
params.setMargins(0, drawerMarginTop, 0, 0);
mDrawerListView.setLayoutParams(params);
mDrawerListView.requestLayout();
You may want to change MATCH_PARENT to WRAP_CONTENT depending on your xml.

Scrolling drop-down-menu over the keyboard in autocompletetextview

I have an Autocompletetextview dropping down the suggestions list, up to the border of the soft-keyboard.
Then, when scrolling over the suggestions list:
- (in a gingerbread phone) the drop-down-menu automatically increases height covering the keyboard, which is nice since it shows more items.
- (in an ICS emulator) the drop-down-menu does not increase height over the keyboard.
Is this related to some system property?
Is there a way to force the first behavior also in ICS?
Just add android:dropDownHeight="100dp" to the AutoCompleteTextView tag in your layout file, it will work.
Let me explain my little trick to avoid that the "drop-down" displays behind the keyboard. The trick is with the dropDownAnchor property.
The solution is set the anchor with a view located on the top of the screen, so the menu will leave from that position, and therefore, will not be covered by the keyboard. For example:
android:dropDownAnchor="#+id/topview"
I know that is an ugly solution but this control is too limited.
You can also use android:dropDownAnchor="#id/ to anchor the dropdown to a view.
Just add getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); to your fragment or activity
A simple solution that works perfectly with all resolutions is to use the android:dropDownAnchor property with a resource ID that references your activity toolbar.
<my.app.ContactAutoCompleteTextView
android:id="#+id/autocomplete_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:dropDownAnchor="#id/appbar"
android:inputType="text|textMultiLine|textCapSentences|textAutoCorrect"
android:paddingBottom="12dp"
android:textColor="#color/text_primary"
android:textColorLink="#color/secondary"
android:textSize="#dimen/text_medium" />
You need to do two things.
First, adjust the soft input mode of that activity in the manifest.
android:windowSoftInputMode="stateHidden|adjustResize"
This ensures views are laid out again when the keyboard is shown. Then, set a global layout listener in your oncreate on the top level view to do the dropdown height calculation when the layout changes. Adjust the dropdown height to be the height of everything below the keyboard, minus some padding if you want.
v.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
autoCompleteView.setDropDownHeight(view2.getHeight());
}
Where view2 is the view/layout that includes everything below the autocompleteview.
If none of the above solutions worked. try this
android:dropDownHeight="match_parent"
or
android:dropDownHeight="500dp"
If we didn't mention the dropdown height, it would be considered wrap_content. Therefore the item will show behind the soft keyboard.

Categories

Resources