当我尝试从 ListView 中向下拖动一行时出现“IndexOutOfBoundsException”(使用 DragSortListView)
Posted
技术标签:
【中文标题】当我尝试从 ListView 中向下拖动一行时出现“IndexOutOfBoundsException”(使用 DragSortListView)【英文标题】:I got "IndexOutOfBoundsException" when I try to drag down a row from my ListView (using DragSortListView) 【发布时间】:2017-08-12 21:01:07 【问题描述】:我在 youtube 上看到了一个教程,展示了如何将数据添加到 sqlLite db,然后将这些数据显示到 ListView Video。
这样做之后...我将 DragSortListView 应用到我的列表视图...但每次我拖动一行。这个错误不断出现,我无法解决它:
FATAL EXCEPTION: main
Process: com.example.justi.ricksonbar, PID: 29157
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:411)
at com.example.justi.ricksonbar.ProductAdapter.getItem(ProductAdapter.java:49)
at com.example.justi.ricksonbar.BackgroundTask$1.drop(BackgroundTask.java:91)
at com.mobeta.android.dslv.DragSortListView.dropFloatView(DragSortListView.java:1501)
at com.mobeta.android.dslv.DragSortListView.access$1200(DragSortListView.java:59)
at com.mobeta.android.dslv.DragSortListView$DropAnimator.onStop(DragSortListView.java:1293)
at com.mobeta.android.dslv.DragSortListView$SmoothAnimator.run(DragSortListView.java:1192)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
这是我的 ProductAdapter.java¨
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;
import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ProductAdapter extends ArrayAdapter
List list = new ArrayList();
public ProductAdapter(Context context,int resource)
super(context, resource);
public void add(Product object)
list.add(object);
super.add(object);
@Override
public int getCount()
return list.size();
@Override
public Object getItem(int position)
return list.get(position);
@Override
public View getView(int position, final View convertView, ViewGroup parent)
View row = convertView;
final ProductHolder productHolder;
if(row == null)
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.product_list, parent, false);
productHolder = new ProductHolder();
productHolder.tx_name = (TextView)row.findViewById(R.id.tvProd_name);
productHolder.tx_price = (TextView)row.findViewById(R.id.tvProd_price);
productHolder.tx_type = (TextView)row.findViewById(R.id.tvProd_type);
row.setTag(productHolder);
else
productHolder = (ProductHolder) row.getTag();
Product product = (Product) getItem(position);
productHolder.tx_name.setText(product.getName().toString());
productHolder.tx_price.setText(Double.toString(product.getPrice()));
productHolder.tx_type.setText(product.getType().toString());
return row;
static class ProductHolder
TextView tx_name, tx_price, tx_type;
和我的 BackgroundTask.java(我放 DragSortListView 方法的地方)
import android.app.Activity;
import android.app.VoiceInteractor;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView;
public class BackgroundTask extends AsyncTask<String, Product, String>
Context ctx;
ProductAdapter productAdapter;
Activity activity;
DragSortListView listView;
BackgroundTask(Context ctx)
this.ctx = ctx;
activity = (Activity)ctx;
@Override
protected void onPreExecute()
super.onPreExecute();
@Override
protected String doInBackground(String... params)
String method = params[0];
DatabaseHelper dHelper = new DatabaseHelper(ctx);
if (method.equals("add_info"))
String name = params[1];
double price = Double.parseDouble(params[2]);
String type = params[3];
SQLiteDatabase db = dHelper.getWritableDatabase();
//Call method of insertion
dHelper.addInformations(db, name, price, type);
return "One row is inserted....";
else if (method.equals("get_info"))
listView = (DragSortListView)activity.findViewById(R.id.display_listview);
SQLiteDatabase db = dHelper.getReadableDatabase();
Cursor cursor = dHelper.getInformations(db);
productAdapter = new ProductAdapter(ctx,R.layout.product_list);
String name, type;
double price;
while (cursor.moveToNext())
name = cursor.getString(cursor.getColumnIndex(ProductContract.ProductEntry.NAME));
price = cursor.getDouble(cursor.getColumnIndex(ProductContract.ProductEntry.PRICE));
type = cursor.getString(cursor.getColumnIndex(ProductContract.ProductEntry.TYPE));
Product product = new Product(name, price, type);
publishProgress(product);
return "get_info";
return null;
@Override
protected void onProgressUpdate(Product... values)
productAdapter.add(values[0]);
private DragSortListView.DropListener onDrop = new DragSortListView.DropListener()
@Override
public void drop(int from, int to)
productAdapter = new ProductAdapter(ctx,R.layout.product_list);
if (from != to)
Object item = productAdapter.getItem(from);
productAdapter.remove(item);
productAdapter.insert(item, to);
;
private DragSortListView.RemoveListener onRemove = new DragSortListView.RemoveListener()
@Override
public void remove(int which)
productAdapter = new ProductAdapter(ctx,R.layout.product_list);
productAdapter.remove(productAdapter.getItem(which));
;
@Override
protected void onPostExecute(String result)
if (result.equals("get_info"))
listView.setAdapter(productAdapter);
listView.setDropListener(onDrop);
listView.setRemoveListener(onRemove);
DragSortController controller = new DragSortController(listView);
controller.setRemoveEnabled(false);
controller.setSortEnabled(true);
controller.setDragInitMode(1);
listView.setFloatViewManager(controller);
listView.setOnTouchListener(controller);
listView.setDragEnabled(true);
else
Toast.makeText(ctx, result, Toast.LENGTH_LONG).show();
请帮助我。非常感谢
【问题讨论】:
【参考方案1】:您正在尝试在适配器中添加任何元素之前获取项目。
@Override
public void drop(int from, int to)
// Adapter is Created here
productAdapter = new ProductAdapter(ctx,R.layout.product_list);
if (from != to)
// here you are trying to get item which must throw indexoutofbounds
// because you didn't added anything yet
Object item = productAdapter.getItem(from);
productAdapter.remove(item);
productAdapter.insert(item, to);
根据你的adapter的add方法会在Adapter中添加元素。
public void add(Product object)
list.add(object);
super.add(object);
【讨论】:
哦,好的。这就说得通了。现在我在想我可以把那个“drop”方法放在哪里。必须在数据添加之后 像这样从 Adapter 中获取 Items 确实不是一个好主意,而是通过 Adapter 您可以传递您的 Items 的引用。 真的吗?我不知道,正如您显然可以看到的,我是 Android 的初学者。我只是看到了这个教程,并从头开始遵循它。 是的,阅读更多关于 AsyncTasks 的内容,您就会知道在异步任务中使用视图/适配器是多么危险。【参考方案2】:使用Cursor Adapter,效率更高:
https://guides.codepath.com/android/Populating-a-ListView-with-a-CursorAdapter
【讨论】:
可以作为评论添加。以上是关于当我尝试从 ListView 中向下拖动一行时出现“IndexOutOfBoundsException”(使用 DragSortListView)的主要内容,如果未能解决你的问题,请参考以下文章
Swift NSTableview 拖动选择多行而不是拖出表格
将 swift storyboard 上的所有控件从屏幕顶部向下拖动,但运行时它们又回到屏幕顶部
从ArrayAdapter每毫秒更新Android ListView中的一行