我正在开发一个应用程序,我必须使用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中的所有项目都已完成,如何获取事件监听器。
答案 0 :(得分:17)
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
中的项目数。
答案 1 :(得分:4)
这三个回调的工作原理如下:
逻辑不应该放在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;
}
}
答案 2 :(得分:1)
感谢Triode提供了很好的答案。
我使用了您为我的项目发布的代码。就我而言,如果用户在最后一个片段上向右滑动,我将完成活动。它工作正常,但是当你向左滑动而不是向右滑动时它仍在完成活动。
我对您的代码进行了更改,并将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;
}
答案 3 :(得分: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;
}
}
}
答案 4 :(得分:0)
建议的答案比我想象的要复杂。所以我创造了一个简单的答案。
我在ViewPager类中使用了OnPageChangeListener。这里我们有3种方法。 void onPageScrolled(int position,float positionOffset,int positionOffsetPixels) void onPageSelected(int position); void onPageScrollStateChanged(int state);
了解onPageScrollStateChanged()中的状态及其执行顺序非常重要。有三种状态为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();
}
我创建了一个完整的示例here.
答案 5 :(得分: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) {
}
}