編輯:關於Android編程
package cc.cd;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.app.Activity;
import android.content.Context;
/**
* Demo描述:
* 側滑菜單SlidingMenu的簡單示例
* 即在一個Activity中加入SlidingMenu
*
* 示例說明:
* 示例中一共兩個界面menu和content.當進入應用時顯示content界面.
* 若手指滑向屏幕右側則顯示menu和隱藏content.反之,同理.
* menu的顯示和隱藏主要是修改menu的LayoutParams中的leftMargin從而達到效果.
*
* 步驟整理:
* 1 初始化時,通過設置menu的LayoutParams中的leftMargin使其完全隱藏.
* 2 為content設置Touch監聽.
* 3 在move的過程中不斷修改menu的LayoutParams中的leftMargin使其按照
* 手勢的滑動而顯示或者隱藏
* 4 在up時通過異步任務AsyncTask修改menu的LayoutParams中的leftMargin
* 從而實現menu的完全顯示或者完全隱藏.
*
* 以上套路還是挺常見的.
*
* 參考資料:
* 1 http://blog.csdn.net/guolin_blog/article/details/8714621
* 2 http://blog.csdn.net/hudashi/article/details/7352157
* Thank you very much
*
* 備注說明:
* 1 示例中使用的圖片亦來自參考資料1
* 2 為簡化邏輯,示例中的兩個界面均為截圖而不是實際View界面
*/
public class MainActivity extends Activity {
private int screenWidth;
private View contentView;
private View menuView;
private float xDown;
private float xMove;
private float xUp;
//當完全顯示menu時content的寬度最小值
private int contentViewMinWidth = 80;
//menu是否可見的標志位,該值在滑動過程中無效.
//只有在滑動結束後,完全顯示或隱藏menu時才會更改此值
private boolean isMenuVisible=false;
private int menuParamsMaxLeftMargin=0;
private int menuParamsMinLeftMargin=0;
//速度追蹤
private VelocityTracker mVelocityTracker;
//阈值
public static final int VELOCITY_THRESHOLD=200;
//TAG
private final static String TAG="MainActivity";
//menu的布局LayoutParams
private LinearLayout.LayoutParams menuLayoutParams;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
}
private void init(){
//獲取屏幕寬度
WindowManager windowManager=(WindowManager) getSystemService(Context.WINDOW_SERVICE);
screenWidth=windowManager.getDefaultDisplay().getWidth();
//初始化contentView
contentView=findViewById(R.id.contentLinearLayout);
//將contentView的寬度設置為屏幕的寬度
contentView.getLayoutParams().width=screenWidth;
//設置Touch監聽
contentView.setOnTouchListener(new TouchListenerImpl());
//初始化menuView
menuView=findViewById(R.id.menuLinearLayout);
menuLayoutParams=(LinearLayout.LayoutParams) menuView.getLayoutParams();
//設置menuView的寬度.
//設置其寬度為屏幕寬度減去contentView的最小寬度
menuLayoutParams.width=screenWidth-contentViewMinWidth;
//初始化時完全隱藏了menuView.
menuParamsMinLeftMargin=-menuLayoutParams.width;
menuLayoutParams.leftMargin=menuParamsMinLeftMargin;
}
/**
* 關於ACTION_MOVE中distanceX的細節說明.
* 在一次滑動過程中(從手指按下到手指抬起)distanceX的值是持續變大或者變小的.
* 因為int distanceX=(int) (xMove-xDown);
* 這個xDown是按下時的坐標值,在Moving的過程中計算distanceX時一直采用
* 的是xDown減去每時刻的xMove.即在滑動過程中xDown一直不變而xMove是不斷
* 在變化的.
* 代碼說明:
* if (isMenuVisible) {
* menuLayoutParams.leftMargin=distanceX;
* } else {
* menuLayoutParams.leftMargin=menuParamsMinLeftMargin+distanceX;
* }
* 在最開始時,menu是隱藏的.手指按下,滑向屏幕的右邊.調用:
* menuLayoutParams.leftMargin=menuParamsMinLeftMargin+distanceX;
* 所以這個menuLayoutParams.leftMargin是不斷在變大的直到0為止(注意越界判斷),此時
* menuView完全顯示.這時手指再按下,滑向屏幕的左邊.調用:
* menuLayoutParams.leftMargin=distanceX;
* distanceX這個負數一直在減小,它就是menuLayoutParams.leftMargin的值直至
* menuView完全隱藏為止,此時它的值為menuParamsMinLeftMargin(注意越界判斷).
*
* 該問題不難,但在此備注一下以防以後反應不過來.
*/
private class TouchListenerImpl implements OnTouchListener{
@Override
public boolean onTouch(View v, MotionEvent event) {
//開始速度追蹤
startVelocityTracker(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
xDown=event.getRawX();
break;
case MotionEvent.ACTION_MOVE:
xMove=event.getRawX();
int distanceX=(int) (xMove-xDown);
Log.i(TAG, "xDown="+xDown+",xMove="+xMove+",distanceX="+distanceX);
if (isMenuVisible) {
menuLayoutParams.leftMargin=distanceX;
} else {
menuLayoutParams.leftMargin=menuParamsMinLeftMargin+distanceX;
}
//處理越界的情況
if(menuLayoutParams.leftMarginmenuParamsMaxLeftMargin){
menuLayoutParams.leftMargin=menuParamsMaxLeftMargin;
}
//設置menuView的LayoutParams
menuView.setLayoutParams(menuLayoutParams);
break;
case MotionEvent.ACTION_UP:
xUp=event.getRawX();
//判斷手勢意圖想顯示menu
if (wantToShowMenu()) {
//判斷是否顯示menu
if (shouldScrollToMenu()) {
scrollToMenu();
} else {
scrollToContent();
}
}
//判斷手勢意圖想顯示content
if (wantToShowContent()) {
//判斷是否顯示content
if (shouldScrollToContent()) {
scrollToContent();
} else {
scrollToMenu();
}
}
//終止速度追蹤
stopVelocityTracker();
break;
default:
break;
}
return true;
}
}
/**
* 判斷當前手勢是否想顯示菜單Menu
* 判斷條件:
* 1 抬起坐標大於按下坐標
* 2 menu本身不可見
*/
private boolean wantToShowMenu(){
return ((xUp-xDown>0)&&(!isMenuVisible));
}
/**
* 判斷是否應該將menu完整顯示出來
* 判斷條件:
* 滑動距離大於屏幕的二分之一
* 或者滑動速度大於速度阈值VELOCITY_THRESHOLD
*/
private boolean shouldScrollToMenu(){
return ((xUp-xDown>screenWidth/2)||(getScrollVelocity()>VELOCITY_THRESHOLD));
}
/**
* 將屏幕滾動到menu.即將menu完整顯示.
* 按照30的步調不斷修改修改menu的LayoutParams中的leftMargin
*/
private void scrollToMenu(){
new ScrollAsyncTask().execute(30);
}
/**
* 判斷當前手勢是否想顯示菜單Content
* 判斷條件:
* 1 抬起坐標小於按下坐標
* 2 menu本身可見
*/
private boolean wantToShowContent(){
return ((xUp-xDown<0)&&(isMenuVisible));
}
/**
* 判斷是否應該將content完整顯示出來
* 判斷條件:
* xDown-xUp+contentViewMinWidth大於屏幕的二分之一
* 或者滑動速度大於速度阈值VELOCITY_THRESHOLD
*/
private boolean shouldScrollToContent(){
return ((xDown-xUp+contentViewMinWidth>screenWidth/2)||(getScrollVelocity()>VELOCITY_THRESHOLD));
}
/**
* 將屏幕滾動到content.即將content完整顯示
* 按照-30的步調不斷修改修改menu的LayoutParams中的leftMargin
*/
private void scrollToContent(){
new ScrollAsyncTask().execute(-30);
}
/**
* 開始速度追蹤
*/
private void startVelocityTracker(MotionEvent event){
if (mVelocityTracker==null) {
mVelocityTracker=VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
}
/**
* 獲取在content上X方向的手指滑動速度
*/
private int getScrollVelocity(){
//設置VelocityTracker單位.1000表示1秒時間內運動的像素
mVelocityTracker.computeCurrentVelocity(1000);
//獲取在1秒內X方向所滑動像素值
int xVelocity=(int) mVelocityTracker.getXVelocity();
return Math.abs(xVelocity);
}
/**
* 終止速度追蹤
*/
private void stopVelocityTracker(){
if (mVelocityTracker!=null) {
mVelocityTracker.recycle();
mVelocityTracker=null;
}
}
/**
* 利用異步任務不斷修改menu的LayoutParams中的leftMargin從而達到一個
* 視圖移動的效果
*/
private class ScrollAsyncTask extends AsyncTask{
@Override
protected Integer doInBackground(Integer... speed) {
int leftMargin=menuLayoutParams.leftMargin;
while(true){
//每次變化的speed
leftMargin=leftMargin+speed[0];
//若越界,則處理越界且跳出循環
if (leftMargin>menuParamsMaxLeftMargin) {
leftMargin=menuParamsMaxLeftMargin;
break;
}
//若越界,則處理越界且跳出循環
if (leftMargin0) {
isMenuVisible=true;
}else{
isMenuVisible=false;
}
return leftMargin;
}
@Override
protected void onProgressUpdate(Integer... leftMargin) {
super.onProgressUpdate(leftMargin);
menuLayoutParams.leftMargin=leftMargin[0];
menuView.setLayoutParams(menuLayoutParams);
}
@Override
protected void onPostExecute(Integer leftMargin) {
super.onPostExecute(leftMargin);
menuLayoutParams.leftMargin=leftMargin;
menuView.setLayoutParams(menuLayoutParams);
}
}
}
ShareSDK集成
第一步:下載SDK:1下載地址:http://www.mob.com/ 根據需求選擇需要的平台:第二步:申請ShareSDK的AppKey把鼠標移到頭像上,點擊進入後台:
android自定義手勢解鎖View
有時候為了程序的安全性,我們經常要采取一些安全措施,就像我們常用的支付寶那樣,隔一定的時間再回到應用程序時會讓用戶利用手勢去解鎖應用程序,最近由於項目需求,也要求做這樣一
Android中Activity生命周期和啟動模式詳解
Activity生命周期經典圖解:按鍵對生命周期的影響:BACK鍵: 當我們按BACK鍵時,我們這個應用程序將結束,這時候我們將先後調用onPause()->on
Android資源之圖像資源(1)
以前看別人的程序的drawable文件夾裡有xml資源,說實話第一次見到這樣的xml圖像資源時,我真心不知道是干什麼的。抽空學習了一下圖像資源,才了解了這類圖像資源的妙用