導航:首頁 > 操作系統 > android滑屏效果

android滑屏效果

發布時間:2023-03-08 08:33:18

android Launcher的滑動效果怎麼實現

滑動功能主要分兩步:
1、在onInterceptTouchEvent中進行攔截。
2、在onTouchEvent中進行滑動。

1,onInterceptTouchEvent(MotionEvent en)
在這個方法中,決定了什麼時候截獲MotionEvent來實現滑動,避免了子View的其他事件的影響(如點擊事件)。
[java] view plain
public boolean onInterceptTouchEvent(MotionEvent ev) {
/**
* This method JUST determines whether we want to intercept the motion.
* If we return true, onTouchEvent will be called and we do the actual
* scrolling there.
**/

//獲取速度跟蹤器,記錄各個時刻的速度。並且添加當前的MotionEvent以記錄更行速度值。
(ev);
......
/**
* Shortcut the most recurring case: the user is in the dragging
* state and he is moving his finger. We want to intercept this
* motion.
* 最常見的需要攔截的情況:用戶已經進入滑動狀態,並且正在滑動手指。
* 對這種情況直接進行攔截,執行onTouchEvent()繼續執行滑動操作。
**/
final int action = ev.getAction();
if ((action == MotionEvent.ACTION_MOVE) &&
(mTouchState == TOUCH_STATE_SCROLLING)) {
return true;
}

switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_MOVE: {

/**
* mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
* whether the user has moved far enough from his original down touch.
*/
/**
* 當在這里接受到ACTION_MOVE時,說明mTouchState!=TOUCH_STATE_SCROLLING並且mIsBeingDragged的值應該為false,
* 否則DragLayer就應該截獲了MotionEvent用於實現拖拽。
* 此時還沒有進入滑動狀態,當mActivePointerId == INVALID_POINTER時,也就是在此之前沒有接收到任何touch事件。
* 這種情況發生在Workspace變小時,也就是之前Workspace處於SPRING_LOADED狀態。當出現這種情況時直接把當前的事件當作ACTION_DOWN進行處理。
* 反之,則通過determineScrollingStart()嘗試能夠進入滑動狀態。
*/
if (mActivePointerId != INVALID_POINTER) {
determineScrollingStart(ev);
break;
}
// if mActivePointerId is INVALID_POINTER, then we must have missed an ACTION_DOWN
// event. in that case, treat the first occurence of a move event as a ACTION_DOWN
// i.e. fall through to the next case (don't break)
// (We sometimes miss ACTION_DOWN events in Workspace because it ignores all events
// while it's small- this was causing a crash before we checked for INVALID_POINTER)
}

case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
// Remember location of down touch
//記錄按下的x的坐標值
mDownMotionX = x;
//記錄前次發生touch時的坐標
mLastMotionX = x;
mLastMotionY = y;
//因為在ScrollBy時只能使用int,而記錄的x和y都是float,會產生誤差,故這里用mLastMotionXRemainder記錄余數
//用於消除誤差
mLastMotionXRemainder = 0;
//x方向上的總位移
mTotalMotionX = 0;
mActivePointerId = ev.getPointerId(0);

//設置mAllowLongPress=true,允許LongClick事件發生。LongClick事件定義在Launcher中
//處理的內容包括啟動對shortcut的拖拽或彈出壁紙選擇的對話框,若mAllowLongPress=false,
//則不會響應以上事件。
mAllowLongPress = true;

/**
* If being flinged and user touches the screen, initiate drag;
* otherwise don't. mScroller.isFinished should be false when
* being flinged.
* 當屏幕處於flinged狀態(快速滑動)時,若此時用戶觸摸了屏幕,需要使滑動停止。
* 並且初始化拖拽的條件
**/
final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
if (finishedScrolling) {
mTouchState = TOUCH_STATE_REST;
mScroller.abortAnimation();
} else {
mTouchState = TOUCH_STATE_SCROLLING;
}

// check if this can be the beginning of a tap on the side of the pages
// to scroll the current page
if (mTouchState != TOUCH_STATE_PREV_PAGE && mTouchState != TOUCH_STATE_NEXT_PAGE) {
if (getChildCount() > 0) {
if (hitsPreviousPage(x, y)) {
mTouchState = TOUCH_STATE_PREV_PAGE;
} else if (hitsNextPage(x, y)) {
mTouchState = TOUCH_STATE_NEXT_PAGE;
}
}
}
break;
}

