Android 高级UI设计笔记03:使用ListView实现左右滑动删除Item
1. 这里就是实现一个很简单的功能,使用ListView实现左右滑动删除Item:
(1)当我们在ListView的某个Item,向左滑动显示一个删除按钮,用户点击按钮,即可以删除该项item,并且有一个简单动画。
(2)然后向右滑动时候,可以撤销删除。
2. 下面是是完整的思维过程:
Android工程结构如下:
(1)首先我们先来到主布局文件main.xml,如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" > <ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView> </RelativeLayout>
(2)上面使用到ListView,自然需要选用Adapter,自定义适配器ListViewAdapter,如下:
package com.himi.listviewdeleteitem; import java.util.ArrayList; import android.content.Context;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView; public class ListViewAdpter extends BaseAdapter {
public ArrayList<String> data; // 数据源
private Context context;
private float downX; // 点下时候获取的x坐标
private float upX; // 手指离开时候的x坐标
private Button button; // 用于执行删除的button
private Animation animation; // 删除时候的动画
private View view; public ListViewAdpter(ArrayList<String> data, Context context) {
this.data = data;
this.context = context;
animation = AnimationUtils.loadAnimation(context, R.anim.push_out); // 用xml获取一个动画
} @Override
public int getCount() {
return data.size();
} @Override
public Object getItem(int arg0) {
return data.get(arg0);
} @Override
public long getItemId(int arg0) {
return arg0;
} @Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.list_item,
null);
holder = new ViewHolder();
holder.textView = (TextView) convertView.findViewById(R.id.text);
holder.button=(Button) convertView.findViewById(R.id.bt);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
convertView.setOnTouchListener(new OnTouchListener() { // 为每个item设置setOnTouchListener事件 @Override
public boolean onTouch(View v, MotionEvent event) {
final ViewHolder holder = (ViewHolder) v.getTag(); // 获取滑动时候相应的ViewHolder,以便获取button按钮
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: // 手指按下
downX = event.getX(); // 获取手指x坐标
if (button != null) {
button.setVisibility(View.GONE); // 隐藏显示出来的button
}
break;
case MotionEvent.ACTION_UP: // 手指离开
upX = event.getX(); // 获取x坐标值
break;
} if (holder.button != null) {
if (Math.abs(downX - upX) > 80 && (upX < downX)) { //向左滑动,删除item
holder.button.setVisibility(View.VISIBLE); // 显示删除button
button = holder.button; // 赋值给全局button,一会儿用
view = v; // 得到itemview,在上面加动画
return true; // 终止事件
} if(Math.abs(downX - upX) > 80 && (upX > downX)) {//撤销删除操作
if(holder.button.getVisibility() == View.VISIBLE) {//此时Button可见
holder.button.setVisibility(View.GONE);
}
return true; // 终止事件
} return false; // 释放事件,使onitemClick可以执行
}
return false;
} }); holder.button.setOnClickListener(new OnClickListener() { // 为button绑定事件 @Override
public void onClick(View v) { if (button != null) {
button.setVisibility(View.GONE); // 点击删除按钮后,影藏按钮
deleteItem(view, position); // 删除数据,加动画
} }
});
holder.textView.setText(data.get(position)); // 显示数据
return convertView;
} public void deleteItem(View view, final int position) {
view.startAnimation(animation); // 给view设置动画
animation.setAnimationListener(new AnimationListener() { @Override
public void onAnimationStart(Animation animation) {
} @Override
public void onAnimationRepeat(Animation animation) {
} @Override
public void onAnimationEnd(Animation animation) { // 动画执行完毕
data.remove(position); // 把数据源里面相应数据删除
notifyDataSetChanged(); }
}); } static class ViewHolder {
TextView textView; // 显示数据的view
Button button; // 删除按钮
} }
上面引用到一个动画为res/anim/push_out.xml,如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" > <translate
android:duration="1000"
android:fromXDelta="0"
android:toXDelta="100%p" /> </set>
(3)接下来我们来到item的布局list_item.xml,如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants"
> <TextView
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="50dp"
android:gravity="center"
android:text="默认" /> <Button
android:id="@+id/bt"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="删除"
android:visibility="gone" /> </LinearLayout>
这里布局稍微注意一点:当我们向左滑动item的时候,显示删除按钮,这个时候我们希望整个item内容相应向左移动,给用户一个删除按钮出现的感觉。
所以这里我们设置TextView的width属性为match_parent,同时weight属性为1,目的是让TextView占据所有剩余空间。
这里我们还设置了Button的height属性也为50dp,和上面TextView文字一样高,用户视觉感觉好一点,width属性为实际内容大小。
当我们向左滑动的时候,删除Button出现了,它会占据TextView显示的空间(TextView是占据所有剩余空间),这样很自然地TextView的内容就会相应地向左显示。
(4)接下来比较简单了,来到MainActivity,如下:
package com.himi.listviewdeleteitem; import java.util.ArrayList; import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast; public class MainActivity extends Activity {
private ListView listView; //listview控件
private ArrayList<String> contentStrings = new ArrayList<String>(); //数据源
private ListViewAdpter adapter; //适配器
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list);
initData(); //初始化数据
setListener(); //绑定事件
}
private void initData() {
contentStrings.add("Item 1");
contentStrings.add("Item 2");
contentStrings.add("Item 3");
contentStrings.add("Item 4");
contentStrings.add("Item 5");
contentStrings.add("Item 6");
contentStrings.add("Item 7");
contentStrings.add("Item 8");
contentStrings.add("Item 9");
contentStrings.add("Item 10");
contentStrings.add("Item 11");
contentStrings.add("Item 12");
contentStrings.add("Item 13");
contentStrings.add("Item 14");
contentStrings.add("Item 15"); adapter=new ListViewAdpter(contentStrings, this);
listView.setAdapter(adapter);
} private void setListener() { listView.setOnItemClickListener(new OnItemClickListener() { //点击每项item时候执行
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(MainActivity.this, "点击事件,执行你的操作", Toast.LENGTH_SHORT).show();
}
}); } }
(5)部署程序到手机上,如下:
Android 高级UI设计笔记03:使用ListView实现左右滑动删除Item的更多相关文章
- Android 高级UI设计笔记07:RecyclerView 的详解
1. 使用RecyclerView 在 Android 应用程序中列表是一个非常重要的控件,适用场合非常多,如新闻列表.应用列表.消息列表等等,但是从Android 一出生到现在并没有非常 ...
- Android 高级UI设计笔记20:RecyclerView 的详解之RecyclerView添加Item点击事件
1. 引言: RecyclerView侧重的是布局的灵活性,虽说可以替代ListView但是连基本的点击事件都没有,这篇文章就来详细讲解如何为RecyclerView的item添加点击事件,顺便复习一 ...
- Android 高级UI设计笔记01:使用ExpandableListView组件(ListView的扩展)
1.ExpandableListView是一个用来显示二级节点的ListView. 比如如下效果的界面: 2.使用ExpandableListView步骤 (1)要给ExpandableListVie ...
- Android 高级UI设计笔记06:仿微信图片选择器(转载)
仿微信图片选择器: 一.项目整体分析: 1. Android加载图片的3个目标: (1)尽可能的去避免内存溢出. a. 根据图片的显示大小去压缩图片 b. 使用缓存对我们图片进行管理(LruCache ...
- Android 高级UI设计笔记09:Android如何实现无限滚动列表
ListView和GridView已经成为原生的Android应用实现中两个最流行的设计模式.目前,这些模式被大量的开发者使用,主要是因为他们是简单而直接的实现,同时他们提供了一个良好,整洁的用户体验 ...
- Android 高级UI设计笔记08:Android开发者常用的7款Android UI组件(转载)
Android开发是目前最热门的移动开发技术之一,随着开发者的不断努力和Android社区的进步,Android开发技术已经日趋成熟,当然,在Android开源社区中也涌现了很多不错的开源UI项目,它 ...
- Android 高级UI设计笔记09:Android实现无限滚动列表
1. 无限滚动列表应用场景: ListView和GridView已经成为原生的Android应用实现中两个最流行的设计模式.目前,这些模式被大量的开发者使用,主要是因为他们是简单而直接的实现,同时他们 ...
- Android 高级UI设计笔记21:Android SegmentView(分段选择控件)
1. 分段控制(SegmentView) 首先我们先看看什么是SegmentView的效果,如下: 分段控制这个View控件是ios7的分段控制,和QQ消息页面顶部的效果一样,android没有这个控 ...
- Android 高级UI设计笔记19:PopupWindow使用详解
1. PopupWindow使用 PopupWindow这个类用来实现一个弹出框,可以使用任意布局的View作为其内容,这个弹出框是悬浮在当前activity之上的. 2. PopupWindow使用 ...
随机推荐
- C++中的重载,隐藏,覆盖,虚函数,多态浅析
直到今日,才发现自己对重载的认识长时间以来都是错误的.幸亏现在得以纠正,真的是恐怖万分,雷人至极.一直以来,我认为重载可以发生在基类和派生类之间,例如: class A { public: void ...
- Type datetime2 is not a defined system type - Entity Framework 摘自网络
"Type datetime2 is not a defined system type" Solution: 把edmx 改为 ProviderManifestToken=&qu ...
- crontab 定时任务格式
如下内容节选自<Linux Crontab 定时任务 命令详解> 用crontab -e 添加要执行的命令 添加的命令必须以如下格式: * * * * * /command path 前五 ...
- 在Delphi7中JSON遍历节点不支持使用IN处理方法
相关资料:http://www.cnblogs.com/del/archive/2009/10/23/1588690.html Delphi2007源代码: procedure TForm1.Butt ...
- 关于Aazure 使用以前保留的vhd创建虚拟机的基本步骤
1. 删除vm保留vhd(只删除虚拟机记录,不删除磁盘)2. 拷贝vhd以及status文件到指定的存储账号3. 使用拷贝的VHD创建disk4. 从disk创建vm,指定指定vnet以及cloud ...
- python 循环
200 ? "200px" : this.width)!important;} --> 介绍 python中有两种循环,分别是for...in循环.while循环:for.. ...
- oracle中的数据读取与查找
数据读取 首先数据块读入到Buffer Cache中,并将其放在LRU(Last Recently Used)链表的MRU(Most Recently Used)端,当需要再次访问该块时可以直接从bu ...
- SqlServer更新视图存储过程函数脚本
--视图.存储过程.函数名称 DECLARE @NAME NVARCHAR(255); --局部游标 DECLARE @CUR CURSOR --自动修改未上状态为旷课 SET @CUR=CURSOR ...
- JSF教程(10)——生命周期之Update Model Values Phase
在整个JSF生命周期中经历了取值.验证的阶段终于从request中拿到合理的值,以下就是在本阶段给相应的服务端对象(ManageBean)赋值了.JSF实现仅仅是去更新和input组件中value属性 ...
- Codeforces Round #331 (Div. 2) E. Wilbur and Strings dfs乱搞
E. Wilbur and Strings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/596 ...