android自定义实现抽屉SlidingDrawer的功能
最近项目中需要实现上拉功能,首先想到的就是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); } }
实现的效果是:
拖拉,点击实现上拉功能,效果图如下:
补充:移动开发 , Android ,