【问题标题】:correct way to implement item touch helper on recyclerview in android在android中的recyclerview上实现项目触摸助手的正确方法
【发布时间】:2016-10-25 12:43:21
【问题描述】:

我遵循了一个教程here,关于如何在我运行我的代码时实现 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 列表,但这只是来自数据库的列表,有人能看到我看不到的东西吗?

【问题讨论】:

    标签: android android-recyclerview itemtouchhelper


    【解决方案1】:

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

    【讨论】:

    • 这很好用,这个解决方案在任何地方都不可用。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-12
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    相关资源
    最近更新 更多