8

我正在开发一个应用程序,我必须在其中使用 viewpager,并且在 viewpager 中的所有项目完成后,我必须调用一个活动。我无法为此获取事件侦听器。这也是我一直在参考的内容: https ://github.com/chiuki/android-swipe-image-viewer/blob/master/src/com/sqisland/android/swipe_image_viewer/MainActivity.java

这是我到目前为止所做的:

public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
    ImagePagerAdapter adapter = new ImagePagerAdapter();
    viewPager.setAdapter(adapter);

    OnPageChangeListener mListener = new OnPageChangeListener() {

        @Override
        public void onPageSelected(int arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {

        }

        @Override
        public void onPageScrollStateChanged(int arg0) {
            Log.i("Doing something here", "On Scroll state changed");
        }
    };
    viewPager.setOnPageChangeListener(mListener);

}

private class ImagePagerAdapter extends PagerAdapter {
    private int[] mImages = new int[] { R.drawable.libin1,
            R.drawable.libin2 };

    @Override
    public int getCount() {
        return mImages.length;

    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == ((ImageView) object);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Context context = MainActivity.this;
        ImageView imageView = new ImageView(context);
        int padding = context.getResources().getDimensionPixelSize(
                R.dimen.padding_medium);
        imageView.setPadding(padding, padding, padding, padding);
        imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
        imageView.setImageResource(mImages[position]);
        ((ViewPager) container).addView(imageView, 0);
        return imageView;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        ((ViewPager) container).removeView((ImageView) object);
    }
}
}

我的问题是如果 viewpager 中的所有项目都已完成,如何获取事件侦听器。

4

6 回答 6

19
private OnPageChangeListener mListener = new OnPageChangeListener() {

    @Override
    public void onPageSelected(int arg0) {
        // TODO Auto-generated method stub
        selectedIndex = arg0;

    }
    boolean callHappened;
    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {
        // TODO Auto-generated method stub
        if( mPageEnd && arg0 == selectedIndex && !callHappened)
        {
            Log.d(getClass().getName(), "Okay");
            mPageEnd = false;//To avoid multiple calls. 
            callHappened = true;
        }else
        {
            mPageEnd = false;
        }
    }

    @Override
    public void onPageScrollStateChanged(int arg0) {
        // TODO Auto-generated method stub
        if(selectedIndex == adapter.getCount() - 1)
        {
            mPageEnd = true;
        }
    }
};
ViewPager.setOnPageChangeListener(mListener);

onPageScrolled或者onPageSelected您可以在此处使用的任何这些,并检查所选页面是否等于ViewPager.

于 2013-04-11T05:20:39.913 回答
3

这三个回调的工作方式如下:

  • onPageScrollStateChanged 使用状态 ViewPager.SCROLL_STATE_DRAGGING 调用
  • onPageScrolled 会被多次调用,其参数 positionOffset 和 positionOffsetPixels 不断增加
  • onPageScrolled 的参数 positionOffset 大于 0.5,onPageScrollStateChanged 调用状态为 SCROLL_STATE_SETTLING
  • onPageSelected 以下一页索引为位置调用
  • onPageScrolled 会被多次调用,其参数 positionOffset 和 positionOffsetPixels 不断增加
  • onPageScrolled 的参数 positionOffset 为 1,调用 onPageScrollStateChanged 状态为 SCROLL_STATE_IDLE

逻辑不应该放在 onPageSelected 和 onPageScrollStateChanged 中,因为有了它们你只知道状态发生了变化。只有在 onPageScrolled 才能获得方向。所以我的实现是这样的:

        private int selectedPageIndex = -1;
        private boolean exitWhenScrollNextPage = false;

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            if (exitWhenScrollNextPage && position == PAGE_COUNT - 1) {
                exitWhenScrollNextPage = false; // avoid call more times
                AndroidLog.error("-------- YEAH!");
            }
        }

        @Override
        public void onPageSelected(int position) {
            selectedPageIndex = position;
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == SCROLL_STATE_IDLE) {
                exitWhenScrollNextPage = selectedPageIndex == PAGE_COUNT - 1;
            }

        }
