展会信息港展会大全

Android: 仿Launcher Workspace左右滑动控件
来源:互联网   发布日期:2016-01-06 19:25:06   浏览:3403次  

导读:修改Launcher的Workspace,去掉Drag相关的操作,精简为一个支持左右滑动的控件每屏中可以自由放置layout主要的问题是对 @Override public boolean dispathTouchEvent(MotionEvent ev) {} @Override......

修改Launcher的Workspace,去掉Drag相关的操作,精简为一个支持左右滑动的控件

每屏中可以自由放置layout

主要的问题是对

@Override

public boolean dispathTouchEvent(MotionEvent ev) {}

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {}

@Override

public boolean onTouchEvent(MotionEvent ev) {}

的理解,不然不好控制touch事件

代码贴上,其实没啥参考价值:

<?xml version="1.0" encoding="utf-8"?>

<com.mylauncher.Workspace

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:launcher="http://schemas.android.com/apk/res/com.mylauncher"

android:id="@+id/workspace"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:scrollbars="horizontal"

android:fadeScrollbars="true"

launcher:defaultScreen="0">

<com.mylauncher.CellLayoutandroid:background="#ff0000ff"

android:id="@+id/cell1"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

>

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:textSize="30sp"

android:textStyle="bold"

android:text="@string/screen1" />

<Button

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:textSize="30sp"

android:textStyle="bold"

android:text="@string/screen1" />

</com.mylauncher.CellLayout>

<com.mylauncher.CellLayoutandroid:background="#ffff0000"

android:id="@+id/cell2"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

>

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:textSize="30sp"

android:textStyle="bold"

android:text="@string/screen2" />

<Button

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:textSize="30sp"

android:textStyle="bold"

android:text="@string/screen2" />

</com.mylauncher.CellLayout>

<com.mylauncher.CellLayoutandroid:background="#ff00ff00"

android:id="@+id/cell3"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

>

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:textSize="30sp"

android:textStyle="bold"

android:text="@string/screen3" />

<Button

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:textSize="30sp"

android:textStyle="bold"

android:text="@string/screen3" />

</com.mylauncher.CellLayout>

</com.mylauncher.Workspace>

package com.mylauncher;

import android.app.WallpaperManager;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Rect;

import android.graphics.drawable.Drawable;

import android.os.IBinder;

import android.os.Parcel;

import android.os.Parcelable;

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.view.ViewParent;

import android.view.animation.Interpolator;

import android.widget.Scroller;

/**

* The workspace is a wide area with a wallpaper and a finite number of screens. Each

* screen contains a number of icons, folders or widgets the user can interact with.

* A workspace is meant to be used with a fixed width only.

*/

