Android 3D滑动菜单彻底解析,实现推拉门式的立体特效

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/10471245html

在上一篇文章中,咱们学习了Camera的基本用法,并借助它们编写了一个例子,实现了相似于API Demos里的图片中轴旋转功能。不过那个例子的核心代码是来自于API Demos中带有的Rotate3dAnimation这个类,是它帮助咱们完成了全部的三维旋转操做,全部Matrix和Camera相关的代码也是封装在这个类中。java

这样说来的话,你们内心会不会痒痒的呢?虽然学习了Camera的用法,但却没有按照本身的理解来实现一套很是炫酷的3D效果。不要着急,今天我就带着你们一块儿来实现一种3D推拉门式的滑动菜单,并且彻底不会借助任何API Demos里面的代码。android

固然若是你还不是很了解Camera的使用方式,能够先去阅读个人上一篇文章 Android中轴旋转特效实现,制道别样的图片浏览器 。canvas

关于滑动菜单的文章我也已经写过好几篇了,相信看过的朋友对滑动菜单的实现方式应该都已经比较熟悉了,那么本篇文章的重点就在于,如何在传统滑动菜单的基础上加入推拉门式的立体效果。还不了解滑动菜单如何实现的朋友,能够去翻一翻我以前的文章。说到这里我必需要吐槽一下了,最近发现有很多的网站和我的将个人文章恶意转走,并且还特地把第一行的原文地址信息去除掉。更可气的是,在百度上搜索我文章的标题时,居然先找到的是那些转载我文章的网站。唉,伤心了,看来仍是谷歌比较正常。所以今天我也是在这里特别申明一下,我所写的全部文章均是首发于CSDN博客,若是你阅读这篇文章时是在别的网站,那么你将没法找到我前面所写的关于传统滑动菜单的文章,并且你的疑问和留言也将得不到解答。浏览器

下面仍是回到正题,首先来说一下此次的实现原理吧,其实传统的滑动菜单功能就是把菜单部分放在了下面,主布局放在了上面,而后根据手指滑动的距离来偏移主布局,让菜单部分得以显示出来就好了。不过咱们此次既然要作推拉门式的立体效果,就须要将传统的思惟稍微转变一下,能够先让菜单部分隐藏掉,但却复制一个菜单的镜像并生成一张图片,而后在手指滑动的时候对这张图片进行三维操做,让它产生推拉门式的效果,等滑动操做结束的时候,才让真正的菜单显示出来,而后将这个图片隐藏。原理示意图以下所示:缓存

                                      

那么下面咱们就开始动手实现吧,首先新建一个Android项目,起名叫作ThreeDSlidingLayoutDemo。框架

而后新建一个Image3dView类继承自View,用于生成镜像图片,以及完成三维操做,代码以下所示:ide

public class Image3dView extends View {

	/**
	 * 源视图,用于生成图片对象。
	 */
	private View sourceView;

	/**
	 * 根据传入的源视图生成的图片对象。
	 */
	private Bitmap sourceBitmap;

	/**
	 * 源视图的宽度。
	 */
	private float sourceWidth;

	/**
	 * Matrix对象,用于对图片进行矩阵操做。
	 */
	private Matrix matrix = new Matrix();

	/**
	 * Camera对象,用于对图片进行三维操做。
	 */
	private Camera camera = new Camera();

	/**
	 * Image3dView的构造函数
	 * 
	 * @param context
	 * @param attrs
	 */
	public Image3dView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	/**
	 * 提供外部接口,容许向Image3dView传入源视图。
	 * 
	 * @param view
	 *            传入的源视图
	 */
	public void setSourceView(View view) {
		sourceView = view;
		sourceWidth = sourceView.getWidth();
	}

