【问题标题】:onScrollStateChanged wont scroll smooth when Scroll_State_IdleScroll_State_Idle 时 onScrollStateChanged 不会平滑滚动
【发布时间】:2014-09-04 11:10:23
【问题描述】:

我有一个 listView,其中包含几个在全屏中具有相同高度的项目。当我释放滚动时,我想自动平滑滚动到该项目,这会占用屏幕上的最大空间。当我滚动到随机位置并点击按钮时,平滑滚动本身会起作用(例如,当第一个可见项目的 60% 可见并且以下项目的 40% 可见时,它会自动平滑滚动到第一个可见项目以在按钮后全屏显示 - 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 调用时不再平滑。为什么会这样,有什么解决办法吗?

【问题讨论】:

    标签: android listview scroll smooth-scrolling onscrolllistener


    【解决方案1】:

    我认为你可以做这样的事情来让平滑滚动。

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

    【讨论】:

    • 感谢@anderson_acs 的帮助。我对您的代码进行了一些优化(仅转发顶部:scrollSmoothTopAfterMiddle(top)),但现在它像以前一样快速滚动到正确的位置而没有动画,并且还平滑地滚动了所需的距离。换句话说,我在滚动时松开手指-> 正确位置非平滑滚动-> 进一步滚动到正确位置平滑滚动的距离。请问我是否表达自己草率。有什么改进的想法吗?再次感谢
    • @Simsala,很抱歉,我无法真正理解您要说什么,您要对哪一部分进行改进?
    【解决方案2】:

    好的,我设法使用处理程序在可运行文件中运行了 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);
                }
            };  
        });
    

    【讨论】:

      【解决方案3】:
      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));
                      }
                  }
              }));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-05
        • 2022-11-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多