今天在一个自定义的ViewGroup中嵌套了ViewPager,为了能显示ViewPager前后两页的内容,但是发现使用过程中,ViewPager的setCurrentItem无效了,始终都是从第0页开始显示,求大侠指导。
自定义ViewGroup代码如下:
public class PagerContainer extends FrameLayout implements ViewPager.OnPageChangeListener {
private ViewPager mViewPager;
private boolean mNeedsRedraw = false;
private Point mCenter = new Point();
private Point mInitialTouch = new Point();
public PagerContainer(Context context) {
this(context, null);
}
public PagerContainer(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PagerContainer(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initData();
}
private void initData() {
// 允许子View在其区域内进行绘制
setClipChildren(false);
// child clip功能在Android3.x之后的版本会因为硬件加速而不起作用,所以这里需要关闭硬件加速功能
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
try {
mViewPager = (ViewPager) getChildAt(0);
mViewPager.setOnPageChangeListener(this);
} catch (Exception e) {
throw new IllegalStateException("The root child of PagerContainer must be a ViewPager");
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCenter.x = w / 2;
mCenter.y = h / 2;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mInitialTouch.x = (int) event.getX();
mInitialTouch.y = (int) event.getY();
default:
event.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y - mInitialTouch.y);
break;
}
return mViewPager.dispatchTouchEvent(event);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (mNeedsRedraw) invalidate();
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
mNeedsRedraw = (state != ViewPager.SCROLL_STATE_IDLE);
}
public ViewPager getViewPager() {
return mViewPager;
}
}
布局如下:
<com.yunos.ui.widget.PagerContainer
android:id="@+id/pager_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager_layout"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"/>
</com.yunos.ui.widget.PagerContainer>
MainActivity初始化代码:
private void initView() {
mPagerContainer = (PagerContainer) findViewById(R.id.pager_container);
mViewPager = mPagerContainer.getViewPager();
Log.e(TAG, "get viewpager current item=" + mViewPager.getCurrentItem());
// 如下方法失效,求指导
mViewPager.setCurrentItem(1);
Log.e(TAG, "get viewpager current item=" + mViewPager.getCurrentItem());
mViewPager.setOffscreenPageLimit(AppPageAdapter.NUM_ITEMS);
mViewPager.setClipChildren(true);
mViewPager.setPageMargin(15);
mFragmentPagerAdapter = new AppPageAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mFragmentPagerAdapter);
}
巴扎黑2017-04-17 15:28:06
Oh, what an idiot, I looked at the source code of ViewPager about setCurrentItem and found:
if (mAdapter == null || mAdapter.getCount() <= 0) {
setScrollingCacheEnabled(false);
return;
}
You should call setCurrentItem after setAdapter. I have made this stupid mistake and I am speechless.
The question will not be deleted, but I will give you a warning to prevent similar mistakes!
巴扎黑2017-04-17 15:28:06
mPagerContainer.setCurrentItem(1);
This is a line of error code. The container does not have a setCurrentItem method. It should be mViewPager.setCurrentItem(1);
setCurrentItem should be after setAdapter.
伊谢尔伦2017-04-17 15:28:06
Whose currentIterm should mPagerContainer set? What is printed in the log is indeed mViewPager