当前位置:首页 » 安卓系统 » android滑动删除

android滑动删除

发布时间: 2023-03-01 20:02:20

A. Android开发一个简单实用的闹铃APP

生活中我们会常常遇到需要闹钟提醒;不管是起床还是生活中的事件提醒。

那作为Android开发如何自己开发一个闹钟功能呢,是不是觉得很酷呢?接下来我们就实战一个闹钟。





本示例采用的是RecyclerView,其适配器类与常无二,其异在于继承一个代理类,为适配之后侧滑删除而准备

建立一个内部类ViewHolder实现控件定义申明

实现onCreateViewHolder方法载入子项布局文件

绑定实体类,实现onBindViewHolder获取数据

此处有三处状态,第一种状态:第一次进入程序,默认加载固定闹钟子项;第二种状态:进入添加子项页面,然后返回其主页面,并判断其switch是否为ture,如果为ture则添加子项;第三种状态:程序被系统回收或者用户停止程序,并再次进入程序,防止加载前一时刻闹钟子项;

添加依赖 实现侧滑主要依赖于一个第三方包,然后使用RecyclerView进行子项绑定 依赖如下:

并在目录build.gradle包下添加如下库

其实现侧滑删除主要的玄机在于布局文件当中,使用RelativeLayout布局,将删除按钮固定在布局右方,并使用其他布局将其覆盖,只有滑动时,才将其显示。掩盖侧滑删除按钮与暴露侧滑删除按钮效果对比图如下





然后,在适配器类中,实现WeSwipeHelper.SwipeLayoutTypeCallBack接口,实现如下三个方法,第一个方法为获取侧滑删除按钮的宽度;第二个方法为需要滑动的视图,也就是覆盖侧滑删除按钮的布局;第三个方法为当视图正在滑动时,用户触发单击事件,自动还原滑动状态

最后,在需要添加子项的视图中绑定RecyclerView即可

通过监听子项滑动删除按钮点击事件,实现子项删除

跳转新增闹钟子项Acticity需要传输实体类对象,传输对象一般需要序列化改类,其操作如下

定义实体类,并实现序列化

然后通过Intent传输Bundle对象

实现时间选择主要使用系统集成的组件TimePicker,其使用方法如下 其有两种显示方式,第一种为spinner,就是下拉滑动式,第二种为clock,即显示一个时钟,通过滑动指针选择时间

在style.xml文件中申明如下样式

然后再指定Activcty申明即可

获取数据比较简单,实现对应接口即可

将获取的数据通过SharedPreferences存储起来,然后点击存储时,进行页面跳转,然后再该界面进行取出数据

存储数据

首先判断回调的switch数据是否为ture,如果为ture则保存该子项,然后再适配器类中进行数据添加

选中与默认两种状态效果图如下




创建thumb和track样式

创建一个选择器文件,有选中和默认两种状态

创新open_thumb.xml文件

创建shut_thumb.xml文件

同样创建一个选择器,并用于两种状态

其中AlarmManager为系统主要操作类,参数为提醒模式、提醒时间(long型)、PendingIntent对象 以下有三种时间传入,第一种,直接传入一个Long型时间用于测试,第二种,通过设置系统启动至今而设置时间,第三种,通过取出设置的时间,然后获取系统当前时间,将其差传入其中。

然后再清单文件中注册服务

使用Intent实现服务启动

杀死程序

本示例总共使用到了三个单例类:SP(SharedPreferences封装)、TimeFormat(时间数据格式封装)、KillProcess(杀死所有Activity)

SharedPreferences

KillProcess

文章带这里就完成了一个简单的闹钟;Android开发还有许多更加更多的知识学习。进一步学习Android技术,我这里推荐这份笔记方便学习,我就放在私信, 发送“核心笔记”或“手册”即可获取。朋友们可以免费领取!

B. android 如何实现边缘拖动侧滑

据需求需要自己自定义一个ListView来实现该功能,接下来先贴出代码再讲解具体的实现

package com.example.slidecutlistview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Scroller;

/**
* @blog http://blog.csdn.net/xiaanming
*
* @author xiaanming
*
*/
public class SlideCutListView extends ListView {
/**
* 当前滑动的ListViewposition
*/
private int slidePosition;
/**
* 手指按下X的坐标
*/
private int downY;
/**
* 手指按下Y的坐标
*/
private int downX;
/**
* 屏幕宽度
*/
private int screenWidth;
/**
* ListView的item
*/
private View itemView;
/**
* 滑动类
*/
private Scroller scroller;
private static final int SNAP_VELOCITY = 600;
/**
* 速度追踪对象
*/
private VelocityTracker velocityTracker;
/**
* 是否响应滑动,默认为不响应
*/
private boolean isSlide = false;
/**
* 认为是用户滑动的最小距离
*/
private int mTouchSlop;
/**
* 移除item后的回调接口
*/
private RemoveListener mRemoveListener;
/**
* 用来指示item滑出屏幕的方向,向左或者向右,用一个枚举值来标记
*/
private RemoveDirection removeDirection;

// 滑动删除方向的枚举值
public enum RemoveDirection {
RIGHT, LEFT;
}

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

public SlideCutListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public SlideCutListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
screenWidth = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();
scroller = new Scroller(context);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}

