展開可能な子ビューを備えたRecyclerViewがあります。子ViewGroupをクリックすると、次のgifのように、ViewGroupの高さを0から測定されたビューグループの高さまでアニメーション化するビューの量が膨らみます。
問題は次のとおりです。recyclerViewでsmoothScrollToPositionを呼び出しています。ビュー位置までスムーズにスクロールしますが、recyclerviewのアンダービューで触れている上記のgifで、まだ展開されていない現在のビューの高さを考慮します。ビューがすでに表示されているため、位置にスクロールしませんが、もう一度タッチすると(smoothscrolltopositionを再度呼び出す)、ビューが既に展開されているため、ビューを正しい位置にスクロールします。
ビューを画面の一番上までスクロールする方法、または単にスクロールしてコンテンツを表示する方法はありますか?
参考までに:これは、ビューを膨らませるために呼び出されるメソッドです。
collapsible_content.removeAllViews();
for(int i = 0; i < 5; i++) {
View link_view = getLayoutInflater().inflate(R.layout.list_item_timeline_step_link, collapsible_content, false);
TextView text = (TextView) link_view.findViewById(R.id.step_link_text);
text.setText("Test");
collapsible_content.addView(link_view);
}
そして、これは私の拡張方法です。
public void toggle() {
collapsible_content.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
Animation a;
if (mExpanded) {
a = new ExpandAnimation(collapsible_content.getLayoutParams().height, 0);
} else {
a = new ExpandAnimation(collapsible_content.getLayoutParams().height, getMeasuredHeight());
}
a.setDuration(mAnimationDuration);
collapsible_content.startAnimation(a);
mExpanded = !mExpanded;
}
そしてアニメーション:
private class ExpandAnimation extends Animation {
private final int mStartHeight;
private final int mDeltaHeight;
public ExpandAnimation(int startHeight, int endHeight) {
mStartHeight = startHeight;
mDeltaHeight = endHeight - startHeight;
}
@Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
final int newHeight = (int) (mStartHeight + mDeltaHeight *
interpolatedTime);
collapsible_content getLayoutParams().height = newHeight;
if (newHeight <= 0) {
collapsible_content setVisibility(View.GONE);
} else {
collapsible_content setVisibility(View.VISIBLE);
}
collapsible_content requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
}
私の解決策は、applyTransformationメソッド内でビューの下部を常にチェックし、それをRecyclerViewの高さと比較することでした。下部がRVの高さよりも高くなった場合は、差分値でスクロールします。
final int bottom = collapsible_content.getBottom();
final int listViewHeight = mRecyclerView.getHeight();
if (bottom > listViewHeight) {
final int top = collapsible_content.getTop();
if (top > 0) {
mRecyclerView.smoothScrollBy(0, Math.min(bottom - listViewHeight + mRecyclerView.getPaddingBottom(), top));
}
}
秘訣は、Math.minを使用してビューの上部を取得することでした。これにより、上にスクロールして上部が表示されなくなります。
ListViewAnimations に基づくソリューション
アニメーションリスナーを追加し、アニメーションの展開が終了したら、リサイクラービューのスクロールを開始します。