android侧滑高大上效果
来源:互联网 发布:淘宝朵色是真的吗 编辑:程序博客网 时间:2024/05/22 08:23
一、概述
侧滑的实现效果有很多,有谷歌官方的Drawerlayout实现侧滑,不过今天要介绍的是用HorizontalScrollview实现侧滑效果,其实HorizontalScrollview实现侧滑非常简单,我们只要自定义一个View然后继承HorizontalScrollview就可以的,我先说一下思路,首先我们要在HorizontalScrollview中放入两个布局一个是要拉出来的布局,一个是我们主界面的布局。 第二我们先要通过屏幕的宽度和我们设置的与屏幕右边的距离来计算出来滑出菜单的距离。第三我们在这些都计算出来之后我们首先需要设置一下默认滑动的距离,这个距离也就是菜单的宽度。然后我们还需要通过监听滑动的距离来判断这个菜单是否需要滑动过去,如果滑动距离超过了菜单宽度的一半那么我们就需要滑动过去,如果没超过一半就退回。好了下面我们一步步实现。
二、实现
1、首先看一下布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:andya="http://schemas.android.com/apk/res/com.transfar.andya.sildelayoutdemo" android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/bg1"> <com.transfar.andya.sildelayoutdemo.ui.SlidingLayout android:layout_width="wrap_content" android:layout_height="fill_parent" android:id="@+id/sll_slide_menu" andya:slidepadding="200dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="fill_parent" android:orientation="horizontal" > <include layout="@layout/layout_menu" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/qq" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="toggleMenu" android:text="切换菜单" /> </LinearLayout> </LinearLayout> </com.transfar.andya.sildelayoutdemo.ui.SlidingLayout></LinearLayout>
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="1" android:gravity="center" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="2" android:gravity="center" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="3" android:gravity="center" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="4" android:gravity="center" /> </LinearLayout></RelativeLayout>
此段代码应该很好理解 我们重写了一个view,Sildinglayout有一个属性是slidepadding,这个值的含义就是主界面的左边距和屏幕的右边的距离。这个值是可以设置的,所以我们可以动态设置侧滑出来的距离。关于此值的用法后面我会降到。我们还需要在value中新增一个attr属性,然后在去设置一下slidepadding看一下attr文件的代码。
<?xml version="1.0" encoding="utf-8"?><resources> <attr name="slidepadding" format="dimension"/> <declare-styleable name="SlidingLayout"> <attr name="slidepadding"/> </declare-styleable></resources>
第二步的实现,第二步我们首先要获取我们设置的值,然后通过这个值去计算侧滑的宽度,下面代码:
mScreenWidth = ScreenUtils.getScreenWidth(context); //这个是写的一个工具类获取屏幕的宽度 TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SlidingLayout, defStyle, 0); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.SlidingLayout_slidepadding: // 默认50 mMenuRightPadding = a.getDimensionPixelSize(attr, //这个字段就是我们设置的字段 (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 50f, getResources().getDisplayMetrics()));// 默认为10DP break; } } a.recycle();
此处的代码应该很好理解的,但是细心的人应该发现这个地方的扩展性是非常好的,我们还可以在attr中定义一些新的属性,然后我们可以在上面的代码中去获取属性的值,这也就是这个地方为什么要去写一个switch的原因。那么我们第二步的工作基本上也算完成了侧滑的宽度就用屏幕的宽度减去mMenuRigthPadding就可以了。
其实第三步相对简单了很多,相关的值我们都得到了下面我们只需在onMeasure中去设置一下我们计算得到的值就可以的了下面看代码:
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { /** * 显示的设置一个宽度 */ if (!once) { LinearLayout wrapper = (LinearLayout) getChildAt(0); //此句话是获取SlideLayout的第一个子孩子 mMenu = (ViewGroup) wrapper.getChildAt(0); //这个是获取菜单布局 mContent = (ViewGroup) wrapper.getChildAt(1); //这个是获取主布局 mMenuWidth = mScreenWidth - mMenuRightPadding; mHalfMenuWidth = mMenuWidth / 2; mMenu.getLayoutParams().width = mMenuWidth; mContent.getLayoutParams().width = mScreenWidth; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); }
此段代码我就不做过多的解释了,下面我们就需要设置一下位置了,设置位置也是非常简单的,就一句话就可以实现的看代码:
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); if (changed) { // 将菜单隐藏 this.scrollTo(mMenuWidth, 0); once = true; //此字段是判断我们的SlideLayout有没有生成,如果生成了那么就不要在去画了 } }
最后我们要去监听一下用户是否滑动了侧滑宽度的一半我们重写 onTouchEvent监听一下滑动的距离就可以了,下面看代码:
@Override public boolean onTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { // Up时,进行判断,如果显示区域大于菜单宽度一半则完全显示,否则隐藏 case MotionEvent.ACTION_UP: int scrollX = getScrollX(); if (scrollX > mHalfMenuWidth) { this.smoothScrollTo(mMenuWidth, 0); isOpen = false; } else { this.smoothScrollTo(0, 0); isOpen = true; } return true; } return super.onTouchEvent(ev); }
这样就完成了我们基本的流程,我们还可以在主界面设置一个按钮来对菜单进行开关,通过几句话就可以完成侧滑的,开的时候就向左滑动,关的时候就向右滑动就可以了看代码:
this.smoothScrollTo(0, 0); //开this.smoothScrollTo(mMenuWidth, 0); //关
好了这基本就全都完成了主流程,看一下全部代码:
public class SlidingLayout extends HorizontalScrollView{ /** * 屏幕宽度 */ private int mScreenWidth; /** * dp */ private int mMenuRightPadding; /** * 菜单的宽度 */ private int mMenuWidth; private int mHalfMenuWidth; private boolean isOpen; private boolean once; private ViewGroup mMenu; private ViewGroup mContent; public SlidingLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SlidingLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle);// WindowManager wm = (WindowManager) context// .getSystemService(Context.WINDOW_SERVICE);// DisplayMetrics outMetrics = new DisplayMetrics();// wm.getDefaultDisplay().getMetrics(outMetrics);// mScreenWidth = outMetrics.widthPixels; mScreenWidth = ScreenUtils.getScreenWidth(context); TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SlidingLayout, defStyle, 0); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.SlidingLayout_slidepadding: // 默认50 mMenuRightPadding = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 50f, getResources().getDisplayMetrics()));// 默认为10DP break; } } a.recycle(); } public SlidingLayout(Context context) { this(context, null, 0); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { /** * 显示的设置一个宽度 */ if (!once) { LinearLayout wrapper = (LinearLayout) getChildAt(0); mMenu = (ViewGroup) wrapper.getChildAt(0); mContent = (ViewGroup) wrapper.getChildAt(1); mMenuWidth = mScreenWidth - mMenuRightPadding; mHalfMenuWidth = mMenuWidth / 2; mMenu.getLayoutParams().width = mMenuWidth; mContent.getLayoutParams().width = mScreenWidth; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); if (changed) { // 将菜单隐藏 this.scrollTo(mMenuWidth, 0); once = true; } } @Override public boolean onTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { // Up时,进行判断,如果显示区域大于菜单宽度一半则完全显示,否则隐藏 case MotionEvent.ACTION_UP: int scrollX = getScrollX(); if (scrollX > mHalfMenuWidth) { this.smoothScrollTo(mMenuWidth, 0); isOpen = false; } else { this.smoothScrollTo(0, 0); isOpen = true; } return true; } return super.onTouchEvent(ev); } /** * 打开菜单 */ public void openMenu() { if (isOpen) return; this.smoothScrollTo(0, 0); isOpen = true; } /** * 关闭菜单 */ public void closeMenu() { if (isOpen) { this.smoothScrollTo(mMenuWidth, 0); isOpen = false; } } /** * 切换菜单状态 */ public void toggle() { if (isOpen) { closeMenu(); } else { openMenu(); } }
}
其实我们还可以通过监听滑动的距离来做很多事情,先看一下效果图:
从这张效果图中我们可以看到主窗口的长度是改变的,然后其实滑动过程中可以设置Menu的透明度也是在改变的,所以我们可以通过监听滑动的距离来动态改变主界面的高度,还有Menu的透明度的,通过网上的大神我知道HorizentorScrollview的
protected void onScrollChanged(int l, int t, int oldl, int oldt)
这个方法中的l就是活动的距离,所以我们可以计算出来窗口的高度是如何改变的,
窗口的高度是从1到0.7,然后平移的话是从0到mMenuWidth
,所有我们可以计算出来窗口的高度比率是
,所有我们可以计算出来窗口的高度比率是
(1 - l/mMenuWidth * 0.3) + 0.7;
透明度的变化是从0.6到1然后比率我们也可以算出来:
l/mMenuWidth * 0.3 * 0.4 + 0.6;所以我们可以得到下面的程序:
@Overrideprotected void onScrollChanged(int l, int t, int oldl, int oldt){ super.onScrollChanged(l, t, oldl, oldt); float scale = l * 1.0f / mMenuWidth; ViewHelper.setAlpha(mMenu, 0.6f + 0.4f * (1 - l * 1.0f / mMenuWidth)); //这个地方是需要导入包的 ViewHelper.setScaleY(mContent, 0.7f + (l * 1.0f / mMenuWidth) * 0.3f);}直接把这个代码加入我们自定义view中就可以实现效果了。
总结:好了这样基本就能实现上面的效果了,今天的侧滑就说到这里了,然后这里存在一个问题,就是如果HorizontalScrollview设置背景的话会卡顿,而且是有些图片卡顿,存色的图片不卡顿,然后在API17的时候也不会卡顿,我用的是API24,如果有大神指导为什么请留言指导一下谢谢了。
0 0
- android侧滑高大上效果
- Android层叠式卡片效果实现!(高大上)
- 高大上的多边形字体效果教程
- 高大上
- 高大上的侧滑菜单DrawerLayout,并解决不能全屏滑动的问题
- 什么是高大上、什么事精专尖。
- “高大上”的位运算
- 高大上的链路层简介
- jsp通用高大上分页
- 又一次高大上的培训!
- linux高大上命令001
- 我的高大上专有名词
- 高大上 web ppt 制作
- JS 实现3D立体效果的首页轮播图(瞬间让你的网站高大上,逼格满满)
- android电视开发框架 最齐全资源 音速开发高大上应用!
- 菜鸟入门仿ios高大上--Android沉浸式,复制粘贴动动手
- 高大上的优质JS代码写法
- 互联网思维:高大上难接地气
- 云客Drupal8源码分析之渲染占位符及其产生器
- Widows下利用OpenSSL生成证书
- hdu 2089 不要62(数位dp)
- poj分类
- 2017.1.10 算法测试题集 - 1006 - 编辑距离问题
- android侧滑高大上效果
- 七种方法绕过安卓手机锁屏
- sql中exists用法
- Android开发人员不得不收集的代码
- 面试说了这几句话,offer铁定无望!
- ITE EC代码解析1
- 因此虽然林潇每次包裹
- iOS开发 - 柱状图动态展现动画
- 正则相关