/**
* 设置滑动删除的回调接口
* @param removeListener
*/
public void setRemoveListener(RemoveListener removeListener) {
this.mRemoveListener = removeListener;
}

/**
* 分发事件,主要做的是判断点击的是那个item, 以及通过postDelayed来设置响应左右滑动事件
*/
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
addVelocityTracker(event);

// 假如scroller滚动还没有结束,我们直接返回
if (!scroller.isFinished()) {
return super.dispatchTouchEvent(event);
}
downX = (int) event.getX();
downY = (int) event.getY();

slidePosition = pointToPosition(downX, downY);

// 无效的position, 不做任何处理
if (slidePosition == AdapterView.INVALID_POSITION) {
return super.dispatchTouchEvent(event);
}

// 获取我们点击的item view
itemView = getChildAt(slidePosition - getFirstVisiblePosition());
break;
}
case MotionEvent.ACTION_MOVE: {
if (Math.abs(getScrollVelocity()) > SNAP_VELOCITY
|| (Math.abs(event.getX() - downX) > mTouchSlop && Math
.abs(event.getY() - downY) < mTouchSlop)) {
isSlide = true;
}
break;
}
case MotionEvent.ACTION_UP:
recycleVelocityTracker();
break;
}

return super.dispatchTouchEvent(event);
}

/**
* 往右滑动,getScrollX()返回的是左边缘的距离,就是以View左边缘为原点到开始滑动的距离,所以向右边滑动为负值
*/
private void scrollRight() {
removeDirection = RemoveDirection.RIGHT;
final int delta = (screenWidth + itemView.getScrollX());
// 调用startScroll方法来设置一些滚动的参数,我们在computeScroll()方法中调用scrollTo来滚动item
scroller.startScroll(itemView.getScrollX(), 0, -delta, 0,
Math.abs(delta));
postInvalidate(); // 刷新itemView
}

/**
* 向左滑动,根据上面我们知道向左滑动为正值
*/
private void scrollLeft() {
removeDirection = RemoveDirection.LEFT;
final int delta = (screenWidth - itemView.getScrollX());
// 调用startScroll方法来设置一些滚动的参数,我们在computeScroll()方法中调用scrollTo来滚动item
scroller.startScroll(itemView.getScrollX(), 0, delta, 0,
Math.abs(delta));
postInvalidate(); // 刷新itemView
}

/**
* 根据手指滚动itemView的距离来判断是滚动到开始位置还是向左或者向右滚动
*/
private void scrollByDistanceX() {
// 如果向左滚动的距离大于屏幕的三分之一,就让其删除
if (itemView.getScrollX() >= screenWidth / 3) {
scrollLeft();
} else if (itemView.getScrollX() <= -screenWidth / 3) {
scrollRight();
} else {
// 滚回到原始位置,为了偷下懒这里是直接调用scrollTo滚动
itemView.scrollTo(0, 0);
}

}

/**
* 处理我们拖动ListView item的逻辑
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (isSlide && slidePosition != AdapterView.INVALID_POSITION) {
addVelocityTracker(ev);
final int action = ev.getAction();
int x = (int) ev.getX();
switch (action) {
case MotionEvent.ACTION_MOVE:
int deltaX = downX - x;
downX = x;

// 手指拖动itemView滚动, deltaX大于0向左滚动,小于0向右滚
itemView.scrollBy(deltaX, 0);
break;
case MotionEvent.ACTION_UP:
int velocityX = getScrollVelocity();
if (velocityX > SNAP_VELOCITY) {
scrollRight();
} else if (velocityX < -SNAP_VELOCITY) {
scrollLeft();
} else {
scrollByDistanceX();
}

recycleVelocityTracker();
// 手指离开的时候就不响应左右滚动
isSlide = false;
break;
}

return true; // 拖动的时候ListView不滚动
}

//否则直接交给ListView来处理onTouchEvent事件
return super.onTouchEvent(ev);
}

@Override
public void computeScroll() {
// 调用startScroll的时候scroller.computeScrollOffset()返回true,
if (scroller.computeScrollOffset()) {
// 让ListView item根据当前的滚动偏移量进行滚动
itemView.scrollTo(scroller.getCurrX(), scroller.getCurrY());

postInvalidate();

// 滚动动画结束的时候调用回调接口
if (scroller.isFinished()) {
if (mRemoveListener == null) {
throw new NullPointerException(RemoveListener is null, we should called setRemoveListener());
}

itemView.scrollTo(0, 0);
mRemoveListener.removeItem(removeDirection, slidePosition);
}
}
}

/**
* 添加用户的速度跟踪器
*
* @param event
*/
private void addVelocityTracker(MotionEvent event) {
if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain();
}

