读书人

可动态格局的Android抽屉之完整篇[转]

发布时间: 2012-09-24 13:49:42 作者: rapoo

可动态布局的Android抽屉之完整篇[转]

? ? ? 上次介绍了基础篇,讲解了自定义抽屉控件的基础实现,这次就在基础篇的基础上加入拖拉功能。拖拉功能基于GestureDetector,GestureDetector的基本使用方式不是本文介绍的重点,有兴趣的童鞋可以上网查询相关的教程。

?????? 本文的抽屉控件相对于基础篇的抽屉控件多了以下功能:

1.支持手势拖拉

2.拖拉到一半时,可以自动展开或者收缩。
具体如下图:

可动态格局的Android抽屉之完整篇[转]

?

?

?

?

?

?

本文的源码可以到这里下载:http://download.csdn.net/detail/hellogv/3642418

只贴出抽屉组件的源码,其他源文件与基础篇的一样:

?

public class Panel extends LinearLayout implements GestureDetector.OnGestureListener{            public interface PanelClosedEvent {          void onPanelClosed(View panel);      }            public interface PanelOpenedEvent {          void onPanelOpened(View panel);      }            private final static int HANDLE_WIDTH=30;      private final static int MOVE_WIDTH=20;      private Button btnHandler;      private LinearLayout panelContainer;      private int mRightMargin=0;      private Context mContext;      private GestureDetector mGestureDetector;      private boolean mIsScrolling=false;      private float mScrollX;      private PanelClosedEvent panelClosedEvent=null;      private PanelOpenedEvent panelOpenedEvent=null;            public Panel(Context context,View otherView,int width,int height) {          super(context);          this.mContext=context;                    //定义手势识别          mGestureDetector = new GestureDetector(mContext,this);          mGestureDetector.setIsLongpressEnabled(false);                    //改变Panel附近组件的属性          LayoutParams otherLP=(LayoutParams) otherView.getLayoutParams();          otherLP.weight=1;          otherView.setLayoutParams(otherLP);                    //设置Panel本身的属性          LayoutParams lp=new LayoutParams(width, height);          lp.rightMargin=-lp.width+HANDLE_WIDTH;          mRightMargin=Math.abs(lp.rightMargin);          this.setLayoutParams(lp);          this.setOrientation(LinearLayout.HORIZONTAL);                    //设置Handler的属性          btnHandler=new Button(context);          btnHandler.setLayoutParams(new LayoutParams(HANDLE_WIDTH,height));          //btnHandler.setOnClickListener(handlerClickEvent);          btnHandler.setOnTouchListener(handlerTouchEvent);          this.addView(btnHandler);                    //设置Container的属性          panelContainer=new LinearLayout(context);          panelContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,                  LayoutParams.FILL_PARENT));          this.addView(panelContainer);        }        private View.OnTouchListener handlerTouchEvent=new View.OnTouchListener() {                    @Override          public boolean onTouch(View v, MotionEvent event) {              if(event.getAction()==MotionEvent.ACTION_UP && //onScroll时的ACTION_UP                      mIsScrolling==true)              {                  LayoutParams lp=(LayoutParams) Panel.this.getLayoutParams();                  if (lp.rightMargin >= (-mRightMargin/2)) {//往左超过一半                      new AsynMove().execute(new Integer[] { MOVE_WIDTH });// 正数展开                  }                   else if (lp.rightMargin < (-mRightMargin/2)) {//往右拖拉                      new AsynMove().execute(new Integer[] { -MOVE_WIDTH });// 负数收缩                  }              }              return mGestureDetector.onTouchEvent(event);           }      };        /**      * 定义收缩时的回调函数      * @param event      */      public void setPanelClosedEvent(PanelClosedEvent event)      {          this.panelClosedEvent=event;      }            /**      * 定义展开时的回调函数      * @param event      */      public void setPanelOpenedEvent(PanelOpenedEvent event)      {          this.panelOpenedEvent=event;      }            /**      * 把View放在Panel的Container      * @param v      */      public void fillPanelContainer(View v)      {          panelContainer.addView(v);      }            /**      * 异步移动Panel      * @author hellogv       */      class AsynMove extends AsyncTask<Integer, Integer, Void> {            @Override          protected Void doInBackground(Integer... params) {              int times;              if (mRightMargin % Math.abs(params[0]) == 0)// 整除                  times = mRightMargin / Math.abs(params[0]);              else                  // 有余数                  times = mRightMargin / Math.abs(params[0]) + 1;                for (int i = 0; i < times; i++) {                  publishProgress(params);                  try {                      Thread.sleep(Math.abs(params[0]));                  } catch (InterruptedException e) {                      // TODO Auto-generated catch block                      e.printStackTrace();                  }              }              return null;          }            @Override          protected void onProgressUpdate(Integer... params) {              LayoutParams lp = (LayoutParams) Panel.this.getLayoutParams();              if (params[0] < 0)                  lp.rightMargin = Math.max(lp.rightMargin + params[0],                          (-mRightMargin));              else                  lp.rightMargin = Math.min(lp.rightMargin + params[0], 0);                if(lp.rightMargin==0 && panelOpenedEvent!=null){//展开之后                  panelOpenedEvent.onPanelOpened(Panel.this);//调用OPEN回调函数              }              else if(lp.rightMargin==-(mRightMargin) && panelClosedEvent!=null){//收缩之后                  panelClosedEvent.onPanelClosed(Panel.this);//调用CLOSE回调函数              }              Panel.this.setLayoutParams(lp);          }      }        @Override      public boolean onDown(MotionEvent e) {          mScrollX=0;          mIsScrolling=false;          return false;      }        @Override      public boolean onSingleTapUp(MotionEvent e) {          LayoutParams lp = (LayoutParams) Panel.this.getLayoutParams();          if (lp.rightMargin < 0)// CLOSE的状态              new AsynMove().execute(new Integer[] { MOVE_WIDTH });// 正数展开          else if (lp.rightMargin >= 0)// OPEN的状态              new AsynMove().execute(new Integer[] { -MOVE_WIDTH });// 负数收缩          return false;      }            @Override      public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,              float distanceY) {          mIsScrolling=true;          mScrollX+=distanceX;                    LayoutParams lp=(LayoutParams) Panel.this.getLayoutParams();          if (lp.rightMargin < -1 && mScrollX > 0) {//往左拖拉              lp.rightMargin = Math.min((lp.rightMargin + (int) mScrollX),0);              Panel.this.setLayoutParams(lp);              Log.e("onScroll",lp.rightMargin+"");          }           else if (lp.rightMargin > -(mRightMargin) && mScrollX < 0) {//往右拖拉              lp.rightMargin = Math.max((lp.rightMargin + (int) mScrollX),-mRightMargin);              Panel.this.setLayoutParams(lp);          }                    if(lp.rightMargin==0 && panelOpenedEvent!=null){//展开之后              panelOpenedEvent.onPanelOpened(Panel.this);//调用OPEN回调函数          }          else if(lp.rightMargin==-(mRightMargin) && panelClosedEvent!=null){//收缩之后              panelClosedEvent.onPanelClosed(Panel.this);//调用CLOSE回调函数          }          Log.e("onScroll",lp.rightMargin+"");                    return false;      }            @Override      public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,              float velocityY) {return false;}      @Override      public void onLongPress(MotionEvent e) {}      @Override      public void onShowPress(MotionEvent e) {}    }

?

?

本文来自http://blog.csdn.net/hellogv/article/details/6828584

读书人网 >Android

热点推荐