Simple ViewPager

花了几个小时,搞了一个自定义ViewPager雏形。

没有内存管理,没有封装对外的接口。

以后有时间再慢慢丰满,当是一个记录。

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.Scroller;

public class CustomViewPager extends FrameLayout {

	private float mFlingSlop;//min fling threshold
	private float mDownX;
	private float mLastX;
	private Scroller mScroller;//used to move child view smoothly
	private VelocityTracker mTracker;//calculate the velocity when up key is pressed
	private int mCurrentPage = 0;//record the current page
	private boolean mHitBound = false;//if at first or last page
	private int mChildCount = 0;//child view count

	public CustomViewPager(Context context, AttributeSet attrs) {
		super(context, attrs);
		mScroller = new Scroller(context, new DecelerateInterpolator(2));		
		mFlingSlop = ViewConfiguration.get(context).getScaledMinimumFlingVelocity() * 100 / 4;//this value may not proper, but currently used
	}

	@Override
	public void onLayout(boolean changed, int l, int t, int r, int b) {
		mChildCount = getChildCount();
		int w = r - l;
		for (int i = 0; i < mChildCount; i++) {
			View view = getChildAt(i);
			view.layout(i * w, t, (i + 1) * w, b);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				if (!mScroller.isFinished()) {//clear the scroller effect to make touch fluent
					mScroller.abortAnimation();
					mScroller.forceFinished(true);
				}
				mHitBound = false;
				mLastX = event.getX();
				mDownX = mLastX;
				if (mTracker == null) {
					mTracker = VelocityTracker.obtain();
				}
				mTracker.addMovement(event);
				break;
			case MotionEvent.ACTION_MOVE:
				int scrollX = getScrollX();
				float dx = (mLastX - event.getX());
				if (scrollX + dx <= 0) {//first page hit
					scrollTo(0, 0);
					mHitBound = true;
					return false;
				} else if (scrollX + dx >= getWidth() * (mChildCount - 1)) {//last page hit
					scrollTo(getWidth() * (mChildCount - 1), 0);
					mHitBound = true;
					return false;
				} else {
					mTracker.addMovement(event);
					scrollBy((int) dx, 0);
				}
				mLastX = event.getX();
				break;
			case MotionEvent.ACTION_CANCEL:
			case MotionEvent.ACTION_UP:
				if (mHitBound) {// when hit bound, release VelocityTracker
					releaseTracker();
					return false;
				}
				int deltaX = 0;
				int deltaY = 0;
				int rest = getScrollX() % getWidth();//scroll offset in page
				int direction = event.getX() - mDownX > 0 ? -1 : 1; // 1 forward, -1 backward;
				int toNext = 0;
				int sX = Math.abs((getScrollX() - getWidth() * mCurrentPage) % getWidth());
				if (sX >= getWidth() / 2f) {//when move over half page, move to next page 
					toNext |= 1;
				} else {
					toNext |= 0;
				}

				mTracker.computeCurrentVelocity(1000);
				float velocity = Math.abs(mTracker.getXVelocity());
				if (velocity >= mFlingSlop) {//when move fast enough, move to next page
					toNext |= 1;
				} else {
					toNext |= 0;
				}

				if (toNext == 1) {// next page
					if (direction == 1) {// forward
						deltaX = getWidth() - rest;
						mCurrentPage++;
					} else {// backward
						deltaX = -rest;
						mCurrentPage--;
					}
				} else {
					if (direction == 1) {{// forward
						deltaX = -rest;
					} else {// backward
						deltaX = getWidth() - rest;
					}
				}

				mScroller.startScroll(getScrollX(), getScrollY(), deltaX, deltaY, 500);

				invalidate();

				releaseTracker();
				break;
			default:
				break;
		}
		return true;
	}

	private void releaseTracker() {
		if (mTracker != null) {
			mTracker.clear();
			mTracker.recycle();
			mTracker = null;
		}
	}

	@Override
	public void computeScroll() {
		if (mScroller.computeScrollOffset()) {//when implement mScroller.startScroll(), this will return true
			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
			invalidate();
		} else {
			super.computeScroll();
		}
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ViewPager嵌套ViewPager的实现可以通过使用Fragment来实现。具体步骤如下: 1. 创建外层ViewPager的适配器,内层ViewPager的适配器和内层ViewPager的Fragment适配器; 2. 在外层ViewPager的Fragment中创建内层ViewPager,并设置内层ViewPager的适配器为内层ViewPager的适配器; 3. 在内层ViewPager的Fragment中创建需要的子Fragment,并设置内层ViewPager的Fragment适配器为子Fragment的适配器。 代码示例: ```java public class OuterFragment extends Fragment { private ViewPager mInnerViewPager; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_outer, container, false); mInnerViewPager = view.findViewById(R.id.inner_view_pager); InnerPagerAdapter innerPagerAdapter = new InnerPagerAdapter(getChildFragmentManager()); mInnerViewPager.setAdapter(innerPagerAdapter); return view; } private class InnerPagerAdapter extends FragmentPagerAdapter { public InnerPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return InnerFragment.newInstance(position); } @Override public int getCount() { return 3; } } } public class InnerFragment extends Fragment { private ViewPager mSubViewPager; public static InnerFragment newInstance(int position) { InnerFragment fragment = new InnerFragment(); Bundle args = new Bundle(); args.putInt("position", position); fragment.setArguments(args); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_inner, container, false); mSubViewPager = view.findViewById(R.id.sub_view_pager); SubPagerAdapter subPagerAdapter = new SubPagerAdapter(getChildFragmentManager()); mSubViewPager.setAdapter(subPagerAdapter); return view; } private class SubPagerAdapter extends FragmentPagerAdapter { public SubPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return SubFragment.newInstance(position); } @Override public int getCount() { return 3; } } } public class SubFragment extends Fragment { public static SubFragment newInstance(int position) { SubFragment fragment = new SubFragment(); Bundle args = new Bundle(); args.putInt("position", position); fragment.setArguments(args); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_sub, container, false); return view; } } ``` 其中,fragment_outer.xml、fragment_inner.xml和fragment_sub.xml分别对应外层ViewPager的Fragment、内层ViewPager的Fragment和内层ViewPager的子Fragment的布局文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值