Android实现滑动侧边栏

 更新时间:2020年04月08日 11:40:43   作者:Joe_c  
这篇文章主要为大家详细介绍了Android实现滑动侧边栏效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

在Android应用开发中,滑动侧边栏经常使用,今天我也试着自己进行了一个简单的实践,虽然功能还不是很强大,但是可以保留下来为以后的开发使用,有需要时在进行简单的修改。实现一个滑动侧边栏思路也很简单:

1.重写一个SlidingMenu类继承ViewGroup,病危该ViewGroup添加两个子布局,分别为菜单和主界面显示;

2.为了得到一个滑动的效果,选择Scroller帮助我们实现,配合ViewGroup下的computeScroll方法实现界面的更新;

3.利用一个boolean来记录菜单是否打开,在菜单打开的状态下向右滑动不会响应,在菜单关闭的情况向左滑动不会响应;

4.为了得到一个良好的交互,我们可以为界面滑动与手指移动的距离定义一个比例,如每次触摸事件发生,界面移动的距离仅为手指移动距离的一半;

下面是两张效果图,界面没怎么布局,大家凑合看

SlidingMenu实现代码:

package com.example.test; 
 
import android.content.Context; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Scroller; 
 
public class SlidingMenu extends ViewGroup { 
 
 private static final String TAG = SlidingMenu.class.getName(); 
 
 private enum Scroll_State { 
 Scroll_to_Open, Scroll_to_Close; 
 } 
 
 private Scroll_State state; 
 private int mMostRecentX; 
 private int downX; 
 private boolean isOpen = false; 
 
 private View menu; 
 private View mainView; 
 
 private Scroller mScroller; 
 
 private OnSlidingMenuListener onSlidingMenuListener; 
 
 public SlidingMenu(Context context, View main, View menu) { 
 super(context); 
 // TODO Auto-generated constructor stub 
 setMainView(main); 
 setMenu(menu); 
 init(context); 
 } 
 
 private void init(Context context) { 
 mScroller = new Scroller(context); 
 } 
 
 @Override 
 protected void onLayout(boolean arg0, int l, int t, int r, int b) { 
 // TODO Auto-generated method stub 
 mainView.layout(l, t, r, b); 
 menu.layout(-menu.getMeasuredWidth(), t, 0, b); 
 } 
 
 public void setMainView(View view) { 
 mainView = view; 
 addView(mainView); 
 } 
 
 public void setMenu(View view) { 
 menu = view; 
 addView(menu); 
 } 
 
 @Override 
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
 // TODO Auto-generated method stub 
 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
 mainView.measure(widthMeasureSpec, heightMeasureSpec); 
 menu.measure(widthMeasureSpec - 150, heightMeasureSpec); 
 } 
 
 @Override 
 public boolean onTouchEvent(MotionEvent event) { 
 switch (event.getAction()) { 
 case MotionEvent.ACTION_DOWN: 
  mMostRecentX = (int) event.getX(); 
  downX = (int) event.getX(); 
  break; 
 case MotionEvent.ACTION_MOVE: 
  int moveX = (int) event.getX(); 
  int deltaX = mMostRecentX - moveX; 
  // 如果在菜单打开时向右滑动及菜单关闭时向左滑动不会触发Scroll事件 
  if ((!isOpen && (downX - moveX) < 0) 
   || (isOpen && (downX - moveX) > 0)) { 
  scrollBy(deltaX / 2, 0); 
  } 
  mMostRecentX = moveX; 
  break; 
 case MotionEvent.ACTION_UP: 
  int upX = (int) event.getX(); 
  int dx = upX - downX; 
  if (!isOpen) {// 菜单关闭时 
  // 向右滑动超过menu一半宽度才会打开菜单 
  if (dx > menu.getMeasuredWidth() / 3) { 
   state = Scroll_State.Scroll_to_Open; 
  } else { 
   state = Scroll_State.Scroll_to_Close; 
  } 
  } else {// 菜单打开时 
  // 当按下时的触摸点在menu区域时,只有向左滑动超过menu的一半,才会关闭 
  // 当按下时的触摸点在main区域时,会立即关闭 
  if (downX < menu.getMeasuredWidth()) { 
   if (dx < -menu.getMeasuredWidth() / 3) { 
   state = Scroll_State.Scroll_to_Close; 
   } else { 
   state = Scroll_State.Scroll_to_Open; 
   } 
  } else { 
   state = Scroll_State.Scroll_to_Close; 
  } 
  } 
  smoothScrollto(); 
  break; 
 default: 
  break; 
 } 
 return true; 
 } 
 
 private void smoothScrollto() { 
 int scrollx = getScrollX(); 
 switch (state) { 
 case Scroll_to_Close: 
  mScroller.startScroll(scrollx, 0, -scrollx, 0, 500); 
  if (onSlidingMenuListener != null && isOpen) { 
  onSlidingMenuListener.close(); 
  } 
  isOpen = false; 
  break; 
 case Scroll_to_Open: 
  mScroller.startScroll(scrollx, 0, 
   -scrollx - menu.getMeasuredWidth(), 0, 500); 
  if (onSlidingMenuListener != null && !isOpen) { 
  onSlidingMenuListener.close(); 
  } 
  isOpen = true; 
  break; 
 default: 
  break; 
 } 
 } 
 
 @Override 
 public void computeScroll() { 
 if (mScroller.computeScrollOffset()) { 
  scrollTo(mScroller.getCurrX(), 0); 
 } 
 invalidate(); 
 } 
 
 public void open() { 
 state = Scroll_State.Scroll_to_Open; 
 smoothScrollto(); 
 } 
 
 public void close() { 
 state = Scroll_State.Scroll_to_Close; 
 smoothScrollto(); 
 } 
 
 public boolean isOpen() { 
 return isOpen; 
 } 
 
 public void setOnSlidingMenuListener( 
  OnSlidingMenuListener onSlidingMenuListener) { 
 this.onSlidingMenuListener = onSlidingMenuListener; 
 } 
 
 public interface OnSlidingMenuListener { 
 public void open(); 
 
 public void close(); 
 } 
 
} 

