热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android自定义可编辑、删除的侧滑LisitView

这篇文章主要为大家详细介绍了Android自定义可编辑、删除的侧滑LisitView,感兴趣的小伙伴们可以参考一下

最近由于项目的需要,自定义了一个具有侧滑功能的listview,侧滑后可以点击编辑、删除。好了,大家先看一下效果图,毕竟是看脸的世界。 

好了,我要先讲一下思路,一次编辑很难完善,有什么问题我后来还会补上,欢迎各位大神拍砖:
1、首先先说一下item:item用的LinearLayout布局,删除、编辑分别是写死了宽度的TextView,左边是一个match_parent的RelativeLayout,内容自己随意搞 

2、上下滑动和左右滑动的处理:当用户手指滑动时,可以进行坐标的判断,如果Y轴移动距离大,则listview上下滑动;否则当X轴移动距离达到或者超过一个TextView的宽度时,动态控制item的marginLeft为负的两倍TextView的宽度,从而实现滑动效果 

3、编辑、删除的点击:编辑、删除在adapter中进行监听,然后自己在adapter中再定义一个监听接口,方便用户在使用listview的activity中进行监听 

下面附上item的布局文件:

<&#63;xml version="1.0" encoding="utf-8"&#63;>


 

 
  
  

  
 

 

 

 
 

 
 



Adapter代码: 

package com.lei.slidelistview;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;

/**
 * Created by 磊 on 2016/7/7.
 */
public class ListViewSlideAdapter extends BaseAdapter{

 private List bulbList;
 private Context context;
 private OnClickListenerEditOrDelete onClickListenerEditOrDelete;

 public ListViewSlideAdapter(Context context, List bulbList){
  this.bulbList=bulbList;
  this.cOntext=context;
 }

 @Override
 public int getCount() {
  return bulbList.size();
 }

 @Override
 public Object getItem(int position) {
  return bulbList.get(position);
 }

 @Override
 public long getItemId(int position) {
  return position;
 }

 @Override
 public View getView(final int position, View convertView, ViewGroup parent) {
  final String bulb=bulbList.get(position);
  View view;
  ViewHolder viewHolder;
  if(null == convertView) {
  view = View.inflate(context, R.layout.item_slide_delete_edit, null);
  viewHolder=new ViewHolder();
  viewHolder.tvName=(TextView)view.findViewById(R.id.tvName);
  viewHolder.img=(ImageView)view.findViewById(R.id.imgLamp);
  viewHolder.tvDelete=(TextView)view.findViewById(R.id.delete);
  viewHolder.tvEdit=(TextView)view.findViewById(R.id.tvEdit);
  view.setTag(viewHolder);//store up viewHolder
  }else {
  view=convertView;
  viewHolder=(ViewHolder)view.getTag();
  }

  viewHolder.img.setImageResource(R.mipmap.ic_launcher);
  viewHolder.tvName.setText(bulb);
  viewHolder.tvDelete.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
   if (onClickListenerEditOrDelete!=null){
   onClickListenerEditOrDelete.OnClickListenerDelete(position);
   }
  }
  });
  viewHolder.tvEdit.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
   if (onClickListenerEditOrDelete!=null){
   onClickListenerEditOrDelete.OnClickListenerEdit(position);
   }
  }
  });
  return view;
 }

 private class ViewHolder{
  TextView tvName,tvEdit,tvDelete;
  ImageView img;
 }

 public interface OnClickListenerEditOrDelete{
 void OnClickListenerEdit(int position);
 void OnClickListenerDelete(int position);
 }

 public void setOnClickListenerEditOrDelete(OnClickListenerEditOrDelete onClickListenerEditOrDelete1){
 this.OnClickListenerEditOrDelete=onClickListenerEditOrDelete1;
 }

 }

  

自定义ListView文件代码:

package com.lei.slidelistview;

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.ListView;

