技术共享之QQ条目侧滑菜单

简单介绍:
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

如需转载请标明出处,谢谢

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值