欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现QQ侧滑(删除、置顶等)功能

程序员文章站 2022-03-22 23:36:21
实现类似qq滑动出现可操作项的功能,在网上看到有人自定义linearlayout实现这个效果,但是灵活性有限。此demo使用开源项目swipelayout实现该功能。关于s...

实现类似qq滑动出现可操作项的功能,在网上看到有人自定义linearlayout实现这个效果,但是灵活性有限。此demo使用开源项目swipelayout实现该功能。关于swipelayout的常用设置和属性,这里都做介绍,下面进入正题。

一、效果图

Android实现QQ侧滑(删除、置顶等)功能

二、代码片段

主页布局和主页的java代码都和平时使用没有区别,代码没必要贴出来了。这里使用的listview演示,还可以是gridview,expandablelistview。

最关键的代码部分,listview适配器布局:

<?xml version="1.0" encoding="utf-8"?>
<com.daimajia.swipe.swipelayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:id="@+id/swipe"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 app:drag_edge="right">

 <linearlayout
  android:id="@+id/trash"
  android:layout_width="160dp"
  android:layout_height="match_parent"
  android:gravity="center"
  android:orientation="horizontal"
  android:tag="bottom">

  <textview
   android:id="@+id/swipe_open"
   android:layout_width="1dp"
   android:layout_height="match_parent"
   android:layout_weight="1"
   android:background="#f55509"
   android:gravity="center"
   android:text="打开"
   android:textcolor="@android:color/white"
   android:textsize="20sp" />

  <textview
   android:id="@+id/swipe_delete"
   android:layout_width="1dp"
   android:layout_height="match_parent"
   android:layout_weight="1"
   android:background="@android:color/holo_red_dark"
   android:gravity="center"
   android:text="删除"
   android:textcolor="@android:color/white"
   android:textsize="20sp" />

 </linearlayout>

 <linearlayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="@android:color/white"
  android:gravity="center_vertical"
  android:orientation="horizontal"
  android:padding="5dp">

  <imageview
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:src="@drawable/ic_launcher" />

  <linearlayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:background="@android:color/white"
   android:orientation="vertical"
   android:paddingleft="5dp">

   <textview
    android:id="@+id/tv_nickname"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textsize="17sp" />

   <textview
    android:id="@+id/tv_msg"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margintop="5dp"
    android:textsize="15sp" />
  </linearlayout>
 </linearlayout>
</com.daimajia.swipe.swipelayout>

说明:最外层是我们的swipelayout,里面是两个linearlayout,第一层是我们的页面布局,第二层是我们的侧边划出来的布局。关键的属性这里有体现:

app:drag_edge="right"

此属性是设置我们的侧边布局划出位置,默认是右边,可以设置左边、底部、顶部。

适配器java代码:

package com.example.mjj.swipelayoutdemo;

import android.content.context;
import android.view.view;
import android.view.viewgroup;
import android.widget.textview;
import android.widget.toast;

import com.daimajia.swipe.swipelayout;
import com.daimajia.swipe.adapters.baseswipeadapter;

import java.util.list;

/**
 * description:适配器
 * <p>
 * created by mjj on 2016/12/12.
 */

public class myswipeadapter extends baseswipeadapter implements view.onclicklistener {

 private context context;
 private list<itembean> list;
 private final string tag = "myswipeadapter";

 public myswipeadapter(context context, list<itembean> list) {
  this.context = context;
  this.list = list;
 }

 /**
  * 返回swipelayout的id
  *
  * @param position
  * @return
  */
 @override
 public int getswipelayoutresourceid(int position) {
  return r.id.swipe;
 }

 /**
  * 绑定布局
  *
  * @param position
  * @param parent
  * @return
  */
 @override
 public view generateview(int position, viewgroup parent) {
  view itemview = view.inflate(context, r.layout.item_swipe, null);
  swipelayout swipelayout = (swipelayout) itemview.findviewbyid(getswipelayoutresourceid(position));

  // 设置滑动是否可用,默认为true
  swipelayout.setswipeenabled(true);

  /**
   * 打开时调用:循环调用onstartopen,onupdate,onhandrelease,onupdate,onopen,
   * 关闭时调用:onstartclose,onupdate,onhandrelease,onhandrelease,onupdate,onclose
   */
  swipelayout.addswipelistener(new swipelayout.swipelistener() {
   @override
   public void onstartopen(swipelayout layout) {
//    log.e(tag, "onstartopen: ");
   }

   @override
   public void onopen(swipelayout layout) {
//    log.e(tag, "onopen: ");
   }

   @override
   public void onstartclose(swipelayout layout) {
//    log.e(tag, "onstartclose: ");
   }

   @override
   public void onclose(swipelayout layout) {
//    log.e(tag, "onclose: ");
   }

   @override
   public void onupdate(swipelayout layout, int leftoffset, int topoffset) {
//    log.e(tag, "onupdate: ");
   }

   @override
   public void onhandrelease(swipelayout layout, float xvel, float yvel) {
//    log.e(tag, "onhandrelease: ");
   }
  });

  // 设置为true,在当前一条item(除侧滑以外部分)点击时,可收回侧滑出来部分,默认为false
  swipelayout.setclicktoclose(true);

  // swipelayout单击事件,可替代listview的onitemclicklistener事件.
  swipelayout.setonclicklistener(new view.onclicklistener() {
   @override
   public void onclick(view view) {
//    log.e(tag, "onclick: ");
   }
  });

  return itemview;
 }

 /**
  * 绑定数据
  *
  * @param position
  * @param convertview
  */
 @override
 public void fillvalues(int position, view convertview) {
  textview tvnickname = (textview) convertview.findviewbyid(r.id.tv_nickname);
  textview tvmsg = (textview) convertview.findviewbyid(r.id.tv_msg);
  textview tvswipeopen = (textview) convertview.findviewbyid(r.id.swipe_open);
  textview tvswipedelete = (textview) convertview.findviewbyid(r.id.swipe_delete);
  tvnickname.settext(list.get(position).getnickname());
  tvmsg.settext(list.get(position).getmsg());

  tvswipedelete.setonclicklistener(this);
  tvswipeopen.setonclicklistener(this);
 }

 @override
 public int getcount() {
  return list.size();
 }

 @override
 public itembean getitem(int i) {
  return list.get(i);
 }

 @override
 public long getitemid(int i) {
  return i;
 }

 @override
 public void onclick(view view) {
  int id = view.getid();
  switch (id) {
   case r.id.swipe_open:
    // 关闭所有打开的swipe的item
    this.closeallitems();
    toast.maketext(context, "swipe--open", toast.length_short).show();
    break;
   case r.id.swipe_delete:
    this.closeallitems();
    toast.maketext(context, "swipe--delete", toast.length_short).show();
    break;
  }
 }
}

说明:和平时我们写的适配器不一样的是继承自baseswipeadapter,需要实现的方法除了图中展示的,还有一个getitemid();再没有别的。这里主要解释下几个平时没有见过的方法:

public int getswipelayoutresourceid(int position)

此方法返回的是我们的swipelayout的id,而不是布局的id。

public view generateview(int position, viewgroup parent)

此方法返回的作用是和我们的item布局进行关联的,并在这里设置swipelayout的相关属性。

public void fillvalues(int position, view convertview)

此方法用来给我们的item中的控件绑定数据,并根据需要设置事件等操作。

*三、常用设置介绍*

1、如果我们的这个适配器是重用的,而有些时候不需要滑动功能,那么可以调用此方法来控制滑动是否可用。 

swipelayout.setswipeenabled(true);

2、当我们的侧边布局还出来的时候,此时点击该条item,默认是不会收回的,也就是下面代码默认是false。

falseswipelayout.setclicktoclose(true);

3、如演示,当点击了删除或者打开后,划出来的侧边布局自动收回了,及时通过下面的属性closeallitems()方法控制的。默认是不会收回的。

this.closeallitems();

4、前面已经提到了,我们的侧滑出现的位置,如有需求是需要左边或者右边,别忘了它:

app:drag_edge="right"

*四、使用*

compile 'com.daimajia.swipelayout:library:1.2.0'

五、总结

demo已上传至github,链接放在了公众号”code小生”里,关注查看。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。