如何停止自动旋转 ViewPager 列表视图项?

How to stop autorotating ViewPager listview item?

我有一个包含 ViewPager 的列表视图项。以下代码在我创建的一个方法中,其目的是让ViewPager自动滑动。

但是,当视图滚出屏幕时,runnable 会继续调用自身并滚动。在包含其中几个的列表视图中,即使不在屏幕上,这些回调也会继续被调用。

跟踪每个列表视图的处理程序并在它不再出现在屏幕上时取消它的模式是什么?当它回到屏幕上时,我还必须重新启用它。

谢谢!

    // Inside getView() in my adapter

    if (autoSlide) {

        final int autoSlideDelayMs = 5000;

        final Handler handler = new Handler();

        // Attach handler ref to ViewPager so later we can stop this.
        viewPager.setTag(handler);

        final Runnable scrollRunnable = new Runnable() {
            public void run() {
                final int currentItem = viewPager.getCurrentItem();
                final int itemCount = viewPager.getAdapter().getCount();
                final int itemToShow = currentItem == itemCount - 1 ? 0 : viewPager.getCurrentItem() + 1;
                viewPager.setCurrentItem(itemToShow, true);

                if (handler != null) {
                    handler.postDelayed(this, autoSlideDelayMs);
                }
            }
        };
        handler.postDelayed(scrollRunnable, autoSlideDelayMs);
    }

我也在做以下事情。这可能不是最佳编码实践,但我试图保留对处理程序的引用并在我不再发生自动滑动时将其设为空。

    // In my fragment
    listview.setRecyclerListener(new AbsListView.RecyclerListener() {
        @Override
        public void onMovedToScrapHeap(View view) {
            final ExtendedViewPager viewPager = (ExtendedViewPager)view.findViewById(R.id.pager);
            if (viewPager != null) {
               Handler h = (Handler)viewPager.getTag();

                if (h != null) {
                    h = null;
                    System.gc();
                }
            }
        }
    });

我选择在 View Pager 中使用标签来指示滚动是否应该继续(而不是将 Hander 设置为标签对象)。所以我的代码现在是这样的:

片段中:

/**
 *
 */
@Override
public void onDestroyView() {
    super.onDestroyView();

    // Stop any autosliding slideshow listview items
    final int childCount = listview.getChildCount();
    int currentChild = 0;

    while(currentChild < childCount) {
        stopAutoSliding(listview.getChildAt(currentChild++));
    }
}


/**
 * Set a tag to the view pager to indicate autosliding should stop
 */
private void stopAutoSliding(final View view) {
    final View viewPager = view.findViewById(R.id.pager);
    if (viewPager != null) {
        viewPager.setTag(new Object());
    }
}

在适配器中:

    if (autoSlide) {

        final int autoSlideDelayMs = 5000;

        final Handler handler = new Handler();

        final Runnable scrollRunnable = new Runnable() {
            public void run() {
                final int currentItem = viewPager.getCurrentItem();
                final int itemCount = viewPager.getAdapter().getCount();
                final int itemToShow = currentItem == itemCount - 1 ? 0 : viewPager.getCurrentItem() + 1;
                viewPager.setCurrentItem(itemToShow, true);

                // If the viewPager has a tag, it means we shouldn't keep scrolling.
                final Object continueSliderFlag = viewPager.getTag();

                if (continueSliderFlag == null) {
                    handler.postDelayed(this, autoSlideDelayMs);
                }
            }
        };
        handler.postDelayed(scrollRunnable, autoSlideDelayMs);
    }