欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android仿QQ列表左滑刪除操作

 更新時(shí)間:2016年12月15日 11:45:08   作者:饑渴計(jì)科極客杰鏗  
這篇文章主要為大家詳細(xì)介紹了Android仿QQ列表左滑刪除操作的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

最近學(xué)習(xí)了如何做一個(gè)像QQ的左滑RecyclerView的item顯示選項(xiàng)的,主要是用到Scroller

我們首先新建一個(gè)自己的RecyclerView

定義好一些要用的的變量
重寫構(gòu)造方法,把前兩個(gè)構(gòu)造方法改為如下,使無論如何構(gòu)造都要執(zhí)行第三個(gè)構(gòu)造方法
在第三個(gè)構(gòu)造方法里初始化Scroller

public class LeftSwipeMenuRecyclerView extends RecyclerView {

  //置頂按鈕
  private TextView tvTop;
  //刪除按鈕
  private TextView tvDelete;
  //item相應(yīng)的布局
  private LinearLayout mItemLayout;
  //菜單的最大寬度
  private int mMaxLength;

  //上一次觸摸行為的x坐標(biāo)
  private int mLastX;
  //上一次觸摸行為的y坐標(biāo)
  private int mLastY;

  //當(dāng)前觸摸的item的位置
  private int mPosition;

  //是否在垂直滑動(dòng)列表
  private boolean isDragging;
  //item是在否跟隨手指移動(dòng)
  private boolean isItemMoving;
  //item是否開始自動(dòng)滑動(dòng)
  private boolean isStartScroll;

  //左滑菜單狀態(tài)  0:關(guān)閉 1:將要關(guān)閉 2:將要打開 3:打開
  private int mMenuState;
  private static int MENU_CLOSED = 0;
  private static int MENU_WILL_CLOSED = 1;
  private static int MENU_OPEN = 2;
  private static int MENU_WILL_OPEN = 3;

  //實(shí)現(xiàn)彈性滑動(dòng),恢復(fù)
  private Scroller mScroller;

  //item的事件監(jiān)聽
  private OnItemActionListener mListener;

  public LeftSwipeMenuRecyclerView(Context context) {
    this(context, null);
  }

  public LeftSwipeMenuRecyclerView(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public LeftSwipeMenuRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mScroller = new Scroller(context, new LinearInterpolator());
  }

重寫onTouchEvent方法

event主要有以下幾個(gè)Action

  • ACTION_DOWN 手指接觸到屏幕
  • ACTION_MOVE 手指在屏幕滑動(dòng)
  • ACTION_UP 手指離開屏幕

一開始肯定要獲取x和y的相對(duì)坐標(biāo)

int x= (int) event.getX();
int y= (int) event.getY();

然后接下來分別處理3個(gè)不同的行為

1.ACTION_DOWN

case MotionEvent.ACTION_DOWN:
        if (mMenuState == MENU_CLOSED) {
          //根據(jù)坐標(biāo)獲得view
          View view = findChildViewUnder(x, y);
          if (view == null) {
            return false;
          }
          //獲得這個(gè)view的ViewHolder
          RVAdapter.Holder holder = (RVAdapter.Holder) getChildViewHolder(view);
          //獲得這個(gè)view的position
          mPosition = holder.getAdapterPosition();
          //獲得這個(gè)view的整個(gè)布局
          mItemLayout = holder.llLayout;
          //獲得這個(gè)view的刪除按鈕
          tvDelete = holder.tvDelete;
          //這個(gè)view的整個(gè)置頂按鈕
          tvTop = holder.tvTop;
          //兩個(gè)按鈕的寬度
          mMaxLength = tvDelete.getWidth() + tvTop.getWidth();

          //設(shè)置刪除按鈕點(diǎn)擊監(jiān)聽
          tvDelete.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
              mItemLayout.scrollTo(0, 0);
              mMenuState =MENU_CLOSED;
              mListener.OnItemDelete(mPosition);
            }
          });
          //設(shè)置置頂按鈕點(diǎn)擊監(jiān)聽
          tvTop.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
              mItemLayout.scrollTo(0, 0);
              mMenuState =MENU_CLOSED;
              mListener.OnItemTop(mPosition);
            }
          });
          //如果是打開狀態(tài),點(diǎn)擊其他就把當(dāng)前menu關(guān)閉掉
        } else if (mMenuState == MENU_OPEN) {
          mScroller.startScroll(mItemLayout.getScrollX(), 0, -mMaxLength, 0, 200);
          invalidate();
          mMenuState = MENU_CLOSED;
          //該點(diǎn)擊無效
          return false;
        } else {
          return false;
        }
        break;