public class SlideListView extends ListView {
 private int mScreenWidth; // 屏幕宽度
 private int mDownX; // 按下点的x值
 private int mDownY; // 按下点的y值
 private int mDeleteBtnWidth;// 删除按钮的宽度
 
 private boolean isDeleteShown; // 删除按钮是否正在显示
 
 private ViewGroup mPointChild; // 当前处理的item
 private LinearLayout.LayoutParams mLayoutParams; // 当前处理的item的LayoutParams
 
 public SlideListView(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }

 public SlideListView(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 
 // 获取屏幕宽度
 WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
 DisplayMetrics dm = new DisplayMetrics();
 wm.getDefaultDisplay().getMetrics(dm);
 mScreenWidth = dm.widthPixels;
 }
 
 @Override
 public boolean onTouchEvent(MotionEvent ev) {
 switch (ev.getAction()) {
 case MotionEvent.ACTION_DOWN:
 performActionDown(ev);
 break;
 case MotionEvent.ACTION_MOVE:
 return performActionMove(ev);
 case MotionEvent.ACTION_UP:
 performActionUp();
 break;
 }
 
 return super.onTouchEvent(ev);
 }

 // 处理action_down事件
 private void performActionDown(MotionEvent ev) {
 if(isDeleteShown) {
 turnToNormal();
 }
 
 mDownX = (int) ev.getX();
 mDownY = (int) ev.getY();
 // 获取当前点的item
 mPointChild = (ViewGroup) getChildAt(pointToPosition(mDownX, mDownY)
 - getFirstVisiblePosition());
 // 获取删除按钮的宽度
 mDeleteBtnWidth = mPointChild.getChildAt(1).getLayoutParams().width;
 mLayoutParams = (LinearLayout.LayoutParams) mPointChild.getChildAt(0)
 .getLayoutParams();
 mLayoutParams.width = mScreenWidth;
 mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
 }
 
 // 处理action_move事件
 private boolean performActionMove(MotionEvent ev) {
 int nowX = (int) ev.getX();
 int nowY = (int) ev.getY();
 if(Math.abs(nowX - mDownX) > Math.abs(nowY - mDownY)) {
 // 如果向左滑动
 if(nowX = mDeleteBtnWidth) {
 scroll = -mDeleteBtnWidth;
 }
 // 重新设置leftMargin
 mLayoutParams.leftMargin = scroll*2;
 mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
 }
 return true;
 }
 return super.onTouchEvent(ev);
 }
 
 // 处理action_up事件
 private void performActionUp() {
 // 偏移量大于button的一半,则显示button
 // 否则恢复默认
 if(-mLayoutParams.leftMargin >= mDeleteBtnWidth / 2) {
 mLayoutParams.leftMargin = -mDeleteBtnWidth*2;
 isDeleteShown = true;
 }else {
 turnToNormal();
 }
 
 mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
 }
 /**
 * 变为正常状态
 */
 public void turnToNormal() {
 mLayoutParams.leftMargin = 0;
 mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
 isDeleteShown = false;
 }
 /**
 * 当前是否可点击
 * @return 是否可点击
 */
 public boolean canClick() {
 return !isDeleteShown;
 }


}

下面附上使用布局代码+使用后台代码(2016年7月7日亲测可用)
布局: 

<&#63;xml version="1.0" encoding="utf-8"&#63;>


 

 

 


使用后台代码,这里要注意以下adapter设置监听的位置,放错了会报错哦 

package com.lei.slidelistview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
 private SlideListView listView;
 private List list=new ArrayList();
 private ListViewSlideAdapter listViewSlideAdapter;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 getData();
 initView();
 }

 private void initView(){
 listView=(SlideListView)findViewById(R.id.list);
 listViewSlideAdapter=new ListViewSlideAdapter(this,list);
 listView.setAdapter(listViewSlideAdapter);
 listViewSlideAdapter.setOnClickListenerEditOrDelete(new ListViewSlideAdapter.OnClickListenerEditOrDelete() {
  @Override
  public void OnClickListenerEdit(int position) {
  Toast.makeText(MainActivity.this, "edit position: " + position, Toast.LENGTH_SHORT).show();
  }

  @Override
  public void OnClickListenerDelete(int position) {
  Toast.makeText(MainActivity.this, "delete position: " + position, Toast.LENGTH_SHORT).show();
  }
 });
 }

 private void getData(){
 for (int i=0;i<20;i++){
  list.add(new String("第"+i+"个item"));
 }
 }
}