case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mTouchState = TOUCH_STATE_REST;
mAllowLongPress = false;
mActivePointerId = INVALID_POINTER;
releaseVelocityTracker();
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
releaseVelocityTracker();
break;
}

/**
* The only time we want to intercept motion events is if we are in the
* drag mode.
* 只有進入了滑動狀態,才進行攔截,進入onTouchEvent執行滑動操作。當mTouchState != TOUCH_STATE_REST
* 時,就說明沒有進入滑動狀態。
**/
return mTouchState != TOUCH_STATE_REST;
}

2,onTouchEvent(MotionEvent en)

在這個方法中,執行各種關於滑動的工作的計算,界面的刷新等工作。
[java] view plain
public boolean onTouchEvent(MotionEvent ev) {
......
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
/*
* If being flinged and user touches, stop the fling. isFinished
* will be false if being flinged.
*/
/**
* 如果Workspace此時已經被「擲出去」(靠慣性滑動)。
* 此時發生ACTION_DOWN則需要停止滑動。
*/
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}

// Remember where the motion event started
mDownMotionX = mLastMotionX = ev.getX();
mLastMotionXRemainder = 0;
mTotalMotionX = 0;
mActivePointerId = ev.getPointerId(0);
if (mTouchState == TOUCH_STATE_SCROLLING) {
pageBeginMoving();
}
break;

case MotionEvent.ACTION_MOVE:
if (mTouchState == TOUCH_STATE_SCROLLING) {
......
if (Math.abs(deltaX) >= 1.0f) {
......
if (!mDeferScrollUpdate) {
//調用scrollBy滑動桌面
scrollBy((int) deltaX, 0);
......
} else {
......
}
mLastMotionX = x;
mLastMotionXRemainder = deltaX - (int) deltaX;
} else {
awakenScrollBars();
}
} else {
/**
* 如果條件滿足,則進入滑動狀態,開始滑動。
*/
determineScrollingStart(ev);
}
break;
case MotionEvent.ACTION_UP:
if (mTouchState == TOUCH_STATE_SCROLLING) {
......
boolean isSignificantMove = Math.abs(deltaX) > MIN_LENGTH_FOR_MOVE;

boolean returnToOriginalPage = false;
final int pageWidth = getScaledMeasuredWidth(getPageAt(mCurrentPage));
if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
Math.signum(velocityX) != Math.signum(deltaX)) {
returnToOriginalPage = true;
}

boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
Math.abs(velocityX) > snapVelocity;
int finalPage;

//判斷拿起手指之後應該進入哪個分屏
if (((isSignificantMove && deltaX > 0 && !isFling) ||
(isFling && velocityX > 0)) && mCurrentPage > 0) {
finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
snapToPageWithVelocity(finalPage, velocityX);
} else if (((isSignificantMove && deltaX < 0 && !isFling) ||
(isFling && velocityX < 0)) &&
mCurrentPage < getChildCount() - 1) {
finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
snapToPageWithVelocity(finalPage, velocityX);
} else {
snapToDestination();
}
} else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
//直接進入前一屏
int nextPage = Math.max(0, mCurrentPage - 1);
if (nextPage != mCurrentPage) {
snapToPage(nextPage);
} else {
snapToDestination();
}
} else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
//直接進入後一屏
int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
if (nextPage != mCurrentPage) {
snapToPage(nextPage);
} else {
snapToDestination();
}
} else {
onUnhandledTap(ev);
}
mTouchState = TOUCH_STATE_REST;
mActivePointerId = INVALID_POINTER;
releaseVelocityTracker();
break;

