0

我在这里遵循了一个关于如何在运行我的代码时实现 onItemTouchHelper 和回调方法的教程将强制关闭索引超出范围异常这里有人可以帮助我吗?

这是我的代码,但它与教程中的代码相同,

简单的项目触摸助手回调

public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback 
{

private final predictsCardAdapter mAdapter;

public SimpleItemTouchHelperCallback(predictsCardAdapter adapter){
    mAdapter = adapter;
}

@Override
public boolean isLongPressDragEnabled(){
    return true;
}
@Override
public boolean isItemViewSwipeEnabled(){
    return false;
}

@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    int dragFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
    int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;

    return makeMovementFlags(dragFlags,swipeFlags);
}

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
    mAdapter.onItemMove(viewHolder.getAdapterPosition(), 
    target.getAdapterPosition());
    //mAdapter.notifyItemMoved(viewHolder.getAdapterPosition(), 
    //target.getAdapterPosition());
    return true;
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
}
}

这是我的适配器

public class predictsCardAdapter extends   
RecyclerView.Adapter<predictsCardAdapter.MyViewHolder> implements    
ItemTouchHelperAdapter{
private List<addNewCard> cardMakerList;

@Override
public boolean onItemMove(int fromPosition, int toPosition) {
    if (fromPosition < toPosition){
        for (int i = fromPosition; i < toPosition; i++){
            Collections.swap(cardMakerList,i,i+1);
        }
    }else{
        for (int i = fromPosition; i > toPosition; i--){
            Collections.swap(cardMakerList,i,i-1);
        }
    }
    notifyItemMoved(fromPosition,toPosition);
    return true;
}

@Override
public void onItemDismiss(int position) {
cardMakerList.remove(position);
    notifyItemRemoved(position);
}

public class MyViewHolder extends RecyclerView.ViewHolder{
    public TextView cardText, speechText;
    public ImageView cardImage;
    public ContentLoadingProgressBar progress;

    public MyViewHolder(View view){
        super(view);
        cardText = (TextView) view.findViewById(R.id.predictscardText);
        speechText = (TextView) view.findViewById(R.id.predictsspeechText);
        cardImage = (ImageView) view.findViewById(R.id.predictscardimage);
        progress = (ContentLoadingProgressBar)  
        view.findViewById(R.id.predictsprogress);
    }

}
public predictsCardAdapter(List<addNewCard> cardMakerList){
    this.cardMakerList = cardMakerList;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.predicted_card, parent, false);
    return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder 
(final MyViewHolder predicts_holder, int position) {
    addNewCard cardmaker = cardMakerList.get(position);
    predicts_holder.cardText.setText(cardmaker.getCardName());
    predicts_holder.speechText.setText(cardmaker.getCardName());
    //Drawable d = new  
    BitmapDrawable(Utility.getPhoto(cardmaker.getCardIcon()));

    String url = cardmaker.getCardIcon();
    ImageLoader imageLoader = ImageLoader.getInstance();
    DisplayImageOptions options = new  
    DisplayImageOptions.Builder().cacheInMemory(true)
            .cacheOnDisc(true).resetViewBeforeLoading(true)
            .showImageForEmptyUri(R.drawable.loading_image)
            .showImageOnFail(R.drawable.broken_image).build();

    imageLoader.displayImage
    (url, predicts_holder.cardImage, options, new  
    SimpleImageLoadingListener() {
        @Override
        public void onLoadingStarted(String imageUri, View view) {
            predicts_holder.progress.setVisibility(View.VISIBLE);
        }

        @Override
        public void onLoadingFailed
        (String imageUri, View view, FailReason failReason) {
            predicts_holder.progress.setVisibility(View.GONE);
        }

        @Override
        public void onLoadingComplete
    (String imageUri, View view, Bitmap loadedImage) {
            predicts_holder.progress.setVisibility(View.GONE);
        }
    });
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
predicts_holder.cardText.setTextAppearance
(android.R.style.TextAppearance_Material_Small);
    }
    else{
        predicts_holder.cardText.setTextAppearance
(predicts_holder.cardImage.getContext(    ), 
android.R.style.TextAppearance_Material_Small);
    }
    predicts_holder.cardText.setTextSize(10);
}
@Override
public int getItemCount(){
    return cardMakerList.size();
}
}

我也有一个 ItemTouchHelperAdapter

public interface ItemTouchHelperAdapter {
boolean onItemMove(int fromPosition, int toPosition);
void onItemDismiss(int position);
}

我像这样在我的活动中使用它

 ItemTouchHelper.Callback callback = new     
 SimpleItemTouchHelperCallback(predicts_card_adapter);
    ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
    touchHelper.attachToRecyclerView(recyclerView);

我得到的错误是

java.lang.IndexOutOfBoundsException

at java.util.Collections.swap(Collections.java:1937)

at 

ss.sealstudios.com.socialstories.predictsCardAdapter.
onItemMove(predictsCardAdapter.java:33)

at ss.sealstudios.com.socialstories.SimpleItemTouchHelperCallback
.onMove(SimpleItemTouchHelperCallback.java:36)

在 onMove 方法中,如果我取消注释

mAdapter.onItemMove(viewHolder.getAdapterPosition(),   
target.getAdapterPosition());

拖放一半有效,所以我可以拖动它但不能放下它,并且视图不会移动以适应它,这让我认为它是我的 cardMaker 列表,但这只是来自数据库的列表,有人能看到我看不到的东西吗?

4

1 回答 1

2

我编辑了适配器的 onItemMove 方法,这可以避免异常并获得正确的有序列表,请参见下面的代码:

@Override
public boolean onItemMove(int fromPosition, int toPosition) {
    if (cardMakerList == null || cardMakerList.size() == 0) {
        return;
    }
    if (fromPosition < 0 || fromPosition >= cardMakerList.size()) {
        return;
    }
    if (toPosition < 0 || toPosition >= cardMakerList.size()) {
        return;
    }
    if (fromPosition == toPosition) {
        return;
    }
    T toMoveE = cardMakerList.get(fromPosition);
    if (fromPosition > toPosition) {
        for (int i = fromPosition; i > toPosition; i--) {
            cardMakerList.set(i, cardMakerList.get(i - 1));
        }
    } else {
        for (int i = fromPosition; i < toPosition; i++) {
            cardMakerList.set(i, cardMakerList.get(i + 1));
        }
    }
    cardMakerList.set(toPosition, toMoveE);
    notifyItemMoved(fromPosition, toPosition);
    return true;
}
于 2017-06-05T10:02:28.270 回答