public class Workspace extends ViewGroup {

@SuppressWarnings({"UnusedDeclaration"})

private static final String TAG = "MyLauncher.Workspace";

private static final int INVALID_SCREEN = -1;

/**

* The velocity at which a fling gesture will cause us to snap to the next screen

*/

private static final int SNAP_VELOCITY = 600;

private final WallpaperManager mWallpaperManager;

private int mDefaultScreen;

private boolean mFirstLayout = true;

private int mCurrentScreen;

private int mNextScreen = INVALID_SCREEN;

private Scroller mScroller;

private VelocityTracker mVelocityTracker;

/**

* Target drop area calculated during last acceptDrop call.

*/

private int[] mTargetCell = null;

private float mLastMotionX;

private float mLastMotionY;

private final static int TOUCH_STATE_REST = 0;

private final static int TOUCH_STATE_SCROLLING = 1;

private int mTouchState = TOUCH_STATE_REST;

private OnLongClickListener mLongClickListener;

private int[] mTempCell = new int[2];

private int[] mTempEstimate = new int[2];

private boolean mAllowLongPress = true;

private int mTouchSlop;

private int mMaximumVelocity;

private static final int INVALID_POINTER = -1;

private int mActivePointerId = INVALID_POINTER;

private Drawable mPreviousIndicator;

private Drawable mNextIndicator;

private static final float NANOTIME_DIV = 1000000000.0f;

private static final float SMOOTHING_SPEED = 0.75f;

private static final float SMOOTHING_CONSTANT = (float) (0.016 / Math.log(SMOOTHING_SPEED));

private float mSmoothingTime;

private float mTouchX;

private WorkspaceOvershootInterpolator mScrollInterpolator;

private static final float BASELINE_FLING_VELOCITY = 2500.f;

private static final float FLING_VELOCITY_INFLUENCE = 0.4f;

private static class WorkspaceOvershootInterpolator implements Interpolator {

private static final float DEFAULT_TENSION = 1.3f;

private float mTension;

public WorkspaceOvershootInterpolator() {

mTension = DEFAULT_TENSION;

}

public void setDistance(int distance) {

mTension = distance > 0 ? DEFAULT_TENSION / distance : DEFAULT_TENSION;

}

public void disableSettle() {

mTension = 0.f;

}

public float getInterpolation(float t) {

// _o(t) = t * t * ((tension + 1) * t + tension)

// o(t) = _o(t - 1) + 1

t -= 1.0f;

return t * t * ((mTension + 1) * t + mTension) + 1.0f;

}

}

/**

* Used to inflate the Workspace from XML.

*

* @param context The application's context.

* @param attrs The attribtues set containing the Workspace's customization values.

*/

public Workspace(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

/**

* Used to inflate the Workspace from XML.

*

* @param context The application's context.

* @param attrs The attribtues set containing the Workspace's customization values.

* @param defStyle Unused.

*/

public Workspace(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

mWallpaperManager = WallpaperManager.getInstance(context);

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Workspace, defStyle, 0);

mDefaultScreen = a.getInt(R.styleable.Workspace_defaultScreen, 1);

a.recycle();

setHapticFeedbackEnabled(false);

initWorkspace();

}

/**

* Initializes various states for this workspace.

*/

private void initWorkspace() {

Context context = getContext();

mScrollInterpolator = new WorkspaceOvershootInterpolator();

mScroller = new Scroller(context, mScrollInterpolator);

mCurrentScreen = mDefaultScreen;

final ViewConfiguration configuration = ViewConfiguration.get(getContext());

mTouchSlop = configuration.getScaledTouchSlop();

mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();

}

boolean isDefaultScreenShowing() {

return mCurrentScreen == mDefaultScreen;

}

/**

* Returns the index of the currently displayed screen.

*

* @return The index of the currently displayed screen.

*/

int getCurrentScreen() {

return mCurrentScreen;

}

/**

* Sets the current screen.

*

* @param currentScreen

*/

void setCurrentScreen(int currentScreen) {

if (!mScroller.isFinished()) mScroller.abortAnimation();

mCurrentScreen = Math.max(0, Math.min(currentScreen, getChildCount() - 1));

//mPreviousIndicator.setLevel(mCurrentScreen);

//mNextIndicator.setLevel(mCurrentScreen);

scrollTo(mCurrentScreen * getWidth(), 0);

invalidate();

}

/**

* Registers the specified listener on each screen contained in this workspace.

*

* @param l The listener used to respond to long clicks.

*/

@Override

public void setOnLongClickListener(OnLongClickListener l) {

mLongClickListener = l;

final int count = getChildCount();

for (int i = 0; i < count; i++) {

getChildAt(i).setOnLongClickListener(l);

}

}

private void updateWallpaperOffset(int scrollRange) {

IBinder token = getWindowToken();

if (token != null) {

mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 0 );

mWallpaperManager.setWallpaperOffsets(getWindowToken(),

Math.max(0.f, Math.min(mScrollX/(float)scrollRange, 1.f)), 0);

}

}

@Override

public void scrollTo(int x, int y) {

super.scrollTo(x, y);

mTouchX = x;

mSmoothingTime = System.nanoTime() / NANOTIME_DIV;

}

@Override

public void computeScroll() {

if (mScroller.computeScrollOffset()) {

mTouchX = mScrollX = mScroller.getCurrX();

mSmoothingTime = System.nanoTime() / NANOTIME_DIV;

mScrollY = mScroller.getCurrY();

postInvalidate();

} else if (mNextScreen != INVALID_SCREEN) {

mCurrentScreen = Math.max(0, Math.min(mNextScreen, getChildCount() - 1));

//mPreviousIndicator.setLevel(mCurrentScreen);

//mNextIndicator.setLevel(mCurrentScreen);

mNextScreen = INVALID_SCREEN;

//clearChildrenCache();

} else if (mTouchState == TOUCH_STATE_SCROLLING) {

final float now = System.nanoTime() / NANOTIME_DIV;

final float e = (float) Math.exp((now - mSmoothingTime) / SMOOTHING_CONSTANT);

final float dx = mTouchX - mScrollX;

mScrollX += dx * e;

mSmoothingTime = now;

// Keep generating points as long as we're more than 1px away from the target

if (dx > 1.f || dx < -1.f) {

postInvalidate();

}

}

}

