直接上代码吧:

MainActivity:

package com.example.test;import java.util.ArrayList;import java.util.List;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.view.Window;import android.widget.ArrayAdapter;import android.widget.ListView;public class MainActivity extends ActionBarActivity {private SlidingLayout slidingLayout = null;private ListView leftList = null;private ListView rightList = null;private List leftData = null;private List rightData = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_main);initViews();initData();}/** * 初始化控件 */protected void initViews() {slidingLayout = (SlidingLayout) findViewById(R.id.sliding_layout);leftList = (ListView) findViewById(R.id.left_list);rightList = (ListView) findViewById(R.id.right_list);slidingLayout.setScrollEvent(rightList, findViewById(R.id.vertical_right_shadow));slidingLayout.setLeftView(leftList, findViewById(R.id.left_top_view));}/** * 初始化数据 */protected void initData() {leftData = new ArrayList();leftData.add("left data 1");leftData.add("left data 2");leftData.add("left data 3");leftData.add("left data 4");rightData = new ArrayList();rightData.add("right data 1");rightData.add("right data 2");rightData.add("right data 3");rightData.add("right data 4");ArrayAdapter leftAdapter = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, leftData);ArrayAdapter rightAdapter = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, rightData);leftList.setAdapter(leftAdapter);rightList.setAdapter(rightAdapter);}}
侧滑的slidingLayout是集成于LinearLayout,目前只允许有两个child,然后在slidingLayout分别对两个child(左侧布局和右侧布局)进行移动,以及阴影等效果的添加

SlidingLayout:

