服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android实现QQ侧滑菜单效果

Android实现QQ侧滑菜单效果

2022-09-21 15:13常利兵 Android

这篇文章主要为大家详细介绍了Android实现QQ侧滑菜单效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

QQ侧滑菜单的Android实现代码,供大家参考,具体内容如下

实现逻辑

1.先写出菜单页面和主页面的布局

2.创建一个类,继承RelativeLayout,实现里面的onLayout

3.在主布局文件中添加子空间

4.在onLayout里面获取子控件的宽和高,并对子控件的位置进行绘制

5.给子布局设置滑动事件,分别在手指落下\移动\抬起的时候,获取手指的位置

6.在手指移动的过程中,对菜单页面的移动距离进行限制,防止菜单页面跑出指定的页面

7.在手指抬起的时候,判定一下手指移动的距离,如果移动的距离大于菜单页面宽度的一半,那就让菜单弹出,否则就让菜单回到默认的位置

8.针对菜单的弹出和收起,实现了一个渐变的过程,防止手指抬起的时候,菜单页面会突然间到达指定的位置,这个功能的实现需要借助computeScroll方法

9.滑动冲突的处理,分别求出手指移动时,X和Y方向的偏移量,如果x方向的大于Y方向的,那就判定滑动事件是弹出和收起菜单,否则就判定为菜单页面的内部滑动

代码文件

布局文件

菜单布局文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="240dp"
android:background="@mipmap/menu_bg"
android:layout_height="match_parent"
android:orientation="vertical">
 
<LinearLayout
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
 
  <TextView
    style="@style/menu_style"
    android:text="新闻"
    android:drawableLeft="@mipmap/tab_news" />
  <TextView
    style="@style/menu_style"
    android:text="订阅"
    android:drawableLeft="@mipmap/tab_read" />
  <TextView
    style="@style/menu_style"
    android:text="跟帖"
    android:drawableLeft="@mipmap/tab_ties" />
  <TextView
    style="@style/menu_style"
    android:text="图片"
    android:drawableLeft="@mipmap/tab_pics" />
  <TextView
    style="@style/menu_style"
    android:text="话题"
    android:drawableLeft="@mipmap/tab_ugc" />
  <TextView
    style="@style/menu_style"
    android:text="投票"
    android:drawableLeft="@mipmap/tab_vote" />
  <TextView
    style="@style/menu_style"
    android:text="本地"
    android:drawableLeft="@mipmap/tab_local" />
  <TextView
    style="@style/menu_style"
    android:text="聚合阅读"
    android:drawableLeft="@mipmap/tab_focus" />
 
  <TextView
    style="@style/menu_style"
    android:text="聚合阅读"
    android:drawableLeft="@mipmap/tab_focus" />
 
  <TextView
    style="@style/menu_style"
    android:text="聚合阅读"
    android:drawableLeft="@mipmap/tab_focus" />
 
  <TextView
    style="@style/menu_style"
    android:text="聚合阅读"
    android:drawableLeft="@mipmap/tab_focus" />
 
  <TextView
    style="@style/menu_style"
    android:text="聚合阅读"
    android:drawableLeft="@mipmap/tab_focus" />
 
</LinearLayout>
</ScrollView>

主页面布局

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
 
<LinearLayout
  android:gravity="center_vertical"
  android:background="@mipmap/top_bar_bg"
  android:orientation="horizontal"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">
  <ImageButton
    android:background="@null"
    android:id="@+id/ib_back"
    android:src="@mipmap/main_back"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
  <ImageView
    android:src="@mipmap/top_bar_divider"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
 
  <TextView
    android:layout_weight="1"
    android:gravity="center"
    android:text="黑马新闻"
    android:textSize="20sp"
    android:textColor="#fff"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
 
</LinearLayout>
 
<TextView
  android:gravity="center"
  android:textColor="#cfcfcf"
  android:textSize="20sp"
  android:text="钓鱼岛是中国的..."
  android:layout_width="match_parent"
  android:layout_height="match_parent" />
 
</LinearLayout>