	/**
	 * 清除掉缓存的图片对象。
	 */
	public void clearSourceBitmap() {
		if (sourceBitmap != null) {
			sourceBitmap = null;
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		if (sourceBitmap == null) {
			getSourceBitmap();
		}
		// 计算图片须要旋转的角度
		float degree = 90 - (90 / sourceWidth) * getWidth();
		camera.save();
		camera.rotateY(degree);
		camera.getMatrix(matrix);
		camera.restore();
		// 将旋转的中心点移动到屏幕左边缘的中间位置
		matrix.preTranslate(0, -getHeight() / 2);
		matrix.postTranslate(0, getHeight() / 2);
		canvas.drawBitmap(sourceBitmap, matrix, null);
	}

	/**
	 * 获取源视图对应的图片对象。
	 */
	private void getSourceBitmap() {
		if (sourceView != null) {
			sourceView.setDrawingCacheEnabled(true);
			sourceView.layout(0, 0, sourceView.getWidth(), sourceView.getHeight());
			sourceView.buildDrawingCache();
			sourceBitmap = sourceView.getDrawingCache();
		}
	}

}

能够看到,Image3dView中提供了一个setSourceView()方法,用于传递源视图进来,咱们稍后复制镜像就是对它进行复制。而后在onDraw()方法里对sourceBitmap进行判断,若是为空,则去调用getSourceBitmap()方法来生成一张镜像图片,getSourceBitmap()方法的细节你们本身去看。在得到了镜像图片以后,接下来就是要计算图片的旋转角度了,这里根据Image3dView当前的宽度和源视图的总宽度进行对比,按比例算出旋转的角度。而后调用Camera的rotateY()方法,让图片团练Y轴进行旋转,并将旋转的中心点移动到屏幕左边缘的中间位置,这几行代码咱们在上篇文章中已经见过了,算是挺熟悉了吧!最后调用Canvas的drawBitmap()方法把图片绘制出来。函数

 

完成了Image3dView以后,接着咱们要开始编写滑动菜单部分的代码,其实此次的代码和以前的滑动菜单代码大同小异,看过我前面文章的朋友,此次理解起来必定会垂手可得。新建ThreeDSlidingLayout类,代码以下所示:布局

public class ThreeDSlidingLayout extends RelativeLayout implements OnTouchListener {

	/**
	 * 滚动显示和隐藏左侧布局时,手指滑动须要达到的速度。
	 */
	public static final int SNAP_VELOCITY = 200;

	/**
	 * 滑动状态的一种,表示未进行任何滑动。
	 */
	public static final int DO_NOTHING = 0;

	/**
	 * 滑动状态的一种,表示正在滑出左侧菜单。
	 */
	public static final int SHOW_MENU = 1;

	/**
	 * 滑动状态的一种,表示正在隐藏左侧菜单。
	 */
	public static final int HIDE_MENU = 2;

	/**
	 * 记录当前的滑动状态
	 */
	private int slideState;

	/**
	 * 屏幕宽度值。
	 */
	private int screenWidth;

	/**
	 * 右侧布局最多能够滑动到的左边缘。
	 */
	private int leftEdge = 0;

	/**
	 * 右侧布局最多能够滑动到的右边缘。
	 */
	private int rightEdge = 0;

	/**
	 * 在被断定为滚动以前用户手指能够移动的最大值。
	 */
	private int touchSlop;

	/**
	 * 记录手指按下时的横坐标。
	 */
	private float xDown;

	/**
	 * 记录手指按下时的纵坐标。
	 */
	private float yDown;

	/**
	 * 记录手指移动时的横坐标。
	 */
	private float xMove;

	/**
	 * 记录手指移动时的纵坐标。
	 */
	private float yMove;

	/**
	 * 记录手机抬起时的横坐标。
	 */
	private float xUp;

	/**
	 * 左侧布局当前是显示仍是隐藏。只有彻底显示或隐藏时才会更改此值,滑动过程当中此值无效。
	 */
	private boolean isLeftLayoutVisible;

	/**
	 * 是否正在滑动。
	 */
	private boolean isSliding;

	/**
	 * 是否已加载过一次layout,这里onLayout中的初始化只需加载一次
	 */
	private boolean loadOnce;

	/**
	 * 左侧布局对象。
	 */
	private View leftLayout;

	/**
	 * 右侧布局对象。
	 */
	private View rightLayout;

	/**
	 * 在滑动过程当中展现的3D视图
	 */
	private Image3dView image3dView;

	/**
	 * 用于监听侧滑事件的View。
	 */
	private View mBindView;

	/**
	 * 左侧布局的参数,经过此参数来从新肯定左侧布局的宽度,以及更改leftMargin的值。
	 */
	private MarginLayoutParams leftLayoutParams;

	/**
	 * 右侧布局的参数,经过此参数来从新肯定右侧布局的宽度。
	 */
	private MarginLayoutParams rightLayoutParams;

