Scroll_State_Idle时,onScrollStateChanged不会滚动平滑

时间:2014-09-04 11:10:24

标签: android listview scroll smooth-scrolling onscrolllistener

我有一个listView,其中包含全屏高度相同的几个项目。当我发布滚动时,我想自动滚动到该项目,这占用了屏幕上最大的空间。当我滚动到一个随机位置并点击一个按钮时(例如,当第一个可见项目的60%可见并且下一个项目的40%可见时,它会自动滚动到第一个可见项目,以便在按钮后全屏显示),smoothscrolling本身可以正常工作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秒到那个确切的位置以在全屏显示想要的项目,而是尽可能快地跳跃。当在状态0中调用smoothScrollBy时,它不再平滑。为什么这样,是否有任何解决方案?

3 个答案:

答案 0 :(得分:0)

我认为你可以做那样的事情让光滑的滚动。

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 );
    }
}

答案 1 :(得分:0)

好的,我设法在带有处理程序的runnable中运行smoothScroll,现在它可以工作了! 如果有人遇到同样的问题,那么代码就是

    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);
            }
        };  
    });

答案 2 :(得分:0)

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));
                }
            }
        }));