看到別人實現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源碼下載