主页面布局

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
android:layout_width="match_parent" android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.a1_.MainActivity">
 
<com.example.a1_.SlidingMenu
  android:id="@+id/slidingmenu"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <include layout="@layout/menu"/>
  <include layout="@layout/main"/>
</com.example.a1_.SlidingMenu>
</RelativeLayout>

自定义布局

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package com.example.a1_;
 
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.Scroller;
 
/**
 * Created by Administrator on 2017.05.29.0029.
 */
 
public class SlidingMenu extends RelativeLayout {
 
private float downX;
private int destance;
private int menuWidth;
private int endx;
private int dx;
private final Scroller scroller;
private float downY;
private int dy;
 
public SlidingMenu(Context context, AttributeSet attrs) {
  super(context, attrs);
  //创建Scroller对象
  scroller = new Scroller(context);
}
 
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
  //获取子控件
  View menu = getChildAt(0);
  View main = getChildAt(1);
  //获取菜单布局的宽度
  menuWidth = menu.getMeasuredWidth();
  //把菜单布局布置在屏幕左侧
  menu.layout(-menuWidth,t,0,b);
  //主页面使用默认的位置就可以
  main.layout(l,t,r,b);
}
 
//给布局添加一个touch事件
 
@Override
public boolean onTouchEvent(MotionEvent event) {
  switch (event.getAction()){
    case MotionEvent.ACTION_DOWN:
      //当手指按下时,记录一下手指的位置
      downX = event.getX();
      break;
    case MotionEvent.ACTION_MOVE:
      //当手指移动的时候,记录移动的距离
      destance = (int) (event.getX()- downX+endx);
      //对手指滑动的时候,页面移动做出限制
      if (destance>menuWidth){
        destance = menuWidth;
      }else if (destance<0){
        destance = 0;
      }
      scrollTo(-destance,0);
      break;
    case MotionEvent.ACTION_UP:
      //当手指离开屏幕的时候,记录菜单的位置,根据情况进行判定
      if (destance<menuWidth/2){
        endx = 0;
      }else {
        endx = menuWidth;
      }
      int startX = destance;
      //计算偏移量
      dx = endx-destance;
      scroller.startScroll(startX,0,dx,0,Math.abs(dx)*10);
      invalidate();
      break;
  }
  return true;
}
 
//重写computeScroll
@Override
public void computeScroll() {
  if (scroller.computeScrollOffset()){
    int currx = scroller.getCurrX();
    scrollTo(-currx,0);
    invalidate();
  }
}
 
//处理滑动冲突
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
  switch (ev.getAction()){
    case MotionEvent.ACTION_DOWN:
      //获取当前点击的位置
      downX = ev.getX();
      downY = ev.getY();
      break;
    case MotionEvent.ACTION_MOVE:
      //获取x和y方向的偏移量
      dx = (int) (ev.getX()-downX);
      dy = (int) (ev.getY() - downY);
      //判断是x方向偏移的多还是y方向偏移得多
      if (Math.abs(dx)>Math.abs(dy)){
        //拦截move事件
        return true;
      }
      break;
  }
  return super.onInterceptTouchEvent(ev);
}
 
//判断当前的菜单状态是打开还是关闭的
public void switchMenu(){
  int startX = 0;
  if (endx == 0){
    endx = menuWidth;
  }else {
    endx = 0;
    startX = menuWidth;
  }
  //设置偏移量
  int dx = endx-startX;
  scroller.startScroll(startX,0,dx,0,Math.abs(dx)*10);
  invalidate();
}
}

主页面代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.example.a1_;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
 
public class MainActivity extends AppCompatActivity {
private SlidingMenu slidingMenu;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  //初始化控件
  ImageButton imageButton = (ImageButton) findViewById(R.id.ib_back);
  slidingMenu = (SlidingMenu) findViewById(R.id.slidingmenu);
 
  //设置点击事件
  imageButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      slidingMenu.switchMenu();
    }
  });
}
}

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

原文链接:https://blog.csdn.net/qq_32890771/article/details/72802954

延伸 · 阅读

精彩推荐