@Override

protected void dispatchDraw(Canvas canvas) {

boolean restore = false;

int restoreCount = 0;

// ViewGroup.dispatchDraw() supports many features we don't need:

// clip to padding, layout animation, animation listener, disappearing

// children, etc. The following implementation attempts to fast-track

// the drawing dispatch by drawing only what we know needs to be drawn.

boolean fastDraw = mTouchState != TOUCH_STATE_SCROLLING && mNextScreen == INVALID_SCREEN;

// If we are not scrolling or flinging, draw only the current screen

if (fastDraw) {

drawChild(canvas, getChildAt(mCurrentScreen), getDrawingTime());

} else {

final long drawingTime = getDrawingTime();

final float scrollPos = (float) mScrollX / getWidth();

final int leftScreen = (int) scrollPos;

final int rightScreen = leftScreen + 1;

if (leftScreen >= 0) {

drawChild(canvas, getChildAt(leftScreen), drawingTime);

}

if (scrollPos != leftScreen && rightScreen < getChildCount()) {

drawChild(canvas, getChildAt(rightScreen), drawingTime);

}

}

if (restore) {

canvas.restoreToCount(restoreCount);

}

}

protected void onAttachedToWindow() {

super.onAttachedToWindow();

computeScroll();

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

final int width = MeasureSpec.getSize(widthMeasureSpec);

final int widthMode = MeasureSpec.getMode(widthMeasureSpec);

if (widthMode != MeasureSpec.EXACTLY) {

throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");

}

final int heightMode = MeasureSpec.getMode(heightMeasureSpec);

if (heightMode != MeasureSpec.EXACTLY) {

throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");

}

// The children are given the same width and height as the workspace

final int count = getChildCount();

for (int i = 0; i < count; i++) {

getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);

}

if (mFirstLayout) {

setHorizontalScrollBarEnabled(false);

scrollTo(mCurrentScreen * width, 0);

setHorizontalScrollBarEnabled(true);

updateWallpaperOffset(width * (getChildCount() - 1));

mFirstLayout = false;

}

}

@Override

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

int childLeft = 0;

final int count = getChildCount();

for (int i = 0; i < count; i++) {

final View child = getChildAt(i);

if (child.getVisibility() != View.GONE) {

final int childchildWidth = child.getMeasuredWidth();

child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());

childLeft += childWidth;

}

}

}

@Override

public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {

int screen = indexOfChild(child);

if (screen != mCurrentScreen || !mScroller.isFinished()) {

snapToScreen(screen);

return true;

}

return false;

}

@Override

public boolean dispatchUnhandledMove(View focused, int direction) {

if (direction == View.FOCUS_LEFT) {

if (getCurrentScreen() > 0) {

snapToScreen(getCurrentScreen() - 1);

return true;

}

} else if (direction == View.FOCUS_RIGHT) {

if (getCurrentScreen() < getChildCount() - 1) {

snapToScreen(getCurrentScreen() + 1);

return true;

}

}

return super.dispatchUnhandledMove(focused, direction);

}

@Override

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.

*/

/*

* Shortcut the most recurring case: the user is in the dragging

* state and he is moving his finger.We want to intercept this

* motion.

*/

final int action = ev.getAction();

Log.d(TAG, "onInterceptTouchEvent, action: " + action + " mTouchState: " + mTouchState);

if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) {

Log.d(TAG, "onInterceptTouchEvent, MotionEvent.ACTION_MOVE mTouchState: " + mTouchState);

return true;

}

acquireVelocityTrackerAndAddMovement(ev);

switch (action & MotionEvent.ACTION_MASK) {

case MotionEvent.ACTION_MOVE: {

Log.d(TAG, "onInterceptTouchEvent.ACTION_MOVE.................");

/*

* mIsBeingDragged == false, otherwise the shortcut would have caught it. Check

* whether the user has moved far enough from his original down touch.

*/

/*

* Locally do absolute value. mLastMotionX is set to the y value

* of the down event.

*/

final int pointerIndex = ev.findPointerIndex(mActivePointerId);

final float x = ev.getX(pointerIndex);

final float y = ev.getY(pointerIndex);

final int xDiff = (int) Math.abs(x - mLastMotionX);

final int yDiff = (int) Math.abs(y - mLastMotionY);

final int touchSlop = mTouchSlop;

boolean xMoved = xDiff > touchSlop;

boolean yMoved = yDiff > touchSlop;

if (xMoved || yMoved) {

if (xMoved) {

Log.d(TAG, "onInterceptTouchEvent.ACTION_MOVE.TOUCH_STATE_SCROLLING................");

// Scroll if the user moved far enough along the X axis

mTouchState = TOUCH_STATE_SCROLLING;

mLastMotionX = x;

mTouchX = getScrollX();

mSmoothingTime = System.nanoTime() / NANOTIME_DIV;

//enableChildrenCache(mCurrentScreen - 1, mCurrentScreen + 1);

}

// Either way, cancel any pending longpress

if (mAllowLongPress) {

mAllowLongPress = false;

// Try canceling the long press. It could also have been scheduled

// by a distant descendant, so use the mAllowLongPress flag to block

// everything

final View currentScreen = getChildAt(mCurrentScreen);

currentScreen.cancelLongPress();

}

}

break;

}

case MotionEvent.ACTION_DOWN: {

Log.d(TAG, "onInterceptTouchEvent.ACTION_DOWN.................");

final float x = ev.getX();

final float y = ev.getY();

// Remember location of down touch

mLastMotionX = x;

mLastMotionY = y;

mActivePointerId = ev.getPointerId(0);

mAllowLongPress = true;

/*

* If being flinged and user touches the screen, initiate drag;

* otherwise don't.mScroller.isFinished should be false when

* being flinged.

*/

Log.d(TAG, "mScroller.isFinished()................." + mScroller.isFinished());

mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;

break;

}

case MotionEvent.ACTION_CANCEL:

case MotionEvent.ACTION_UP:

Log.d(TAG, "onInterceptTouchEvent.ACTION_UP.................");

// Release the drag

//clearChildrenCache();

mTouchState = TOUCH_STATE_REST;

mActivePointerId = INVALID_POINTER;

mAllowLongPress = false;

releaseVelocityTracker();

break;

case MotionEvent.ACTION_POINTER_UP:

Log.d(TAG, "onInterceptTouchEvent.ACTION_POINTER_UP.................");

onSecondaryPointerUp(ev);

break;

}

/*

* The only time we want to intercept motion events is if we are in the

* drag mode.

*/

Log.d(TAG, "onInterceptTouchEvent.mTouchState != TOUCH_STATE_REST................." + (mTouchState != TOUCH_STATE_REST));

return mTouchState != TOUCH_STATE_REST;

}

private void onSecondaryPointerUp(MotionEvent ev) {

final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>

MotionEvent.ACTION_POINTER_INDEX_SHIFT;

final int pointerId = ev.getPointerId(pointerIndex);

if (pointerId == mActivePointerId) {

// This was our active pointer going up. Choose a new

// active pointer and adjust accordingly.

// TODO: Make this decision more intelligent.

final int newPointerIndex = pointerIndex == 0 ? 1 : 0;

mLastMotionX = ev.getX(newPointerIndex);

mLastMotionY = ev.getY(newPointerIndex);

mActivePointerId = ev.getPointerId(newPointerIndex);

if (mVelocityTracker != null) {

mVelocityTracker.clear();

}

}

}

/**

* If one of our descendant views decides that it could be focused now, only

* pass that along if it's on the current screen.

*

* This happens when live folders requery, and if they're off screen, they

* end up calling requestFocus, which pulls it on screen.

*/

@Override

public void focusableViewAvailable(View focused) {

View current = getChildAt(mCurrentScreen);

View v = focused;

while (true) {

if (v == current) {

super.focusableViewAvailable(focused);

return;

}

if (v == this) {

return;

}

ViewParent parent = v.getParent();

if (parent instanceof View) {

v = (View)v.getParent();

} else {

return;

}

}

}

@Override

