簡單介紹:
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
如需轉載請標明出處,謝謝