竖直滑动View制作引导页
2016-06-07 15:37
211 查看
传承者(Inheritors)打造共同进步生态圈!!!
转载:http://write.blog.csdn.net/postedit/23692439
三段论:滑动所需要的准备,自定义ViewGoup,布局中使用
转载:http://write.blog.csdn.net/postedit/23692439
三段论:滑动所需要的准备,自定义ViewGoup,布局中使用
自定义ViewGoup
public class VerticalLinearLayout extends ViewGroup { public class VerticalLinearLayout extends ViewGroup { /** * 屏幕的高度 */ private int mScreenHeight; /** * 手指按下时的getScrollY */ private int mScrollStart; /** * 手指抬起时getScrollY */ private int mScrollEnd; /** * 记录移动时的Y */ private int mLastY; /** * 滚动的辅助类 */ private Scroller mScroller; /** * 是否正在滚动 */ private boolean isScrolling; /** * 加速度检测 * */ private VelocityTracker mVelocityTracker; /** * 记录当前页 * */ private int currentPage = 0; private OnPageChangeListener mOnPageChangeListener; private int childHeight; public VerticalLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); /** * 获得屏幕的高度 */ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); mScreenHeight = outMetrics.heightPixels; //初始化 mScroller = new Scroller(context); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int count = getChildCount(); for (int i = 0; i < count; i++) { View childView = getChildAt(i); measureChild(childView,widthMeasureSpec,mScreenHeight); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if(changed){ int childCount = getChildCount(); //设置主布局的高度 MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams(); lp.height = mScreenHeight*childCount; setLayoutParams(lp); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); if(child.getVisibility() != View.GONE){ child.layout(l,i*mScreenHeight,r,(i+1)*mScreenHeight);//调用每个自布局的layout } childHeight = getChildAt(0).getMeasuredHeight(); } } } @Override public boolean onTouchEvent(MotionEvent event) { //如果当前正在滚动,调用父类的onTouchEvent if (isScrolling) { return super.onTouchEvent(event); } int action =event.getAction(); int y = (int)event.getY(); obtainVelocity(event); switch (action){ case MotionEvent.ACTION_DOWN: mScrollStart = getScrollY(); mLastY = y; break; case MotionEvent.ACTION_MOVE: if(!mScroller.isFinished()){ mScroller.abortAnimation(); } int dy = mLastY - y; //边际值检查 int scrollY = getScrollY(); //已经到达顶端,下拉多少,就往上滚动多少 if(dy<0 && scrollY+dy < 0 ){ dy = -scrollY; } //已经达到底部了,上拉多少,留往下滚动多少 if(dy>0 && scrollY+dy > getHeight() - mScreenHeight){ dy = getHeight() - mScreenHeight - scrollY; } scrollBy(0,dy); mLastY = y; break; case MotionEvent.ACTION_UP: mScrollEnd = getScrollY(); int dScrollY = mScrollEnd - mScrollStart; if(wantScrollToNext()){ //往上滑动 if(shouldScrollToNext()){ mScroller.startScroll(0,getScrollY(),0, mScreenHeight - dScrollY); }else{ mScroller.startScroll(0,getScrollY(),0,-dScrollY); } } if(wantScrollToPre()){ //往下下滑 if(shouldScrollToPre()){ mScroller.startScroll(0,getScrollY(),0,-mScreenHeight - dScrollY); }else{ mScroller.startScroll(0,getScrollY(),0 , -dScrollY); } } isScrolling = true; postInvalidateDelayed(0); recycleVelocity(); break; } return true; } /** * 根据滚动距离判断是否能够滚动到下一页 */ private boolean shouldScrollToNext() { return mScrollEnd - mScrollStart > mScreenHeight / 2 || Math.abs(getYVelocity()) > 600; } /** * 根据用户滑动,判断用户的意图是否是滚动到下一页 * */ private boolean wantScrollToNext(){ return mScrollEnd> mScrollStart ; } /** * 根据滚动距离判断是否能够滚动到上一页 * @return */ private boolean shouldScrollToPre(){ return -mScrollEnd + mScrollStart > mScreenHeight / 2 || Math.abs(getYVelocity())>600; } /** * 根据用户滑动,判断用户意图是否是滚动到上一页 * @return */ private boolean wantScrollToPre(){ return mScrollEnd < mScrollStart; } @Override public void computeScroll() { super.computeScroll(); if(mScroller.computeScrollOffset()){ scrollTo(0,mScroller.getCurrY()); postInvalidate(); }else { int position = getScrollY() / mScreenHeight; if(position != currentPage){ if(mOnPageChangeListener!= null){ currentPage = position; mOnPageChangeListener.onPageChange(currentPage); }} isScrolling = false; } } /** * 初始化加速度检测器 * @param event */ private void obtainVelocity(MotionEvent event) { if(mVelocityTracker == null){ mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(event); } /** * 资源释放 */ private void recycleVelocity(){ if(mVelocityTracker != null){ mVelocityTracker.recycle(); mVelocityTracker = null; } } /** * 设置回调接口 * @param onPageChangeListener */ public void setOnPageChangeListener(OnPageChangeListener onPageChangeListener){ mOnPageChangeListener = onPageChangeListener; } public int getYVelocity() { mVelocityTracker.computeCurrentVelocity(1000); return (int) mVelocityTracker.getYVelocity(); } public interface OnPageChangeListener{ void onPageChange(int currentPage); } }
布局出来
<com.example.administrator.testapplication.VerticalLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:id="@+id/id_main_ly" android:background="#fff" tools:context="com.example.administrator.testapplication.MainActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@mipmap/shenang" > </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@mipmap/dragon_boat" > </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@mipmap/zhagao" > </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@mipmap/dragon_boat_fes" > </RelativeLayout> </com.example.administrator.testapplication.VerticalLinearLayout>
在Activity中使用
public class MainActivity extends Activity { private VerticalLinearLayout mMainLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMainLayout = (VerticalLinearLayout) findViewById(R.id.id_main_ly); mMainLayout.setOnPageChangeListener(new VerticalLinearLayout.OnPageChangeListener() { @Override public void onPageChange(int currentPage) { Toast.makeText(MainActivity.this, "第"+(currentPage+1)+"页", Toast.LENGTH_SHORT).show(); } }); } }
相关文章推荐
- arm汇编中ldr指令中出现的等号作用
- (Android)线程池
- iOS巅峰之摇一摇功能的实现
- ubuntu修改host
- 图像的变换模型
- scrollview拦截子控件的滑动
- 如何检测鼠标/触摸点碰到某个collider2D?
- iOS中常见的6种传值方式,UIPageViewController
- python itertools模块指南
- APK加固
- ERP升级实施分布整理
- Spring容器初始化过程
- jQuery 如何先创建、再修改、后添加DOM元素
- TortoiseGit和Git操作git@osc简要说明
- JRDB:iOS对FMDB的超好用封装
- Android 动画 - AnimationSet 动画集合使用(附图)
- 动态加载so库文件
- 4、redis.conf中replication配置项说明
- android的Toast吐司在子线程中弹出的工具类
- ubuntu 16.04下最下新firefox 46 安装flash player