2.ACTION_MOVE

      case MotionEvent.ACTION_MOVE:
        //計(jì)算偏移量
        int dx = mLastX - x;
        int dy = mLastY - y;
        //當(dāng)前滑動(dòng)的x
        int scrollx = mItemLayout.getScrollX();

        if (Math.abs(dx) > Math.abs(dy)) {

          isItemMoving = true;
          //超出左邊界則始終保持不動(dòng)
          if (scrollx + dx <= 0) {
            mItemLayout.scrollTo(0, 0);
            //滑動(dòng)無效
            return false;
          //超出右邊界則始終保持不動(dòng)
          } else if (scrollx + dx >= mMaxLength) {
            mItemLayout.scrollTo(mMaxLength, 0);
            //滑動(dòng)無效
            return false;
          }
          //菜單隨著手指移動(dòng)
          mItemLayout.scrollBy(dx, 0);
        //如果水平移動(dòng)距離大于30像素的話,recyclerView不會(huì)上下滑動(dòng)
        }else if (Math.abs(dx) > 30){
          return true;
        }
        //如果菜單正在打開就不能上下滑動(dòng)
        if (isItemMoving){
          mLastX = x;
          mLastY = y;
          return true;
        }
        break;

3.ACTION_UP

case MotionEvent.ACTION_UP:
        //手指抬起時(shí)判斷是否點(diǎn)擊,靜止且有Listener才能點(diǎn)擊
        if (!isItemMoving && !isDragging && mListener != null) {
          mListener.OnItemClick(mPosition);
        }
        isItemMoving = false;

        //等一下要移動(dòng)的距離
        int deltaX = 0;
        int upScrollx = mItemLayout.getScrollX();
        //滑動(dòng)距離大于1/2menu長度就自動(dòng)展開,否則就關(guān)掉
        if (upScrollx >= mMaxLength / 2) {
          deltaX = mMaxLength - upScrollx;
          mMenuState = MENU_WILL_OPEN;
        } else if (upScrollx < mMaxLength / 2) {
          deltaX = -upScrollx;
          mMenuState = MENU_WILL_CLOSED;
        }
        //知道我們?yōu)槭裁床恢苯影裮MenuState賦值為MENU_OPEN或者M(jìn)ENU_CLOSED嗎?因?yàn)榛瑒?dòng)時(shí)有時(shí)間的,我們可以在滑動(dòng)完成時(shí)才把狀態(tài)改為已經(jīng)完成
        mScroller.startScroll(upScrollx, 0, deltaX, 0, 200);
        isStartScroll = true;
        //刷新界面
        invalidate();
        break;

之后還要在onTouchEvent方法里刷新坐標(biāo)

   //只有更新mLastX,mLastY數(shù)據(jù)才會(huì)準(zhǔn)確
    mLastX = x;
    mLastY = y;
    return super.onTouchEvent(e);

因?yàn)槲覀冇玫搅藄tartScroll所以要重寫computeScroll方法

  public void computeScroll() {
    //判斷scroller是否完成滑動(dòng)
    if (mScroller.computeScrollOffset()) {
      mItemLayout.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
      //這個(gè)很重要
      invalidate();
    //如果已經(jīng)完成就改變狀態(tài)
    } else if (isStartScroll) {
      isStartScroll = false;
      if (mMenuState == MENU_WILL_CLOSED) {
        mMenuState = MENU_CLOSED;
      }
      if (mMenuState == MENU_WILL_OPEN) {
        mMenuState = MENU_OPEN;
      }
    }
  }

**還要監(jiān)聽RecyclerView是否在上下滑動(dòng)

 @Override
  public void onScrollStateChanged(int state) {
    super.onScrollStateChanged(state);
    //是否在上下滑動(dòng)
    isDragging = state == SCROLL_STATE_DRAGGING;
  }

還要設(shè)置Listener

//設(shè)置Listener
  public void setOnItemActionListener(OnItemActionListener onItemActionListener) {
    this.mListener = onItemActionListener;
  }

這個(gè)Listener是要自己新建的

public interface OnItemActionListener {
  void OnItemClick(int position);
  void OnItemTop(int position);
  void OnItemDelete(int position);
}

最后是點(diǎn)擊,置頂,刪除在Activity里的回調(diào)

