編輯:關於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 (leftMargin 0) { 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); } } }
第一步:下載SDK:1下載地址:http://www.mob.com/ 根據需求選擇需要的平台:第二步:申請ShareSDK的AppKey把鼠標移到頭像上,點擊進入後台:
有時候為了程序的安全性,我們經常要采取一些安全措施,就像我們常用的支付寶那樣,隔一定的時間再回到應用程序時會讓用戶利用手勢去解鎖應用程序,最近由於項目需求,也要求做這樣一
Activity生命周期經典圖解:按鍵對生命周期的影響:BACK鍵: 當我們按BACK鍵時,我們這個應用程序將結束,這時候我們將先後調用onPause()->on
以前看別人的程序的drawable文件夾裡有xml資源,說實話第一次見到這樣的xml圖像資源時,我真心不知道是干什麼的。抽空學習了一下圖像資源,才了解了這類圖像資源的妙用