case MotionEvent.ACTION_CANCEL:
if (mTouchState == TOUCH_STATE_SCROLLING) {
snapToDestination();
}
mTouchState = TOUCH_STATE_REST;
mActivePointerId = INVALID_POINTER;
releaseVelocityTracker();
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
}
return true;
}

② android怎麼實現滑動效果

工具/原料
ViewFlipper類和OnGestureListener介面
animation動畫效果translate和alpha
方法/步驟

1、設置布局文件,其中使用到ViewFlipper控制項,內容如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:background="@drawable/background"
android:paddingBottom="@dimen/activity_optopns_vertical_margin"
android:paddingLeft="@dimen/activity_options_horizontal_margin"
android:paddingRight="@dimen/activity_options_horizontal_margin"
android:paddingTop="@dimen/activity_optopns_vertical_margin"
tools:context=".ImageFlipperActivity" >
<RelativeLayout
android:id="@id/rl_image_flipper_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/btn_image_flipper_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginBottom="10dp"
android:background="@drawable/custom_button"
android:text="@string/back"
android:textColor="@color/textColor"
android:textSize="16sp"
android:visibility="visible" />
<TextView
android:id="@id/tv_image_flipper_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/image_flipper"
android:textColor="@color/textColor"
android:textSize="30sp"
android:textStyle="bold" />
</RelativeLayout>
<LinearLayout
android:id="@id/ll_image_flipper_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/rl_image_flipper_title"
android:layout_marginBottom="20dp"
android:layout_marginTop="20dp"
android:gravity="center"
android:orientation="vertical" >
<ViewFlipper
android:id="@id/vf_image_flipper"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</RelativeLayout>

2、從左邊進入的動畫文件,其內容如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- translate:畫面轉換位置移動動畫效果 -->
<translate
android:ration="500"
android:fromXDelta="100%p"
android:toXDelta="0" />
<!-- alpha:漸變透明度動畫效果 -->
<alpha
android:ration="500"
android:fromAlpha="0.1"
android:toAlpha="1.0" />
</set>

3、從左邊退出的動畫文件,其內容如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:ration="500"
android:fromXDelta="0"
android:toXDelta="-100%p" />
<alpha
android:ration="500"
android:fromAlpha="1.0"
android:toAlpha="0.1" />
</set>

4、從右邊進入的動畫文件,其內容如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:ration="500"
android:fromXDelta="-100%p"
android:toXDelta="0" />
<alpha
android:ration="500"
android:fromAlpha="0.1"
android:toAlpha="1.0" />
</set>

5、從右邊退出的動畫文件,其內容如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:ration="500"
android:fromXDelta="0"
android:toXDelta="100%p" />
<alpha
android:ration="500"
android:fromAlpha="1.0"
android:toAlpha="0.1" />
</set>