在MainActivity中进行调用

package com.example.test; 
 
import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
 
public class MainActivity extends Activity { 
 
 private Button openButton; 
 private Button closeButton; 
 private SlidingMenu mSlidingMenu; 
 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
 super.onCreate(savedInstanceState); 
 mSlidingMenu = new SlidingMenu(this, LayoutInflater 
  .from(this).inflate(R.layout.fragment1, null), LayoutInflater 
  .from(this).inflate(R.layout.fragment2, null)); 
 setContentView(mSlidingMenu);//注意setContentView需要换为我们的SlidingMenu 
 openButton = (Button) findViewById(R.id.button1); 
 closeButton = (Button) findViewById(R.id.button_close); 
 openButton.setOnClickListener(new OnClickListener() { 
  
  @Override 
  public void onClick(View arg0) { 
  // TODO Auto-generated method stub 
  mSlidingMenu.open(); 
  } 
 }); 
 closeButton.setOnClickListener(new OnClickListener() { 
  
  @Override 
  public void onClick(View arg0) { 
  // TODO Auto-generated method stub 
  mSlidingMenu.close(); 
  } 
 }); 
 } 
 
} 

更多关于滑动功能的文章,请点击专题: 《Android滑动功能》

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Flutter数据库的使用方法

    Flutter数据库的使用方法

    这篇文章主要介绍了Flutter数据库的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • 移动端android上line-height不居中的问题的解决

    移动端android上line-height不居中的问题的解决

    现在越来越多的移动界面使用rem适配,最近发现了移动端android上line-height不居中的问题,今日就来介绍一下解决的方法,非常具有实用价值,需要的朋友可以参考下
    2018-03-03
  • Android全面屏与异形(刘海)屏的适配教程

    Android全面屏与异形(刘海)屏的适配教程

    Apple一直在引领设计的潮流,自从 iPhone X 发布之后,各种异形屏、刘海屏也都出来,下面这篇文章主要给大家分享介绍了关于Android全面屏与异形(刘海)屏的适配教程,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-07-07
  • 深入android中The connection to adb is down的问题以及解决方法

    深入android中The connection to adb is 

    本篇文章是对android中The connection to adb is down的问题以及解决方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • Flutter app页面路由以及路由拦截的实现

    Flutter app页面路由以及路由拦截的实现

    本篇介绍了介绍了Flutter如何使用路由来实现页面的跳转,从而简化页面之间的耦合,并可以实现路由拦截。
    2021-06-06
  • Android App中ViewPager所带来的滑动冲突问题解决方法

    Android App中ViewPager所带来的滑动冲突问题解决方法

    Android中我们经常使用ViewPager配合Fragment实现视图滑动,但在实际操作中又会经常发生方向上的冲突问题,这里我们就来总结一下Android App中ViewPager所带来的滑动冲突问题解决方法:
    2016-06-06
  • Android split分割特殊字符取名称的方法

    Android split分割特殊字符取名称的方法

    这篇文章主要为大家详细介绍了Android split分割特殊字符取名称的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Android实现上拉加载更多ListView(PulmListView)

    Android实现上拉加载更多ListView(PulmListView)

    这篇文章主要介绍了Android实现上拉加载更多ListView:PulmListView,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • 关于Gradle下载失败问题的快速解决方法

    关于Gradle下载失败问题的快速解决方法

    这篇文章主要给大家分享了关于Gradle下载失败问题的快速解决方法,文中介绍了两种解决方法,分别是使用已存在的gradle版本和手动下载gradle,文中介绍的非常详细,需要的朋友们下面来一起看看吧。
    2017-05-05
  • Android中使用ViewStub实现布局优化

    Android中使用ViewStub实现布局优化

    ViewStub是Android布局优化中一个很不错的标签/控件,直接继承自View。虽然Android开发人员基本上都听说过,但是真正用的可能不多。今天我们就来详细探讨下ViewStub的使用
    2016-09-09

最新评论