public boolean onTouchEvent(MotionEvent ev) {

acquireVelocityTrackerAndAddMovement(ev);

final int action = ev.getAction();

switch (action & MotionEvent.ACTION_MASK) {

case MotionEvent.ACTION_DOWN:

Log.d(TAG, "onTouchEvent.ACTION_DOWN.................");

/*

* If being flinged and user touches, stop the fling. isFinished

* will be false if being flinged.

*/

if (!mScroller.isFinished()) {

mScroller.abortAnimation();

}

// Remember where the motion event started

mLastMotionX = ev.getX();

mActivePointerId = ev.getPointerId(0);

if (mTouchState == TOUCH_STATE_SCROLLING) {

//enableChildrenCache(mCurrentScreen - 1, mCurrentScreen + 1);

}

break;

case MotionEvent.ACTION_MOVE:

Log.d(TAG, "onTouchEvent.ACTION_MOVE.................");

if (mTouchState == TOUCH_STATE_SCROLLING) {

Log.d(TAG, "onTouchEvent.ACTION_MOVE.TOUCH_STATE_SCROLLING................");

// Scroll to follow the motion event

final int pointerIndex = ev.findPointerIndex(mActivePointerId);

final float x = ev.getX(pointerIndex);

final float deltaX = mLastMotionX - x;

mLastMotionX = x;

if (deltaX < 0) {

if (mTouchX > 0) {

mTouchX += Math.max(-mTouchX, deltaX);

mSmoothingTime = System.nanoTime() / NANOTIME_DIV;

invalidate();

}

} else if (deltaX > 0) {

final float availableToScroll = getChildAt(getChildCount() - 1).getRight() -

mTouchX - getWidth();

if (availableToScroll > 0) {

mTouchX += Math.min(availableToScroll, deltaX);

mSmoothingTime = System.nanoTime() / NANOTIME_DIV;

invalidate();

}

} else {

awakenScrollBars();

}

}

break;

case MotionEvent.ACTION_UP:

Log.d(TAG, "onTouchEvent.ACTION_UP.................");

if (mTouchState == TOUCH_STATE_SCROLLING) {

final VelocityTracker velocityTracker = mVelocityTracker;

velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);

final int velocityX = (int) velocityTracker.getXVelocity(mActivePointerId);

final int screenWidth = getWidth();

final int whichScreen = (getScrollX() + (screenWidth / 2)) / screenWidth;

final float scrolledPos = (float) getScrollX() / screenWidth;

if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) {

// Fling hard enough to move left.

// Don't fling across more than one screen at a time.

final int bound = scrolledPos < whichScreen ?

mCurrentScreen - 1 : mCurrentScreen;

snapToScreen(Math.min(whichScreen, bound), velocityX, true);

} else if (velocityX < -SNAP_VELOCITY && mCurrentScreen < getChildCount() - 1) {

// Fling hard enough to move right

// Don't fling across more than one screen at a time.

final int bound = scrolledPos > whichScreen ?

mCurrentScreen + 1 : mCurrentScreen;

snapToScreen(Math.max(whichScreen, bound), velocityX, true);

} else {

snapToScreen(whichScreen, 0, true);

}

}

mTouchState = TOUCH_STATE_REST;

mActivePointerId = INVALID_POINTER;

releaseVelocityTracker();

break;

case MotionEvent.ACTION_CANCEL:

if (mTouchState == TOUCH_STATE_SCROLLING) {

final int screenWidth = getWidth();

final int whichScreen = (getScrollX() + (screenWidth / 2)) / screenWidth;

snapToScreen(whichScreen, 0, true);

}

mTouchState = TOUCH_STATE_REST;

mActivePointerId = INVALID_POINTER;

releaseVelocityTracker();

break;

case MotionEvent.ACTION_POINTER_UP:

Log.d(TAG, "onTouchEvent.ACTION_POINTER_UP.................");

onSecondaryPointerUp(ev);

break;

}

return true;

}

private void acquireVelocityTrackerAndAddMovement(MotionEvent ev) {

if (mVelocityTracker == null) {

mVelocityTracker = VelocityTracker.obtain();

}

mVelocityTracker.addMovement(ev);

}

private void releaseVelocityTracker() {

if (mVelocityTracker != null) {

mVelocityTracker.recycle();

mVelocityTracker = null;

}

}

void snapToScreen(int whichScreen) {

snapToScreen(whichScreen, 0, false);

}

private void snapToScreen(int whichScreen, int velocity, boolean settle) {

//if (!mScroller.isFinished()) return;

whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));

//enableChildrenCache(mCurrentScreen, whichScreen);

mNextScreen = whichScreen;

//mPreviousIndicator.setLevel(mNextScreen);

//mNextIndicator.setLevel(mNextScreen);

View focusedChild = getFocusedChild();

if (focusedChild != null && whichScreen != mCurrentScreen &&

focusedChild == getChildAt(mCurrentScreen)) {

focusedChild.clearFocus();

}