6、載入布局文件和動畫文件的類,其源碼內容為:
/**
*
*/
package com.i114gbox.aglieguy;
import android.content.Context;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ViewFlipper;
import com.i114gbox.sdk.activity.I114gBoxActivity;
import com.i114gbox.sdk.utils.I114gBoxCollectActivityUtils;
import com.i114gbox.sdk.utils.I114gBoxLogUtils;
import com.i114gbox.sdk.utils.I114gBoxResourceUtils;
/**
* 圖片滑動Activity
*
* @author SJC
*
*/
public class ImageFlipperActivity extends I114gBoxActivity implements
OnGestureListener {
private static String TAG = "ImageFlipperActivity";
private Context ctx = null;
private GestureDetector gestureDetector;// 手勢監聽
private ViewFlipper viewFlipper;// 視圖輪播
@Override
protected void onCreate(Bundle savedInstanceState) {
I114gBoxLogUtils.d(TAG, "The onCreate method execute.");
super.onCreate(savedInstanceState);
I114gBoxCollectActivityUtils.getInstance().addActivity(this);// 收集Activity
ctx = this;
setContentView(I114gBoxResourceUtils.getLayoutId(ctx,
"activity_image_flipper"));
gestureDetector = new GestureDetector(this);
viewFlipper = (ViewFlipper) findViewById(I114gBoxResourceUtils.getId(
ctx, "vf_image_flipper"));
viewFlipper.addView(addImageView(I114gBoxResourceUtils.getDrawableId(
ctx, "flipper_01")));
viewFlipper.addView(addImageView(I114gBoxResourceUtils.getDrawableId(
ctx, "flipper_02")));
viewFlipper.addView(addImageView(I114gBoxResourceUtils.getDrawableId(
ctx, "flipper_03")));
viewFlipper.addView(addImageView(I114gBoxResourceUtils.getDrawableId(
ctx, "flipper_04")));
viewFlipper.addView(addImageView(I114gBoxResourceUtils.getDrawableId(
ctx, "flipper_05")));
viewFlipper.addView(addImageView(I114gBoxResourceUtils.getDrawableId(
ctx, "flipper_06")));
// viewFlipper.addView(addImageView(R.drawable.one));
// viewFlipper.addView(addImageView(R.drawable.two));
// viewFlipper.addView(addImageView(R.drawable.three));
// viewFlipper.addView(addImageView(R.drawable.four));
// viewFlipper.addView(addImageView(R.drawable.five));
Button backButton = (Button) findViewById(I114gBoxResourceUtils.getId(
ctx, "btn_image_flipper_back"));
backButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
/** 添加ImageView控制項 **/
private View addImageView(int id) {
ImageView imageView = new ImageView(this);
imageView.setImageResource(id);
return imageView;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
I114gBoxLogUtils.d(TAG, "The onTouchEvent method execute.");
return gestureDetector.onTouchEvent(event);
}
@Override
public boolean onDown(MotionEvent e) {
I114gBoxLogUtils.d(TAG, "The onDown method execute.");
return false;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
I114gBoxLogUtils.d(TAG, "The onFling method execute.");
I114gBoxLogUtils.i(TAG, "e1.x:" + e1.getX() + "|" + "e2.x:" + e2.getX()
+ "|" + "velocityX:" + velocityX + "|" + "velocityY:"
+ velocityY);
if (e1.getX() - e2.getX() > 120) {
this.viewFlipper.setInAnimation(AnimationUtils.loadAnimation(ctx,
R.anim.push_left_in));// 進入屏幕的動畫
this.viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(ctx,
R.anim.push_left_out));// 離開屏幕的動畫
this.viewFlipper.showNext();// 手動顯示下一個視圖
return true;
} else if (e1.getX() - e2.getX() < -120) {
this.viewFlipper.setInAnimation(AnimationUtils.loadAnimation(ctx,
R.anim.push_right_in));
this.viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(ctx,
R.anim.push_right_out));
this.viewFlipper.showPrevious();// 手動顯示前一個視圖
return true;
}
return false;
}
@Override
public void onLongPress(MotionEvent e) {
I114gBoxLogUtils.d(TAG, "The onLongPress method execute.");
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
I114gBoxLogUtils.d(TAG, "The onScroll method execute.");
I114gBoxLogUtils.i(TAG, "e1.X:" + e1.getX() + "|" + "e2.X:" + e2.getX()
+ "|" + "distanceX:" + distanceX + "|" + "distanceY:"
+ distanceY);
return false;
}
@Override
public void onShowPress(MotionEvent e) {
I114gBoxLogUtils.d(TAG, "The onShowPress method execute.");
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
I114gBoxLogUtils.d(TAG, "The onSingleTapUp method execute.");
return false;
}
}

③ android平台中頁面切換時如果要用觸摸屏左右滑動,怎麼實現

左右滑動切換是通過viewPager來實現的,完整代碼查看附件。

ViewPager的數據是通過PageAdapter來裝載的:

1.調用adapter.notifyDataSetChanged(); 刷新控制項,但是要覆蓋PagerAdapter的getItemPosition方法,並返回return POSITION_NONE;

