`
ff20081528
  • 浏览: 85401 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

android仿腾讯安全管家首页抽屉效果

阅读更多
转载请说明出处
最近在做公司新产品的设计,看到腾讯安全管家首页的抽屉效果设计的挺不错,一方面可以讲经常使用的功能模块直接显示给用户,另一方面将用户不常用的功能模块隐藏起来,而这些功能模块的显示和隐藏可以通过一个抽屉组建实现。所以我们想将这个设计理念加入到我们的产品中。腾讯安全管家效果图如下:



虽然android 文档中向我们提供了一个叫SlidingDrawer的抽屉组建,但是这个组建的使用限制比较多,也实现不了我们想要的效果。故到网上搜了一会,也没看到有开发者写这样的组建。所以只能靠自己了,但是在网上还是看到了一下有价值的参考案例。
不费话了,直接上实现后的效果图:


下面是自定义组建的实现代码
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

public class CustomSlidingDrawer extends LinearLayout implements GestureDetector.OnGestureListener, View.OnTouchListener{
	private final static String TAG = "CustomSlidingDrawer";
	
	private Button btnHandler;
	private LinearLayout container;
	private int mBottonMargin=0;
	private GestureDetector mGestureDetector;
	private boolean mIsScrolling=false;
	private float mScrollY;
	private int moveDistance;
	
	public CustomSlidingDrawer(Context context,View otherView,int width,int height, int hideDistance) {
		super(context);
		moveDistance = hideDistance;
		//定义手势识别
		mGestureDetector = new GestureDetector(context,this);
		mGestureDetector.setIsLongpressEnabled(false);
		
		//改变CustomSlidingDrawer附近组件的属性
		LayoutParams otherLP=(LayoutParams) otherView.getLayoutParams();
		//这一步很重要,要不组建不会显示
		otherLP.weight=1;
		otherView.setLayoutParams(otherLP);
		
		//设置CustomSlidingDrawer本身的属性
		LayoutParams lp=new LayoutParams(width, height);
		lp.bottomMargin = -moveDistance;
		mBottonMargin=Math.abs(lp.bottomMargin);
		this.setLayoutParams(lp);
		this.setOrientation(LinearLayout.VERTICAL);
		//this.setBackgroundColor(Color.BLUE);
		
		//设置Handler的属性
		btnHandler=new Button(context);
		btnHandler.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 35));
		btnHandler.setOnTouchListener(this);
		this.addView(btnHandler);
		
		//设置Container的属性
		container=new LinearLayout(context);
		//container.setBackgroundColor(Color.GREEN);
		container.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
				LayoutParams.MATCH_PARENT));
		this.addView(container);
	}
	
	/**
	 * 把View放在CustomSlidingDrawer的Container
	 * @param v
	 */
	public void fillPanelContainer(View v)
	{
		container.addView(v);
	}
	
	/**
	 * 异步移动CustomSlidingDrawer
	 */
	class AsynMove extends AsyncTask<Integer, Integer, Void> {
		@Override
		protected Void doInBackground(Integer... params) {
			Log.e(TAG, "AsynMove doInBackground");
			int times;
			if (mBottonMargin % Math.abs(params[0]) == 0)// 整除
				times = mBottonMargin / Math.abs(params[0]);
			else
				// 有余数
				times = mBottonMargin / Math.abs(params[0]) + 1;
			for (int i = 0; i < times; i++) {
				publishProgress(params);
			}
			return null;
		}
		@Override
		protected void onProgressUpdate(Integer... params) {
			Log.e(TAG, "AsynMove onProgressUpdate");
			LayoutParams lp = (LayoutParams) CustomSlidingDrawer.this.getLayoutParams();
			if (params[0] < 0)
				lp.bottomMargin = Math.max(lp.bottomMargin + params[0],
						(-mBottonMargin));
			else
				lp.bottomMargin = Math.min(lp.bottomMargin + params[0], 0);
			CustomSlidingDrawer.this.setLayoutParams(lp);
		}
	}
	
	@Override
	public boolean onDown(MotionEvent e) {
		mScrollY=0;
		mIsScrolling=false;
		return false;
	}
	
	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		LayoutParams lp = (LayoutParams) CustomSlidingDrawer.this.getLayoutParams();
		if (lp.bottomMargin < 0)
			new AsynMove().execute(new Integer[] { moveDistance });// 正数展开
		else if (lp.bottomMargin >= 0)
			new AsynMove().execute(new Integer[] { -moveDistance });// 负数收缩
		return false;
	}
	
	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		mIsScrolling=true;
		mScrollY+=distanceY;
		LayoutParams lp=(LayoutParams) CustomSlidingDrawer.this.getLayoutParams();
		if (lp.bottomMargin < -1 && mScrollY > 0) {//往上拖拉
			lp.bottomMargin = Math.min((lp.bottomMargin + (int) mScrollY),0);
			CustomSlidingDrawer.this.setLayoutParams(lp);
		} else if (lp.bottomMargin > -(mBottonMargin) && mScrollY < 0) {//往下拖拉
			lp.bottomMargin = Math.max((lp.bottomMargin + (int) mScrollY),-mBottonMargin);
			CustomSlidingDrawer.this.setLayoutParams(lp);
		}
		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) {}
	
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		if(event.getAction()==MotionEvent.ACTION_UP && //onScroll时的ACTION_UP
				mIsScrolling==true)
		{
			LayoutParams lp=(LayoutParams) CustomSlidingDrawer.this.getLayoutParams();
			if (lp.bottomMargin >= (-mBottonMargin/2)) {//往上超过一半
				new AsynMove().execute(new Integer[] { moveDistance });// 正数展开
			} 
			else if (lp.bottomMargin < (-mBottonMargin/2)) {//往下拖拉
				new AsynMove().execute(new Integer[] { -moveDistance });// 负数收缩
			}
		}
		return mGestureDetector.onTouchEvent(event); 
	}
}


下面是demo的源码:
  • 大小: 74.2 KB
  • 大小: 71.1 KB
  • 大小: 51 KB
  • 大小: 52.2 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics