Reputation: 517
I am using the BottomSheet view for one of my layouts. For a very specific case, I need the animation duration of the BottomSheet which slides in the layout via the setState(...) method. It should be something around 400ms but I would prefer not to have a "magic" number for that case.
Upvotes: 4
Views: 8280
Reputation: 624
The duration of BottomSheetBehavior animation triggered by setState or touch events depends on various conditions.
BottomSheetBehavior
internally uses ViewDragHelper which determines animation duration time inside computeAxisDuration() private method.
This duration depends on some arbitrary values and cannot change it by official API:
public class ViewDragHelper {
...
private static final int BASE_SETTLE_DURATION = 256; // ms
private static final int MAX_SETTLE_DURATION = 6000; // ms
...
}
The hack solution to change show/hide animation time is...
BottomSheetBehavior
and ViewDragHelper
classes souce code to your project (with different package name)import ViewDragHelper
to use your ViewDragHelper
instead of original Android API class.computeAxisDuration
to satisfy your requirements, e.g. return exactly 400 ms.BottomSheetBehavior
class instead of original one.It is very bad solution but it works in my project. Details below.
File ViewDragHelper.java
public class ViewDragHelper {
// Additional fields and methods defined.
private int mSettleDuration = BASE_SETTLE_DURATION;
public void setDurationSpeedFactor(final float factor) {
mSettleDuration = (int)(factor * BASE_SETTLE_DURATION);
}
private boolean mSkipAnimation = false;
public void setSkipAnimation(final boolean skipAnimation) {
this.mSkipAnimation = skipAnimation;
}
// Modified version of private function.
private int computeAxisDuration(int delta, int velocity, int motionRange) {
if (delta == 0) {
return 0;
}
final int width = mParentView.getWidth();
final int halfWidth = width / 2;
final float distanceRatio = Math.min(1f, (float) Math.abs(delta) / width);
final float distance = halfWidth + halfWidth
* distanceInfluenceForSnapDuration(distanceRatio);
int duration;
velocity = Math.abs(velocity);
if (velocity > 0) {
duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
} else {
final float range = (float) Math.abs(delta) / motionRange;
duration = (int) ((range + 1) * mSettleDuration);
}
return Math.min(duration, MAX_SETTLE_DURATION);
}
// Rest of original class body here...
}
File BottomSheetBehavior.java
// Comment out original ViewDragHelper and use above modified version.
//import androidx.customview.widget.ViewDragHelper;
import your.custom.ViewDragHelper;
public class BottomSheetBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {
/**
* Allows to set up ViewDragHelper immediately or when it is created.
*/
public interface IDragHelperConfig {
void onDragHelperCreated(ViewDragHelper viewDragHelper);
}
private IDragHelperConfig iDragHelperConfig;
public void setIDragHelperConfig(IDragHelperConfig iDragHelperConfig) {
this.iDragHelperConfig = iDragHelperConfig;
if (viewDragHelper != null) {
iDragHelperConfig.onDragHelperCreated(viewDragHelper);
}
}
//...
public boolean onLayoutChild(...) {
if (viewDragHelper == null) {
viewDragHelper = ViewDragHelper.create(parent, dragCallback);
if (iDragHelperConfig != null) {
iDragHelperConfig.onDragHelperCreated(viewDragHelper);
}
}
}
//...
}
Sample code inside any android View initialization
val params: CoordinatorLayout.LayoutParams = myLayout.layoutParams as CoordinatorLayout.LayoutParams
val behavior = BottomSheetBehavior<FrameLayout>(myLayout.context, null)
// Optionally, set the height of the bottom sheet when it is collapsed (usefull for experiments).
// behavior.peekHeight = 20
// Configure bottom sheet behavior.
behavior.setIDragHelperConfig {
// Set how many times to slow the speed of the animation
// (relative to original Android animation speed).
it.setDurationSpeedFactor(20f)
// Optionally, turn off animation
// Useful when entering a new activity and
// initial animation is not desired.
it.setSkipAnimation(false)
}
params.behavior = behavior
Upvotes: 3
Reputation: 180
Yes you can add animations in bottom sheet. h
// init the bottom sheet behavior
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(mBottomSheet);
// change the state of the bottom sheet
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
// set callback for changes
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
// Called every time when the bottom sheet changes its state.
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
if (isAdded()) {
animateBottomSheetArrows(slideOffset);
}
}
});
}
private void animateBottomSheetArrows(float slideOffset) {
// Animate counter-clockwise
mLeftArrow.setRotation(slideOffset * -180);
// Animate clockwise
mRightArrow.setRotation(slideOffset * 180);
}
Upvotes: 0