smoothScrollToPosition()
の方法はGridView
正しく機能しますか?未解決のバグレポートを見つけましたが、私のものも正しく機能していません。
setSelection()
正常に動作していますが、スムーズなスクロール効果が必要です。
この問題について何か考えがありますか?
これが永続的な問題である場合、どこから適切なスクロール効果を実装し始める必要がありますか?
smoothScrollToPosition()
の方法はGridView
正しく機能しますか?未解決のバグレポートを見つけましたが、私のものも正しく機能していません。
setSelection()
正常に動作していますが、スムーズなスクロール効果が必要です。
この問題について何か考えがありますか?
これが永続的な問題である場合、どこから適切なスクロール効果を実装し始める必要がありますか?
投稿したサンプルコードの実行で問題は発生していませんが、アプリケーションで一貫した結果が表示されない場合は、独自のスクロールコントローラーを作成するのはそれほど難しいことではありません。使用できる実装例は次のとおりです。
private class ScrollPositioner {
private static final int SCROLL_DURATION = 20;
private static final int DIR_UP = 1;
private static final int DIR_DOWN = 2;
int mTargetPosition = AdapterView.INVALID_POSITION;
int mDirection = AdapterView.INVALID_POSITION;
int mLastSeenPosition = AdapterView.INVALID_POSITION;
int mExtraScroll;
GridView mGrid;
public ScrollPositioner(GridView grid) {
mGrid = grid;
mExtraScroll = ViewConfiguration.get(mGrid.getContext()).getScaledFadingEdgeLength();
}
Handler mHandler = new Handler();
Runnable mScroller = new Runnable() {
public void run() {
int firstPos = mGrid.getFirstVisiblePosition();
switch(mDirection) {
case DIR_UP: {
if (firstPos == mLastSeenPosition) {
// No new views, let things keep going.
mHandler.postDelayed(mScroller, SCROLL_DURATION);
return;
}
final View firstView = mGrid.getChildAt(0);
if (firstView == null) {
return;
}
final int firstViewTop = firstView.getTop();
final int extraScroll = firstPos > 0 ? mExtraScroll : mGrid.getPaddingTop();
mGrid.smoothScrollBy(firstViewTop - extraScroll, SCROLL_DURATION);
mLastSeenPosition = firstPos;
if (firstPos > mTargetPosition) {
mHandler.postDelayed(mScroller, SCROLL_DURATION);
}
break;
}
case DIR_DOWN: {
final int lastViewIndex = mGrid.getChildCount() - 1;
final int lastPos = firstPos + lastViewIndex;
if (lastViewIndex < 0) {
return;
}
if (lastPos == mLastSeenPosition) {
// No new views, let things keep going.
mHandler.postDelayed(mScroller, SCROLL_DURATION);
return;
}
final View lastView = mGrid.getChildAt(lastViewIndex);
final int lastViewHeight = lastView.getHeight();
final int lastViewTop = lastView.getTop();
final int lastViewPixelsShowing = mGrid.getHeight() - lastViewTop;
final int extraScroll = lastPos < mGrid.getAdapter().getCount() - 1 ? mExtraScroll : mGrid.getPaddingBottom();
mGrid.smoothScrollBy(lastViewHeight - lastViewPixelsShowing + extraScroll, SCROLL_DURATION);
mLastSeenPosition = lastPos;
if (lastPos < mTargetPosition) {
mHandler.postDelayed(mScroller, SCROLL_DURATION);
}
break;
}
default:
break;
}
}
};
public void scrollToPosition(int position) {
mTargetPosition = position;
mLastSeenPosition = AdapterView.INVALID_POSITION;
if(position < mGrid.getFirstVisiblePosition()) {
mDirection = DIR_UP;
} else if (position > mGrid.getLastVisiblePosition()) {
mDirection = DIR_DOWN;
} else {
return;
}
mHandler.post(mScroller);
}
}
これは、フレームワーク実装の代わりにスクロールを実行するこの新しいクラスを含む、リンクした例のスニペットです。
GridView g;
boolean t= false;
@Override
public void onBackPressed() {
//Instantiate and attach the custom positioner
if(mPositioner == null) {
mPositioner = new ScrollPositioner(g);
}
//Use the custom object to scroll the view
mPositioner.scrollToPosition(0);
if(t) {
super.onBackPressed();
}
else {
t = true;
}
}
スクロール方向が下向きでも、選択した位置が常に上にスクロールする機能を追加したい場合は、それを行うことができます。 これは、フレームワークの実装が行うように設計されたものではありませんがDIR_DOWN
、最初の表示位置がターゲットと一致するまでスクロールを継続するコードを追加することで実現できます(DIR_UP
そうするように)。また、位置が一番上に到達する前にスクロールが終了する場合にも注意する必要があります。そのため、異なる結果が得られない場合にハンドラーを常に投稿しているわけではありません。
HTH
Had the same issue- I built a simple GridView and for some reason the smoothScrollToPosition()
didn't work at all (just bounce from time to time).
after lot of debugging it turn out to be that I need to remove the android:padding
parameter from the GridView.
very strange, I really don't know why it is like this, but at least now it works.