Android animation starts only after scrolling it's parent view
I'm trying to create an expandable menu item in android, which will look like a button and on button click, button will expand to down with animation. I set an expand animation for the layout which i want to expand when clicked to my view and I have problem with animation. It doesn't start immediately when I clicked the view, and it starts when I scroll-down or scroll-up the container of the view. And if the container is not scrollable, my animation never starts. What am I doing wrong?
Here is my expand method, onClick method and the layout xml file for my custom view which will do this things:
expand:
public void expand(final View v) {
try {
Method m = v.getClass().getDeclaredMethod("onMeasure", int.class, int.class);
m.setAccessible(true);
m.invoke(v,
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(((View)v.getParent()).getMeasuredWidth(), MeasureSpec.AT_MOST)
);
} catch (Exception e) {
Log.e(TAG , "Caught an exception!", e);
}
final int initialHeight = v.getMeasuredHeight();
Log.d("test", "initialHeight="+initialHeight);
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
Animation a = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
final int newHeight = (int) (initialHeight * interpolatedTime);
v.getLayoutParams().height = newHeight;
v.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration(1000);
a.setInterpolator(AnimationUtils.loadInterpolator(context,
android.R.anim.accelerate_decelerate_interpolator));
v.startAnimation(a);
isExpanded = !isExpanded;
}
onClick:
public void onClick(View v) {
if (!isExpanded) {
expand(subButtonsLay开发者_运维问答out);
} else {
collapse(subButtonsLayout);
}
}
Layout xml for custom menu item view:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mtx="http://schemas.android.com/apk/res/com.matriksdata.trademaster"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<LinearLayout
android:id="@+id/xExpandableMenuButtonTop"
android:background="@drawable/opened_menu_bg_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</LinearLayout>
<LinearLayout
android:background="@drawable/opened_menu_bg_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical">
<LinearLayout
android:id="@+id/xExpandableMenuButtonTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:id="@+id/xExpandableMenuButtonText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:textAppearance="@style/expandable_menu_button_textstyle"
android:text="Button Text">
</TextView>
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="6"
android:src="@drawable/menu_button_down_arrow">
</ImageView>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/xExpandableMenuButtonSubButtonsLayout"
android:background="@drawable/opened_menu_bg_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical"
android:visibility="gone">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<com.myproject.control.XSubMenuButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
mtx:XSubMenuButtonText="SubMenu1">
</ccom.myproject.control.XSubMenuButton>
<com.myproject.control.XSubMenuButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
mtx:XSubMenuButtonText="SubMenu2">
</com.myproject.control.XSubMenuButton>
<com.myproject.control.XSubMenuButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
mtx:XSubMenuButtonText="SubMenu3">
</com.myproject.control.XSubMenuButton>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/xExpandableMenuButtonBottom"
android:background="@drawable/opened_menu_bg_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</LinearLayout>
</LinearLayout>
If you haven't solved your problem or if anyone else comes across this problem, here is a quick solution. Invalidate your parent view on each click (in the onClick
method). This should work regardless of if the parent is scrollable or not.
That is, your code will be something like:
public void onClick(View v) {
if (!isExpanded) {
expand(subButtonsLayout);
} else {
collapse(subButtonsLayout);
}
rootView.invalidate();
}
To anyone who might face this again.
If your view, the one that you are animating is in the gone state, then in that case, before starting the animation, set Visiblity to invisible. And it will work in the first go.
Source from here.
I had a view that I declared at the end of my layout to keep its Z index above its siblings. I had to touch the page to make the animation work.
So I set the Z index again through Java and it worked.
view.bringToFront();
Well, I fixed the problem using only 2 lines.
scroll.setFocusableInTouchMode(true);
scroll.requestFocus();
animation.Start();//Start anim
Good luck
"If the container is not scrollable, the animation never starts" --> Have a look at my similar problem, Scrollview doesn't swipe when it's too short to scroll. I figured out in my case it's a touch bug in Android 2.1 and under.
精彩评论