当前位置:操作系统 > 安卓/Android >>

Android实现多页左右滑动效果,支持子view动态创建和cache

要实现多页滑动效果,主要是需要处理onTouchEvent和onInterceptTouchEvent,要处理好touch事件的子控件和父控件的传递问题。滚动控制可以利用android的Scroller来实现。
对于不清楚android Touch事件的传递过程的,先google一下。
这里提供两种做法:
1、自定义MFlipper控件,从ViewGroup继承,利用Scroller实现滚动,重点是onTouchEvent和onInterceptTouchEvent的重写,要注意什么时候该返回true,什么时候false。否则会导致界面滑动和界面内按钮点击事件相冲突。
由于采用了ViewGroup来管理子view,只适合于页面数较少而且较固定的情况,因为viewgroup需要一开始就调用addView,把所有view都加进去并layout,太多页面会有内存问题。如果是页面很多,而且随时动态增长的话,就需要考虑对view做cache和动态创建,动态layout,具体做法参考下面的方法二;
 
2、从AdapterView继承,参考Android自带ListView的实现,实现子view动态创建和cache,滑动效果等。源码如下:
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.Scroller;
 
/**
 * 自定义一个横向滚动的AdapterView,类似与全屏的Gallery,但是一次只滚动一屏,而且每一屏支持子view的点击处理
 * @author weibinke
 *
 */
public class MultiPageSwitcher extends AdapterView<BaseAdapter> {
 
private BaseAdapter mAdapter = null;
private Scroller mScroller;
private int mTouchSlop;
private float mTouchStartX;
private float mLastMotionX;
private final static String TAG = "MultiPageSwitcher";
 
private int mLastScrolledOffset = 0;               
 
/** User is not touching the list */
    private static final int TOUCH_STATE_RESTING = 0;
 
    /** User is scrolling the list */
    private static final int TOUCH_STATE_SCROLL = 2;
 
    private int mTouchState = TOUCH_STATE_RESTING;
private int mHeightMeasureSpec;
private int mWidthMeasureSpec;
private int mSelectedPosition;
private int mFirstPosition;                                //第一个可见view的position
private int mCurrentSelectedPosition;
 
private VelocityTracker mVelocityTracker;
private static final int SNAP_VELOCITY = 600;
 
protected RecycleBin mRecycler = new RecycleBin();
 
private OnPostionChangeListener mOnPostionChangeListener = null;
 
public MultiPageSwitcher(Context context, AttributeSet attrs) {
super(context, attrs);
mScroller = new Scroller(context);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
 
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
// TODO Auto-generated method stub
MLog.d("MultiPageSwitcher.onlayout start");
super.onLayout(changed, left, top, right, bottom);
 
if (mAdapter == null) {
return ;
}
 
recycleAllViews();
detachAllViewsFromParent();
mRecycler.clear();
 
fillAllViews();
 
MLog.d("MultiPageSwitcher.onlayout end");
}
 
/**
 * 从当前可见的view向左边填充
 */
private void fillToGalleryLeft() {
        int itemSpacing = 0;
        int galleryLeft = 0;
      
        // Set state for initial iteration
        View prevIterationView = getChildAt(0);
        int curPosition;
        int curRightEdge;
      
        if (prevIterationView != null) {
            curPosition = mFirstPosition - 1;
            curRightEdge = prevIterationView.getLeft() - itemSpacing;
        } else {
            // No children available!
            curPosition = 0;
            curRightEdge = getRight() - getLeft();
        }
              
        while (curRightEdge > galleryLeft && curPosition >= 0) {
            prevIterationView = makeAndAddView(curPosition, curPosition - mSelectedPosition,
                    curRightEdge, false);
 
            // Remember some state
            mFirstPosition = curPosition;
          
            // Set state for next iteration
            curRightEdge = prevIterationView.getLeft() - itemSpacing;
            curPosition--;
        }
    }
  
    private void fillToGalleryRight() {
        int itemSpacing = 0;
        int galleryRight = getRight() - getLeft();
        int numChildren = getChildCount();
        int numItems = mAdapter.getCount();
      
        // Set state for initial iteration
        View prevIterationView = getChildAt(numChildren - 1);
        int curPosition;
        int curLeftEdge;
      
        if (prevIterationView != null) {
            curPosition = mFirstPosition + numChildren;
            curLeftEdge = prevIterationView.getRight() + itemSpacing;
        } else {
            mFirstPosition = curPosition = numItems - 1;
            curLeftEdge = 0;
        }
              

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,