2.利用PagerAdapter的工作機制,就是PagerAdapter的執行順序,PagerAdapter作為ViewPager的適配器,無論ViewPager有多少頁,PagerAdapter在初始化時也只初始化開始的2個View,即調用2次instantiateItem方法。而接下來每當ViewPager滑動時,PagerAdapter都會調用destroyItem方法將距離該頁2個步幅以上的那個View銷毀,以此保證PagerAdapter最多隻管轄3個View,且當前View是3個中的中間一個,如果當前View缺少兩邊的View,那麼就instantiateItem,如里有超過2個步幅的就destroyItem。

3.每當Adapter調用instantiateItem時,運用View.setTag方法將該View標識。當需要更新這個View的數據時,通過調用ViewPager.findViewWithTag方法找到相應的View,然後更新View中的數據。

④ android 左右滑屏怎麼實現 哪位大神教教我

代碼如下:
package kexc.scroll;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;
/**
* 仿Launcher中的WorkSapce,可以左右滑動切換屏幕的類
*
*/
public class ScrollLayout extends ViewGroup {
/*
* onMeasure方法在控制項的父元素正要放置它的子控制項時調用。它會問一個問題,「你想要用多大地方啊?」,然後傳入兩個參數——
* widthMeasureSpec和heightMeasureSpec。它們指明控制項可獲得的空間以及關於這個空間描述的元數據。
* 比返回一個結果要好的方法是你傳遞View的高度和寬度到setMeasuredDimension方法里。
* 一個MeasureSpec包含一個尺寸和模式。
* 有三種可能的模式:
* UNSPECIFIED:父布局沒有給子布局任何限制,子布局可以任意大小。
* EXACTLY:父布局決定子布局的確切大小。不論子布局多大,它都必須限制在這個界限里。
* AT_MOST:子布局可以根據自己的大小選擇任意大小。
*/
/*
* VelocityTracker類
*
* 功能: 根據觸摸位置計算每像素的移動速率。
*
* 常用方法有:
*
* public void addMovement (MotionEvent ev) 功能:添加觸摸對象MotionEvent , 用於計算觸摸速率。
* public void computeCurrentVelocity (int units)
* 功能:以每像素units單位考核移動速率。額,其實我也不太懂,賦予值1000即可。 參照源碼 該units的意思如下: 參數 units :
* The units you would like the velocity in. A value of 1 provides pixels
* per millisecond, 1000 provides pixels per second, etc. public float
* getXVelocity () 功能:獲得X軸方向的移動速率。
*/
/*
* ViewConfiguration類
*
* 功能: 獲得一些關於timeouts(時間)、sizes(大小)、distances(距離)的標准常量值 。
*
* 常用方法:
*
* public int getScaledEdgeSlop()
*
* 說明:獲得一個觸摸移動的最小像素值。也就是說,只有超過了這個值,才代表我們該滑屏處理了。
*
* public static int getLongPressTimeout()
*
* 說明:獲得一個執行長按事件監聽(onLongClickListener)的值。也就是說,對某個View按下觸摸時,只有超過了
*
* 這個時間值在,才表示我們該對該View回調長按事件了;否則,小於這個時間點松開手指,只執行onClick監聽
*/
private static final String TAG = "ScrollLayout";
private Scroller mScroller;
private VelocityTracker mVelocityTracker;
private int mCurScreen;//當前屏幕
private int mDefaultScreen = 0;
//兩種狀態: 是否處於滑屏狀態
private static final int TOUCH_STATE_REST = 0;//靜止狀態
private static final int TOUCH_STATE_SCROLLING = 1;//滑屏狀態
private static final int SNAP_VELOCITY = 600; //最小的滑動速率
private int mTouchState = TOUCH_STATE_REST;
private int mTouchSlop;// change 多少像素算是發生move操作
private float mLastMotionX;
private float mLastMotionY;
public ScrollLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
// TODO Auto-generated constructor stub
}
public ScrollLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
mScroller = new Scroller(context);
mCurScreen = mDefaultScreen;
//初始化一個最小滑動距離
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
/**
* 生成view
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
if (changed) {
int childLeft = 0;
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View childView = getChildAt(i);
if (childView.getVisibility() != View.GONE) {
final int childWidth = childView.getMeasuredWidth();
childView.layout(childLeft, 0, childLeft + childWidth,
childView.getMeasuredHeight());
childLeft += childWidth;
}
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.e(TAG, "onMeasure");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException(
"ScrollLayout only canmCurScreen run at EXACTLY mode!");
}
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException(
"ScrollLayout only can run at EXACTLY mode!");
}
// The children are given the same width and height as the scrollLayout
final int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
}
// Log.e(TAG, "moving to screen "+mCurScreen);
scrollTo(mCurScreen * width, 0);
}
/**
* According to the position of current layout scroll to the destination
* page.
*/
public void snapToDestination() {
// 判斷是否超過下一屏的中間位置,如果達到就抵達下一屏,否則保持在原屏幕
// 這樣的一個簡單公式意思是:假設當前滑屏偏移值即 scrollCurX 加上每個屏幕一半的寬度,除以每個屏幕的寬度就是
// 我們目標屏所在位置了。 假如每個屏幕寬度為320dip, 我們滑到了500dip處,很顯然我們應該到達第二屏,索引值為1
// 即(500 + 320/2)/320 = 1
final int screenWidth = getWidth();
final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth;
snapToScreen(destScreen);
}
public void snapToScreen(int whichScreen) {
// get the valid layout page
whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
if (getScrollX() != (whichScreen * getWidth())) {
final int delta = whichScreen * getWidth() - getScrollX();
mScroller.startScroll(getScrollX(), 0, delta, 0,
Math.abs(delta) * 5);
mCurScreen = whichScreen;
onScreenChangeListener.onScreenChange(mCurScreen);
invalidate(); // Redraw the layout
}
}
public void setToScreen(int whichScreen) {
whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
mCurScreen = whichScreen;
scrollTo(whichScreen * getWidth(), 0);
}
public int getCurScreen() {
return mCurScreen;
}
/**
* 控制view跟隨手指滑動 由父視圖調用用來請求子視圖根據偏移值 mScrollX,mScrollY重新繪制
*/
@Override
public void computeScroll() {
// 如果返回true,表示動畫還沒有結束
// 因為前面startScroll,所以只有在startScroll完成時 才會為false
if (mScroller.computeScrollOffset()) {
// 產生了動畫效果,根據當前值 每次滾動一點
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
/*
* 其中:onInterceptTouchEvent()主要功能是控制觸摸事件的分發,例如是子視圖的點擊事件還是滑動事件。
* 其他所有處理過程均在onTouchEvent()方法里實現了。 1、屏幕的滑動要根據手指的移動而移動 ----
* 主要實現在onTouchEvent()方法中
*

閱讀全文

與android滑屏效果相關的資料

熱點內容
760貼片機編程視頻 瀏覽:333
歐姆龍plc編程第36講 瀏覽:915
我的世界如何將一個伺服器弄崩 瀏覽:8
php網站訪問量代碼 瀏覽:431
怠速壓縮機咔咔響 瀏覽:176
怎麼才能修改APP中的數據 瀏覽:688
哪裡有搶單的app 瀏覽:462
演算法概率題 瀏覽:465
長方形拉伸的命令 瀏覽:279
python代碼函數編程技術 瀏覽:194
java正則式 瀏覽:429
外包程序員好進嗎 瀏覽:384
雲伺服器服務模型架構 瀏覽:901
刪文件夾什麼指令 瀏覽:509
極速抖音已加密怎麼辦 瀏覽:603
matlab拉格朗日演算法框圖 瀏覽:430
華為公司計算機視覺演算法顧問 瀏覽:254
夏老師講的單片機 瀏覽:298
在編程中如何將圖片放大 瀏覽:163
appstore怎麼看是否付費 瀏覽:603