少し長くなるかもしれませんが、分かりやすく説明します。
基本的にレイアウトで構成され、2 つの相対的なレイアウトを持つアプリを開発しています。2 つのレイアウトのいずれかをクリックすると、2 番目のレイアウトは、実際の可視性に応じて拡大または縮小します。
これはレイアウトです:
これは、「メイン」または「子」をクリックして展開/縮小するのをリッスンするコードです。
public void toggleAmagar(View v){
View parent = (View) v.getParent();
View child = parent.findViewById(R.id.child);
Log.d("debugging","toggle amagar. Child visibility is :"+child.getVisibility()+". Clickable? Child: "+child.isClickable()+". Parent: "+v.isClickable());
ExpandAnimation expandAni = new ExpandAnimation(child, 500);
child.startAnimation(expandAni);
}
そして、これはアニメーションクラスです:
public class ExpandAnimation extends Animation {
private View mAnimatedView;
private LayoutParams mViewLayoutParams;
private int mMarginStart, mMarginEnd;
private boolean mIsVisibleAfter = false;
private boolean mWasEndedAlready = false;
public ExpandAnimation(View view, int duration) {
setDuration(duration);
mAnimatedView = view;
mViewLayoutParams = (LayoutParams) view.getLayoutParams();
// decide to show or hide the view
mIsVisibleAfter = (view.getVisibility() == View.VISIBLE);
mMarginStart = mViewLayoutParams.bottomMargin;
mMarginEnd = (mMarginStart == 0 ? (0- view.getHeight()) : 0);
view.setVisibility(View.VISIBLE);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
Log.d("debugging","aplicant. Visible = "+this.mAnimatedView.getVisibility());
mAnimatedView.setClickable(false);
if (this.hasEnded()){
mAnimatedView.setClickable(true);
View pare = (View) mAnimatedView.getParent();
View germa = (View) pare.findViewById(R.id.main);
germa.setClickable(true);
} else {
mAnimatedView.setClickable(false);
View pare = (View) mAnimatedView.getParent();
View germa = (View) pare.findViewById(R.id.main);
germa.setClickable(false);
}
if (interpolatedTime < 1.0f) {
// Calculating the new bottom margin, and setting it
mViewLayoutParams.bottomMargin = mMarginStart
+ (int) ((mMarginEnd - mMarginStart) * interpolatedTime);
// Invalidating the layout, making us seeing the changes we made
mAnimatedView.requestLayout();
// Making sure we didn't run the ending before (it happens!)
} else if (!mWasEndedAlready) {
mViewLayoutParams.bottomMargin = mMarginEnd;
mAnimatedView.requestLayout();
if (mIsVisibleAfter) {
mAnimatedView.setVisibility(View.GONE);
}
mWasEndedAlready = true;
}
}
Android 2.3 では次のようになります。
生成されるログは次のとおりです。
ログ A:
03-17 13:57:17.509: D/debugging(403): toggle amagar. Child visibility is :0. Clickable? Child: true. Parent: true
03-17 13:57:17.521: D/debugging(403): aplicant. Visible = 0
03-17 13:57:17.549: D/debugging(403): aplicant. Visible = 0
03-17 13:57:17.619: D/debugging(403): aplicant. Visible = 0
03-17 13:57:17.699: D/debugging(403): aplicant. Visible = 0
03-17 13:57:17.789: D/debugging(403): aplicant. Visible = 0
03-17 13:57:17.929: D/debugging(403): aplicant. Visible = 0
03-17 13:57:18.119: D/debugging(403): aplicant. Visible = 0
03-17 13:57:18.189: D/debugging(403): aplicant. Visible = 8
ログB
03-17 13:57:45.439: D/debugging(403): toggle amagar. Child visibility is :8. Clickable? Child: true. Parent: true
今、私は同じことをしていますが、4.2 で (4.0.4 の実際のデバイスは同じように動作します):
ログは次のとおりです。
ログ A:
03-17 14:13:06.104: D/debugging(815): toggle amagar. Child visibility is :0. Clickable? Child: true. Parent: true
03-17 14:13:06.192: D/debugging(815): aplicant. Visible = 0
03-17 14:13:06.212: D/debugging(815): aplicant. Visible = 0
03-17 14:13:06.475: D/debugging(815): aplicant. Visible = 0
03-17 14:13:06.692: D/debugging(815): aplicant. Visible = 0
03-17 14:13:06.792: D/debugging(815): aplicant. Visible = 8
ログ B:
03-17 14:13:08.923: D/debugging(815): toggle amagar. Child visibility is :8. Clickable? Child: true. Parent: true
03-17 14:13:09.013: D/debugging(815): aplicant. Visible = 0
03-17 14:13:09.022: D/debugging(815): aplicant. Visible = 0
03-17 14:13:09.232: D/debugging(815): aplicant. Visible = 0
03-17 14:13:09.442: D/debugging(815): aplicant. Visible = 0
03-17 14:13:09.666: D/debugging(815): aplicant. Visible = 0
03-17 14:13:09.803: D/debugging(815): aplicant. Visible = 0
ご覧のとおり、唯一の違いは、2.3 デバイスでは 2 回目のクリックでアニメーションが適用されないことです。
2.3 の実際のデバイスと 4.0.4 の他のデバイスでテストしましたが、それも起こっています。それらは仮想化されています。
さらに情報が必要な場合は、私に尋ねてください。
ところで、Animation クラス内の setClickable() トリックは、ユーザーがダブルクリックしてアニメーションとレイアウトにバグを発生させないようにするものです。
ありがとうございました。
セルジ
編集 いくつかのSDKで試しました:
- 2.2 -> バグ
- 2.3 -> バグ
- 4.2 -> OK
- 4.0 -> OK
編集 19/03
更新: まだ発生しており、理由がわかりません。明日、誰も答えが見つからない場合は、デバッグを続けます...ありがとう。