velocityTracker.addMovement(event);
}

/**
* 移除用户速度跟踪器
*/
private void recycleVelocityTracker() {
if (velocityTracker != null) {
velocityTracker.recycle();
velocityTracker = null;
}
}

/**
* 获取X方向的滑动速度,大于0向右滑动,反之向左
*
* @return
*/
private int getScrollVelocity() {
velocityTracker.computeCurrentVelocity(1000);
int velocity = (int) velocityTracker.getXVelocity();
return velocity;
}

/**
*
* 当ListView item滑出屏幕,回调这个接口
* 我们需要在回调方法removeItem()中移除该Item,然后刷新ListView
*
* @author xiaanming
*
*/
public interface RemoveListener {
public void removeItem(RemoveDirection direction, int position);
}

}

C. 为什么 Android 的应用上较少左(右)划删除,大多是长按删除

Android 应用少采用向左向右滑动删除,大多数为长按删除的原因如下:

  1. 向左向右滑动,需要给每个listview的item单独的加上很多代码来控制显示和隐藏文字,更容易出现bug。

  2. 长按删除这一操作,是从android系统推出以来就有的功能,便于用户操作,积累了操作习惯。

Android点击事件分为点击事件和长按事件,两个事件可以单独进行相应的,底层就是识别接触点,回调执行相应的业务逻辑。

D. 安卓手机比iPhone好在哪些地方呢

现如今,许多人在手机的选择上已经从iPhone逐渐转移到安卓,若放在几年前,这绝对是令人震惊的消息,其实主要是因为近年来安卓对手机的优化也越来越好了,那么安卓手机比苹果好在哪些地方呢?

1. 屏幕锁定通知

Iphone12在屏幕底部有一个白色的条形图标。 然而,在玩游戏时,这个白色条不能自动隐藏。 每次看到这个白色的条形物,我都觉得不舒服。 网上似乎有个教程可以把这个隐藏起来,但我还没试过。 当我每次玩游戏时,我仍然认为android更好。

4. 文档管理

IPHONE12的文件管理真的很糟糕。 首先,你在手机浏览器中下载的图片不会保存在你的手机中。 相册,文件,icloud无处可寻。 如果你想保存到你的相册,你还需要打开共享-保存图像,这样你就可以在你的相册中看到它们。 不仅如此,Iphone的文件管理应用程序非常难使用。 难道我不能在手机上看到任何文件吗? 为什么这么多文件我看不见? 还有一个文件在iPhone里无法修改后缀名,想必你应该有网上的朋友把下载的TXT格式手动解压成zip格式的经验,在iPhone里做不到。 文件管理编辑器仍然喜欢Android可以控制一切的感觉。

5. 文件传输

IPhone不支持直接数据线连接电脑传输文件,你需要下载一个软件叫做iTunes,但是这个软件是非常耐用,各种各样的网络就学会了如何传输文件,和只能转移的指定格式文件,不能被转移许多格式不支持, 而且传播的速度非常慢。 更糟糕的是,iphone12只提供了一个照明到C线。 为了传输数据,你必须买一根usb的连接线,因为并不是所有的电脑都有C端口。

6. 无法设置动态墙纸

你可以在Android手机上设置动态壁纸,这在iPhone 12上是做不到的,因为iPhone不支持它。 它只有一个动态壁纸,当你按住它一段时间后,它会移动,而且仅限于锁屏壁纸。

E. Android的listview的点击和滑动效果冲突了

ViewDragHelper.Callback做滑动效果,你是不是在这里屏蔽了onTouch

如果这里重写了onTouch 你要在onTouch里返回false这样,事件才能继续传递

还有,你想实现listView item的动画,或者滑动删除,左右滑动操作的话,建议你直接用开源框架

我这里给你上传一份,关于listView的各种动画,各种控件,你可以直接用这些源代码了

热点内容
linuxcftp服务器 发布:2025-05-14 23:58:18 浏览:716
探岳什么配置才有驾驶模式选择 发布:2025-05-14 23:53:17 浏览:143
如何在手机上看无限流量密码 发布:2025-05-14 23:43:31 浏览:114
19投篮脚本 发布:2025-05-14 23:36:57 浏览:513
编译器怎么处理c变长数组 发布:2025-05-14 23:31:46 浏览:663
存折每天可以输错多少次密码 发布:2025-05-14 23:22:06 浏览:909
安卓手机怎么找微信隐藏对话 发布:2025-05-14 23:07:47 浏览:338
怎么查看泰拉服务器ip 发布:2025-05-14 23:03:29 浏览:74
c语言学生成绩查询系统 发布:2025-05-14 22:58:30 浏览:6
怎么进别人的服务器 发布:2025-05-14 22:45:55 浏览:774