Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android實現可動態布局的抽屜(二)

Android實現可動態布局的抽屜(二)

編輯:Android開發實例

       上次介紹了基礎篇,講解了自定義抽屜控件的基礎實現,這次就在基礎篇的基礎上加入拖拉功能。拖拉功能基於GestureDetector,GestureDetector的基本使用方式不是本文介紹的重點,有興趣的童鞋可以上網查詢相關的教程。

       本文的抽屜控件相對於基礎篇的抽屜控件多了以下功能:

1.支持手勢拖拉

2.拖拉到一半時,可以自動展開或者收縮。
具體如下圖:

 

 

 

 

 

 

本文的源碼可以到這裡下載:http://download.csdn.net/detail/hellogv/3642418

只貼出抽屜組件的源碼,其他源文件與基礎篇的一樣:

  1. public class Panel extends LinearLayout implements GestureDetector.OnGestureListener{ 
  2.      
  3.     public interface PanelClosedEvent { 
  4.         void onPanelClosed(View panel); 
  5.     } 
  6.      
  7.     public interface PanelOpenedEvent { 
  8.         void onPanelOpened(View panel); 
  9.     } 
  10.      
  11.     private final static int HANDLE_WIDTH=30; 
  12.     private final static int MOVE_WIDTH=20; 
  13.     private Button btnHandler; 
  14.     private LinearLayout panelContainer; 
  15.     private int mRightMargin=0; 
  16.     private Context mContext; 
  17.     private GestureDetector mGestureDetector; 
  18.     private boolean mIsScrolling=false; 
  19.     private float mScrollX; 
  20.     private PanelClosedEvent panelClosedEvent=null; 
  21.     private PanelOpenedEvent panelOpenedEvent=null; 
  22.      
  23.     public Panel(Context context,View otherView,int width,int height) { 
  24.         super(context); 
  25.         this.mContext=context; 
  26.          
  27.         //定義手勢識別 
  28.         mGestureDetector = new GestureDetector(mContext,this); 
  29.         mGestureDetector.setIsLongpressEnabled(false); 
  30.          
  31.         //改變Panel附近組件的屬性 
  32.         LayoutParams otherLP=(LayoutParams) otherView.getLayoutParams(); 
  33.         otherLP.weight=1; 
  34.         otherView.setLayoutParams(otherLP); 
  35.          
  36.         //設置Panel本身的屬性 
  37.         LayoutParams lp=new LayoutParams(width, height); 
  38.         lp.rightMargin=-lp.width+HANDLE_WIDTH; 
  39.         mRightMargin=Math.abs(lp.rightMargin); 
  40.         this.setLayoutParams(lp); 
  41.         this.setOrientation(LinearLayout.HORIZONTAL); 
  42.          
  43.         //設置Handler的屬性 
  44.         btnHandler=new Button(context); 
  45.         btnHandler.setLayoutParams(new LayoutParams(HANDLE_WIDTH,height)); 
  46.         //btnHandler.setOnClickListener(handlerClickEvent); 
  47.         btnHandler.setOnTouchListener(handlerTouchEvent); 
  48.         this.addView(btnHandler); 
  49.          
  50.         //設置Container的屬性 
  51.         panelContainer=new LinearLayout(context); 
  52.         panelContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 
  53.                 LayoutParams.FILL_PARENT)); 
  54.         this.addView(panelContainer); 
  55.  
  56.     } 
  57.  
  58.     private View.OnTouchListener handlerTouchEvent=new View.OnTouchListener() { 
  59.          
  60.         @Override 
  61.         public boolean onTouch(View v, MotionEvent event) { 
  62.             if(event.getAction()==MotionEvent.ACTION_UP && //onScroll時的ACTION_UP 
  63.                     mIsScrolling==true) 
  64.             { 
  65.                 LayoutParams lp=(LayoutParams) Panel.this.getLayoutParams(); 
  66.                 if (lp.rightMargin >= (-mRightMargin/2)) {//往左超過一半 
  67.                     new AsynMove().execute(new Integer[] { MOVE_WIDTH });// 正數展開 
  68.                 }  
  69.                 else if (lp.rightMargin < (-mRightMargin/2)) {//往右拖拉 
  70.                     new AsynMove().execute(new Integer[] { -MOVE_WIDTH });// 負數收縮 
  71.                 } 
  72.             } 
  73.             return mGestureDetector.onTouchEvent(event);  
  74.         } 
  75.     }; 
  76.  
  77.     /** 
  78.      * 定義收縮時的回調函數 
  79.      * @param event 
  80.      */ 
  81.     public void setPanelClosedEvent(PanelClosedEvent event) 
  82.     { 
  83.         this.panelClosedEvent=event; 
  84.     } 
  85.      
  86.     /** 
  87.      * 定義展開時的回調函數 
  88.      * @param event 
  89.      */ 
  90.     public void setPanelOpenedEvent(PanelOpenedEvent event) 
  91.     { 
  92.         this.panelOpenedEvent=event; 
  93.     } 
  94.      
  95.     /** 
  96.      * 把View放在Panel的Container 
  97.      * @param v 
  98.      */ 
  99.     public void fillPanelContainer(View v) 
  100.     { 
  101.         panelContainer.addView(v); 
  102.     } 
  103.      
  104.     /** 
  105.      * 異步移動Panel 
  106.      * @author hellogv  
  107.      */ 
  108.     class AsynMove extends AsyncTask<Integer, Integer, Void> { 
  109.  
  110.         @Override 
  111.         protected Void doInBackground(Integer... params) { 
  112.             int times; 
  113.             if (mRightMargin % Math.abs(params[0]) == 0)// 整除 
  114.                 times = mRightMargin / Math.abs(params[0]); 
  115.             else 
  116.                 // 有余數 
  117.                 times = mRightMargin / Math.abs(params[0]) + 1; 
  118.  
  119.             for (int i = 0; i < times; i++) { 
  120.                 publishProgress(params); 
  121.                 try { 
  122.                     Thread.sleep(Math.abs(params[0])); 
  123.                 } catch (InterruptedException e) { 
  124.                     // TODO Auto-generated catch block 
  125.                     e.printStackTrace(); 
  126.                 } 
  127.             } 
  128.             return null; 
  129.         } 
  130.  
  131.         @Override 
  132.         protected void onProgressUpdate(Integer... params) { 
  133.             LayoutParams lp = (LayoutParams) Panel.this.getLayoutParams(); 
  134.             if (params[0] < 0) 
  135.                 lp.rightMargin = Math.max(lp.rightMargin + params[0], 
  136.                         (-mRightMargin)); 
  137.             else 
  138.                 lp.rightMargin = Math.min(lp.rightMargin + params[0], 0); 
  139.  
  140.             if(lp.rightMargin==0 && panelOpenedEvent!=null){//展開之後 
  141.                 panelOpenedEvent.onPanelOpened(Panel.this);//調用OPEN回調函數 
  142.             } 
  143.             else if(lp.rightMargin==-(mRightMargin) && panelClosedEvent!=null){//收縮之後 
  144.                 panelClosedEvent.onPanelClosed(Panel.this);//調用CLOSE回調函數 
  145.             } 
  146.             Panel.this.setLayoutParams(lp); 
  147.         } 
  148.     } 
  149.  
  150.     @Override 
  151.     public boolean onDown(MotionEvent e) { 
  152.         mScrollX=0; 
  153.         mIsScrolling=false; 
  154.         return false; 
  155.     } 
  156.  
  157.     @Override 
  158.     public boolean onSingleTapUp(MotionEvent e) { 
  159.         LayoutParams lp = (LayoutParams) Panel.this.getLayoutParams(); 
  160.         if (lp.rightMargin < 0)// CLOSE的狀態 
  161.             new AsynMove().execute(new Integer[] { MOVE_WIDTH });// 正數展開 
  162.         else if (lp.rightMargin >= 0)// OPEN的狀態 
  163.             new AsynMove().execute(new Integer[] { -MOVE_WIDTH });// 負數收縮 
  164.         return false; 
  165.     } 
  166.      
  167.     @Override 
  168.     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, 
  169.             float distanceY) { 
  170.         mIsScrolling=true; 
  171.         mScrollX+=distanceX; 
  172.          
  173.         LayoutParams lp=(LayoutParams) Panel.this.getLayoutParams(); 
  174.         if (lp.rightMargin < -1 && mScrollX > 0) {//往左拖拉 
  175.             lp.rightMargin = Math.min((lp.rightMargin + (int) mScrollX),0); 
  176.             Panel.this.setLayoutParams(lp); 
  177.             Log.e("onScroll",lp.rightMargin+""); 
  178.         }  
  179.         else if (lp.rightMargin > -(mRightMargin) && mScrollX < 0) {//往右拖拉 
  180.             lp.rightMargin = Math.max((lp.rightMargin + (int) mScrollX),-mRightMargin); 
  181.             Panel.this.setLayoutParams(lp); 
  182.         } 
  183.          
  184.         if(lp.rightMargin==0 && panelOpenedEvent!=null){//展開之後 
  185.             panelOpenedEvent.onPanelOpened(Panel.this);//調用OPEN回調函數 
  186.         } 
  187.         else if(lp.rightMargin==-(mRightMargin) && panelClosedEvent!=null){//收縮之後 
  188.             panelClosedEvent.onPanelClosed(Panel.this);//調用CLOSE回調函數 
  189.         } 
  190.         Log.e("onScroll",lp.rightMargin+""); 
  191.          
  192.         return false; 
  193.     } 
  194.      
  195.     @Override 
  196.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
  197.             float velocityY) {return false;} 
  198.     @Override 
  199.     public void onLongPress(MotionEvent e) {} 
  200.     @Override 
  201.     public void onShowPress(MotionEvent e) {} 
  202.  

 

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved