技术共享之QQ条目侧滑菜单
程序员文章站
2022-05-15 18:25:49
...
简单介绍:
QQ 会话条目的侧滑菜单实现原理就是 重写 LinearLayout 或者HorienzentalScrollView ,划出来的菜单无疑是已经摆放好,只是在屏幕的可见范围之外而已,我们只需要做做事件传递的工作和一些逻辑即可。本博客主要以重写LineaLayout 为主 可以节省大量开发工作,如果你想用来练手,可以使用HorienzentalScrollView 来实现。老规矩 先上 效果图
挺简单的 主要就是做一些事件传递的处理逻辑就行了
第一步 写 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<com.liang.boke.sliddingitemmenu.SliddingItemMenu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.liang.boke.sliddingitemmenu.MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="侧滑item"
android:gravity="center"
android:textSize="18sp"
android:textColor="#fff"
android:layout_marginTop="30dp"
android:background="#44000000"
/>
<TextView
android:layout_width="60dp"
android:layout_height="40dp"
android:text="删除"
android:gravity="center"
android:textSize="18sp"
android:textColor="#fff"
android:layout_marginTop="30dp"
android:background="@color/colorAccent"
/>
</com.liang.boke.sliddingitemmenu.SliddingItemMenu>
注意 父容器 要写成 类所在的包名 + . + 类名
如 : 类所在的包名 :com.liang.boke.sliddingitemmenu
类名:SliddingItemMenu
第二步 新建类SliddingItemMenu 继承 LinearLayout
package com.liang.boke.sliddingitemmenu;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.LinearLayout;
import android.widget.Scroller;
/**
* Created by 梁 on 2017/12/8.
* 位置已经摆放完成
* 处理滑动的效果即可
*/
public class SliddingItemMenu extends LinearLayout{
private Scroller mScroller;
private float startX;
private float startY;
private float dx;
private float dy;
private View leftItem;
private View rightItem;
public SliddingItemMenu(Context context) {
this(context,null);
}
public SliddingItemMenu(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public SliddingItemMenu(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mScroller = new Scroller(context,null,true);
}
@Override
protected void onFinishInflate() {
leftItem = getChildAt(0);
rightItem = getChildAt(1);
super.onFinishInflate();
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction())
{
case MotionEvent.ACTION_DOWN :
startX = ev.getX();
startY = ev.getY();
super.dispatchTouchEvent(ev);
return true ;
case MotionEvent.ACTION_MOVE :
//做滑动的动作
// 计算 滑动的偏移量
dx = ev.getX() - startX;
dy = ev.getY() - startY;
if(Math.abs(dx) - Math.abs(dy) > ViewConfiguration.getTouchSlop())
{ //如果 x 轴的偏移量 减去 y 轴的偏移量 大于 能被 设备监测到滑动的最小位移 为了 x 轴 与 y 轴 滑动不冲突
//滑动的距离不能大于rightWidth
//getScrollX() 左滑 大于 0 右滑 小于0
if( getScrollX() + (-dx) > rightItem.getWidth()||getScrollX() + (-dx)<0){
return true;
}
this.scrollBy((int) -dx,0);
}
startX = ev.getX() ;
startY = ev.getY();
return true ;
case MotionEvent.ACTION_UP:
//计算往哪划 如果松开手 已经划出 右边控件的一半 就移动完剩下的距离
// 否则回弹到原来的位置
int offset = (getScrollX() / (float) rightItem.getWidth() > 0.5) ? rightItem.getWidth() - getScrollX() : -getScrollX() ;
mScroller.startScroll(getScrollX(),getScrollY(), offset,0);
invalidate(); //重绘的时候会不停的调用computeScroll 方法
startX = 0 ;
startY = 0;
dx = 0 ;
dy = 0 ;
break;
}
return super.dispatchTouchEvent(ev);
}
//在开启滑动的情况下(mScroller.startScroll),滑动的过程当中此方法会被不断调用
@Override
public void computeScroll() {
if(mScroller.computeScrollOffset()){
this.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
super.computeScroll();
}
}
如有不明白的可以 可以看源码 但是源码要C 币 没办法 平台最低需要2C币
源码已上传至http://download.csdn.net/download/baidu_38477614/10150775
但是源码要C 币 没办法 平台最低需要2C币 想要免费源码 和讨论技术的加我 Q 1915528523
如需转载请标明出处,谢谢
推荐阅读