這里只展示回調(diào)實(shí)現(xiàn)部分,我這里用的List是LinkedList,可以在第一位添加數(shù)據(jù)

rv.setOnItemActionListener(new OnItemActionListener() {
      //點(diǎn)擊
      @Override
      public void OnItemClick(int position) {
        Toast.makeText(MainActivity.this,"Click"+position,Toast.LENGTH_SHORT).show();
      }
      //置頂
      @Override
      public void OnItemTop(int position) {
        //獲得當(dāng)前位置的內(nèi)容
        String temp =list.get(position);
        //移除這個(gè)item
        list.remove(position);
        //把它添加到第一個(gè)
        list.addFirst(temp);
        //更新數(shù)據(jù)源
        adapter.notifyDataSetChanged();
      }
      //刪除
      @Override
      public void OnItemDelete(int position) {
        list.remove(position);
        //更新數(shù)據(jù)源
        adapter.notifyDataSetChanged();
      }
    });

Adapter和布局的代碼太簡單我就不放出來了,大家可以到源碼里看看有什么

效果圖

源碼地址:https://github.com/jkgeekJack/SlideLeftMenuRecyclerView

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android利用Palette實(shí)現(xiàn)提取圖片顏色

    Android利用Palette實(shí)現(xiàn)提取圖片顏色

    Palette是一個(gè)類似調(diào)色板的工具類,根據(jù)傳入的bitmap,提取出主體顏色,使得圖片和顏色更加搭配,界面更協(xié)調(diào)。本文將詳解如何利用Palette實(shí)現(xiàn)提取圖片顏色,需要的可以參考一下
    2022-03-03
  • Android 實(shí)現(xiàn)自定義圓形進(jìn)度條的實(shí)例代碼

    Android 實(shí)現(xiàn)自定義圓形進(jìn)度條的實(shí)例代碼

    進(jìn)度條在Android中教程使用到,本文章向大家介紹一下Android自定義圓形進(jìn)度條實(shí)現(xiàn)代碼,需要的朋友可以參考一下。
    2016-11-11
  • Android自定義組件跟隨自己手指主動(dòng)畫圓

    Android自定義組件跟隨自己手指主動(dòng)畫圓

    這篇文章主要為大家詳細(xì)介紹了Android自定義組件跟隨自己手指主動(dòng)畫圓,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Android MVP模式面向接口寫法

    Android MVP模式面向接口寫法

    這篇文章主要介紹了Android MVP模式面向接口寫法,MVP模式也出來好幾年了,很成熟所以也導(dǎo)致寫法有很多種,google提供了多種mvp模式,但我今天只講解最簡單的面向接口,需要詳細(xì)了解可以參考下文
    2023-05-05
  • 幾個(gè)Android編程時(shí)需要注意的 web 問題

    幾個(gè)Android編程時(shí)需要注意的 web 問題

    這篇文章主要介紹了幾個(gè)Android編程時(shí)需要注意的 web 問題,需要的朋友可以參考下
    2014-12-12
  • Android 圖片縮放實(shí)例詳解

    Android 圖片縮放實(shí)例詳解

    本文主要介紹Android 圖片的縮放的功能,這里簡單示例代碼和實(shí)現(xiàn)效果圖,幫助大家學(xué)習(xí)理解,有興趣的小伙伴可以參考下
    2016-09-09
  • Android 調(diào)用WCF實(shí)例詳解

    Android 調(diào)用WCF實(shí)例詳解

    這篇文章主要介紹了Android 調(diào)用WCF實(shí)例詳解的相關(guān)資料,這里提供了實(shí)例代碼及實(shí)現(xiàn)效果圖,需要的朋友可以參考下
    2016-11-11
  • 解決Android Studio突然不顯示logcat日志的問題

    解決Android Studio突然不顯示logcat日志的問題

    這篇文章主要介紹了解決Android Studio突然不顯示logcat日志的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • Android系統(tǒng)添加Linux驅(qū)動(dòng)

    Android系統(tǒng)添加Linux驅(qū)動(dòng)

    今天小編就為大家分享一篇關(guān)于Android系統(tǒng)添加Linux驅(qū)動(dòng)的文章,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • Android圖片性能優(yōu)化詳解

    Android圖片性能優(yōu)化詳解

    這篇文章給大家分享了關(guān)于Android性能優(yōu)化之圖片優(yōu)化的相關(guān)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友參考下。
    2018-07-07

最新評(píng)論