Android中使用系統桌面背景作爲應用背景,支持拖動

在Android應用開發中,使用系統桌面背景作爲應用的背景,需要把應用的背景設置爲透明背景,然後設置窗口的屬性爲FLAG_SHOW_WALLPAPER即可顯示背景。

修改AndroidManifest.xml文件裏面activity屬性:

 

        <activity android:name=".WallPaperTest"

                  android:label="@string/app_name"

                  android:theme="@android:style/Theme.Translucent">

然後在使用的時候,在onCreate裏面添加一個窗口屬性

getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);

 

在背景拖動的時候主要是使用了WallpaperManager這個類的兩個方法

 

public void setWallpaperOffsetSteps (float xStep, float yStep)

Since: API Level 7

For applications that use multiple virtual screens showing a wallpaper, specify the step size between virtual screens. For example, if the launcher has 3 virtual screens, it would specify an xStep of 0.5, since the X offset for those screens are 0.0, 0.5 and 1.0

Parameters
xStepThe X offset delta from one screen to the next one
yStepThe Y offset delta from one screen to the next one

public void setWallpaperOffsets (IBinder windowToken, float xOffset, float yOffset)

Since: API Level 5

Set the position of the current wallpaper within any larger space, when that wallpaper is visible behind the given window. The X and Y offsets are floating point numbers ranging from 0 to 1, representing where the wallpaper should be positioned within the screen space. These only make sense when the wallpaper is larger than the screen.

Parameters
windowTokenThe window who these offsets should be associated with, as returned by View.getWindowToken().
xOffsetThe offset along the X dimension, from 0 to 1.
yOffset

The offset along the Y dimension, from 0 to 1.

 

修改了之前ScrollLayout的類,讓它支持顯示系統背景,並且拖動的時候背景也跟着拖動,跟Launcher中的效果一致。。。
基本類文件ScrollLayout.java
package com.yao_guet;
import android.app.WallpaperManager;
import android.content.Context;
import android.os.IBinder;
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,可以左右滑動切換屏幕的類,支持顯示系統背景和滑動
 * @author Yao.GUET
 * blog: http://blog.csdn.net/Yao_GUET
 * date: 2011-05-04
 */
public class ScrollLayout extends ViewGroup {
	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;
	private float mLastMotionX;
	private float mLastMotionY;
	
	private WallpaperManager mWallpaperManager;
	private int mScrollX;
	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
		
		mWallpaperManager = WallpaperManager.getInstance(context);
		mScroller = new Scroller(context);
		
		mCurScreen = mDefaultScreen;
		mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
	}
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		// TODO Auto-generated method stub
		Log.e(TAG, "onLayout");
		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;
			}
		}
		updateWallpaperOffset();
	}

    @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() {
    	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)*2);
    		mCurScreen = whichScreen;
    		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;
    }
    
	@Override
	public void computeScroll() {
		// TODO Auto-generated method stub
		mScrollX = mScroller.getCurrX();
		if (mScroller.computeScrollOffset()) {
			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
			updateWallpaperOffset();
			
			postInvalidate();
		}
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		
		if (mVelocityTracker == null) {
			mVelocityTracker = VelocityTracker.obtain();
		}
		mVelocityTracker.addMovement(event);
		
		final int action = event.getAction();
		final float x = event.getX();
		final float y = event.getY();
		
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			Log.e(TAG, "event down!");
			if (!mScroller.isFinished()){
				mScroller.abortAnimation();
			}
			mLastMotionX = x;
			break;
			
		case MotionEvent.ACTION_MOVE:
			int deltaX = (int)(mLastMotionX - x);
			mLastMotionX = x;
            scrollBy(deltaX, 0);
            updateWallpaperOffset();
			break;
			
		case MotionEvent.ACTION_UP:
			Log.e(TAG, "event : up");   
            // if (mTouchState == TOUCH_STATE_SCROLLING) {   
            final VelocityTracker velocityTracker = mVelocityTracker;   
            velocityTracker.computeCurrentVelocity(1000);   
            int velocityX = (int) velocityTracker.getXVelocity();   
            Log.e(TAG, "velocityX:"+velocityX); 
            
            if (velocityX > SNAP_VELOCITY && mCurScreen > 0) {   
                // Fling enough to move left   
            	Log.e(TAG, "snap left");
                snapToScreen(mCurScreen - 1);   
            } else if (velocityX < -SNAP_VELOCITY   
                    && mCurScreen < getChildCount() - 1) {   
                // Fling enough to move right   
            	Log.e(TAG, "snap right");
                snapToScreen(mCurScreen + 1);   
            } else {   
                snapToDestination();   
            }   
            if (mVelocityTracker != null) {   
                mVelocityTracker.recycle();   
                mVelocityTracker = null;   
            }   
            // }   
            mTouchState = TOUCH_STATE_REST;   
			break;
		case MotionEvent.ACTION_CANCEL:
			mTouchState = TOUCH_STATE_REST;
			break;
		}
		
		return true;
	}
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		Log.e(TAG, "onInterceptTouchEvent-slop:"+mTouchSlop);
		
		final int action = ev.getAction();
		if ((action == MotionEvent.ACTION_MOVE) && 
				(mTouchState != TOUCH_STATE_REST)) {
			return true;
		}
		
		final float x = ev.getX();
		final float y = ev.getY();
		
		switch (action) {
		case MotionEvent.ACTION_MOVE:
			final int xDiff = (int)Math.abs(mLastMotionX-x);
			if (xDiff>mTouchSlop) {
				mTouchState = TOUCH_STATE_SCROLLING;
				
			}
			break;
			
		case MotionEvent.ACTION_DOWN:
			mLastMotionX = x;
			mLastMotionY = y;
			mTouchState = mScroller.isFinished()? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
			break;
			
		case MotionEvent.ACTION_CANCEL:
		case MotionEvent.ACTION_UP:
			mTouchState = TOUCH_STATE_REST;
			break;
		}
		
		return mTouchState != TOUCH_STATE_REST;
	}
	
	
	private void updateWallpaperOffset() {
        int scrollRange = getChildAt(getChildCount() - 1).getRight() - getWidth();
        IBinder token = getWindowToken();
        if (token != null) {
            mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 0 );
            mWallpaperManager.setWallpaperOffsets(getWindowToken(),
                    Math.max(0.f, Math.min(getScrollX()/(float)scrollRange, 1.f)), 0);
        }
    }
}


測試代碼WallPaperTest.java:
package com.yao_guet;
import android.app.Activity;
import android.app.WallpaperManager;
import android.content.Context;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
public class WallPaperTest extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.wallpaper_test);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
	}
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		return super.onKeyDown(keyCode, event);
	}
}


layout佈局文件wallpaper_test.xml:
<?xml version="1.0" encoding="utf-8"?>
<com.sf.test.ScrollLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/WallPaperTest"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
<LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
  	android:layout_width="fill_parent"
  	android:layout_height="wrap_content"
  	android:text="This is page 1" />
  </LinearLayout>
  
<LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
  	android:layout_width="fill_parent"
  	android:layout_height="wrap_content"
  	android:text="This is page 2" />
  </LinearLayout>
  
<LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
  	android:layout_width="fill_parent"
  	android:layout_height="wrap_content"
  	android:text="This is page 3" />
  </LinearLayout>
  
<LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
  	android:layout_width="fill_parent"
  	android:layout_height="wrap_content"
  	android:text="This is page 4" />
  </LinearLayout>
<LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
  	android:layout_width="fill_parent"
  	android:layout_height="wrap_content"
  	android:text="This is page 5" />
  </LinearLayout>
<LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
  	android:layout_width="fill_parent"
  	android:layout_height="wrap_content"
  	android:text="This is page 6" />
  </LinearLayout>
  
<LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
  	android:layout_width="fill_parent"
  	android:layout_height="wrap_content"
  	android:text="This is page 7" />
  </LinearLayout>
</com.sf.test.ScrollLayout>


然後記得修改AndroidManifest.xml文件。。。

        <activity android:name=".WallPaperTest"

                  android:label="@string/app_name"

                  android:theme="@android:style/Theme.Translucent">

 

發佈了79 篇原創文章 · 獲贊 6 · 訪問量 91萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章