于 2015-10-31T18:36:20.543 回答
1

感谢三极管的出色回答。

我使用了您为我的项目发布的代码。就我而言,如果用户在最后一个片段上向右滑动,我将完成活动。它运行良好,但是当您向左滑动而不是向右滑动时,它仍在完成活动。

我对您的代码进行了更改并adapter.getCount() - 1替换了selectedIndex. 在这种情况下,如果用户向左滑动,它将不会完成活动。

if( mPageEnd && arg0 == adapter.getCount()-1 && !callHappened){
    Log.d(getClass().getName(), "Okay");
    mPageEnd = false;//To avoid multiple calls. 
    callHappened = true;
}else{
    mPageEnd = false;
}
于 2015-06-26T19:24:20.510 回答
1

建议的答案比我想象的要复杂。所以我创建了一个简单的答案。

我在 ViewPager 类中使用了 OnPageChangeListener。这里我们有 3 种方法。void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) void onPageSelected(int position); 无效 onPageScrollStateChanged(int state);

重要的是要知道 onPageScrollStateChanged() 中的状态是什么以及它们的执行顺序。有 3 个状态,即 SCROLL_STATE_IDLE、SCROLL_STATE_DRAGGING 和 SCROLL_STATE_SETTLING。

这是执行顺序。Scroll_state_dragging --> Scroll_state_settling --> onPageSelected() --> Scroll_state_idle

这个想法是在 onPageSelected() 中保留一个标志来记录当前页码。然后,如果用户在最后一页向左滑动 scroll_state_dragging 调用并启动下一个视图。

private int pagePosition; // keep a class variable
private int[] layouts= new int[]{
    R.layout.welcome_slide1,
    R.layout.welcome_slide2,
    R.layout.welcome_slide3}; 

ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() {
@Override    
public void onPageSelected(int position) {
    addBottomDots(position);
    pagePosition = position;
}

@Override 
public void onPageScrolled(int position, float positionOffset, int arg2) {
}

@Override  
public void onPageScrollStateChanged(int state) {
    if (state == ViewPager.SCROLL_STATE_DRAGGING) {
        if (pagePosition == layouts.length - 1) {
            launchHomeScreen();
        }
    }
}
};

private void launchHomeScreen() {
startActivity(new Intent(IntroductionActivity.this, MainDockerActivity.class));
finish();
}

我在这里创建了一个完整的示例。

于 2017-12-12T04:14:23.677 回答
0

当您在最后一页并滑动完成活动时,状态 SCROLL_STATE_SETTLING 被跳过,寻呼机直接进入 SCROLL_STATE_IDLE

private val viewPagerPageChangeListener = object  : ViewPager.OnPageChangeListener{

    var blnPageTriesToSettle = false

    override fun onPageScrollStateChanged(state: Int) {
        when(state){
            SCROLL_STATE_IDLE ->{
                if (!blnPageTriesToSettle){

                    println("You are at the last page and you slide to finish")
                    finish()

                }
            }
            SCROLL_STATE_DRAGGING ->{  blnPageTriesToSettle = false }
            SCROLL_STATE_SETTLING ->{  blnPageTriesToSettle = true }
        }
    }

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
    }

    override fun onPageSelected(position: Int) {
    }
}
于 2018-11-02T13:25:47.173 回答
0
@Override
public void onPageScrolled(int pageScrolledOn, float positionOffset, int positionOffsetPixels) {

            if(positionOffset == 0F){
                // meaning you cannot scroll further in current scroll direction

                int lastPage = viewPagerAdapter.getCount - 1;
                if (pageScrolledOn == lastPage){

                    //scroll on last page has occured
                    scrolledOnLastPage = true;
                }
            }

        }
于 2015-10-05T19:05:29.447 回答