onScrollStateChanged не будет плавно прокручиваться при Scroll_State_Idle
Я получил listView, содержащий несколько элементов с одинаковой высотой в полноэкранном режиме. Когда я отпускаю прокрутку, я хочу автоматически прокрутить сглаживание до этого элемента, который занимает больше места на экране. Само сглаживание работает, когда я прокручиваю в произвольную позицию и нажимаю кнопку (например, когда 60% первого элемента Visis видимы и 40% следующего элемента видимы, он автоматически прокручивается до первого элемента Visis, чтобы быть полноэкранным после кнопки-OnClick) см. Код:
ListView mylistView= (ListView)findViewById(R.id.ListViewLayout);
int midScreen = mylistView.getMeasuredHeight() / 2;
public void onClick(View v) {
View v = mylistView.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
top =-top;
if (top <= midScreen) {
mylistView.smoothScrollBy(-top, 1000); // if first item takes more space, scroll up
} else {
mylistView.smoothScrollBy((midScreen*2)-top, 1000); // if second item takes more space, scroll down
}
Теперь я хочу, чтобы эта рабочая процедура была вызвана, когда список перестает прокручиваться. Я создал onScrollListener и в onScrollStateChanged я попробовал это, если listScroll останавливается (поэтому состояние 0, режим ожидания):
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState==OnScrollListener.SCROLL_STATE_IDLE) {
View vX = mylistView.getChildAt(0);
int top = (vX == null) ? 0 : vX.getTop();
top =-top;
if (top <= midScreen) {
mylistView.smoothScrollBy(-top, 1000);
} else mylistView.smoothScrollBy((midScreen*2)-top, 1000);
}
}
Проблема: вместо того, чтобы плавно прокрутить 1 секунду до этой точной позиции, чтобы показать нужный элемент в полноэкранном режиме, он прыгает так быстро, как только может. SmoothScrollBy больше не является плавным, когда он вызывается в состоянии 0. Почему это и есть какое-либо решение?
3 ответа
Хорошо, мне удалось запустить smoothScroll в runnable с обработчиком, и теперь он работает! Если у кого-то есть такая же проблема, вот код
listViewAnlagen.setOnScrollListener(new OnScrollListener() {
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState==OnScrollListener.SCROLL_STATE_IDLE) {
View vX = listViewAnlagen.getChildAt(0);
int top = (vX == null) ? 0 : vX.getTop();
top =-top;
if (top <= mitteScreen) {
handler.post(obenRunnable);
} else {
handler.post(untenRunnable);
}
}
}
Handler handler = new Handler();
Runnable obenRunnable = new Runnable()
{
public void run()
{
View vX = listViewAnlagen.getChildAt(0);
int top = (vX == null) ? 0 : vX.getTop();
top =-top;
listViewAnlagen.smoothScrollBy(-top, 200);
}
};
Runnable untenRunnable = new Runnable()
{
public void run()
{
View vX = listViewAnlagen.getChildAt(0);
int top = (vX == null) ? 0 : vX.getTop();
top =-top;
listViewAnlagen.smoothScrollBy((mitteScreen*2)-top, 200);
}
};
});
Я думаю, что вы можете сделать что-то подобное, чтобы позволить плавную прокрутку.
public void scrollSmoothTopAfterMiddle( final int top ) {
final ValueAnimator anim = ValueAnimator.ofInt( top, 0 );
anim.addUpdateListener( new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate( final ValueAnimator animation ) {
final int value = ( Integer ) animation.getAnimatedValue();
mListView.smoothScrollBy( ( midScreen * 2 ) - top, value );
}
} );
anim.setDuration( 250 );
anim.setInterpolator( new DecelerateInterpolator() );
anim.start();
}
public void scrollSmoothTopBeforeMiddle( final int top ) {
final ValueAnimator anim = ValueAnimator.ofInt( top, 0 );
anim.addUpdateListener( new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate( final ValueAnimator animation ) {
final int value = ( Integer ) animation.getAnimatedValue();
mListView.smoothScrollBy( -top, value );
}
} );
anim.setDuration( 250 );
anim.setInterpolator( new DecelerateInterpolator() );
anim.start();
}
if ( scrollState == OnScrollListener.SCROLL_STATE_IDLE ) {
final View vX = mListView.getChildAt( 0 );
int top = ( vX == null ) ? 0 : vX.getTop();
top = -top;
if ( top <= midScreen ) {
scrollSmoothTopBeforeMiddle( -top );
} else {
scrollSmoothTopAfterMiddle( ( midScreen * 2 ) - top );
}
}
private final Runnable SCROLLING_RUNNABLE = new Runnable() {
@Override
public void run() {
bannerItemRV.smoothScrollBy(pixelsToMove, 0);
mHandler.postDelayed(this, duration);
}
};
and We use bellow for
bannerItemRV.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int lastItem = bannerlinearLayoutManager.findLastCompletelyVisibleItemPosition();
if (lastItem == bannerlinearLayoutManager.getItemCount() - 1) {
mHandler.removeCallbacks(SCROLLING_RUNNABLE);
Handler postHandler = new Handler();
postHandler.postDelayed(new Runnable() {
@Override
public void run() {
bannerItemRV.setAdapter(null);
bannerItemRV.setAdapter(bannerPagerAdapter);
mHandler.postDelayed(SCROLLING_RUNNABLE, 2000);
}
}, 2000);
}
}
});
mHandler.postDelayed(SCROLLING_RUNNABLE, 2000);
bannerItemRV.addOnItemTouchListener(new SwipeableItemClickListener(this, new com.talentedge.ui.widget.swipeDelete.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
bannerListResultData=bannerListResultDatas.get(position);
String url=bannerListResultData.getUrl();
if(!TextUtils.isEmpty(url) && !StringUtils.isNullOrEmpty(url)) {
showWebpage(Uri.parse(url));
}
}
}));