SwipeListView實現QQ消息側滑刪除功能

看到別人實現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 右偏移量
下面是我的demo

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源碼下載


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章