final int screenDelta = Math.max(1, Math.abs(whichScreen - mCurrentScreen));

final int newX = whichScreen * getWidth();

final int delta = newX - mScrollX;

int duration = (screenDelta + 1) * 100;

if (!mScroller.isFinished()) {

mScroller.abortAnimation();

}

if (settle) {

mScrollInterpolator.setDistance(screenDelta);

} else {

mScrollInterpolator.disableSettle();

}

velocity = Math.abs(velocity);

if (velocity > 0) {

duration += (duration / (velocity / BASELINE_FLING_VELOCITY))

* FLING_VELOCITY_INFLUENCE;

} else {

duration += 100;

}

awakenScrollBars(duration);

mScroller.startScroll(mScrollX, 0, delta, 0, duration);

invalidate();

}

@Override

protected Parcelable onSaveInstanceState() {

final SavedState state = new SavedState(super.onSaveInstanceState());

state.currentScreen = mCurrentScreen;

return state;

}

@Override

protected void onRestoreInstanceState(Parcelable state) {

SavedState savedState = (SavedState) state;

super.onRestoreInstanceState(savedState.getSuperState());

if (savedState.currentScreen != -1) {

mCurrentScreen = savedState.currentScreen;

}

}

public void scrollLeft() {

Log.d(TAG, "scrollLeft.................");

if (mScroller.isFinished()) {

if (mCurrentScreen > 0) snapToScreen(mCurrentScreen - 1);

} else {

if (mNextScreen > 0) snapToScreen(mNextScreen - 1);

}

}

public void scrollRight() {

Log.d(TAG, "scrollRight.................");

if (mScroller.isFinished()) {

if (mCurrentScreen < getChildCount() -1) snapToScreen(mCurrentScreen + 1);

} else {

if (mNextScreen < getChildCount() -1) snapToScreen(mNextScreen + 1);

}

}

public int getScreenForView(View v) {

int result = -1;

if (v != null) {

ViewParent vvp = v.getParent();

int count = getChildCount();

for (int i = 0; i < count; i++) {

if (vp == getChildAt(i)) {

return i;

}

}

}

return result;

}

/**

* @return True is long presses are still allowed for the current touch

*/

public boolean allowLongPress() {

return mAllowLongPress;

}

/**

* Set true to allow long-press events to be triggered, usually checked by

* {@link Launcher} to accept or block dpad-initiated long-presses.

*/

public void setAllowLongPress(boolean allowLongPress) {

mAllowLongPress = allowLongPress;

}

void moveToDefaultScreen(boolean animate) {

if (animate) {

snapToScreen(mDefaultScreen);

} else {

setCurrentScreen(mDefaultScreen);

}

getChildAt(mDefaultScreen).requestFocus();

}

//void setIndicators(Drawable previous, Drawable next) {

//mPreviousIndicator = previous;

//mNextIndicator = next;

//previous.setLevel(mCurrentScreen);

//next.setLevel(mCurrentScreen);

//}

public static class SavedState extends BaseSavedState {

int currentScreen = -1;

SavedState(Parcelable superState) {

super(superState);

}

private SavedState(Parcel in) {

super(in);

currentScreen = in.readInt();

}

@Override

public void writeToParcel(Parcel out, int flags) {

super.writeToParcel(out, flags);

out.writeInt(currentScreen);

}

public static final Parcelable.Creator<SavedState> CREATOR =

new Parcelable.Creator<SavedState>() {

public SavedState createFromParcel(Parcel in) {

return new SavedState(in);

}

public SavedState[] newArray(int size) {

return new SavedState[size];

}

};

}

}

package com.mylauncher;

import android.content.Context;

import android.util.AttributeSet;

import android.view.View;

import android.widget.LinearLayout;

import android.view.MotionEvent;

import android.util.Log;

public class CellLayout extends LinearLayout {

private static final String TAG = "MyLauncher.CellLayout";

public CellLayout(Context context, AttributeSet attrs) {

super(context, attrs);

// TODO Auto-generated constructor stub

}

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

Log.d(TAG, "onInterceptTouchEvent, action=" + ev.getAction());

return true;

}

@Override

public boolean onTouchEvent(MotionEvent ev) {

Log.d(TAG, "onTouchEvent, action=" + ev.getAction());

return true;

}

}

赞助本站

人工智能实验室

相关热词: Workspace 左右滑动

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港