Android自定義實現抽屜SlidingDrawer的功能

jopen 11年前發布 | 46K 次閱讀 Android Android開發 移動開發

最近項目中需要實現上拉功能,首先想到的就是Android本身自帶的抽屜 SlidingDrawer,最后也實現了不過,出現的問題就是設置背景色問題,handler和content是兩個不同的部分,這就造成圖片要做成兩部分,從而產生兩個部分圖片看起來不是一個整體,而且我這個上拉功能,里面要實現一個水平滾動功能,而 SlidingDrawer還有其他的限制,同時官方給出api 17以后,這個功能已經廢棄,所以自己自定這樣一個上拉功能是必須的。

這里我是繼承LinearLayout同時實現GestureDetector.OnGestureListener來實現上拉功能。下面是代碼:

    package com.example.test;  

    import android.content.Context;  
    import android.os.AsyncTask;  
    import android.util.AttributeSet;  
    import android.view.GestureDetector;  
    import android.view.MotionEvent;  
    import android.widget.LinearLayout;  
    import android.widget.RelativeLayout;  

    public class PanelBom extends LinearLayout implements GestureDetector.OnGestureListener{  

        GestureDetector mGesture = null;  
        private boolean isScrolling = false;  
        private int MAX_HEIGHT = 80;//拖動的最大高度,當前布局位于父布局下面-80位置,這個僅僅是調試參數,這個變量是動態設置的。  
        private float mScrollX; // 滑塊滑動距離  
        public PanelBom(Context context) {  
            super(context);  
            init();  
        }  
        public PanelBom(Context context, AttributeSet attrs) {  
            super(context, attrs);  
            init();  
        }  
        //初始化一些參數  
        public void init(){  
            mGesture = new GestureDetector(this);  
            mGesture.setIsLongpressEnabled(false);  
            setBackgroundResource(R.drawable.button_bar);  
        }  

        @Override  
        public boolean onTouchEvent(MotionEvent event) {  
            if (MotionEvent.ACTION_UP == event.getAction() && isScrolling == true) {  
                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)getLayoutParams();  
                // 縮回去  
                if (layoutParams.bottomMargin < -MAX_HEIGHT / 2) {  
                    new AsynMove().execute(-20);//負--往下  
                } else {  
                    new AsynMove().execute(20);//正--往上  
                }  
            }  
            return mGesture.onTouchEvent(event);  
        }  
        //Touch down時觸發   
        @Override  
        public boolean onDown(MotionEvent e) {  
            mScrollX = 0;  
            isScrolling = false;  
            // 將之改為true,不然事件不會向下傳遞.  
            return true;  
        }  
        //Touch了還沒有滑動時觸發   
        @Override  
        public void onShowPress(MotionEvent e) {  

        }  
        @Override  
        public boolean onSingleTapUp(MotionEvent e) {  
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();  
            // 說明在上面,要往下  
            if (layoutParams.bottomMargin >= 0) {  
                new AsynMove().execute(-20);//負--往下  
            } else {  
                new AsynMove().execute(20);//正--往上  
            }  
            return true;  
        }  
        //Touch了滑動時觸發  
        @Override  
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,  
                float distanceY) {  
            isScrolling = true;  
            mScrollX += distanceY;  
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)getLayoutParams();  
            layoutParams.bottomMargin += mScrollX;  
            if (layoutParams.bottomMargin >= 0) {  
                isScrolling = false;// 拖過頭了不需要再執行AsynMove了  
                layoutParams.bottomMargin = 0;  
            } else if (layoutParams.bottomMargin <= -MAX_HEIGHT) {  
                // 拖過頭了不需要再執行AsynMove了  
                isScrolling = false;  
                layoutParams.bottomMargin = -MAX_HEIGHT;  
            }  
            setLayoutParams(layoutParams);  
            return false;  
        }  
        //Touch了不移動一直Touch down時觸發   
        @Override  
        public void onLongPress(MotionEvent e) {  

        }  
        //Touch了滑動一點距離后,up時觸發。  
        @Override  
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  
                float velocityY) {  
            return false;  
        }  
        //異步更新布局的位置  
        class AsynMove extends AsyncTask<Integer, Integer, Void> {  
            @Override  
            protected Void doInBackground(Integer... params) {  
                int times = 0;  
                int divi = Math.abs(params[0]);  
                if (MAX_HEIGHT % divi == 0)// 整除  
                    times = MAX_HEIGHT / Math.abs(params[0]);  
                else  
                    times = MAX_HEIGHT / divi + 1;// 有余數  

                for (int i = 0; i < times; i++) {  
                    publishProgress(params[0]);  
                    try {  
                        Thread.sleep(divi);  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  
                }  
                return null;  
            }  
            @Override  
            protected void onProgressUpdate(Integer... values) {  
                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();  
                if (values[0] < 0) {  
                    layoutParams.bottomMargin = Math.max(layoutParams.bottomMargin + values[0], -MAX_HEIGHT);  
                } else {  
                    layoutParams.bottomMargin = Math.min(layoutParams.bottomMargin + values[0], 0);  
                }  
                setLayoutParams(layoutParams);  

                super.onProgressUpdate(values);  
            }  
        }  
    }  
主界面:
    package com.example.test;  

    import android.app.Activity;  
    import android.os.Bundle;  
    import android.widget.RelativeLayout;  

    public class Main5 extends Activity{  

        RelativeLayout Parent;  
        PanelBom panelBom;  
        RelativeLayout.LayoutParams parentParams;  
        RelativeLayout.LayoutParams paneBomParams;  
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            Parent = new RelativeLayout(getApplicationContext());  
            panelBom = new PanelBom(getApplicationContext());  
            parentParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);  
            paneBomParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 150);  
            paneBomParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);  
            paneBomParams.bottomMargin = -80;  
            Parent.addView(panelBom, paneBomParams);  
            setContentView(Parent, parentParams);  
        }  

    }  
實現的效果是: 拖拉,點擊實現上拉功能,效果圖如下:

20130715162754765.jpeg

來自:http://blog.csdn.net/jwzhangjie/article/details/9333515

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!