zoukankan      html  css  js  c++  java
  • 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);
    	}
    
    }
    


    实现的效果是:

    拖拉,点击实现上拉功能,效果图如下:




  • 相关阅读:
    log4j在eclipse下使用
    Java实现IOS推送(利用javapns1.6)
    [转]浅谈多核CPU、多线程与并行计算
    关于select的字段加别名的语法
    [转]maven环境快速搭建
    Java实现IOS推送(Javapns2.2)
    千年服务器GM命令及使用详解
    [转载 蓝韦巍]类似浩方、VS对战平台系统的实现
    召唤和删除怪物程序段
    WPE下载 & WPE & 各版本下载 及 教程
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3192050.html
Copyright © 2011-2022 走看看