android抽屉式侧滑
来源:互联网 发布:网络金融培训 编辑:程序博客网 时间:2024/06/06 10:06
侧滑效果展示
原理
要实现这种侧滑效果,首先自定义一个滑动Layout继承自RelativeLayout,里面有两个View分别是用来存放内容和菜单布局的,然后记录手指一动的距离更改内容View的leftMargin(注意:只有leftMargin的值是负数才能够向左偏移,如果是正数的话那么会向右压缩),在内容View移动的同时,调用菜单的setTranslateX()方法就可以达到菜单移动了
代码
首先上代码:
<cn.karent.slide.UI.SlideLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <!--侧滑菜单--> <RelativeLayout android:id="@+id/slide_menu" android:layout_width="300dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:layout_marginRight="-150dp" android:background="@android:color/holo_purple" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="侧滑菜单"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="测试按钮"/> </RelativeLayout> <!--内容View--> <RelativeLayout android:id="@+id/slide_content" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:background="@android:color/holo_red_dark"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是内容"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button" android:layout_centerInParent="true"/> </RelativeLayout></cn.karent.slide.UI.SlideLayout>
注意,我直接让菜单项往右偏移一半,这样就不会有完全滚动的效果,而是菜单的偏移比内容的偏移更慢一点,下面上自定义Layout的代码:
package cn.karent.slide.UI;import android.content.Context;import android.os.AsyncTask;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.RelativeLayout;import cn.karent.slide.R;import cn.karent.slide.util.ScreenUtil;/** * Created by wan on 2016/12/6. * 侧滑菜单,内容会偏移 */public class SlideLayout extends RelativeLayout { private Context mContext; private static final int MOTION_VELOCITY = 300; /* 是否是第一次调用onLayout方法 */ private boolean mLoadOnece = false; /* 左边内容的布局参数 */ private MarginLayoutParams mLeftParams; /* 右边菜单的布局参数 */ private MarginLayoutParams mMenuParams; /* 左边的内容View */ private View mLeftView; /* 侧滑菜单View */ private View mMenuView; private float mOldX; private float mOldY; /* * 屏幕的宽度 */ private int mScreenWidth; /** * 控件能够移动到的左边界,内容View能向左偏移的最大边界 */ private int mLeftEdge ; public SlideLayout(Context context) { super(context); mContext = context; } public SlideLayout(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; } /** * 布局 */ public void onLayout(boolean change, int l, int t, int r, int b) { super.onLayout(change, l, t, r, b); if( change && !mLoadOnece) { mLeftEdge = ScreenUtil.dp2px(300); mLeftView = findViewById(R.id.slide_content); mMenuView = findViewById(R.id.slide_menu); mLeftParams = (MarginLayoutParams) mLeftView.getLayoutParams(); mMenuParams = (MarginLayoutParams)mMenuView.getLayoutParams(); DisplayMetrics dm = getResources().getDisplayMetrics(); mScreenWidth = dm.widthPixels; mLoadOnece = true; } } /** * 事件拦截 * @param e * @return * true 表示拦截子类的Touch事件 * false 表示 */ public boolean onInterceptTouchEvent(MotionEvent e) { int action = e.getAction(); switch( action ) { case MotionEvent.ACTION_DOWN: return false; case MotionEvent.ACTION_MOVE: mOldX = e.getRawX(); break; case MotionEvent.ACTION_UP: break; } return true; } public boolean onTouchEvent(MotionEvent e) { int action = e.getAction(); switch( action ) { case MotionEvent.ACTION_DOWN: //e.getX()得到的是相对当前容器的坐标 mOldX = e.getRawX(); mOldY = e.getRawY(); break; case MotionEvent.ACTION_MOVE: float x = e.getRawX(); float y = e.getRawY(); if( y - mOldY > 20 || y - mOldY < -20) { return false; } //获取移动了多少个px int moveX = (int)(x - mOldX); mOldX = x; mOldY = y; //侧滑 modifyLeftMargin(mLeftParams.leftMargin + moveX); break; case MotionEvent.ACTION_UP: //当手指拿起时,计算是向哪边滑动 int l = mLeftParams.leftMargin > (-mLeftEdge / 2) ? 0 : -mLeftEdge; new SmoothScrollTack().execute(l, mLeftParams.leftMargin); break; } return true; } /** * 修改View的边距来达到移动的效果 * @param leftMargin */ private void modifyLeftMargin(int leftMargin) { //如果左边距大于0代表将要向右变压缩,应该禁止 if( leftMargin > 0 ) { mLeftParams.leftMargin = 0; mMenuView.setTranslationX(0); //控制左边界滑动 } else if( leftMargin < -mLeftEdge) { mLeftParams.leftMargin = -mLeftEdge; mMenuView.setTranslationX(-mLeftEdge / 2); } else { mLeftParams.leftMargin = leftMargin; mMenuView.setTranslationX(leftMargin / 2); } mLeftParams.width = mScreenWidth; mLeftView.setLayoutParams(mLeftParams); } /** * 当侧滑停止的时候来处理接下来的滑动 */ private class SmoothScrollTack extends AsyncTask<Integer, Integer, Integer> { @Override protected void onProgressUpdate(Integer... values) { int leftMargin = values[0]; modifyLeftMargin(leftMargin); } /** * 计算下一个leftMargin值 * @param params * @return */ @Override protected Integer doInBackground(Integer... params) { int targetLeftMargin = params[0]; int currentLeftMargin = params[1]; int leftMargin = currentLeftMargin; //计算增加的步长 int step = targetLeftMargin == 0 ? 10 : -10; while(true) { leftMargin += step; //判断是否滑动完成 if( leftMargin < -mLeftEdge ) { leftMargin = -mLeftEdge; break; } if( leftMargin > 0 ) { leftMargin = 0; break; } publishProgress(leftMargin); try { Thread.sleep(5); } catch( InterruptedException e) { e.printStackTrace(); } } publishProgress(leftMargin); return leftMargin; } }}
ScreenUtil:
package cn.karent.slide.util;import android.util.DisplayMetrics;import android.util.Log;/** * Created by wan on 2016/12/22. * */public class ScreenUtil { /** * 获取屏幕的密度 * @return */ public static float getDensity() { DisplayMetrics dm = MyApplication.getContext().getResources().getDisplayMetrics(); float density = dm.density; Log.d("density", density + ""); return density; } public static DisplayMetrics getDislayMetrics() { return MyApplication.getContext().getResources().getDisplayMetrics(); } public static int px2dp(float p) { float density = getDensity(); return (int)(p / density + 0.5f); } public static int dp2px(float dip) { return (int)(dip * getDensity() + 0.5f); }}
获取全局的Context:
package cn.karent.slide.util;import android.app.Application;import android.content.Context;/** * Created by wan on 2016/12/22. * 获取全局Context对象 */public class MyApplication extends Application { private static Context mContext; @Override public void onCreate() { mContext = getApplicationContext(); super.onCreate(); } public static Context getContext() { return mContext; }}
androidManifest.xml:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.karent.slide"> <application android:name=".util.MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@android:style/Theme.NoTitleBar"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
只要在下面使用android:name=”.util.MyApplication”那么我们自己定义的Application就会覆盖系统默认的Application了
0 0
- android 抽屉式侧滑菜单
- android抽屉式侧滑
- android抽屉式侧滑
- Android 抽屉
- Android 抽屉
- Android 抽屉
- Android使用DrawerLayout实现抽屉式侧滑菜单
- 实现Android 抽屉效果
- android 抽屉功能初试
- Android去掉抽屉
- android 抽屉 效果
- android抽屉实现
- android下拉抽屉
- android 抽屉效果
- android抽屉实现
- android下拉抽屉
- Android抽屉实现
- android抽屉效果
- 有关java中的单例模式
- Ambari的架构与设计思想
- maven常用命令集
- Lua(二):变量
- unity 实现Game窗口的Stats
- android抽屉式侧滑
- 反思随笔一:我执、相轻、推己及人
- 解决ListView和ScrollView的冲突
- Error:SSL peer shut down incorrectly的解决方案
- fullPage.js插件的应用
- 用互联网改造装修施工环节,他提出HaaS模式
- 现代通信网复习资料(第二章:传送网)
- MySql_x64免安装版在win10下的详细配置过程
- 在Ubuntu中的root用户与普通用户之间的自由切换