技術共享之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

如需轉載請標明出處,謝謝

發佈了27 篇原創文章 · 獲贊 12 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章