I am trying to use a Snackbar. I have a FloatingActionButton wrapped in a CoordinatorLayout. When the Snackbar shows, the button is correctly moved up. When it dismisses automatically, the button moves down. But if I dismiss the Snackbar programmatically, the button does not go down. My code is simple:
mSnackbar = Snackbar.make(mCoordinatorLayout, text, Snackbar.LENGTH_LONG)
.setAction(R.string.undo, new View.OnClickListener() {
#Override
public void onClick(View v) {
undoDeleteTasks();
}
});
mSnackbar.show();
Is there a way to make the FloatingActionButton move down when the Snackbar is dismissed programmatically?
Try this:
Snackbar mysnack = Snackbar.make( fab, "Hi, welcome to my app!", Snackbar.LENGTH_LONG );
mysnack.getView().addOnAttachStateChangeListener( new View.OnAttachStateChangeListener() {
#Override
public void onViewAttachedToWindow( View v ) {
}
#Override
public void onViewDetachedFromWindow( View v ) {
fab.setTranslationY( 0 );
}
});
mysnack.show();
The problem is, in an CoordinatorLayout, the FAB is moved because its behavior class's onDependentViewChanged() is called when the Snackbar animates in or out.
However, when you call Snabackbar.dismiss() no animation takes place. And therefore no onDependentViewChanged(). And thus movement of the FAB.
I want to know if it possible to either
animate the Snackbar dismiss?
create a behavior that moves the FAB when the Snackbar causes onDependentViewRemoved()?
Farzad119's answer is arguably a little brittle. My approach--although not satisfactory either--is to alter the behavior on the FAB to move the FAB down when the SnackBar is removed:
#Override
public void onDependentViewRemoved(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
super.onDependentViewRemoved(parent, child, dependency);
float translationY = Math.min(0, parent.getBottom() - child.getBottom());
child.setTranslationY(translationY);
}
To solve this issue I defined a RelativeLayout Behavior like this. This can be done for any view, just replace all RelativeLayout with desired UI element.
public class RelativeLayoutBehavior extends CoordinatorLayout.Behavior<RelativeLayout> {
public RelativeLayoutBehavior(Context context, AttributeSet attrs) {
}
#Override
public boolean layoutDependsOn(CoordinatorLayout parent, RelativeLayout child, View dependency) {
return dependency instanceof Snackbar.SnackbarLayout;
}
#Override
public boolean onDependentViewChanged(CoordinatorLayout parent, RelativeLayout child, final View dependency) {
Float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
child.setTranslationY(translationY);
return true;
}
#Override
public void onDependentViewRemoved(CoordinatorLayout parent, RelativeLayout child, View dependency) {
child.setTranslationY(0);
}
}
Then you need to add the Behavior into the RelativeLayout "android:layout_behavior" property like this. Make sure the RelativeLayout you want to slide up is inside of a CoordinateLayout also.
<?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/main_coordinate_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#323232"
tools:context="com.choch.michaeldicioccio.myapplication.MainActivity">
<RelativeLayout
android:id="#+id/bottom_navigation_relative_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="bottom"
app:layout_behavior="com.yourPackagePath.RelativeLayoutBehavior" >
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#color/colorPrimary"
android:clickable="true"
app:elevation="8dp"
app:itemBackground="#color/colorPrimary"
app:itemIconTint="#drawable/bottom_navigation_color_selector"
app:itemTextColor="#drawable/bottom_navigation_color_selector"
app:menu="#menu/bottom_bar_menu" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/add_car_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_above="#id/bottom_navigation"
android:layout_margin="#dimen/fab_margin"
android:scaleType="center"
android:src="#mipmap/ic_plus_black_36dp"
android:tint="#color/colorPrimary"
app:elevation="8dp"/>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
Related
In my android app, i used the Floating Action Button from the Clans' 3rd-party library. Like -
<com.github.clans.fab.FloatingActionButton
android:id="#+id/fab3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_help_outline"
fab:fab_colorNormal="#009688"
fab:fab_label="Learn How-To Use"
fab:fab_size="mini" />
When my snackbar pops up, the clans fab doesn't animate like the default floating action button from the design library of google.
I saw some proguard rules that would fix the issue. Like:
-keep class android.support.design.widget.** { *; }
-keep interface android.support.design.widget.** { *; }
I added those lines to the proguard-rules.pro file, but didn't help at all.
Could anyone suggest what i'm doing wrong?
Any suggestions/advice would be very much appreciated :)
The default animation you're thinking of is provided by CoordinatorLayout and its companion Behavior class.
Behaviors may be used to implement a variety of interactions and additional layout modifications ranging from sliding drawers and panels to swipe-dismissable elements and buttons that stick to other elements as they move and animate.
You need to make two changes. First, you should wrap your RelativeLayout with a CoordinatorLayout and move your FloatingActionButton out of the RelativeLayout so that it is a direct descendant of the CoordinatorLayout. Your layout should look like this:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
... your RelativeLayout here
<com.github.clans.fab.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:layout_gravity="bottom|end"
app:layout_behavior="com.example.stackoverflow.MyBehavior"/>
</android.support.design.widget.CoordinatorLayout>
Next, you have to create the MyBehavior class. I basically just took the design library's FloatingActionButton.Behavior class and stripped out everything that wasn't strictly necessary. Here's what's left:
public class MyBehavior extends CoordinatorLayout.Behavior<FloatingActionButton> {
public MyBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void onAttachedToLayoutParams(CoordinatorLayout.LayoutParams lp) {
if (lp.dodgeInsetEdges == Gravity.NO_GRAVITY) {
lp.dodgeInsetEdges = Gravity.BOTTOM;
}
}
#Override
public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
return false;
}
#Override
public boolean onLayoutChild(CoordinatorLayout parent, FloatingActionButton child, int layoutDirection) {
parent.onLayoutChild(child, layoutDirection);
return true;
}
#Override
public boolean getInsetDodgeRect(CoordinatorLayout parent, FloatingActionButton child, Rect rect) {
rect.set(child.getLeft(), child.getTop(), child.getRight(), child.getBottom());
return true;
}
}
With those in place, I get the animation you're looking for:
Long story short, can you get the floatingActionButton to move up and down when a custom view is moved up and down in the same way as it does with the snackbar?
I have a Floating Action Button in a coordinator layout that moves up when the snackbar is shown. I've even managed to customize the FABs "Behaviour" through tutorials to make it shrink and grow rather than move up and down.
I also have a custom made popup (LinearLayout) that animates up from the bottom and back down again when a button is pressed and that currently just pops up behind the floating action button which doesn't move. Both are in a CoordinatorLayout I would like the floating action button to go up and down when the custom popup animates up and down...in the same way it does for the snackbar.
I've kind of managed to get it to work by adding my custom popup as a dependency on calls to the layoutDependsOn method of the FloatingActionButton behaviour class. However my implementation for the onDependentViewChanged method to actually get the FAB to animate up and down just feels wrong as i'm effectively having to animate the floatingActionButton seperately with the a coordinated animation to match the custom popups animation.
Can anybody point me at how to do this better and more easily?
I'll try to provide meaningful code snippets....
custom popup:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:id="#+id/selected_item_popup_linear_layout"
android:elevation="4dp"
android:visibility="gone"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/selectedItemPopupBackground" android:elevation="4dp"
android:id="#+id/selected_item_popup_content">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/selected_item_popup_delete_button"
android:layout_gravity="center"
android:padding="14dp"
android:src="#drawable/ic_delete_black_24dp"
android:background="#color/selectedItemPopupBackground"
android:tint="#color/selectedItemPopupDeleteTint"
/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/selected_item_popup_edit_button"
android:layout_gravity="center"
android:padding="14dp"
android:src="#drawable/ic_mode_edit_black_24dp"
android:background="#color/selectedItemPopupBackground"
android:tint="#color/selectedItemPopupEditTint"/>
</LinearLayout>
Floating action button:
<android.support.design.widget.FloatingActionButton
android:id="#+id/floating_action_button_add_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_add_white_24dp"
android:visibility="visible"
android:layout_marginBottom="#dimen/fab_margin_bottom"
android:layout_marginRight="#dimen/fab_margin_right"
app:layout_anchor="#id/pager"
app:layout_anchorGravity="bottom|right|end"
app:layout_behavior=".FloatingActionButtonBehaviour"
app:rippleColor="#color/boardItemBackgroundSelected"/>
Floating Action Button Behaviour:
public class FloatingActionButtonBehaviour extends CoordinatorLayout.Behavior<FloatingActionButton> {
private Context mContext;
public FloatingActionButtonBehaviour(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
#Override
public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
if (dependency.equals(parent.findViewById(R.id.selected_item_popup_linear_layout))) {
return true;
}
if (dependency instanceof Snackbar.SnackbarLayout) {
return true;
}
return false;
}
#Override
public boolean onDependentViewChanged(CoordinatorLayout parent, final FloatingActionButton child, View dependency) {
if(dependency instanceof Snackbar.SnackbarLayout) {
float translationY = getFabTranslationYForSnackbar(parent, child);
float percentComplete = -translationY / dependency.getHeight();
float scaleFactor = 1 - percentComplete;
child.setScaleX(scaleFactor);
child.setScaleY(scaleFactor);
}
if (dependency.equals(parent.findViewById(R.id.selected_item_popup_linear_layout))) {
View contentView = dependency.findViewById(R.id.selected_item_popup_content);
int contentViewHeight = contentView.getHeight();
if (dependency.getVisibility() == View.VISIBLE) {
Animation bottomUp = AnimationUtils.loadAnimation(mContext, R.anim.fab_move_up);
child.startAnimation(bottomUp);
child.setVisibility(View.VISIBLE);
float translationY = Math.min(0, dependency.getTranslationY() - contentViewHeight);
child.setTranslationY(translationY);
} else {
Animation bottomDown = AnimationUtils.loadAnimation(mContext, R.anim.fab_move_down);
child.startAnimation(bottomDown);
child.setVisibility(View.VISIBLE);
child.setTranslationY(dependency.getTranslationY());
}
}
return true;
}
private float getFabTranslationYForSnackbar(CoordinatorLayout parent, FloatingActionButton fab) {
float minOffset = 0;
final List<View> dependencies = parent.getDependencies(fab);
for (int i = 0, z = dependencies.size(); i < z; i++) {
final View view = dependencies.get(i);
if (view instanceof Snackbar.SnackbarLayout && parent.doViewsOverlap(fab, view)) {
minOffset = Math.min(minOffset, ViewCompat.getTranslationY(view) - view.getHeight());
}
}
return minOffset;
}
}
Code to Animate the custom popup:
Animation bottomUp = AnimationUtils.loadAnimation(mActivity, R.anim.bottom_up);
final ViewGroup selectedItemPopupLinearLayout = (ViewGroup)mActivity.findViewById(R.id.selected_item_popup_linear_layout);
selectedItemPopupLinearLayout.startAnimation(bottomUp);
selectedItemPopupLinearLayout.setVisibility(View.VISIBLE);
I think I found my answer in BottomSheets/ModalSheets....
https://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout#bottom-sheets
Not tried it yet but it looks the business
I've managed to get a snackbar show successfully using a coordinator layout wrapped around a MapView in a fragment. The map view successfully slides up to allow room for the snackbar, however, once the snackbar has gone, the view stays were it is and leaves a white bar where the snackbar would appear. How can I fix this? I'm currently applying the following code as a behavior on the map view:
#Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
child.setTranslationY(translationY);
return true;
}
#Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
// we only want to trigger the change
// only when the changes is from a snackbar
return dependency instanceof Snackbar.SnackbarLayout;
}
and my fragments view is this:
<android.support.design.widget.CoordinatorLayout
android:id="#+id/places_coordinator_layout"
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">
<com.google.android.gms.maps.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.adamshort.canieatthis.FloatingActionButtonBehaviour"/>
</android.support.design.widget.CoordinatorLayout>
I've tried searching around, but either I'm searching for the wrong thing or I no one's had a similar issue. I've seen the behavior code I have posted and working successfully in various tutorials and videos, but it doesn't behave well with the map view. Any thoughts?
Please, my answer below is an attempt to help you... Let me know if it helps you or not... Then, I delete if it is useless...
Maybe, you need to define and anchor to your MapView. In my case, I had to created a dummy view in the bottom and set it as archor to the view which will move with the SnackBar
<android.support.design.widget.CoordinatorLayout
android:id="#+id/places_coordinator_layout"
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.v4.widget.Space
android:id="#+id/anchor"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#android:color/transparent"
android:layout_gravity="bottom" />
<com.google.android.gms.maps.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_anchor="#id/anchor"
app:layout_behavior="com.adamshort.canieatthis.FloatingActionButtonBehaviour"/>
</android.support.design.widget.CoordinatorLayout>
This is intended by Google to prevent interfering with accessibility operation.
https://code.google.com/p/android/issues/detail?id=209953
Had exactly the same problem.
To fix this I changed the onDependentViewChanged() method to store the initial Y position of the view this behaviour is attached to. Then on removal of the snackbar, which calls the onDependentViewRemoved() method, reset the position of that view to the stored Y position.
private static float initialPositionY;
#Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
initialPositionY = child.getY();
float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
child.setTranslationY(translationY);
return true;
}
#Override
public void onDependentViewRemoved(CoordinatorLayout parent, View child, View dependency) {
super.onDependentViewRemoved(parent, child, dependency);
child.setTranslationY(initialPositionY);
}
I want to try BottomSheetDialog introduced in Android Support Library 23.2 but it doesn't seem to work correctly. Here is what the doc says:
While BottomSheetBehavior captures the persistent bottom sheet case, this release also provides a BottomSheetDialog and
BottomSheetDialogFragment to fill the modal bottom sheets use case.
Simply replace AppCompatDialog or AppCompatDialogFragment with their
bottom sheet equivalents to have your dialog styled as a bottom
sheet."
So I changed my AppCompatDialog to BottomSheetDialog:
package my.package.ui.dialog;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.BottomSheetDialog;
import my.package.R;
public class AccountActionsDialog extends BottomSheetDialog {
public AccountActionsDialog(Context context) {
super(context);
if (context instanceof Activity) {
setOwnerActivity((Activity) context);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutInflater().inflate(R.layout.dialog_account_actions, null));
}
}
Here is my layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff0000"
android:padding="16dp"
android:text="Delete account"
android:textColor="#ffffff" />
</LinearLayout>
Then I use the following code in my Activity:
new AccountActionsDialog(this).show();
My screen becomes dimmed but the content of my dialog is not visible. Any thoughts on what might be missing? It works fine when I use AppCompatDialog instead.
Instead of having a separate class, you can simply create an instance for BottomSheetDialog in your Activity/Fragment like following and you can use it. It is very easier and simpler I think.
val dialog = BottomSheetDialog(this)
val bottomSheet = layoutInflater.inflate(R.layout.bottom_sheet, null)
bottomSheet.buttonSubmit.setOnClickListener { dialog.dismiss() }
dialog.setContentView(bottomSheet)
dialog.show()
This is the layout file of BottomSheetDialog.
<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:soundEffectsEnabled="false">
<FrameLayout
android:id="#+id/design_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
app:layout_behavior="#string/bottom_sheet_behavior"
style="?attr/bottomSheetStyle"/>
</android.support.design.widget.CoordinatorLayout>
Your content view is inside the view design_bottom_sheet, it will be positioned center vertically by CoordinatorLayout, and BottomSheetBehavior will offset it.
mParentHeight = parent.getHeight();
mMinOffset = Math.max(0, mParentHeight - child.getHeight());
mMaxOffset = mParentHeight - mPeekHeight;
if (mState == STATE_EXPANDED) {
ViewCompat.offsetTopAndBottom(child, mMinOffset);
} else if (mHideable && mState == STATE_HIDDEN) {
ViewCompat.offsetTopAndBottom(child, mParentHeight);
} else if (mState == STATE_COLLAPSED) {
ViewCompat.offsetTopAndBottom(child, mMaxOffset);
}
It intented to positon design_bottom_sheet at mMaxOffset, but actually the initial getTop of the child view is not 0, but (mParentHeight - childHeight) / 2, so you view if offset more than the desired offset.
Find the view design_bottom_sheet and set its gravity to Gravity.TOP | Gravity.CENTER_HORIZONTAL will fix it. But, if the childHeight is less than mPeekHeight, there will be blank area below you content view.
However, if peekHeight > childHeight, the mMaxOffset will less than mMinOffset, which will cause weird behavior.
Maybe the code should be changed to
mMaxOffset = Math.max((mParentHeight - mPeekHeight), mMinOffset);
insted of
mMaxOffset = mParentHeight - child.getHeight();
Here's the issue on code.google.com https://code.google.com/p/android/issues/detail?id=201793
An issue some users are seeing boils down to the FrameLayout that wraps our content view being centered vertically. The BottomSheetBehavior only works if this view is top aligned. I haven't figured out what causes the FrameLayout to become centered vertically yet, but here's a possible workaround:
View contentView = ...
// You may have to measure your content view first.
dialog.setContentView(contentView);
// Change this to a percentage or a constant, whatever you want to do.
// The default is 1024 - any views smaller than this will be pulled off
// the bottom of the screen.
float peekHeight = contentView.getMeasuredHeight();
View parent = (View)contentView.getParent();
BottomSheetBehavior behavior = BottomSheetBehavior.from(parent);
behavior.setPeekHeight(peekHeight);
CoordinatorLayout.LayoutParams layoutParams =
(CoordinatorLayout.LayoutParams)parent.getLayoutParams();
layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
I was expriencing the same issue, dimmed background and content not visible. Here is how I managed to workaround it by setting the content view in setupDialog() hidden method.
public class CustomBottomSheetDialogFragment extends BottomSheetDialogFragment {
private TextView mOffsetText;
private TextView mStateText;
private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
setStateText(newState);
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss();
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
setOffsetText(slideOffset);
}
};
private LinearLayoutManager mLinearLayoutManager;
private ApplicationAdapter mAdapter;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return super.onCreateDialog(savedInstanceState);
}
#Override
public void onViewCreated(View contentView, #Nullable Bundle savedInstanceState) {
super.onViewCreated(contentView, savedInstanceState);
}
#Override
public void setupDialog(Dialog dialog, int style) {
super.setupDialog(dialog, style);
View contentView = View.inflate(getContext(), R.layout.bottom_sheet_dialog_content_view, null);
dialog.setContentView(contentView);
mBottomSheetBehavior = BottomSheetBehavior.from(((View) contentView.getParent()));
if (mBottomSheetBehavior != null) {
mBottomSheetBehavior.setBottomSheetCallback(mBottomSheetBehaviorCallback);
}
mOffsetText = (TextView) contentView.findViewById(R.id.offsetText);
mStateText = (TextView) contentView.findViewById(R.id.stateText);
}
}
And the layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/offsetText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/black" />
<TextView
android:id="#+id/stateText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/black" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
It started to work when I set fixed height for my TextView (200dp), although for some height values it still behaves incorrectly. Obviously it's an issue of support lib. There are already few reports related to BottomSheetDialog in the bug tracker:
https://code.google.com/p/android/issues/detail?id=201793&sort=-opened&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened
https://code.google.com/p/android/issues/detail?id=201826
I want to implement a custom behavior on LinearLayout.
This is the structure of my xml:
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout.../>
<android.support.v4.widget.DrawerLayout.../>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_behavior="com.xxx.BottomBarBehavior"
android:layout_gravity="bottom|center_horizontal".../>
</android.support.design.widget.CoordinatorLayout>
The LinearLayout is inside CoordinatorLayout, below the DrawerLayout.
The LinearLayout is not moving up when the snackbar is shown. I just can't get my head around it. The layout is such that the DrawerLayout contains a ViewPager and this viewPager is populated by another xml by a fragment. And the snackbar is generated by an element in the recyclerView of this fragment.
This is how my BottomBarBehavior custom behavior class looks like:
public class BottomBarBehavior extends CoordinatorLayout.Behavior<LinearLayout> {
public BottomBarBehavior(Context context, AttributeSet attrs) {}
#Override
public boolean layoutDependsOn(CoordinatorLayout parent, LinearLayout child, View dependency) {
return ( dependency instanceof Snackbar.SnackbarLayout ) ||
( dependency instanceof DrawerLayout );
}
#Override
public boolean onDependentViewChanged(CoordinatorLayout parent, LinearLayout child, View dependency) {
if( dependency instanceof Snackbar.SnackbarLayout ) {
float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
child.setTranslationY(translationY);
}
return true;
}
}
I think you are just missing a super(); in the constructor of BottomBarBehavior.