它们的定义android滑动菜单
在这里实现了两个滑动菜单效果,的拖放内容的第一部分,菜单拖出像这样的效果感觉,另一种是拖动内容。后面的内容固定菜单。我感觉有层次感的效果,如下面
第一种效果的代码实现例如以下:
package com.tenghu.customsideslip.menu.view; import android.content.Context;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout; /**
* Created by Arvin_Li on 2014/11/19.
*/
public class ScrollSideslipMenu extends LinearLayout{ private static final int SNAP_VELOCITY=200;//速度阈值
private View mMenu;//菜单布局
private View mContent;//内容布局 private int screenWidth;//屏幕宽度
private int menuWidth;//菜单宽度 private int leftEdge;//左边界
private int rightEdge=0;//右边界。值恒为0 private float xUp;//手指抬起时记录横坐标
private float xDown;//手指按下时记录横坐标
private float xMove;//手指移动时记录横坐标 private int toRightPaddingWidth=50;//菜单全然显示时,留给内容的宽度
private LayoutParams menuParams;//菜单布局參数 private boolean once=false;//初始化数据仅仅载入一次
private boolean isShowMenu;//是否显示菜单 private VelocityTracker velocityTracker;//速度跟踪器 public ScrollSideslipMenu(Context context) {
super(context);
initWindowWidth(context);
} public ScrollSideslipMenu(Context context, AttributeSet attrs) {
super(context, attrs);
initWindowWidth(context);
} /**
* 初始化获取屏幕宽度
*/
private void initWindowWidth(Context context){
WindowManager windowManager= (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics displayMetrics=new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
//获取屏幕宽度
screenWidth=displayMetrics.widthPixels;
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(!once){
mMenu=this.getChildAt(0);//获取菜单布局
mContent=this.getChildAt(1);//获取内容布局
menuParams= (LayoutParams) mMenu.getLayoutParams();//获取菜单布局參数
menuWidth=menuParams.width=screenWidth-toRightPaddingWidth;//设置菜单宽度
mContent.getLayoutParams().width=screenWidth;//设置内容宽度
leftEdge=-menuWidth;//左边界
menuParams.leftMargin=leftEdge;//默认菜单不显示
once=true;
}
} @Override
public boolean onTouchEvent(MotionEvent event) {
createVelocityTracker(event);
switch (event.getAction()){
//按下
case MotionEvent.ACTION_DOWN:
xDown=event.getRawX();//记录按下时的横坐标
break;
//移动
case MotionEvent.ACTION_MOVE:
//记录移动时的横坐标
xMove=event.getRawX();
//计算移动时与按下时的距离
int moveDistanceX= (int) (xMove-xDown);
if(isShowMenu){
menuParams.leftMargin=moveDistanceX;
}else{
menuParams.leftMargin=leftEdge+moveDistanceX;
} if(menuParams.leftMargin<leftEdge){
menuParams.leftMargin=leftEdge;
} if(menuParams.leftMargin>rightEdge){
menuParams.leftMargin=rightEdge;
} mMenu.setLayoutParams(menuParams);//设置參数
break;
//抬起
case MotionEvent.ACTION_UP:
//记录抬起时的横坐标
xUp=event.getRawX();
//计算抬起时与按下时的距离
int upDistanceX= (int) (xUp-xDown);
if(upDistanceX>0&&!isShowMenu){
if(upDistanceX>menuWidth/2||getScrollVelocity()>SNAP_VELOCITY){
scrollToMenu(); }else{
scrollToContent();
}
}else if(upDistanceX<0&&isShowMenu){
if(Math.abs(upDistanceX)>menuWidth/2||getScrollVelocity()>SNAP_VELOCITY){
scrollToContent();
}else{
scrollToMenu();
}
}
mMenu.setLayoutParams(menuParams);
break;
}
return true;
} /**
* 滚动内容部分
*/
private void scrollToContent(){
new ScrollTask().execute(-30);
} /**
* 滚动菜单部分
*/
private void scrollToMenu(){
new ScrollTask().execute(30);
} /**
* 创建速度阈值
*/
private void createVelocityTracker(MotionEvent event){
if(null==velocityTracker){
velocityTracker=VelocityTracker.obtain();
}
velocityTracker.addMovement(event);
} /**
* 获取滚动时的速度
* @return
*/
private int getScrollVelocity(){
velocityTracker.computeCurrentVelocity(1000);
int velocity= (int) velocityTracker.getXVelocity();//获取横向速度
return Math.abs(velocity);
} /**
* 创建一个异步滚动任务
*/
class ScrollTask extends AsyncTask<Integer,Integer,Integer>{ @Override
protected Integer doInBackground(Integer... params) {
int leftMargin=menuParams.leftMargin;
while(true){
leftMargin=leftMargin+params[0];
if(leftMargin<leftEdge){
leftMargin=leftEdge;
break;
}
if(leftMargin>rightEdge){
leftMargin=rightEdge;
break;
}
publishProgress(leftMargin);
sleep(20);
} if(params[0]>0){
isShowMenu=true;
}else{
isShowMenu=false;
}
return leftMargin; } /**
* 运行结束
* @param integer
*/
@Override
protected void onPostExecute(Integer integer) {
menuParams.leftMargin=integer;
mMenu.setLayoutParams(menuParams);
} /**
* 运行doInBackground中的publishProgress调用该方法
* @param values
*/
@Override
protected void onProgressUpdate(Integer... values) {
menuParams.leftMargin=values[0];
mMenu.setLayoutParams(menuParams);
}
} /**
* 当前线程睡眠多少毫秒
* @param millis
*/
private void sleep(long millis){
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"? >
<com.tenghu.customsideslip.menu.view.ScrollSideslipMenu xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@drawable/bg_01">
<!--引用菜单布局文件-->
<include layout="@layout/left_menu"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_02"></LinearLayout>
</com.tenghu.customsideslip.menu.view.ScrollSideslipMenu>
另外一种效果实现:
package com.tenghu.customsideslip.menu.view; import android.content.Context;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.WindowManager;
import android.widget.RelativeLayout; /**
* Created by Arvin_Li on 2014/11/19.
*/
public class CustomSideslipMenu extends RelativeLayout {
private static final int SNAP_VELOCITY=200;//手势滑动的速度
//屏幕宽度
private int mScreenWidth;
//菜单布局
private View mMenu;
//主体内容部分
private View mContent;
//声明菜单宽度
private int menuWidth;
//菜单全然显示时。留给内容部分的宽度
private int toRightPaddingWidth=50;
//主体内容布局參数
private LayoutParams contentParams;
//主体内容滑动到左边缘,由菜单宽度来决定
private int leftEdge;
//菜单显示时。主体内容到右边界,值恒为0
private int rightEdge=0;
private VelocityTracker velocityTracker;//声明速度跟踪器
private float xDown;//记录手指按下的横坐标
private float xUp;//记录手指抬起时的横坐标
private float xMove;//记录手指移动时的横坐标
private boolean once=false;//仅仅运行一次
private boolean isShowMenu=true;//是否显示菜单
public CustomSideslipMenu(Context context) {
super(context);
init(context);
} public CustomSideslipMenu(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
} /**
* 初始化
*/
private void init(Context context){
//获取窗体管理类
WindowManager windowManager= (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
//创建DisplayMetrics
DisplayMetrics displayMetrics=new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
//获取屏幕宽度
mScreenWidth=displayMetrics.widthPixels;
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(!once){
//获取菜单布局
mMenu=this.getChildAt(0);
//获取主体内容布局
mContent=this.getChildAt(1);
contentParams= (LayoutParams) mContent.getLayoutParams();//获取主体菜单參数
//菜单宽度
menuWidth=mMenu.getLayoutParams().width=mScreenWidth-toRightPaddingWidth;
//设置主体内容的宽度
mContent.getLayoutParams().width=mScreenWidth;
leftEdge=menuWidth;//设置左边界
once=true;
}
} @Override
public boolean onTouchEvent(MotionEvent event) {
//调用创建速度跟踪器
createVelocityTracker(event);
switch (event.getAction()){
//手指按下
case MotionEvent.ACTION_DOWN:
xDown=event.getRawX();
break;
//手指移动
case MotionEvent.ACTION_MOVE:
xMove=event.getRawX();
//计算移动距离
int distanceX= (int) (xMove-xDown);
if(isShowMenu){
contentParams.leftMargin=distanceX;
contentParams.rightMargin=-distanceX;
}else{
contentParams.leftMargin=leftEdge+distanceX;
} if(contentParams.leftMargin>leftEdge){
contentParams.leftMargin=leftEdge;
contentParams.rightMargin=-leftEdge;
} if(contentParams.leftMargin<rightEdge){
contentParams.leftMargin=rightEdge;
contentParams.rightMargin=rightEdge;
}
mContent.setLayoutParams(contentParams);//測试參数
break;
//手指抬起
case MotionEvent.ACTION_UP:
xUp=event.getRawX();//手指抬起时横坐标
//计算抬起时与按下时的距离
int upDistanceX=(int) (xDown-xUp);
if(upDistanceX>0&&!isShowMenu){
if(upDistanceX>menuWidth/2||getScrollVelocity()>SNAP_VELOCITY){
scrollToMenu();
}else{
scrollToContent();
}
}else if(upDistanceX<0&&isShowMenu){
if(Math.abs(upDistanceX)>menuWidth/2||getScrollVelocity()>SNAP_VELOCITY){
scrollToContent();
}else{
scrollToMenu();
}
//手指抬起时销毁
recycleVelocityTracker();
}
break;
}
return true;
} /**
* 滚动菜单
*/
private void scrollToMenu(){
new ScrollTask().execute(-30);
} /**
* 滚动内容
*/
private void scrollToContent(){
new ScrollTask().execute(30);
} /**
* 获取速度
* @return
*/
private int getScrollVelocity(){
velocityTracker.computeCurrentVelocity(1000);
int velocity= (int) velocityTracker.getXVelocity();
return Math.abs(velocity);
} /**
* 销毁速度跟踪器
*/
private void recycleVelocityTracker(){
if (null != velocityTracker) {
velocityTracker.recycle();
velocityTracker = null;
}
} /**
* 创建速度跟踪器
*/
private void createVelocityTracker(MotionEvent event){
if(null==velocityTracker){
velocityTracker=velocityTracker.obtain();
}
velocityTracker.addMovement(event);
} /**
* 创建异步滚动任务类
*/
class ScrollTask extends AsyncTask<Integer,Integer,Integer>{ @Override
protected Integer doInBackground(Integer... params) {
int leftMargin=contentParams.leftMargin;
while(true){
leftMargin=leftMargin+params[0];
if(leftMargin>leftEdge){
leftMargin=leftEdge;
break;
} if(leftMargin<rightEdge){
leftMargin=rightEdge;
break;
}
if(params[0]<0){
isShowMenu=true;
// leftMargin=rightEdge;
}else{
isShowMenu=false;
}
publishProgress(leftMargin);
sleep(20);
}
return leftMargin;
} @Override
protected void onProgressUpdate(Integer... values) {
contentParams.leftMargin=values[0];
contentParams.rightMargin=-values[0];
mContent.setLayoutParams(contentParams);
} @Override
protected void onPostExecute(Integer integer) {
contentParams.leftMargin=integer;
contentParams.rightMargin=-integer;
mContent.setLayoutParams(contentParams);
}
} /**
* 当前线程睡眠多少毫秒
* @param millis
*/
private void sleep(long millis){
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
布局文件:
<com.tenghu.customsideslip.menu.view.CustomSideslipMenu 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"
android:background="@drawable/bg_01"
tools:context=".MainActivity"> <include layout="@layout/left_menu" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_02"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="testScrollMenu"
android:text="測试另外一种側滑菜单"/>
</LinearLayout>
</LinearLayout>
</com.tenghu.customsideslip.menu.view.CustomSideslipMenu>
菜单布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:orientation="vertical"> <RelativeLayout
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginBottom="10dp"> <ImageView
android:id="@+id/iv_img_01"
android:layout_width="50dp"
android:layout_height="match_parent"
android:src="@drawable/app_01" /> <TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@id/iv_img_01"
android:gravity="center_vertical"
android:text="第一个Item" />
</RelativeLayout> <RelativeLayout
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginBottom="10dp"> <ImageView
android:id="@+id/iv_img_02"
android:layout_width="50dp"
android:layout_height="match_parent"
android:src="@drawable/app_02" /> <TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@id/iv_img_02"
android:gravity="center_vertical"
android:text="第二个Item" />
</RelativeLayout> <RelativeLayout
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginBottom="10dp"> <ImageView
android:id="@+id/iv_img_03"
android:layout_width="50dp"
android:layout_height="match_parent"
android:src="@drawable/app_03" /> <TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@id/iv_img_03"
android:gravity="center_vertical"
android:text="第三个Item" />
</RelativeLayout> <RelativeLayout
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginBottom="10dp"> <ImageView
android:id="@+id/iv_img_04"
android:layout_width="50dp"
android:layout_height="match_parent"
android:src="@drawable/app_04" /> <TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@id/iv_img_04"
android:gravity="center_vertical"
android:text="第四个Item" />
</RelativeLayout> <RelativeLayout
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginBottom="10dp"> <ImageView
android:id="@+id/iv_img_05"
android:layout_width="50dp"
android:layout_height="match_parent"
android:src="@drawable/app_05" /> <TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@id/iv_img_05"
android:gravity="center_vertical"
android:text="第五个Item" />
</RelativeLayout> </LinearLayout>
</RelativeLayout>
这里的菜单,能够是用ListView来布局,做測试就没有那样做了。所有代码所有在这里了。能够看出。两种效果仅仅是继承了不通的布局,感觉另外一种效果在设置背景时有点问题,就是在这里
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_02"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="testScrollMenu"
android:text="測试另外一种側滑菜单"/>
</LinearLayout>
</LinearLayout>
假设将背景设置到第一层的LinearLayout上,那么自己定义側滑菜单那里设置背景就显示不出来,设置到第二层就能够,我不知道是怎么回事肿。假设我们掌握发现,麻烦告诉小弟。
版权声明:本文博客原创文章。博客,未经同意,不得转载。
它们的定义android滑动菜单的更多相关文章
- Android滑动菜单框架完全解析,教你如何一分钟实现滑动菜单特效
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/8744400 之前我向大家介绍了史上最简单的滑动菜单的实现方式,相信大家都还记得.如 ...
- Android 滑动菜单SlidingMenu
首先我们看下面视图: 这种效果大家都不陌生,网上好多都说是仿人人网的,估计人家牛逼出来的早吧,我也参考了一一些例子,实现起来有三种方法,我下面简单介绍下: 方法一:其实就是对GestureDetect ...
- Android 滑动菜单框架--SwipeMenuListView框架完全解析
SwipeMenuListView(滑动菜单) A swipe menu for ListView.--一个非常好的滑动菜单开源项目. Demo 一.简介 看了挺长时间的自定义View和事件分发,想找 ...
- android ——滑动菜单
一.DrawerLayout是一个拥有两个子控件的布局,第一个子控件是主屏幕中显示的内容,第二个子控件是滑动菜单中显示的内容: <android.support.v4.widget.Drawer ...
- android 滑动菜单SlidingMenu的实现
首先我们看下面视图: 这种效果大家都不陌生,网上好多都说是仿人人网的,估计人家牛逼出来的早吧,我也参考了一一些例子,实现起来有三种方法,我下面简单介绍下: 方法一:其实就是对Gesture ...
- Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
http://blog.csdn.net/guolin_blog/article/details/8714621 http://blog.csdn.net/lmj623565791/article/d ...
- Android滑动菜单使用(MenuDrawer和SlidingMenu)
项目地址: https://github.com/gokhanakkurt/android-menudrawer https://github.com/jfeinstein10/SlidingMe ...
- Android双向滑动菜单完全解析,教你如何一分钟实现双向滑动特效
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9671609 记得在很早之前,我写了一篇关于Android滑动菜单的文章,其中有一个 ...
- Android 学习笔记之AndBase框架学习(七) SlidingMenu滑动菜单的实现
PS:努力的往前飞..再累也无所谓.. 学习内容: 1.使用SlidingMenu实现滑动菜单.. SlidingMenu滑动菜单..滑动菜单在绝大多数app中也是存在的..非常的实用..Gith ...
随机推荐
- VOJ 1067 Warcraft III 守望者的烦恼 (矩阵高速功率+dp)
主题链接 明显的 dp[n] = dp[n-k] + dp[n-k+1] + ... +dp[n-1]; 然后要用矩阵来优化后面的状态转移. 也就是矩阵 0 1 0 0 a b 0 0 ...
- 开源远程控制RealVNC源代码中的通讯协议RFB(远程帧缓冲)(转)
在网上流传的gh0st3.6源代码中,远程桌面总是存在CPU占用率高和画面更新不及时等问题.于是想到了著名的开源远程控制RealVNC 它采用了远程帧缓存的协议(Remote Frame buffe ...
- bootstrap+jQuery.validate
bootstrap+jQuery.validate表单校验 谈谈表单校验 这大概是一种惯例,学习前台后台最开始接触的业务都是用户注册和登录.现在社会坚持以人为本的理念,在网站开发过程同样如此.Us ...
- 分布式中使用Redis实现Session共享(转)
上一篇介绍了如何使用nginx+iis部署一个简单的分布式系统,文章结尾留下了几个问题,其中一个是"如何解决多站点下Session共享".这篇文章将会介绍如何使用Redis,下一篇 ...
- hdu 3001 Travelling (TSP问题 )
Travelling Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- Azure VM Public IP设置
Azure虚拟机的Public IP是用于客户端直连云中的虚拟机,可以认为是一个外网IP,一般我们为虚拟机设置终结点,例如HTTP的80端口,如果使用Public IP可以不使用Azure Porta ...
- 探索Scala(1)-- 运算符重载
Scala语言运算符重载全然是语法层面的小把戏,本文记录我对Scala语言运算符重载的一些理解. 方法调用语法糖 调用方法时,Scala同意省略点号和圆括号,如以下代码所看到的: 把运算符映射成单词 ...
- about greenplum collection tool
three collection tool for greenplum:pstack.strace.gcore. ...
- Linux centos 主机名颜色设置 和 别名设置
方便和乐趣写今天.至于为什么主机名颜色设置 和 别名设置放在一起写.这是因为他们的设置是在一个文件中..bashrc. .bashrc放在cd /root 这个文件夹下! 这个文件主要保存个人的一些个 ...
- Hadoop它——跑start-all.sh时间namenode不启动
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46353211 近期遇到了一个问题,运行start-all.sh的时候发现JPS一下 ...