とcollapse
TextViews
のうち、次の2つの方法をScrollView
に「TextView
」をクリックして使用します。Expand/Collapseアニメーション:スモールラグ|| MeasureSpecが間違った値を返します
擬似レイアウト構造:
<ScrollView>
<LinearLayout>
<LinearLayout>
<!-- some other stuff here -->
</LinearLayout>
<TextView "header1"/>
<View "fancydivider"/>
<TextView "content1">
<TextView "header2"/>
<View "fancydivider"/>
<TextView "content2">
</LinearLayout>
</ScrollView>
除算が単純View
、1dp
にheight
セットです。たContent TextViews
スタイルが含まれています:
<item name="android:layout_height">0dp</item>
<item name="android:layout_width">match_parent</item>
とある程度のマージン&パディングを。ここ
方法:ここ
public static void expand(final View v) {
//v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
int matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) v.getParent()).getWidth(), View.MeasureSpec.EXACTLY);
int wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
v.measure(matchParentMeasureSpec, wrapContentMeasureSpec);
final int targetHeight = v.getMeasuredHeight();
// Older versions of android (pre API 21) cancel animations for views with a height of 0.
v.getLayoutParams().height = 1;
v.setVisibility(View.VISIBLE);
Animation a = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? ViewGroup.LayoutParams.WRAP_CONTENT
: (int) (targetHeight * interpolatedTime);
scrollView.smoothScrollTo(0, (int) (targetHeight * interpolatedTime));
v.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
};
a.setInterpolator(easeInOutQuart);
a.setDuration(computeDurationFromHeight(v));
v.startAnimation(a);
}
public static void collapse(final View v) {
final int initialHeight = v.getMeasuredHeight();
Animation a = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1) {
v.setVisibility(View.GONE);
} else {
v.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime);
v.requestLayout();
}
}
@Override
public boolean willChangeBounds() {
return true;
}
};
a.setInterpolator(easeInOutQuart);
a.setDuration(computeDurationFromHeight(v));
v.startAnimation(a);
}
private static int computeDurationFromHeight(View view) {
// 1dp/ms * multiplier
return (int) (view.getMeasuredHeight()/view.getContext().getResources().getDisplayMetrics().density) * 4;
}
問題:すべてが正常に動作します - expand animation
は、テキストの最後の行に到達するまで - characters
少なすぎるがそれに存在する場合、それはは、に遅れるジャンプ爆発する?完全に展開されるまで、あなたはそれを呼びたいと思っています。
Collapsing
うまくいくようです。
私は他のInterpolator
値を試しました。方法の別の乗数はcomputeDurationFromHeight
でした。
いくつかのテスト:
4行、4行目のすべてのは、以上の17の文字が18文字より少ない、正常に動作し、それが遅れています。
最後の行の3行と無関係な量の文字が正常に動作します。
animation
は、最初にexpand
で動作しますが、2番目では動作しません。TextView
が正しく計算されていないようです。私はexpand
にいくつかのtext
がsmoothScrollTo
を削除する次のヘッダTextView
- 上< 0.5秒間アップplopping見てきた高
multiplier
と(もちろんスクロールを除く。)何も変更しない - 他の補間も「しゃっくり」を持っています(下記参照)トンに私を得た
applyTransformation
で - いくつかのログ:重要
、より短いです彼はポイント、私はfinal height
が表示されていることを確認2回 - 正確に50ポイント(ピクセル? dp?)の違い。 //smoothly increasing height and then:
final height = 202 height = 252 final height = 252
私はtargetHeight = 203
を取得していますが、height
は最初に間違って計算されますが、その後にいくつかの魔法が発生しますか?
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? ViewGroup.LayoutParams.WRAP_CONTENT
: (int) (targetHeight * interpolatedTime);
v.requestLayout();
scrollView.smoothScrollTo(0, interpolatedTime == 1
? v.getHeight() : (int) (targetHeight * interpolatedTime));
Log.d("Anim", "height = " + v.getHeight());
if (interpolatedTime == 1){
Log.d("Anim", "final height = " + v.getHeight());
}
}
誰もが私が行方不明です何を指摘することはできますか?
補間された時刻が1かどうかを確認してから、高さをWRAP_CONTENTに設定する理由はありますか?なぜこれを行うのですか?高さが常にinterpolatedTime * targetHeightと等しいというだけではないのですか?補間された時間= 1の場合、高さはtargetHeightになります。私は終わりにWRAP_CONTENTに高さを設定することは、スタッターを引き起こしているものだと思う。 –
私は上記のリンクから答えを取り出しました。もし 'interpolatedTime * targetHeight'だけを使うと最後の行はまったく表示されません。私はすでにこの問題が 'height'の間違った計算によって引き起こされていることを発見しました。:/ – yennsarah
' v.requestLayout(); 'ビューを親に呼び出すlayout()メソッドとすべての子を再度レイアウトにします。連続した呼び出しは遅れにつながる可能性があります。レイアウトパラメータの代わりにRectをアニメーション化しようとします。 –