看到别人实现SwipeListView,说的不清楚,好多细节要注意,作为菜鸟的我,也是拿来主义。
在 github有这个开源项目https://github.com/47deg/android-swipelistview
好了,我整理好了这些,也不必大家去github下载。点击此处下载必要源码。
空说无意,先看一下效果图。
one,先建立一个工程demo,
two,另外再建立一个包,取名为com.fortysevendeg.swipelistview
为什么取这个名,下面再讲
three,把我上传的文件中的四个Java文件复制到名为com.fortysevendeg.swipelistview的包中
会发现四个Java的顶部是package com.fortysevendeg.swipelistview;为了不必要的麻烦这样去步奏2的包名。
four,把我上传的文件中的swipelistview__attrs.xml复制到res/values文件夹在
其中要添加
xmlns:swipe="http://schemas.android.com/apk/res-auto"
必需要添加,自定义的SwipeListView因为添加了,可定义属性要添加这一句
<com.fortysevendeg.swipelistview.SwipeListView
xmlns:swipe="http://schemas.android.com/apk/res-auto"
android:id="@+id/example_lv_list"
android:listSelector="#00000000"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
swipe:swipeFrontView="@+id/front"
swipe:swipeBackView="@+id/back"
swipe:swipeActionLeft="[reveal | dismiss]"
swipe:swipeActionRight="[reveal | dismiss]"
swipe:swipeMode="[none | both | right | left]"
swipe:swipeCloseAllItemsWhenMoveList="[true | false]"
swipe:swipeOpenOnLongPress="[true | false]"
swipe:swipeAnimationTime="[miliseconds]"
swipe:swipeOffsetLeft="[dimension]"
swipe:swipeOffsetRight="[dimension]"
/>
基本属性如下:
swipeFrontView
- Required - front view id. 即ListView Item正常显示的控件Id,且必须与Item的布局文件中的控件id一样swipeBackView
- Required - back view id. 手指滑动时显示的,隐藏在FrontView后面,且必须与item的布局文件中控件Id一样swipeActionLeft
- Optional - left swipe action Default: 'reveal' 左滑的动作,默认reveal,即显示BackView,还有dismiss,choice会触发响应的方法。swipeActionRight
- Optional - right swipe action Default: 'reveal' 同上swipeMode
- Gestures to enable or 'none'. Default: 'both' 设置左滑、右滑、都支持swipeCloseAllItemsWhenMoveList
- Close revealed items on list motion. Default: 'true' 当滚动listview时,关闭所有展开的Item,最好不要设置为false,由于item的复用,false存在一些问题。swipeOpenOnLongPress
- Reveal on long press Default: 'true' 长按时触发显示swipeAnimationTime
- item drop animation time. Default: android configuration 动画时间长度swipeOffsetLeft
- left offset 左偏移量swipeOffsetRight
- right offset 右偏移量
activity_main.xml
记得加上这句:xmlns:swipe="http://schemas.android.com/apk/res-auto"
<span style="font-size:14px;"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swipe="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.demo.swipelistviewdemo.MainActivity" >
<com.fortysevendeg.swipelistview.SwipeListView
android:id="@+id/example_lv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:listSelector="#00000000"
swipeActionLeft="reveal"
swipe:swipeAnimationTime="0"
swipe:swipeBackView="@+id/back"
swipe:swipeCloseAllItemsWhenMoveList="true"
swipe:swipeFrontView="@+id/front"
swipe:swipeMode="left"
swipe:swipeOffsetLeft="0dp"
swipe:swipeOffsetRight="0dp"
swipe:swipeOpenOnLongPress="false"/>
</RelativeLayout></span>
要注意两个属性
swipe:swipeFrontView="@+id/front"
swipe:swipeBackView="@+id/back"
必须与Item的布局文件中的控件id一样
swipeActionLeft要最好swipeMode=“left”,属性要一致,否则,很容易有bug;
list_item.xml布局
注意前台布局,和隐藏布局的id要与swipe:swipeFrontView="@+id/front"和swipe:swipeBackView="@+id/back"
一致。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- linearlayout中的布局是每一项后面隐藏的布局 -->
<LinearLayout
android:id="@+id/back"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#eee"
android:tag="back" >
<Button
android:id="@+id/example_row_b_action_2"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:background="@android:color/holo_purple"
android:text="删除" />
<Button
android:id="@+id/example_row_b_action_3"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:layout_weight="1"
android:background="@android:color/holo_red_dark"
android:text="编辑" />
</LinearLayout>
<!-- 这里是前台显示的布局 -->
<RelativeLayout
android:id="@+id/front"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#ffffff"
android:orientation="vertical"
android:tag="front" >
<TextView
android:id="@+id/example_row_tv_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="18sp" />
</RelativeLayout>
</FrameLayout>
下面是Mainactivity.Java源码
package com.demo.swipelistviewdemo;
import java.util.ArrayList;
import java.util.List;
import com.fortysevendeg.swipelistview.BaseSwipeListViewListener;
import com.fortysevendeg.swipelistview.SwipeListView;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private SwipeListView mSwipeListView;
private SwipeAdapter adapter;
public static int deviceWidth ;
private List<String> testData ;
private int closeItem=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSwipeListView=(SwipeListView)findViewById(R.id.example_lv_list);
testData=getTestData();
adapter=new SwipeAdapter();
//拿到设备宽度
deviceWidth = getResources().getDisplayMetrics().widthPixels;
//数据适配
mSwipeListView.setAdapter(adapter);
reload();
//设置监听事件
mSwipeListView.setSwipeListViewListener(new testBaseSwipeListViewListener());
}
//设置SwipeListView的属性
private void reload() {
//滑动时向左偏移量,根据设备的大小来决定偏移量的大小
mSwipeListView.setOffsetLeft(deviceWidth * 1 / 3);
mSwipeListView.setOffsetRight(0);
//设置动画时间
mSwipeListView.setAnimationTime(30);
mSwipeListView.setSwipeOpenOnLongPress(false);
}
//虚拟数据
private List<String> getTestData() {
String [] obj = new String[]{"红楼梦","西游记","水浒传","管锥编","宋诗选注","三国演义","android开发高级编程","红楼梦","西游记","水浒传","管锥编","宋诗选注","三国演义","android开发高级编程"};
List<String> list = new ArrayList<String>();
for (String string : obj) {
list.add(string);
}
return list;
}
public class SwipeAdapter extends BaseAdapter{
private LayoutInflater mInflater ;
public SwipeAdapter(){
mInflater=LayoutInflater.from(MainActivity.this);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return testData.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null ;
if(convertView == null){
convertView = mInflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.mFrontText = (TextView) convertView.findViewById(R.id.example_row_tv_title);
holder.mBackEdit = (Button) convertView.findViewById(R.id.example_row_b_action_3);
holder.mBackDelete = (Button) convertView.findViewById(R.id.example_row_b_action_2);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
closeItem=position;
holder.mFrontText.setText(testData.get(position));
holder.mBackDelete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//关闭动画
mSwipeListView.closeAnimate(position);
//调用dismiss方法删除该项(这个方法在MainActivity中)
mSwipeListView.dismiss(position);
//可以在此删除testData
}
});
return convertView;
}
private class ViewHolder{
TextView mFrontText ;
Button mBackEdit;
Button mBackDelete ;
}
}
//ListView的监听事件
public class testBaseSwipeListViewListener extends BaseSwipeListViewListener{
//点击每一项的响应事件
@Override
public void onClickFrontView(int position) {
// TODO Auto-generated method stub
super.onClickFrontView(position);
Toast.makeText(getApplicationContext(), testData.get(position),
Toast.LENGTH_SHORT).show();
mSwipeListView.closeOpenedItems();
}
//关闭事件
@Override
public void onDismiss(int[] reverseSortedPositions) {
// TODO Auto-generated method stub
super.onDismiss(reverseSortedPositions);
for (int position : reverseSortedPositions) {
Log.i("lenve", "position--:"+position);
testData.remove(position);
}
adapter.notifyDataSetChanged();
}
@Override
public void onChoiceChanged(int position, boolean selected)
{
Log.d("msg", "onChoiceChanged:" + position + ", " + selected);
mSwipeListView.closeOpenedItems();
}
@Override
public void onChoiceEnded()
{
Log.d("msg", "onChoiceEnded");
}
@Override
public void onChoiceStarted()
{
Log.d("msg", "onChoiceStarted");
}
@Override
public void onClickBackView(int position)
{
Log.d("msg", "onClickBackView:" + position);
}
//滑动时调用已关闭
@Override
public void onClosed(int position, boolean fromRight)
{
Log.d("msg", "onClosed:" + position + "," + fromRight);
}
@Override
public void onFirstListItem()
{
Log.d("msg", "onFirstListItem");
}
@Override
public void onLastListItem()
{
Log.d("msg", "onLastListItem");
}
//删除一个item会list会changed调用
@Override
public void onListChanged()
{
Log.d("msg", "onListChanged");
mSwipeListView.closeOpenedItems();
}
//滑动时调用正在滑动
@Override
public void onMove(int position, float x)
{
Log.d("msg", "onMove:" + position + "," + x);
}
//滑动时调用已展开
@Override
public void onOpened(int position, boolean toRight)
{
Log.d("msg", "onOpened:" + position + "," + toRight);
}
//滑动时调用开始关闭
@Override
public void onStartClose(int position, boolean right)
{
Log.d("msg", "onStartClose:" + position + "," + right);
}
//滑动时调用开始打开
@Override
public void onStartOpen(int position, int action, boolean right)
{
Log.d("msg", "onStartOpen:" + position + "," + action + ","
+ right);
if (closeItem!=position) {
mSwipeListView.closeOpenedItems();
mSwipeListView.openAnimate(position);
}
}
}
}
在监听事件中的这几个方法中关闭 mSwipeListView.closeOpenedItems();就可以实现QQ侧滑效果
@Override
public void onStartOpen(int position, int action, boolean right)
{
Log.d("msg", "onStartOpen:" + position + "," + action + ","
+ right);
if (closeItem!=position) {
mSwipeListView.closeOpenedItems();
mSwipeListView.openAnimate(position);
}
}
@Override
public void onListChanged()
{
Log.d("msg", "onListChanged");
mSwipeListView.closeOpenedItems();
}
@Override
public void onChoiceChanged(int position, boolean selected)
{
Log.d("msg", "onChoiceChanged:" + position + ", " + selected);
<span style="white-space:pre"> </span>mSwipeListView.closeOpenedItems();
}
经过一些调试,勉强达到我的效果,demo源码下载