Reputation: 2110
Here's what I want to achieve.
When I click a FAB
button, a menu will toogle display at the bottom of the screen.
When the menu is opened/closed, the map has to be resized so there is no blank space when the menu is animated.
My problem is that when I animate the map's container (ViewPager), the container animates as expected but the map is streched out instead of resizing to the proper dimensions.
I have a ViewPager with a TabLayout that display a fragment per page:
Here's my toggle menu code:
public void animateFAB(FABStates state) {
if (state.equals(FABStates.show)) {
isFABOpen = true;
viewPager.animate()
.scaleY(1f)
.setInterpolator(INTERPOLATOR)
.setDuration(500);
mapUtilsContainer.animate().scaleY(1f)
.setInterpolator(INTERPOLATOR)
.setDuration(500);
MapView mapV = mapFragment.getMapView();
ViewGroup.LayoutParams lps = mapV.getLayoutParams();
lps.height = ViewGroup.LayoutParams.MATCH_PARENT;
mapV.requestLayout();
// for (int v = 0; v < FABMenu.length; v++) {
// FABMenu[v].animate().translationX(0).setStartDelay(90 * v);
// }
} else {
isFABOpen = false;
mapUtilsContainer.setPivotY(mapUtilsContainer.getMeasuredHeight());
mapUtilsContainer.setPivotX(0);
viewPager.animate()
.scaleY(1.5f)
.setInterpolator(INTERPOLATOR)
.setDuration(500);
mapUtilsContainer.animate()
.scaleY(0f)
.setInterpolator(INTERPOLATOR)
.setDuration(500);
MapView mapV = mapFragment.getMapView();
ViewGroup.LayoutParams lps = mapV.getLayoutParams();
lps.height = ViewGroup.LayoutParams.MATCH_PARENT;
mapV.requestLayout();
// for (int v = 0; v < FABMenu.length; v++) {
// FABMenu[v].animate().translationX(10000).setStartDelay(90 * v);
// }
}
}
public void animateFAB(FABStates state) {
if (state.equals(FABStates.show)) {
isFABOpen = true;
ValueAnimator va = ValueAnimator.ofInt(ViewGroup.LayoutParams.WRAP_CONTENT, 0);
va.setDuration(500);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
mapUtilsContainer.getLayoutParams().height = value.intValue();
mapUtilsContainer.requestLayout();
}
});
va.start();
View v = findViewById(R.id.coordinator_layout);
v.requestLayout();
// for (int v = 0; v < FABMenu.length; v++) {
// FABMenu[v].animate().translationX(0).setStartDelay(90 * v);
// }
} else {
isFABOpen = false;
ValueAnimator va = ValueAnimator.ofInt(0, ViewGroup.LayoutParams.WRAP_CONTENT);
va.setDuration(500);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
mapUtilsContainer.getLayoutParams().height = value.intValue();
mapUtilsContainer.requestLayout();
}
});
va.start();
View v = findViewById(R.id.coordinator_layout);
v.requestLayout();
// for (int v = 0; v < FABMenu.length; v++) {
// FABMenu[v].animate().translationX(10000).setStartDelay(90 * v);
// }
}
}
Is the WRAP_CONTENT
used wrongfully here?
Upvotes: 1
Views: 32
Reputation: 439
I think it is because of scale()
. As I have just tested it works fine if you set the height in pixels. Try ValueAnimator
to animate height. This way you should take record of opened/closed height of map beforehand. Example:
ValueAnimator va = ValueAnimator.ofInt(oldHeight, newHeight);
va.setDuration(500);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
v.getLayoutParams().height = value.intValue();
v.requestLayout();
}
});
Instead of WRAP_CONTENT
assign initial height while it is open and use it to reopen:
public void animateFAB(FABStates state) {
if (state.equals(FABStates.show)) {
isFABOpen = true;
initialHeight = mapUtilsContainer.getLayoutParams().height;
ValueAnimator va = ValueAnimator.ofInt(initialHeight, 0);
...
} else {
isFABOpen = false;
ValueAnimator va = ValueAnimator.ofInt(0, initialHeight);
...
}
}
Upvotes: 1