在android

时间:2016-10-25 12:43:22

标签: android android-recyclerview itemtouchhelper

我按照教程here关于如何实现onItemTouchHelper和回调方法,当我运行我的代码时,它可以工作到我可以长按并拿起项目的那一刻,但是当我将它移动到其中一个时列表中的其他项目我的应用程序将强制关闭索引超出范围异常可以在这有人帮助我吗?

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

Simple Item Touch Helper Callback

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列表,但这只是一个数据库列表,任何人都能看到我无法看到的东西吗?

1 个答案:

答案 0 :(得分:0)

我编辑你的适配器的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;
}