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