package com.example.test;import android.content.Context;import android.graphics.Color;import android.os.AsyncTask;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.VelocityTracker;import android.view.View;import android.view.View.OnTouchListener;import android.view.ViewConfiguration;import android.widget.LinearLayout;public class SlidingLayout extends LinearLayout implements OnTouchListener {/** * 滚动显示和隐藏左侧布局时,手指滑动需要达到的速度 */public static final int SNAP_VELOCITY = 200;/** * 屏幕宽度值�? */private int screenWidth;/** * 在被判定为滚动之前用户手指可以移动的�?��值�? */private int touchSlop;/** * 记录手指按下时的横坐标�? */private float xDown;/** * 记录手指按下时的纵坐标�? */private float yDown;/** * 记录手指移动时的横坐标�? */private float xMove;/** * 记录手指移动时的纵坐标�? */private float yMove;/** * 记录手机抬起时的横坐标�? */private float xUp;/** * 左侧布局当前是显示还是隐藏�?只有完全显示或隐藏时才会更改此�?,滑动过程中此�?无效�? */private boolean isLeftLayoutVisible;/** * 是否正在滑动�? */private boolean isSliding;/** * 左侧布局对象�? */private View leftLayout;/** * 右侧布局对象�? */private View rightLayout;/** * 用于监听侧滑事件的View�? */private View mBindView;/** * 左侧布局的参数,通过此参数来重新确定左侧布局的宽度,以及更改leftMargin的�?�? */private MarginLayoutParams leftLayoutParams;/** * 右侧布局的参数,通过此参数来重新确定右侧布局的宽度�? */private MarginLayoutParams rightLayoutParams;private MarginLayoutParams shadowLayoutParams;/** * 用于计算手指滑动的�?度�? */private VelocityTracker mVelocityTracker;private int fixWidth;private int contentWidth;private boolean isOpen = false;private View fixView;// 固定的view;private View topView;private View shadowView;private boolean flag = false;///** * 重写SlidingLayout的构造函数,其中获取了屏幕的宽度�? *  * @param context * @param attrs */public SlidingLayout(Context context, AttributeSet attrs) {super(context, attrs);fixWidth = SystemUtil.dipToPx(context,52);screenWidth = SystemUtil.getScreenWidth(context);touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();contentWidth = screenWidth - fixWidth;}/** * 绑定监听侧滑事件的View,即在绑定的View进行滑动才可以显示和隐藏左侧布局 *  * @param bindView */public void setScrollEvent(View bindView ,View shadowView) {mBindView = bindView;this.shadowView = shadowView;mBindView.setOnTouchListener(this);}/** * 设置left view * @param view * @param topView */public void setLeftView(View view, View topView) {fixView = view;fixView.setOnTouchListener(this);//设置透明度this.topView = topView;if (topView.getBackground() == null) {topView.setBackgroundColor(Color.WHITE);;topView.getBackground().setAlpha(0);}}/** * 将屏幕滚动到左侧布局界面,滚动速度设定为30. */public void scrollToLeftLayout() {new ScrollTask().execute(30);}/** * 将屏幕滚动到右侧布局界面,滚动速度设定为-30. */public void scrollToRightLayout() {new ScrollTask().execute(-30);}/** * 左侧布局是否显示出来 */public boolean isLeftLayoutVisible() {return isLeftLayoutVisible;}/** * 在onLayout中重新设定左侧布�?��右侧布局的参数�? */@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);if (changed) {// 获取左侧布局对象leftLayout = getChildAt(0);leftLayoutParams = (MarginLayoutParams) leftLayout.getLayoutParams();leftLayoutParams.width = contentWidth;leftLayout.setLayoutParams(leftLayoutParams);// 获取右侧布局对象rightLayout = getChildAt(1);rightLayoutParams = (MarginLayoutParams) rightLayout.getLayoutParams();rightLayoutParams.width = contentWidth;rightLayout.setLayoutParams(rightLayoutParams);shadowLayoutParams = (MarginLayoutParams) shadowView.getLayoutParams();}}@Overridepublic boolean onTouch(View v, MotionEvent event) {if (v.getId() == R.id.left_list) {if (isOpen) {if(event.getRawX() >= fixWidth && !flag) {xDown = event.getRawX();yDown = event.getRawY();flag = true;} else if(event.getRawX() < fixWidth) {flag = false;return true;}} else {return false;}}createVelocityTracker(event);switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 手指按下时,记录按下时的横坐�?xDown = event.getRawX();yDown = event.getRawY();break;case MotionEvent.ACTION_MOVE:// 手指移动时,对比按下时的横坐标,计算出移动的距离,来调整右侧布局的leftMargin值,从�?显示和隐藏左侧布�?xMove = event.getRawX();yMove = event.getRawY();int moveDistanceX = (int) (xMove - xDown);float alpha = 0;int distanceY = (int) (yMove - yDown);if (moveDistanceX <= 0 && (-moveDistanceX > touchSlop || isSliding)) {if (!isOpen) {isSliding = true;rightLayoutParams.leftMargin = moveDistanceX;if (rightLayoutParams.leftMargin < -(contentWidth - fixWidth)) {rightLayoutParams.leftMargin = -(contentWidth - fixWidth);}} else {rightLayoutParams.leftMargin = -(contentWidth - fixWidth);}rightLayout.setLayoutParams(rightLayoutParams);shadowLayoutParams.rightMargin = -rightLayoutParams.leftMargin;shadowView.setLayoutParams(shadowLayoutParams);}if (moveDistanceX >= 0 && (moveDistanceX > touchSlop || isSliding))  {if ((isSliding || Math.abs(distanceY) <= touchSlop) && isOpen) {isSliding = true;rightLayoutParams.leftMargin = moveDistanceX- (contentWidth - fixWidth);if (rightLayoutParams.leftMargin > 0) {rightLayoutParams.leftMargin = 0;}} else if((isSliding || Math.abs(distanceY) <= touchSlop)){rightLayoutParams.leftMargin = 0;}rightLayout.setLayoutParams(rightLayoutParams);shadowLayoutParams.rightMargin = -rightLayoutParams.leftMargin;shadowView.setLayoutParams(shadowLayoutParams);}alpha = Math.abs(rightLayoutParams.leftMargin)/ (float) (1.5 * (contentWidth - fixWidth));if (topView.getBackground() != null) {topView.getBackground().setAlpha((int) (alpha * 255));topView.invalidate();}break;case MotionEvent.ACTION_UP:xUp = event.getRawX();int upDistanceX = (int) (xUp - xDown);if (isSliding) {// 手指抬起时,进行判断当前手势的意图,从�?决定是滚动到左侧布局,还是滚动到右侧布局if (wantToShowLeftLayout()) {if (shouldScrollToLeftLayout()) {scrollToLeftLayout();} else {scrollToRightLayout();}} else if (wantToShowRightLayout()) {if (shouldScrollToRightLayout()) {scrollToRightLayout();} else {scrollToLeftLayout();}}} else if (Math.abs(upDistanceX) < touchSlop && !isOpen) {//点击效果scrollToRightLayout();}recycleVelocityTracker();break;}if(v.getId() == R.id.left_list) {if(isOpen) {return true;}}if (v.isEnabled()) {if (isSliding) {unFocusBindView();unFocusLeftView();return true;}if (isOpen) {return false;}}return true;}/** * 判断当前手势的意图是不是想显示右侧布�??如果手指移动的距离是负数,且当前左侧布局是可见的,则认为当前手势是想要显示右侧布�?? *  * @return 当前手势想显示右侧布�?��回true,否则返回false�? */private boolean wantToShowRightLayout() {return xUp - xDown < 0 && !isOpen;}/** * 判断当前手势的意图是不是想显示左侧布�??如果手指移动的距离是正数,且当前左侧布局是不可见的,则认为当前手势是想要显示左侧布局�? *  * @return 当前手势想显示左侧布�?��回true,否则返回false�? */private boolean wantToShowLeftLayout() {return xUp - xDown > 0 && isOpen;}/** * 判断是否应该滚动将左侧布�?��示出来�?如果手指移动距离大于屏幕�?/2,或者手指移动�?度大于SNAP_VELOCITY�? * 就认为应该滚动将左侧布局展示出来�? *  * @return 如果应该滚动将左侧布�?��示出来返回true,否则返回false�? */private boolean shouldScrollToLeftLayout() {return xUp - xDown > (contentWidth - fixWidth) / 2|| getScrollVelocity() > SNAP_VELOCITY;}/** * 判断是否应该滚动将右侧布�?��示出来�?如果手指移动距离加上leftLayoutPadding大于屏幕�?/2�? * 或�?手指移动速度大于SNAP_VELOCITY�?就认为应该滚动将右侧布局展示出来�? *  * @return 如果应该滚动将右侧布�?��示出来返回true,否则返回false�? */private boolean shouldScrollToRightLayout() {return xDown - xUp > (contentWidth - fixWidth) / 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);}}private void unFocusLeftView() {if (fixView != null) {fixView.setPressed(false);fixView.setFocusable(false);fixView.setFocusableInTouchMode(false);}}class ScrollTask extends AsyncTask {@Overrideprotected Integer doInBackground(Integer... speed) {int leftMargin = rightLayoutParams.leftMargin;// 根据传入的�?度来滚动界面,当滚动到达左边界或右边界时,跳出循环�?while (true) {leftMargin = leftMargin + speed[0];if (leftMargin < -(contentWidth - fixWidth)) {leftMargin = -(contentWidth - fixWidth);publishProgress(leftMargin);break;}if (leftMargin > 0) {leftMargin = 0;publishProgress(leftMargin);break;}publishProgress(leftMargin);// 为了要有滚动效果产生,每次循环使线程睡眠20毫秒,这样肉眼才能够看到滚动动画�?sleep(15);}if (speed[0] > 0) {isLeftLayoutVisible = false;isOpen = false;} else {isLeftLayoutVisible = true;isOpen = true;}isSliding = false;return leftMargin;}@Overrideprotected void onProgressUpdate(Integer... leftMargin) {rightLayoutParams.leftMargin = leftMargin[0];rightLayout.setLayoutParams(rightLayoutParams);shadowLayoutParams.rightMargin = Math.abs(rightLayoutParams.leftMargin);shadowView.setLayoutParams(shadowLayoutParams);float alpha = Math.abs(rightLayoutParams.leftMargin)/ (float) (1.5 * (contentWidth - fixWidth));if (topView.getBackground() != null) {topView.getBackground().setAlpha((int) (alpha * 255));topView.invalidate();}unFocusBindView();}@Overrideprotected void onPostExecute(Integer leftMargin) {rightLayoutParams.leftMargin = leftMargin;rightLayout.setLayoutParams(rightLayoutParams);shadowLayoutParams.rightMargin = Math.abs(rightLayoutParams.leftMargin);shadowView.setLayoutParams(shadowLayoutParams);}}/** * 重新再次设置布局 */public void resetLayoutParams() {//�?��在重新设置下,在contactDetailActivity中添加笔记后才能自动刷新,不知道为什么???rightLayout.setLayoutParams(rightLayoutParams);shadowLayoutParams.rightMargin = -rightLayoutParams.leftMargin;shadowView.setLayoutParams(shadowLayoutParams);}/** * 使当前线程睡眠指定的毫秒数�? *  * @param millis *            指定当前线程睡眠多久,以毫秒为单�? */private void sleep(long millis) {try {Thread.sleep(millis);} catch (InterruptedException e) {e.printStackTrace();}}}
这个其实是借鉴大神做的修改,详细地址:http://blog.csdn.net/guolin_blog/article/details/8744400

最后的activity_main.xml文件

                                                                                                                

实现的效果:动画没有安装录制软件,看下图吧

分享一个Android左右侧滑的效果实现 sliding layout_第1张图片   分享一个Android左右侧滑的效果实现 sliding layout_第2张图片

点击下载

更多相关文章

  1. Android小程序开发--跟随手指动的绿色小球
  2. RecyclerView竖直和水平的瀑布流布局
  3. Android适配底部虚拟键盘遮挡布局的解决方案
  4. Android参数设置父布局集体宽高
  5. Android手势ImageView三部曲 第三部
  6. Android 四大组件,五大存储,六大布局
  7. android 布局随笔----用户登录界面

随机推荐

  1. linux--输入子系统
  2. linux usb枚举过程分析之守护进程及其唤
  3. 进程间通讯概述
  4. 字符串处理函数strcat和strtok
  5. (转)linux字体安装
  6. eclipse maven 插件安装 for mac,linux,win
  7. Linux系统只能连上内网不能够连上外网。U
  8. linux shell基础语法
  9. Linux系统的文件传输工具RZSZ
  10. 使用wdcp完成网站搭建