侧滑菜单(一):带缩放动画
2016-12-06 13:31
85 查看
实现效果
实现代码
新建项目A新建自定义控件Draglayout继承FrameLayout
/** * Created by Administrator on 2016/9/30. * 创建自定义控件 */ public class Draglayout extends FrameLayout { public Draglayout(Context context) { this(context,null); } public Draglayout(Context context, AttributeSet attrs) { this(context, attrs,-1); } public Draglayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //初始化控件 init(); } /** * 初始化控件 */ private void init() { } }
对activity_main.xml进行修改
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <com.one1go.draglayout.Draglayout android:background="@drawable/bg" android:layout_width="match_parent" android:layout_height="match_parent" > </com.one1go.draglayout.Draglayout>
</RelativeLayout>
新建一个menu.xml布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#6f599c"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/head"/> </LinearLayout>
新建一个main.xml布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#3c3645"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#18b4ed"> <ImageView android:layout_width="50dp" android:layout_height="50dp" android:padding="10dp" android:src="@drawable/head"/> </LinearLayout> </LinearLayout>
对activity_main.xml添加以上两个布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ... > <com.itheima.draglayout.Draglayout ... > <!--在上面的在下面--> <include layout="@layout/menu"/> <include layout="@layout/main"/> </com.itheima.draglayout.Draglayout> </RelativeLayout>
在清单文件中去除标题栏:由于MainActivity中继承的是AppCompatActivity,所以它没有title,只有actionbar
application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/Theme.AppCompat.NoActionBar"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
实现界面的左右上下滑动:在DrawLayout中进行修改
/** * Created by Administrator on 2016/x/xx. * 创建自定义控件 */ public class Draglayout extends FrameLayout { private ViewDragHelper helper; ... public Draglayout(Context context, AttributeSet attrs, int defStyleAttr) { ... } /** * 初始化控件 * Google I/O ViewDragHelper封装了触摸,滑动等操作,可以轻松的控件触摸滑动 */ private void init() { //创建ViewDragHelper //参数1 : 为谁处理触摸操作 helper = ViewDragHelper.create(this,callback); } /** * 新建一个callback */ private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() { /** * 尝试捕获视图 * @param child 被捕获的子视图 * @param pointerId 多指触摸,某个手指的id * @return 如果返回true,表示所有的孩子都可以被触摸,返回true表示可以移动 */ @Override public boolean tryCaptureView(View child, int pointerId) { return true; } /** * 处理水平移动 * @param child 被触摸的孩子 * @param left oldLeft + dx = newLeft * @param dx 系统每隔一段时间检测手指移动的距离 * @return */ @Override public int clampViewPositionHorizontal(View child, int left, int dx) { return left; } /** * 处理垂直移动 * @param child * @param top * @param dy * @return */ // @Override // public int clampViewPositionVertical(View child, int top, int dy) { // return top; // } }; /** * 让helper接手触摸事件的处理 * @param event * @return 必须返回true才能处理 */ @Override public boolean onTouchEvent(MotionEvent event) { helper.processTouchEvent(event); return true; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return helper.shouldInterceptTouchEvent(ev); } }
处理滑动的最大范围:DrawLayout -- 1.在当前控件及其子控件全部测量完的时候,调用此方法。
/*自定义控件的4个基本流程 * 1,加载 * 2,测量 * 3,布局 * 4,绘制 * */ /** * 在当前控件及其子控件全部加载完毕时,调用此方法 */ @Override protected void onFinishInflate() { super.onFinishInflate(); //对当前加入的控件的子视图进行限制 //代码健壮性处理 //孩子的数目不能超过2个 if(getChildCount() != 2) { throw new RuntimeException("Are you kedding me?there only hava two childs"); } //必须包含ViewGroup if(!(getChildAt(0) instanceof ViewGroup) || !(getChildAt(1) instanceof ViewGroup)) { throw new RuntimeException("hehe,you never can use it if it isn't ViewGroup"); } menu = getChildAt(0); main = getChildAt(1); }
处理滑动的最大范围:DrawLayout -- 2.获取在onMeasure方法执行后执行,可以获得测量结果
/** * 在onMeasure()方法执行后执行,可以获得测量结果 * @param w * @param h * @param oldw * @param oldh */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); int width = main.getMeasuredWidth(); //获取最大拖动范围 maxDragRange = (int) (width * 0.6f); }
处理滑动的最大范围:DrawLayout -- 处理移动的最大范围
/** * 新建一个callback */ private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() { ... ... @Override public int clampViewPositionHorizontal(View child, int left, int dx) { //处理滑动的最大范围 if(child == main) { if(left < 0) { left = 0; } else if(left > maxDragRange) { left = maxDragRange; } } return left; } ... };
menu的滑动处理:DragLayout
/** * Created by Administrator on 2016/9/30. * 创建自定义控件 */ public class Draglayout extends FrameLayout { private ViewDragHelper helper; private View menu; private View main; private int maxDragRange; ... ... private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() { ... /** * 位置已经便改变的回掉方法 * @param changedView 被改变位置的孩子视图 * @param left 已经移动的left * @param top * @param dx 手指移动的dx * @param dy */ @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { super.onViewPositionChanged(changedView, left, top, dx, dy); //判断当前的视图是menu的时候 //1.禁止menu滑动 //2.将meun移动的距离传给main if(changedView == menu) { //滑动的底层都是调用这个代码 menu.offsetLeftAndRight(-dx); //处理滑动menu造成menu移动的边界范围 int oldLeft = main.getLeft(); int newLeft = oldLeft + dx; //限制newLeft的范围 if(newLeft > maxDragRange) { newLeft = maxDragRange; } else if(newLeft < 0) { newLeft = 0; } int newDx = newLeft - oldLeft; main.offsetLeftAndRight(newDx); } } ... }; ... }
抬起手的操作
public class Draglayout extends FrameLayout { ... private ViewDragHelper.Callback callback = new ViewDragHelpe acea r.Callback() { ... /** * 释放视图的回调 * @param releasedChild 被释放的孩子视图 * @param xvel 释放瞬间x方向的速度 * @param yvel */ @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { super.onViewReleased(releasedChild, xvel, yvel); //判断当释放视图的时候,main的左边距与最大范围的一半进行比较 if(main.getLeft() < maxDragRange / 2) { close(); } else { open(); } } ... }; /** * 开启侧滑菜单 */ private void open() { //设置目标点 //平滑的开始滚动视图 if(helper.smoothSlideViewTo(main,maxDragRange,0)) { //绘制界面 invalidate(); } } /** * 计算滚动过程中的某帧 */ @Override public void computeScroll() { super.computeScroll(); if(helper.continueSettling(true)) { invalidate(); } } /**' * 关闭侧滑菜单 */ private void close() { if(helper.smoothSlideViewTo(main,0,0)) { //绘制界面 invalidate(); } } ... }
让main缩放
... public class Draglayout extends FrameLayout { ... /** * 新建一个callback */ private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() { ... /** * 位置已经便改变的会掉方法 * @param changedView 被改变位置的孩子视图 * @param left 已经移动的left * @param top * @param dx 手指移动的dx * @param dy */ @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { ... if(changedView == menu) { ... } //计算移动的距离占总距离的百分比 float percent = main.getLeft() * 1.0f / maxDragRange; executeAnimation(percent); } ... }; /** * 执行移动时main的缩放动画 * @param percent */ private void executeAnimation(float percent) { // Log.i("test", "executeAnimation: percent=" + percent); //1.让main越来越小 : 1.0f - 0.75f //估值器.插值器 float evaluateResult = evaluate(percent,1.0f,0.75f); //2.让main缩放 main.setScaleX(evaluateResult); main.setScaleY(evaluateResult); } private float evaluate(float fraction, float startValue, float endValue) { return startValue + fraction * (endValue - startValue); } ... }
相关文章推荐
- Android中侧滑菜单效果实现(主界面和菜单界面实现平移、缩放、滚动动画)
- ios每日源码,侧滑菜单精美动画曲线表弹性碰撞效果视频播放器渐变背景动画效果源码
- Android 侧滑缩放菜单(HorizontalScrollView简单实现)
- iOS 模仿QQ侧滑菜单和UITabBar拖动动画
- jquery动画实现菜单侧滑
- 非常棒的、多达288种动画效果定制的侧滑菜单库。集成也是非常简单。
- 非常棒的、多达288种动画效果定制的侧滑菜单库。集成也是非常简单。
- android实战之 视觉差侧滑菜单简单版+Activity视觉差动画
- android 动画实现侧滑菜单效果
- 使用Design包实现QQ动画侧滑效果和滑动菜单导航
- 仿Android 5.0 侧滑菜单按钮动画 以及侧滑菜单联动
- Android侧滑菜单 仿QQ 百度贴吧 侧滑菜单 自带动画
- ios每日源码,侧滑菜单精美动画曲线表弹性碰撞效果视频播放器渐变背景动画效果源码
- QQ菜单侧滑4种动画效果
- 侧滑菜单 ——仿QQ实现动画效果
- 自定义View:侧滑菜单动画实现
- Android程序开发之使用Design包实现QQ动画侧滑效果和滑动菜单导航
- [Android]类QQ,百度贴吧侧滑缩放菜单问题解析
- Android 自定义SlidingMenu 实现QQ5.0侧滑菜单动画效果
- Android酷炫动画、有侧滑菜单,刷新动画和自定义字体