	/**
	 * 3D视图的参数,经过此参数来从新肯定3D视图的宽度。
	 */
	private ViewGroup.LayoutParams image3dViewParams;

	/**
	 * 用于计算手指滑动的速度。
	 */
	private VelocityTracker mVelocityTracker;

	/**
	 * 重写SlidingLayout的构造函数,其中获取了屏幕的宽度。
	 * 
	 * @param context
	 * @param attrs
	 */
	public ThreeDSlidingLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		screenWidth = wm.getDefaultDisplay().getWidth();
		touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
	}

	/**
	 * 绑定监听侧滑事件的View,即在绑定的View进行滑动才能够显示和隐藏左侧布局。
	 * 
	 * @param bindView
	 *            须要绑定的View对象。
	 */
	public void setScrollEvent(View bindView) {
		mBindView = bindView;
		mBindView.setOnTouchListener(this);
	}

	/**
	 * 将屏幕滚动到左侧布局界面,滚动速度设定为10.
	 */
	public void scrollToLeftLayout() {
		image3dView.clearSourceBitmap();
		new ScrollTask().execute(-10);
	}

	/**
	 * 将屏幕滚动到右侧布局界面,滚动速度设定为-10.
	 */
	public void scrollToRightLayout() {
		image3dView.clearSourceBitmap();
		new ScrollTask().execute(10);
	}

	/**
	 * 左侧布局是否彻底显示出来,或彻底隐藏,滑动过程当中此值无效。
	 * 
	 * @return 左侧布局彻底显示返回true,彻底隐藏返回false。
	 */
	public boolean isLeftLayoutVisible() {
		return isLeftLayoutVisible;
	}

