zoukankan      html  css  js  c++  java
  • Android UI(继承控件)--VerticalViewPager 垂直方向的viewpager

      1 package com.wzq.verticalViewPager;
      2 
      3 import android.content.Context;
      4 import android.util.AttributeSet;
      5 import android.util.DisplayMetrics;
      6 import android.util.Log;
      7 import android.view.MotionEvent;
      8 import android.view.VelocityTracker;
      9 import android.view.View;
     10 import android.view.ViewGroup;
     11 import android.view.WindowManager;
     12 import android.widget.Scroller;
     13 
     14 /**
     15  * 垂直方向上的ViewPager
     16  */
     17 public class VerticalViewPager extends ViewGroup {
     18 
     19     /**
     20      * 屏幕的高度
     21      */
     22     private int mScreenHeight;
     23     /**
     24      * 手指按下时的getScrollY
     25      */
     26     private int mScrollStart;
     27     /**
     28      * 手指抬起时的getScrollY
     29      */
     30     private int mScrollEnd;
     31     /**
     32      * 记录移动时的Y
     33      */
     34     private int mLastY;
     35     /**
     36      * 滚动的辅助类
     37      */
     38     private Scroller mScroller;
     39     /**
     40      * 是否正在滚动
     41      */
     42     private boolean isScrolling;
     43     /**
     44      * 加速度检测
     45      */
     46     private VelocityTracker mVelocityTracker;
     47     /**
     48      * 记录当前页
     49      */
     50     private int currentPage = 0;
     51 
     52     private OnPageChangeListener mOnPageChangeListener;
     53 
     54     /**
     55      * 回调接口
     56      */
     57     public interface OnPageChangeListener {
     58         void onPageChange(int currentPage);
     59     }
     60 
     61     /**
     62      * 设置回调接口
     63      * 
     64      * @param listener
     65      */
     66     public void setOnPageChangeListener(OnPageChangeListener listener) {
     67         mOnPageChangeListener = listener;
     68     }
     69 
     70     public VerticalViewPager(Context context, AttributeSet attrs) {
     71         super(context, attrs);
     72         /**
     73          * 获取屏幕高度
     74          */
     75         DisplayMetrics dm = new DisplayMetrics();
     76         WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
     77         wm.getDefaultDisplay().getMetrics(dm);
     78         mScreenHeight = dm.heightPixels;
     79         // 初始化滚动辅助类
     80         mScroller = new Scroller(context);
     81     }
     82 
     83     @Override
     84     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     85         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     86         int count = getChildCount();
     87         for (int i = 0; i < count; i++) {
     88             View childView = getChildAt(i);
     89             measureChild(childView, widthMeasureSpec, heightMeasureSpec);
     90         }
     91     }
     92 
     93     @Override
     94     protected void onLayout(boolean changed, int l, int t, int r, int b) {
     95         if (changed) {
     96             childCount = getChildCount();
     97 
     98             // 1, 设置主布局的高度(孩子个数 * 屏幕高度)
     99             MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
    100             lp.height = mScreenHeight * childCount;
    101             setLayoutParams(lp);
    102             // 2,调整每个孩子的高度
    103             for (int i = 0; i < childCount; i++) {
    104                 View child = getChildAt(i);
    105                 if (child.getVisibility() != View.GONE) {
    106                     child.layout(l, i * mScreenHeight, r, (i + 1) * mScreenHeight);
    107                 }
    108             }
    109         }
    110     }
    111 
    112     private String TAG = "VerticalViewPager";
    113     private int childCount;
    114 
    115     @Override
    116     public boolean onTouchEvent(MotionEvent event) {
    117         // 如果当前正在滚动,调用父类的onTouchEvent
    118         if (isScrolling)
    119             return super.onTouchEvent(event);
    120         int action = event.getAction();
    121         int y = (int) event.getY();
    122         obtainVelocity(event);
    123         switch (action) {
    124         case MotionEvent.ACTION_DOWN:
    125             mScrollStart = getScrollY();
    126             mLastY = y;
    127             Log.i(TAG, "111111---ACTION_DOWN getScrollY = " + mScrollStart + " ; mLastY = "
    128                     + mLastY);
    129             break;
    130         case MotionEvent.ACTION_MOVE:
    131             if (!mScroller.isFinished()) {
    132                 mScroller.abortAnimation();
    133             }
    134             int dy = mLastY - y;
    135             int scrollY = getScrollY();
    136             // 边界值检查
    137             Log.i(TAG, "2---ACTION_MOVE ; dy =  " + dy + " scrollY = " + scrollY);
    138             // 已经到达控件最顶端,此时下拉,拉拽速度减半
    139             if (dy < 0 && scrollY <= 0) {
    140                 dy = dy / 2;// 控件移动速度减半
    141             }
    142             // 已经到达控件最底部,此时上拉,拉拽速度减半
    143             // if (dy > 0 && scrollY + dy > getHeight() - mScreenHeight) {
    144             if (dy > 0 && scrollY > (childCount - 1) * mScreenHeight) {
    145                 dy = dy / 2;// 控件移动速度减半
    146             }
    147             scrollBy(0, dy);
    148             mLastY = y;
    149             break;
    150         case MotionEvent.ACTION_UP:
    151             mScrollEnd = getScrollY();
    152             int dScrollY = mScrollEnd - mScrollStart;
    153             Log.i(TAG, "333333---ACTION_UP_UP getScrollY = " + mScrollEnd + " ; dScrollY = "
    154                     + dScrollY);
    155             if (wantScrollToNext()) {// 往上滑动
    156                 if (mScrollStart == (childCount - 1) * mScreenHeight) {// 已经在整个控件的最底部了
    157                     mScroller.startScroll(0, getScrollY(), 0, -dScrollY);// 回弹(用户不想换页)
    158                 } else {
    159                     if (shouldScrollToNext()) {
    160                         mScroller.startScroll(0, getScrollY(), 0, mScreenHeight - dScrollY);// 换页
    161                     } else {
    162                         mScroller.startScroll(0, getScrollY(), 0, -dScrollY);// 回弹
    163                     }
    164                 }
    165             }
    166             if (wantScrollToPre()) {// 往下滑动
    167                 if (mScrollStart == 0) {// 已经在整个控件的最顶部了
    168                     mScroller.startScroll(0, getScrollY(), 0, -dScrollY);// 回弹
    169                 } else {
    170                     if (shouldScrollToPre()) {
    171                         mScroller.startScroll(0, getScrollY(), 0, -mScreenHeight - dScrollY);// 换页
    172                     } else {
    173                         mScroller.startScroll(0, getScrollY(), 0, -dScrollY);// 回弹
    174                     }
    175                 }
    176             }
    177             isScrolling = true;
    178             postInvalidate();
    179             recycleVelocity();
    180             break;
    181         }
    182         return true;
    183     }
    184 
    185     @Override
    186     public void computeScroll() {
    187         super.computeScroll();
    188         // the animation is not yet finished
    189         if (mScroller.computeScrollOffset()) {
    190             scrollTo(0, mScroller.getCurrY());
    191             postInvalidate();
    192             Log.i(TAG, "44---computeScroll  animation is not not not not not yet finished");
    193         } else {// animation is finished
    194             Log.i(TAG, "44---computeScroll  animation finished");
    195             int position = getScrollY() / mScreenHeight;
    196             Log.i(TAG, "~~~~~~~~~computeScroll  position = " + position + " , currentPage = "
    197                     + currentPage);
    198             if (position != currentPage) {
    199                 if (mOnPageChangeListener != null) {
    200                     currentPage = position;
    201                     mOnPageChangeListener.onPageChange(currentPage);
    202                 }
    203             }
    204             isScrolling = false;
    205         }
    206     }
    207 
    208     /**
    209      * 根据滚动距离判断是否能够滚到下一页
    210      * 
    211      * @return
    212      */
    213     private boolean shouldScrollToNext() {
    214         return mScrollEnd - mScrollStart > mScreenHeight / 2 || Math.abs(getVelocity()) > 600;
    215     }
    216 
    217     /**
    218      * 根据滚动距离判断是否能够滚动到上一页
    219      * 
    220      * @return
    221      */
    222     private boolean shouldScrollToPre() {
    223         return -mScrollEnd + mScrollStart > mScreenHeight / 2 || Math.abs(getVelocity()) > 600;
    224     }
    225 
    226     /**
    227      * 根据用户滑动,判断用户的意图是否是滚动到上一页,即手向下滑动。
    228      * 
    229      * @return
    230      */
    231     private boolean wantScrollToPre() {
    232         return mScrollEnd < mScrollStart;
    233     }
    234 
    235     /**
    236      * 根据用户滑动,判断用户的意图是否是滚到到下一页,即手向上滑动。
    237      * 
    238      * @return
    239      */
    240     private boolean wantScrollToNext() {
    241         return mScrollEnd > mScrollStart;
    242     }
    243 
    244     /**
    245      * 获取Y方向的加速度
    246      * 
    247      * @return
    248      */
    249     private int getVelocity() {
    250         mVelocityTracker.computeCurrentVelocity(1000);
    251         return (int) mVelocityTracker.getYVelocity();
    252     }
    253 
    254     /**
    255      * 初始化加速度检测器
    256      * 
    257      * @param event
    258      */
    259     private void obtainVelocity(MotionEvent event) {
    260         if (mVelocityTracker == null) {
    261             mVelocityTracker = VelocityTracker.obtain();
    262         }
    263         mVelocityTracker.addMovement(event);
    264     }
    265 
    266     /**
    267      * 是否资源
    268      */
    269     private void recycleVelocity() {
    270         if (mVelocityTracker != null) {
    271             mVelocityTracker.recycle();
    272             mVelocityTracker = null;
    273         }
    274     }
    275 
    276 }

    xml文件 

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <com.wzq.verticalViewPager.VerticalViewPager xmlns:android="http://schemas.android.com/apk/res/android"
     3     xmlns:tools="http://schemas.android.com/tools"
     4     android:id="@+id/id_main_ly"
     5     android:layout_width="match_parent"
     6     android:layout_height="match_parent"
     7     android:orientation="vertical" >
     8 
     9     <RelativeLayout
    10         android:layout_width="match_parent"
    11         android:layout_height="match_parent"
    12         android:background="@drawable/introduce" >
    13 
    14         <Button
    15             android:layout_width="wrap_content"
    16             android:layout_height="wrap_content"
    17             android:text="position = 0" />
    18     </RelativeLayout>
    19 
    20     <RelativeLayout
    21         android:layout_width="match_parent"
    22         android:layout_height="match_parent"
    23         android:background="@drawable/introduce" >
    24 
    25         <Button
    26             android:layout_width="wrap_content"
    27             android:layout_height="wrap_content"
    28             android:text="position = 1" />
    29     </RelativeLayout>
    30 
    31     <RelativeLayout
    32         android:layout_width="match_parent"
    33         android:layout_height="match_parent"
    34         android:background="@drawable/introduce" >
    35 
    36         <Button
    37             android:layout_width="wrap_content"
    38             android:layout_height="wrap_content"
    39             android:text="position = 2" />
    40     </RelativeLayout>
    41 
    42     <RelativeLayout
    43         android:layout_width="match_parent"
    44         android:layout_height="match_parent"
    45         android:background="@drawable/introduce" >
    46 
    47         <Button
    48             android:layout_width="wrap_content"
    49             android:layout_height="wrap_content"
    50             android:text="position = 3" />
    51     </RelativeLayout>
    52 
    53 </com.wzq.verticalViewPager.VerticalViewPager>

    引用

     1 public class VerticalViewPagerActivity extends Activity {
     2     private VerticalViewPager mMianLayout;
     3 
     4     @Override
     5     protected void onCreate(Bundle savedInstanceState) {
     6         super.onCreate(savedInstanceState);
     7         setContentView(R.layout.a_vertical_viewpager);
     8 
     9         mMianLayout = (VerticalViewPager) findViewById(R.id.id_main_ly);
    10         mMianLayout.setOnPageChangeListener(new OnPageChangeListener() {
    11             @Override
    12             public void onPageChange(int currentPage) {
    13                 // TODO
    14             }
    15         });
    16     }
    17 
    18 }

    参考:http://blog.csdn.net/lmj623565791/article/details/23692439 

  • 相关阅读:
    由当前acitivty直接退到桌面
    Android中SharedPreference多进程数据共享出错
    java回调机制
    Android 监听apk安装替换卸载广播
    jquery中如何退出each循环
    旋转六面体源码
    用CSS3制作的旋转六面体动画
    CSS中常用的字体单位:px、em、rem和%的区别
    css属性简写集合
    小游戏--别踩白块
  • 原文地址:https://www.cnblogs.com/wangziqiang/p/4187222.html
Copyright © 2011-2022 走看看