Android開(kāi)發(fā)實(shí)現(xiàn)可拖動(dòng)排序的ListView功能【附源碼下載】
本文實(shí)例講述了Android開(kāi)發(fā)實(shí)現(xiàn)可拖動(dòng)排序的ListView功能。分享給大家供大家參考,具體如下:
一、上圖

二、簡(jiǎn)述
1、需要實(shí)現(xiàn)的效果是長(zhǎng)按右側(cè)可拖動(dòng)部分布局實(shí)現(xiàn)列表項(xiàng)的拖動(dòng)排序
2、當(dāng)點(diǎn)擊列表項(xiàng)前面的單選按鈕時(shí),在該條目右側(cè)顯示刪除圖標(biāo),點(diǎn)擊該圖標(biāo)刪除當(dāng)前條目。
三、實(shí)現(xiàn)思路
借助github上的開(kāi)源代碼drag-sort-listview-master加以改造。
四、主要源碼展示
1、Activity代碼
package com.gengducun.dslvdemo;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import com.mobeta.android.dslv.DragSortListView;
public class MainActivity extends Activity {
protected static final String TAG = "MainActivity";
/**產(chǎn)品信息列表**/
private ArrayList<ProductInfoBean> productInfoList;
/**產(chǎn)品列表控件**/
private DragSortListView mDslvProductList;
/**產(chǎn)品信息列表*/
private ProductListAdapter mProductListAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDslvProductList = (DragSortListView) findViewById(R.id.dslv_product_list);
initProductList();
mProductListAdapter = new ProductListAdapter(productInfoList, this);
mDslvProductList.setAdapter(mProductListAdapter);
mDslvProductList.setDropListener(onDrop);
mDslvProductList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
private DragSortListView.DropListener onDrop = new DragSortListView.DropListener() {
@Override
public void drop(int from, int to) {
if (from != to) {
ProductInfoBean item = (ProductInfoBean) mProductListAdapter.getItem(from);
mProductListAdapter.remove(item);
mProductListAdapter.insert(item,from, to);
mDslvProductList.moveCheckState(from, to);
}
}
};
private void initProductList() {
productInfoList = new ArrayList<ProductInfoBean>();
ProductInfoBean productInfo1 = new ProductInfoBean("EURUSD1");
ProductInfoBean productInfo2 = new ProductInfoBean("EURUSD2");
ProductInfoBean productInfo3 = new ProductInfoBean("EURUSD3");
ProductInfoBean productInfo4 = new ProductInfoBean("EURUSD4");
ProductInfoBean productInfo5 = new ProductInfoBean("EURUSD5");
ProductInfoBean productInfo6 = new ProductInfoBean("EURUSD6");
ProductInfoBean productInfo7 = new ProductInfoBean("EURUSD7");
productInfoList.add(productInfo1);
productInfoList.add(productInfo2);
productInfoList.add(productInfo3);
productInfoList.add(productInfo4);
productInfoList.add(productInfo5);
productInfoList.add(productInfo6);
productInfoList.add(productInfo7);
}
}
2、Adapter代碼
package com.gengducun.dslvdemo;
import java.util.ArrayList;
import android.content.Context;
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.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.TextView;
public class ProductListAdapter extends BaseAdapter {
private static final String TAG = "ProductListAdapter1";
/**產(chǎn)品信息列表*/
private ArrayList<ProductInfoBean> productInfoList;
/**上下文*/
private Context mContext;
/**布局加載器*/
private LayoutInflater mInflater;
/**布局緩存*/
private ViewHolder mHolder;
/**本類適配器對(duì)象**/
private ProductListAdapter mProductListAdapter1;
/**選中項(xiàng)位置**/
private int mSelectPosition = -1;
public ProductListAdapter(ArrayList<ProductInfoBean> productInfoList, Context context) {
super();
this.productInfoList = productInfoList;
this.mContext = context;
this.mInflater = LayoutInflater.from(context);
this.mProductListAdapter1 = this;
}
@Override
public int getCount() {
return null == productInfoList ? 0 : productInfoList.size();
}
@Override
public Object getItem(int position) {
return productInfoList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public int getmSelectPosition() {
return mSelectPosition;
}
public void setmSelectPosition(int mSelectPosition) {
this.mSelectPosition = mSelectPosition;
}
/**
* 刪除產(chǎn)品
* @param productInfoBean
*/
public void remove(ProductInfoBean productInfoBean) {
synchronized (this) {
productInfoList.remove(productInfoBean);
}
notifyDataSetChanged();
}
/**
* 將產(chǎn)品移動(dòng)到指定的位置
* @param productInfoBean
* @param from 移動(dòng)之前的位置
* @param to 移動(dòng)完成之后,該產(chǎn)品所在的位置
*/
public void insert(ProductInfoBean productInfoBean, int from, int to) {
synchronized (this) {
Log.i(TAG, "from=" + from + " to =" + to);
if (mSelectPosition != -1) {//有選中項(xiàng)的前提下
if ((from < mSelectPosition && to < mSelectPosition) || (from > mSelectPosition && to > mSelectPosition)) {
//在選中項(xiàng)之前的位置進(jìn)行拖拉或者在選中項(xiàng)之后的區(qū)域拖拉,不會(huì)影響選中項(xiàng)
} else if (from < mSelectPosition && to > mSelectPosition) {
//將選中項(xiàng)之前的移動(dòng)到選中項(xiàng)之后的位置,則選中項(xiàng)的索引需要發(fā)生變化,應(yīng)該是選中項(xiàng)的位置-1
mSelectPosition = mSelectPosition - 1;
} else if (from > mSelectPosition && to < mSelectPosition) {
//將選中項(xiàng)之后的項(xiàng)移動(dòng)到選中項(xiàng)之前的位置,索引也需要變化,應(yīng)該是選中項(xiàng)的位置+1
mSelectPosition = mSelectPosition + 1;
} else if ((from == mSelectPosition && from > to) || (from == mSelectPosition && from < to)) {
//如果將選中項(xiàng)往選中項(xiàng)前面的方向拖,則選中項(xiàng)的索引也需要變化,應(yīng)該是拖動(dòng)到的位置
mSelectPosition = to;
} else if ((from < mSelectPosition && to == mSelectPosition)) {
//將選中項(xiàng)之前的移動(dòng)到當(dāng)前選中項(xiàng)的位置,索引需要變化,選中項(xiàng)的索引應(yīng)該是 選中項(xiàng)的值-1
mSelectPosition = mSelectPosition - 1;
} else if (from > mSelectPosition && to == mSelectPosition) {
//將選中項(xiàng)之后的移動(dòng)到當(dāng)前項(xiàng)的位置,索引需要變化,選中項(xiàng)的索引應(yīng)該是選中項(xiàng)的值+1
mSelectPosition = mSelectPosition + 1;
}
}
productInfoList.add(to, productInfoBean);
}
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
convertView = mInflater.inflate(R.layout.list_item_product_list_1, null);
mHolder = new ViewHolder();
mHolder.rbSelect = (RadioButton) convertView.findViewById(R.id.rb_select);
mHolder.tvPurductName = (TextView) convertView.findViewById(R.id.tv_product_name);
mHolder.llDragLayout = (LinearLayout) convertView.findViewById(R.id.drag_handle);
mHolder.ivDrag = (ImageView) convertView.findViewById(R.id.iv_drag);
mHolder.ivDeleteProduct = (ImageView) convertView.findViewById(R.id.iv_product_delete);
convertView.setTag(mHolder);
} else {
mHolder = (ViewHolder) convertView.getTag();
}
ProductInfoBean productInfoBean = productInfoList.get(position);
if (null != productInfoBean) {
//設(shè)置單選按鈕的選中狀態(tài)
if (mSelectPosition == position) {
mHolder.rbSelect.setChecked(true);
mHolder.ivDrag.setVisibility(View.GONE);
mHolder.ivDeleteProduct.setVisibility(View.VISIBLE);
mHolder.ivDeleteProduct.setOnClickListener(new RemoveItemClickListener(mSelectPosition));
} else {
mHolder.rbSelect.setChecked(false);
mHolder.ivDrag.setVisibility(View.VISIBLE);
mHolder.ivDeleteProduct.setVisibility(View.GONE);
}
mHolder.rbSelect.setOnClickListener(new ProductClickListener(position));
//設(shè)置產(chǎn)品名稱
if (null != productInfoBean.getProductName() && !("".equals(productInfoBean.getProductName()))) {
mHolder.tvPurductName.setText(productInfoBean.getProductName());
}
}
return convertView;
}
class ViewHolder {
RadioButton rbSelect;
TextView tvPurductName;
LinearLayout llDragLayout;
ImageView ivDrag;
ImageView ivDeleteProduct;
}
/**
* 單選按鈕事件監(jiān)聽(tīng)
* @author Wilson
*/
class ProductClickListener implements OnClickListener {
private int position;
public ProductClickListener(int position) {
super();
this.position = position;
}
@Override
public void onClick(View v) {
if (mSelectPosition == position) {
mSelectPosition = -1;
} else {
mSelectPosition = position;
}
Log.i(TAG, "mSelectPosition=" + mSelectPosition + " position=" + position);
mProductListAdapter1.notifyDataSetChanged();
}
}
/**
* 刪除當(dāng)前產(chǎn)品項(xiàng)監(jiān)聽(tīng)事件
*/
class RemoveItemClickListener implements OnClickListener {
private int position;
public RemoveItemClickListener(int position) {
super();
this.position = position;
}
@Override
public void onClick(View v) {
//1、刪除集合中的數(shù)據(jù)
productInfoList.remove(position);
//2、刪除服務(wù)器端的數(shù)據(jù)
mProductListAdapter1.notifyDataSetChanged();
//
mSelectPosition = -1;
}
}
}
四、源碼
完整實(shí)例代碼點(diǎn)擊此處本站下載。
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android控件用法總結(jié)》、《Android開(kāi)發(fā)入門(mén)與進(jìn)階教程》、《Android視圖View技巧總結(jié)》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android數(shù)據(jù)庫(kù)操作技巧總結(jié)》及《Android資源操作技巧匯總》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
- Android實(shí)現(xiàn)ImageView圖片縮放和拖動(dòng)
- Android實(shí)現(xiàn)跟隨手指拖動(dòng)并自動(dòng)貼邊的View樣式(實(shí)例demo)
- Android自定義View實(shí)現(xiàn)拖動(dòng)選擇按鈕
- Android實(shí)現(xiàn)單頁(yè)面浮層可拖動(dòng)view的一種方法
- Android通過(guò)自定義ImageView控件實(shí)現(xiàn)圖片的縮放和拖動(dòng)的實(shí)現(xiàn)代碼
- Android DragImageView實(shí)現(xiàn)下拉拖動(dòng)圖片放大效果
- Android RecyclerView滑動(dòng)刪除和拖動(dòng)排序
- Android ViewDragHelper仿淘寶拖動(dòng)加載效果
- Android自定義View圓形和拖動(dòng)圓、跟隨手指拖動(dòng)效果
- android實(shí)現(xiàn)可拖動(dòng)的浮動(dòng)view
相關(guān)文章
Android開(kāi)發(fā)組件化架構(gòu)設(shè)計(jì)原理到實(shí)戰(zhàn)
這篇文章主要為大家介紹了Android開(kāi)發(fā)組件化架構(gòu)設(shè)計(jì)原理到實(shí)戰(zhàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
Android碎片fragment實(shí)現(xiàn)靜態(tài)加載的實(shí)例代碼
這篇文章主要介紹了Android碎片fragment實(shí)現(xiàn)靜態(tài)加載的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11
android開(kāi)發(fā)環(huán)境中SDK文件夾下的所需內(nèi)容詳解
在本篇文章里小編給大家整理的是關(guān)于android開(kāi)發(fā)環(huán)境中SDK文件夾下的所需內(nèi)容詳解,有興趣的朋友們參考學(xué)習(xí)下。2019-09-09
Android開(kāi)發(fā)之瀏覽器用法實(shí)例詳解(調(diào)用uc,opera,qq瀏覽器訪問(wèn)網(wǎng)頁(yè))
這篇文章主要介紹了Android開(kāi)發(fā)之瀏覽器用法,結(jié)合實(shí)例形式詳細(xì)分析了Android調(diào)用瀏覽器的具體步驟與相關(guān)使用技巧,需要的朋友可以參考下2016-01-01
詳解Android 基于TCP和UDP協(xié)議的Socket通信
這篇文章主要介紹了詳解Android 基于TCP和UDP協(xié)議的Socket通信,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11

