在PagerAdapter中实现循环滚动
我正在使用PagerAdapter进行水平滑动,以在我的应用中显示报纸页面。
目前我想在这个应用程序中实现循环滚动。现在我已经做了什么, whenever I am getting on last page I try to set the currentItem to first page
即该功能适用于最后一页到第一页,但问题是那我该如何从第一页转到最后一页。 在这里,我粘贴与pagerAdapter&onPageChangeListener相关的代码: -
awesomeAdapter = new AwesomePagerAdapter(awesomePager);
awesomePager.setAdapter(awesomeAdapter);
awesomePager.setPageMargin(10);
awesomePager.setOnPageChangeListener(new OnPageChangeListener() {
int lastPosition;
float posOffset = 0;
@Override
public void onPageSelected(int position) {
viewerPage = position;
CommonLogic.logMessage("Viewer Page:- "+ viewerPage, TAG, Log.VERBOSE);
posOffset = 0;
}
@Override
public void onPageScrolled(int position,float positionOffset,int positionOffsetPixels) {
if (positionOffset == 0 && positionOffsetPixels == 0 && position != 0) {
lastPosition = position;
}
posOffset -= positionOffset;
CommonLogic.logMessage(" Position:- "
+ position + " Position Offset:- " + positionOffset
+ " Position Offset Variable:- "
+ posOffset
+ " Position Offset Pixels:- "
+ positionOffsetPixels
+ " Last Position " + lastPosition,
TAG, Log.VERBOSE);
CommonLogic.logMessage(" Last Position "
+ lastPosition, TAG, Log.VERBOSE);
}
@Override
public void onPageScrollStateChanged(int state) {
// To Detect the Last Page & This Sets it to first page.This working fine.
if (state == ViewPager.SCROLL_STATE_DRAGGING && viewerPage == (uris.size() - 1)) {
CommonLogic.logMessage("Scroll State Changed ", TAG,Log.VERBOSE);
postDelayed(new Runnable() {
@Override
public void run() {
awesomePager.setCurrentItem(0, true);
}
}, 200);
}
// I have also used this to detect whether the user is on first & try to move on last page,but it is not working well.
else if (state == ViewPager.SCROLL_STATE_DRAGGING && (lastPosition == 0 || lastPosition == (uris.size() - 1)) && viewerPage == 0 && posOffset <= 0) {
CommonLogic.logMessage( "Scroll State Changed ", TAG,Log.VERBOSE);
postDelayed(new Runnable() {
@Override
public void run() {
awesomePager.setCurrentItem((uris.size() - 1), true);
}
}, 200);
}
}
}
});
在我的情况下,PagerAdapter即AwesomweAdapter也是如此: -
private class AwesomePagerAdapter extends PagerAdapter {
ViewPager pdfContainer;
DocumentNewView documentNewView;
CustomViewPager customViewPager;
public AwesomePagerAdapter(CustomViewPager awesomePager) {
this.customViewPager = awesomePager;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public int getCount() {
return uris.size();
}
public DocumentNewView addViewAt(int position, DocumentNewView mainView) {
CommonLogic.logMessage("Position of View:- " + position, TAG,
Log.VERBOSE);
pdfContainer.addView(mainView);
return mainView;
}
/**
* Create the page for the given position. The adapter is responsible
* for adding the view to the container given here, although it only
* must ensure this is done by the time it returns from
* {@link #finishUpdate()}.
*
* @param container
* The containing View in which the page will be shown.
* @param position
* The page position to be instantiated.
* @return Returns an Object representing the new page. This does not
* need to be a View, but can be some other container of the
* page.
*/
@Override
public Object instantiateItem(View collection, int position) {
CommonLogic
.logMessage("Instantiate Item Called ", TAG, Log.VERBOSE);
documentNewView = new DocumentNewView(cxt, display, customViewPager);
documentNewView.setPdfContext(new PdfContext());
CodecDocument codecDocument = documentNewView.open(uris
.get(position));
documentNewView.renderDocument(codecDocument);
documentNewView.setMaxZoom(4f);
documentNewView.setVerticalScrollBarEnabled(true);
codecDocument = null;
this.pdfContainer = (ViewPager) collection;
return addViewAt(position, documentNewView);
}
/**
* Remove a page for the given position. The adapter is responsible for
* removing the view from its container, although it only must ensure
* this is done by the time it returns from {@link #finishUpdate()}.
*
* @param container
* The containing View from which the page will be removed.
* @param position
* The page position to be removed.
* @param object
* The same object that was returned by
* {@link #instantiateItem(View, int)}.
*/
@Override
public void destroyItem(View collection, int position, Object view) {
pdfContainer.removeView((DocumentNewView) view);
}
/**
* Called when the a change in the shown pages has been completed. At
* this point you must ensure that all of the pages have actually been
* added or removed from the container as appropriate.
*
* @param container
* The containing View which is displaying this adapter's
* page views.
*/
@Override
public void finishUpdate(View arg0) {
CommonLogic.logMessage("Finish Update Called ", TAG, Log.VERBOSE);
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void startUpdate(View arg0) {
CommonLogic.logMessage("State Update Called ", TAG, Log.VERBOSE);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == ((DocumentNewView) object);
}
请给我任何建议/更改我的代码(如果适用)。 提前致谢。
我可以通过覆盖OnPageChangeListener
onPageSelected
方法来实现此onPageSelected
。 考虑你有三个页面,按照A<->B<->C
顺序排列。 如果我们从A
向右滚动,并且如果从C
向左滚动,则达到A
目标是达到C
要做到这一点,定义你有5页(3 + 2),并组织页面如下:
C
<->A<->B<->C<->
A
现在在onPageSelected
方法中,检查位置是否为0
,将其更改为3
( getCount()-2
),如果位置为4
( getCount()-1
),则将其更改为1
。 确保使用该方法:
setCurrentItem(item, smoothScroll)
这里是CircularPagerAdaptor类的完整代码:
package zolender.adapters;
import android.content.Context;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
public class CircularPagerAdapter extends PagerAdapter{
private int[] pageIDsArray;
private int count;
public CircularPagerAdapter(final ViewPager pager, int... pageIDs) {
super();
int actualNoOfIDs = pageIDs.length;
count = actualNoOfIDs + 2;
pageIDsArray = new int[count];
for (int i = 0; i < actualNoOfIDs; i++) {
pageIDsArray[i + 1] = pageIDs[i];
}
pageIDsArray[0] = pageIDs[actualNoOfIDs - 1];
pageIDsArray[count - 1] = pageIDs[0];
pager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
int pageCount = getCount();
if (position == 0){
pager.setCurrentItem(pageCount-2,false);
} else if (position == pageCount-1){
pager.setCurrentItem(1,false);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
});
}
public int getCount() {
return count;
}
public Object instantiateItem(View container, int position) {
LayoutInflater inflater = (LayoutInflater) container.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int pageId = pageIDsArray[position];
View view = inflater.inflate(pageId, null);
((ViewPager) container).addView(view, 0);
return view;
}
@Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
@Override
public void finishUpdate(View container) {
// TODO Auto-generated method stub
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == ((View) object);
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
// TODO Auto-generated method stub
}
@Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
}
@Override
public void startUpdate(View container) {
// TODO Auto-generated method stub
}
}
这里是你如何使用它:
myPager = (ViewPager) findViewById(R.id.myfivepanelpager);
PagerAdapter adapter = new CircularPagerAdapter(myPager, new int[]{R.layout.farleft, R.layout.left, R.layout.middle, R.layout.right, R.layout.farright});
myPager.setAdapter(adapter);
myPager.setCurrentItem(3);
我还需要一个圆形的ViewPager。 这就是我所做的。 我假设你从某处获得pageCount值。
...
pager = (ViewPager) findViewById(R.id.pager);
//Gesture detection
final GestureDetector gestureDetector = new GestureDetector(new MyGestureDetector());
pager.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
});
//pagelistener is just for getting selected page
pager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
selectedPage = position;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
这里是手势检测器。 从这里复制
class MyGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
int SWIPE_MIN_DISTANCE = Utils.ConvertToPixel(mContext, 50);
int SWIPE_MAX_OFF_PATH = Utils.ConvertToPixel(mContext, 250);
int SWIPE_THRESHOLD_VELOCITY = Utils.ConvertToPixel(mContext, 200);
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
// right to left swipe
if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY
&& selectedPage == (pageCount - 1)) {
pager.setCurrentItem(0);
return true;
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY
&& selectedPage == 0) {
pager.setCurrentItem(pageCount - 1);
return true;
}
} catch (Exception e) {
// nothing
}
return false;
}
}
在Z0lenDer的回答中展开,当使用常规的ViewPager
,您不需要为每个关联的视图释放内存,因此存储创建的视图而不是布局ID会更高效。 如果想要在切换项目时摆脱任何延迟和闪烁,这是必要的。
使用onPageSelected
,动画也存在问题,因为它在切换之前不会让幻灯片完成。 我发现要避免这种情况的唯一方法是只有在滚动状态更改为SCROLL_STATE_IDLE
并仅在onPageSelected
设置当前项目时才执行切换。
private int currentPage = 0;
...
pager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
currentPage = position;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
Log.d(TAG, "onPageScrollStateChanged: " + state);
if (state == ViewPager.SCROLL_STATE_IDLE) {
int pageCount = getCount();
if (currentPage == 0){
pager.setCurrentItem(pageCount-2,false);
} else if (currentPage == pageCount-1){
pager.setCurrentItem(1,false);
}
}
}
});
链接地址: http://www.djcxy.com/p/91219.html
上一篇: Implementing Circular Scrolling In PagerAdapter
下一篇: ListView slide left/right like Samsung contact ListView