	/**
	 * 在onLayout中从新设定左侧布局和右侧布局的参数。
	 */
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		if (changed && !loadOnce) {
			// 获取左侧布局对象
			leftLayout = findViewById(R.id.menu);
			leftLayoutParams = (MarginLayoutParams) leftLayout.getLayoutParams();
			rightEdge = -leftLayoutParams.width;
			// 获取右侧布局对象
			rightLayout = findViewById(R.id.content);
			rightLayoutParams = (MarginLayoutParams) rightLayout.getLayoutParams();
			rightLayoutParams.width = screenWidth;
			rightLayout.setLayoutParams(rightLayoutParams);
			// 获取3D视图对象
			image3dView = (Image3dView) findViewById(R.id.image_3d_view);
			// 将左侧布局传入3D视图中做为生成源
			image3dView.setSourceView(leftLayout);
			loadOnce = true;
		}
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		createVelocityTracker(event);
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			// 手指按下时,记录按下时的横坐标
			xDown = event.getRawX();
			yDown = event.getRawY();
			slideState = DO_NOTHING;
			break;
		case MotionEvent.ACTION_MOVE:
			// 手指移动时,对比按下时的横坐标,计算出移动的距离,来调整右侧布局的leftMargin值,从而显示和隐藏左侧布局
			xMove = event.getRawX();
			yMove = event.getRawY();
			int moveDistanceX = (int) (xMove - xDown);
			int moveDistanceY = (int) (yMove - yDown);
			checkSlideState(moveDistanceX, moveDistanceY);
			switch (slideState) {
			case SHOW_MENU:
				rightLayoutParams.rightMargin = -moveDistanceX;
				onSlide();
				break;
			case HIDE_MENU:
				rightLayoutParams.rightMargin = rightEdge - moveDistanceX;
				onSlide();
				break;
			default:
				break;
			}
			break;
		case MotionEvent.ACTION_UP:
			xUp = event.getRawX();
			int upDistanceX = (int) (xUp - xDown);
			if (isSliding) {
				// 手指抬起时,进行判断当前手势的意图
				switch (slideState) {
				case SHOW_MENU:
					if (shouldScrollToLeftLayout()) {
						scrollToLeftLayout();
					} else {
						scrollToRightLayout();
					}
					break;
				case HIDE_MENU:
					if (shouldScrollToRightLayout()) {
						scrollToRightLayout();
					} else {
						scrollToLeftLayout();
					}
					break;
				default:
					break;
				}
			} else if (upDistanceX < touchSlop && isLeftLayoutVisible) {
				scrollToRightLayout();
			}
			recycleVelocityTracker();
			break;
		}
		if (v.isEnabled()) {
			if (isSliding) {
				unFocusBindView();
				return true;
			}
			if (isLeftLayoutVisible) {
				return true;
			}
			return false;
		}
		return true;
	}

	/**
	 * 执行滑动过程当中的逻辑操做,如边界检查,改变偏移值,可见性检查等。
	 */
	private void onSlide() {
		checkSlideBorder();
		rightLayout.setLayoutParams(rightLayoutParams);
		image3dView.clearSourceBitmap();
		image3dViewParams = image3dView.getLayoutParams();
		image3dViewParams.width = -rightLayoutParams.rightMargin;
		// 滑动的同时改变3D视图的大小
		image3dView.setLayoutParams(image3dViewParams);
		// 保证在滑动过程当中3D视图可见,左侧布局不可见
		showImage3dView();
	}

	/**
	 * 根据手指移动的距离,判断当前用户的滑动意图,而后给slideState赋值成相应的滑动状态值。
	 * 
	 * @param moveDistanceX
	 *            横向移动的距离
	 * @param moveDistanceY
	 *            纵向移动的距离
	 */
	private void checkSlideState(int moveDistanceX, int moveDistanceY) {
		if (isLeftLayoutVisible) {
			if (!isSliding && Math.abs(moveDistanceX) >= touchSlop && moveDistanceX < 0) {
				isSliding = true;
				slideState = HIDE_MENU;
			}
		} else if (!isSliding && Math.abs(moveDistanceX) >= touchSlop && moveDistanceX > 0
				&& Math.abs(moveDistanceY) < touchSlop) {
			isSliding = true;
			slideState = SHOW_MENU;
		}
	}

	/**
	 * 在滑动过程当中检查左侧菜单的边界值,防止绑定布局滑出屏幕。
	 */
	private void checkSlideBorder() {
		if (rightLayoutParams.rightMargin > leftEdge) {
			rightLayoutParams.rightMargin = leftEdge;
		} else if (rightLayoutParams.rightMargin < rightEdge) {
			rightLayoutParams.rightMargin = rightEdge;
		}
	}

	/**
	 * 判断是否应该滚动将左侧布局展现出来。若是手指移动距离大于屏幕的1/2,或者手指移动速度大于SNAP_VELOCITY,
	 * 就认为应该滚动将左侧布局展现出来。
	 * 
	 * @return 若是应该滚动将左侧布局展现出来返回true,不然返回false。
	 */
	private boolean shouldScrollToLeftLayout() {
		return xUp - xDown > leftLayoutParams.width / 2 || getScrollVelocity() > SNAP_VELOCITY;
	}

	/**
	 * 判断是否应该滚动将右侧布局展现出来。若是手指移动距离加上leftLayoutPadding大于屏幕的1/2,
	 * 或者手指移动速度大于SNAP_VELOCITY, 就认为应该滚动将右侧布局展现出来。
	 * 
	 * @return 若是应该滚动将右侧布局展现出来返回true,不然返回false。
	 */
	private boolean shouldScrollToRightLayout() {
		return xDown - xUp > leftLayoutParams.width / 2 || getScrollVelocity() > SNAP_VELOCITY;
	}

	/**
	 * 建立VelocityTracker对象,并将触摸事件加入到VelocityTracker当中。
	 * 
	 * @param event
	 *            右侧布局监听控件的滑动事件
	 */
	private void createVelocityTracker(MotionEvent event) {
		if (mVelocityTracker == null) {
			mVelocityTracker = VelocityTracker.obtain();
		}
		mVelocityTracker.addMovement(event);
	}

	/**
	 * 获取手指在右侧布局的监听View上的滑动速度。
	 * 
	 * @return 滑动速度,以每秒钟移动了多少像素值为单位。
	 */
	private int getScrollVelocity() {
		mVelocityTracker.computeCurrentVelocity(1000);
		int velocity = (int) mVelocityTracker.getXVelocity();
		return Math.abs(velocity);
	}

	/**
	 * 回收VelocityTracker对象。
	 */
	private void recycleVelocityTracker() {
		mVelocityTracker.recycle();
		mVelocityTracker = null;
	}

	/**
	 * 使用能够得到焦点的控件在滑动的时候失去焦点。
	 */
	private void unFocusBindView() {
		if (mBindView != null) {
			mBindView.setPressed(false);
			mBindView.setFocusable(false);
			mBindView.setFocusableInTouchMode(false);
		}
	}

	/**
	 * 保证此时让左侧布局不可见,3D视图可见,从而让滑动过程当中产生3D的效果。
	 */
	private void showImage3dView() {
		if (image3dView.getVisibility() != View.VISIBLE) {
			image3dView.setVisibility(View.VISIBLE);
		}
		if (leftLayout.getVisibility() != View.INVISIBLE) {
			leftLayout.setVisibility(View.INVISIBLE);
		}
	}

	class ScrollTask extends AsyncTask<Integer, Integer, Integer> {

		@Override
		protected Integer doInBackground(Integer... speed) {
			int rightMargin = rightLayoutParams.rightMargin;
			// 根据传入的速度来滚动界面,当滚动到达左边界或右边界时,跳出循环。
			while (true) {
				rightMargin = rightMargin + speed[0];
				if (rightMargin < rightEdge) {
					rightMargin = rightEdge;
					break;
				}
				if (rightMargin > leftEdge) {
					rightMargin = leftEdge;
					break;
				}
				publishProgress(rightMargin);
				// 为了要有滚动效果产生,每次循环使线程睡眠5毫秒,这样肉眼才可以看到滚动动画。
				sleep(5);
			}
			if (speed[0] > 0) {
				isLeftLayoutVisible = false;
			} else {
				isLeftLayoutVisible = true;
			}
			isSliding = false;
			return rightMargin;
		}

		@Override
		protected void onProgressUpdate(Integer... rightMargin) {
			rightLayoutParams.rightMargin = rightMargin[0];
			rightLayout.setLayoutParams(rightLayoutParams);
			image3dViewParams = image3dView.getLayoutParams();
			image3dViewParams.width = -rightLayoutParams.rightMargin;
			image3dView.setLayoutParams(image3dViewParams);
			showImage3dView();
			unFocusBindView();
		}

		@Override
		protected void onPostExecute(Integer rightMargin) {
			rightLayoutParams.rightMargin = rightMargin;
			rightLayout.setLayoutParams(rightLayoutParams);
			image3dViewParams = image3dView.getLayoutParams();
			image3dViewParams.width = -rightLayoutParams.rightMargin;
			image3dView.setLayoutParams(image3dViewParams);
			if (isLeftLayoutVisible) {
				// 保证在滑动结束后左侧布局可见,3D视图不可见。
				image3dView.setVisibility(View.INVISIBLE);
				leftLayout.setVisibility(View.VISIBLE);
			}
		}
	}

	/**
	 * 使当前线程睡眠指定的毫秒数。
	 * 
	 * @param millis
	 *            指定当前线程睡眠多久,以毫秒为单位
	 */
	private void sleep(long millis) {
		try {
			Thread.sleep(millis);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

代码比较长,我仍是带着你们来理一下思路。首先在onLayout方法中,咱们分别初始化了左侧布局对象、右侧布局对象和Image3dView对象,这三个对象稍后都要配置到Activity布局里面的。在onLayout()方法的最后,调用了Image3dView的setSourceView()方法,并将左侧布局对象传了进去,说明咱们后面就要对它进行镜像复制。

 

当手指在界面上拖动来显示左侧布局的时候,就会进入到onTouch()方法中,这里会调用checkSlideState()方法来检查滑动的状态,以判断用户是想要显示左侧布局仍是隐藏左侧布局,而后根据手指滑动的距离对右侧布局进行偏移,就能够实现基本的滑动效果了。接下来是重点内容,这里会根据右侧布局的偏移量来改变Image3dView的宽度,当Image3dView大小发生改变时,固然会调用onDraw()方法来进行重绘,此时咱们编写的三维旋转逻辑就能够获得执行了,因而就会产生立体的推拉门式效果。注意,在整个的滑动过程当中,真正的左侧布局一直都是不可见的,咱们所看到的只是它的一张镜像图片。

当手指离开屏幕后,会根据当前的移动距离来决定是显示左侧布局仍是隐藏左侧布局,并会调用scrollToLeftLayout()方法或scrollToRightLayout()方法来完成后续的滚动操做。当整个滚动操做完成以后,才会将真正的左侧布局显示出来,再把镜像图片隐藏掉,这样用户就能够点击左侧布局上按钮之类的东西了。

接着咱们须要在Activity的布局文件当中去引用这个三维滑动菜单框架,打开或新建activity_main.xml做为程序的主布局文件,代码以下所示:

<com.example.slidinglayout3d.ThreeDSlidingLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/slidingLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <RelativeLayout
        android:id="@+id/menu"
        android:layout_width="270dip"
        android:layout_height="fill_parent"
        android:layout_alignParentLeft="true"
        android:background="#00ccff"
        android:visibility="invisible" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:orientation="vertical" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text="This is menu"
                android:textColor="#000000"
                android:textSize="28sp" />

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text="Test Button" />
        </LinearLayout>
    </RelativeLayout>

    <LinearLayout
        android:id="@+id/content"
        android:layout_width="320dip"
        android:layout_height="fill_parent"
        android:layout_alignParentRight="true"
        android:background="#e9e9e9"
        android:orientation="vertical"
        android:visibility="visible" >

        <Button
            android:id="@+id/menuButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Menu" />

        <ListView
            android:id="@+id/contentList"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:cacheColorHint="#00000000" >
        </ListView>
    </LinearLayout>

    <com.example.slidinglayout3d.Image3dView
        android:id="@+id/image_3d_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:visibility="invisible" />

</com.example.slidinglayout3d.ThreeDSlidingLayout>

能够看到,在最外层的ThreeDSlidingLayout布局里面,咱们放入了三个直接子布局,第一个RelativeLayout也就是左侧布局了,里面简单地放了一个TextView和一个按钮。第二个LinearLayout是右侧布局,里面放入了一个按钮和一个ListView,都是用于显示左侧布局而准备的。第三个是Image3dView,固然是用于在滑动过程当中显示左侧布局的镜像图片了。

 

最后,打开或新建MainActivity做为程序的主Activity,在里面加入以下代码:

public class MainActivity extends Activity {

	/**
	 * 侧滑布局对象,用于经过手指滑动将左侧的菜单布局进行显示或隐藏。
	 */
	private ThreeDSlidingLayout slidingLayout;

	/**
	 * menu按钮,点击按钮展现左侧布局,再点击一次隐藏左侧布局。
	 */
	private Button menuButton;

	/**
	 * 放在content布局中的ListView。
	 */
	private ListView contentListView;

	/**
	 * 做用于contentListView的适配器。
	 */
	private ArrayAdapter<String> contentListAdapter;

	/**
	 * 用于填充contentListAdapter的数据源。
	 */
	private String[] contentItems = { "Content Item 1", "Content Item 2", "Content Item 3",
			"Content Item 4", "Content Item 5", "Content Item 6", "Content Item 7",
			"Content Item 8", "Content Item 9", "Content Item 10", "Content Item 11",
			"Content Item 12", "Content Item 13", "Content Item 14", "Content Item 15",
			"Content Item 16" };

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		slidingLayout = (ThreeDSlidingLayout) findViewById(R.id.slidingLayout);
		menuButton = (Button) findViewById(R.id.menuButton);
		contentListView = (ListView) findViewById(R.id.contentList);
		contentListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
				contentItems);
		contentListView.setAdapter(contentListAdapter);
		// 将监听滑动事件绑定在contentListView上
		slidingLayout.setScrollEvent(contentListView);
		menuButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (slidingLayout.isLeftLayoutVisible()) {
					slidingLayout.scrollToRightLayout();
				} else {
					slidingLayout.scrollToLeftLayout();
				}
			}
		});
		contentListView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				String text = contentItems[position];
				Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
			}
		});
	}
}

这些代码应该都很是简单和眼熟了吧,和之前滑动菜单中的代码彻底同样,调用ThreeDSlidingLayout的setScrollEvent方法,将ListView做为绑定布局传入,这样就能够经过拖动ListView来显示或隐藏左侧布局。而且在按钮的点击事件里也加入了显示和隐藏左侧布局的逻辑。

 

好了,这样全部的编码工做就已经完成了,让咱们来运行一下吧,效果以下图所示:

                                                 

怎么样?效果很是炫丽吧!其实只要对Camera进行巧妙地运用,还能够编写出不少很是精彩的特效,就看你敢不敢去发挥你的想象力了。

好了,今天的讲解到此结束,有疑问的朋友请在下面留言。

源码下载,请点击这里

相关文章
相关标签/搜索