更多学习内容,可以点击《Android侧滑效果汇总》学习。

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


推荐阅读
  • 一个建表一个执行crud操作建表代码importandroid.content.Context;importandroid.database.sqlite.SQLiteDat ... [详细]
  • 华为捐赠欧拉操作系统,承诺不推商用版
    华为近日宣布将欧拉开源操作系统捐赠给开放原子开源基金会,并承诺不会推出欧拉的商用发行版。此举旨在推动欧拉和鸿蒙操作系统的全场景融合与生态发展。 ... [详细]
  • Python多线程详解与示例
    本文介绍了Python中的多线程编程,包括僵尸进程和孤儿进程的概念,并提供了具体的代码示例。同时,详细解释了0号进程和1号进程在系统中的作用。 ... [详细]
  • 本文将介绍如何在混合开发(Hybrid)应用中实现Native与HTML5的交互,包括基本概念、学习目标以及具体的实现步骤。 ... [详细]
  • 本文详细介绍了Linux系统中用于管理IPC(Inter-Process Communication)资源的两个重要命令:ipcs和ipcrm。通过这些命令,用户可以查看和删除系统中的消息队列、共享内存和信号量。 ... [详细]
  • 一、Tomcat安装后本身提供了一个server,端口配置默认是8080,对应目录为:..\Tomcat8.0\webapps二、Tomcat8.0配置多个端口,其实也就是给T ... [详细]
  • A*算法在AI路径规划中的应用
    路径规划算法用于在地图上找到从起点到终点的最佳路径,特别是在存在障碍物的情况下。A*算法是一种高效且广泛使用的路径规划算法,适用于静态和动态环境。 ... [详细]
  • NX二次开发:UFUN点收集器UF_UI_select_point_collection详解
    本文介绍了如何在NX中使用UFUN库进行点收集器的二次开发,包括必要的头文件包含、初始化和选择点集合的具体实现。 ... [详细]
  • 解决SQL Server数据库sa登录名无法连接的问题
    在安装SQL Server数据库后,使用Windows身份验证成功,但使用SQL Server身份验证时遇到问题。本文将介绍如何通过设置sa登录名的密码、启用登录名状态以及开启TCP协议来解决这一问题。 ... [详细]
  • MySQL 数据库连接方法
    本文介绍了如何使用 MySQL 命令行工具连接到指定的数据库。 ... [详细]
  • 在 Mac 上配置 NDK
    本文详细介绍了如何在 Mac 上配置 Android NDK,包括设置环境变量和解决常见问题的方法。 ... [详细]
  • 如何解决8080端口被占用问题
    本文介绍了如何通过命令行和任务管理器查找并终止占用8080端口的进程,以确保该端口能够正常使用。 ... [详细]
  • Excel 数据分析基础
    Excel 是数据分析中最基本且强大的工具之一,具备多种实用功能和操作方法。本文将简要介绍 Excel 的不同版本及其兼容性问题,并探讨在处理大数据时的替代方案。 ... [详细]
  • 本文介绍了如何在 ASP.NET 中设置 Excel 单元格格式为文本,获取多个单元格区域并作为表头,以及进行单元格合并、赋值、格式设置等操作。 ... [详细]
  • LDAP服务器配置与管理
    本文介绍如何通过安装和配置SSSD服务来统一管理用户账户信息,并实现其他系统的登录调用。通过图形化交互界面配置LDAP服务器,确保用户账户信息的集中管理和安全访问。 ... [详细]
author-avatar
手机用户2502895987
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有