您的位置:首页 > 其它

竖直滑动View制作引导页

2016-06-07 15:37 211 查看
传承者(Inheritors)打造共同进步生态圈!!!

转载: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();
}
});

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: