1

RecyclerViewのレイアウトはGridLayoutで3列です。私はRecyclerViewGridLayoutにドラッグアンドドロップするためにItemTouchHelperを使用しています。私のアダプターには、私が移動したアイテムを通知するメソッドonItemMove()があります。それは、私がドラッグアンドドロップしたArrayListのアイテムだけを交換します。しかし、ドラッグアンドドロップのために、他の要素にもシフトがあります。私はArrayListで彼らの位置を更新したいと思います。ArrayList内のすべてのアイテムをrecyclerviewのドラッグアンドドロップでシフトする方法

public class GridAdapter extends RecyclerView.Adapter<GridAdapter.MyViewHolder> implements com.sagar.quizdemo.helper.ItemTouchHelperAdapter { 
    String[] str = {"Level 1", "Level 2", "Level 3", "Level 4", "Level 5", "Level 6", "Level 7", "Level 8", "Level 9"}; 
    List<String> itemList, actualList; 
    LayoutInflater inflater; 
    Context context; 
    private final OnStartDragListener mDragStartListener; 

    public GridAdapter(Context context, OnStartDragListener dragStartListener) { 
     this.context = context; 
     mDragStartListener = dragStartListener; 
     inflater = LayoutInflater.from(context); 
     itemList = new ArrayList<>(); 
     actualList = new ArrayList<>(Arrays.asList(str)); 
    } 

    public void getItemList(List<String> nameList) { 
     int currentSize = itemList.size(); 
     itemList.clear(); 
     itemList.addAll(nameList); 
     notifyItemRangeRemoved(0, currentSize); 
     notifyItemRangeInserted(0, nameList.size()); 
    } 

    @Override 
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = inflater.inflate(R.layout.custom_level_row, parent, false); 
     return new MyViewHolder(view); 
    } 

    @Override 
    public void onBindViewHolder(final MyViewHolder holder, int position) { 
     holder.textView.setText(itemList.get(position)); 
     // Start a drag whenever the handle view it touched 
     holder.cardView.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) { 
        mDragStartListener.onStartDrag(holder); 
       } 
       return false; 
      } 
     }); 
    } 

    @Override 
    public int getItemCount() { 
     return itemList.size(); 
    } 

    @Override 
    public boolean onItemMove(int fromPosition, int toPosition) { 
     Collections.swap(itemList, fromPosition, toPosition); 
     notifyItemMoved(fromPosition, toPosition); 
     notifyItemChanged(fromPosition); 
     notifyItemChanged(toPosition); 
     return true; 
    } 

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

    public class MyViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder { 

     CardView cardView; 
     TextView textView; 

     public MyViewHolder(View itemView) { 
      super(itemView); 
      cardView = (CardView) itemView.findViewById(R.id.gameCard); 
      textView = (TextView) itemView.findViewById(R.id.gameText); 
     } 

     @Override 
     public void onItemSelected() { 
      itemView.setBackgroundColor(Color.LTGRAY); 
     } 

     @Override 
     public void onItemClear() { 
      itemView.setBackgroundColor(Color.WHITE); 
     } 
    } 
} 

最初にリストがある場合:

{"Level 1", "Level 2", "Level 3", "Level 4", "Level 5", "Level 6", "Level 7", "Level 8", "Level 9"} 

私はRecyclerViewで2番目と4番目の位置の要素を交換した後ここで

は私Recyclerviewのアダプタです。

{"Level 1", "Level 5", "Level 2", "Level 3", "Level 4", "Level 6", "Level 7", "Level 8", "Level 9"} 

しかし、私はこの更新されたリストを取得しています:更新されたリストは、(私がをしたい)のようになります

{"Level 1", "Level 5", "Level 3", "Level 4", "Level 2", "Level 6", "Level 7", "Level 8", "Level 9"} 

答えて

2

Collections.swap(itemList, fromPosition, toPosition);を使用して、指定された位置のオブジェクトを交換することが問題だと思います。したがって、出力は正しいです。ただし、必要なもの:

String item = itemList.remove(fromPostion); 
itemList.insert(item, toPosition); 
+0

更新されたリストを確認したい。ドラッグアンドドロップ後にアダプタの更新リストをどこで確認できますか? 'onItemMove()'の中でリストをチェックすることはできません。私は更新されたリストを別のリストと比較したいと思う。 – XoXo

+0

素晴らしいです。ヘルプありがとう – XoXo

+0

@Hiren、最終的な組み合わせが正しいかどうか確認したいですか?さて、すべての「RecyclerView」のアニメーションが終了したら、そうすることを提案します。私はそれがこのスレッドで提案されたカスタム 'ItemAnimator'を使って行うことができると思います。https://stackoverflow.com/questions/33710605/detect-animation-finish-in-androids-recyclerview – MeliX

1

はonItemMove menthodでnotifyDataSetChanged()を呼び出してみてください。

@Override 
    public boolean onItemMove(int fromPosition, int toPosition) { 
     notifyItemMoved(fromPosition, toPosition); 
     notifyItemChanged(fromPosition); 
     notifyItemChanged(toPosition); 
     notifyDataSetChanged();  
     return true; 
    } 
+0

しかし、ドラッグアンドドロップで問題が発生しています。私はアイテムをドラッグしている瞬間です。すぐ隣のアイテムにドロップする。 – XoXo

+0

スワップを使用しないで、スワップすると、アイテムをドラッグした位置で選択したアイテムの位置が変更されます –

+0

ドラッグアンドドロップでアイテムの位置を変更できるパズルゲームを作成しています。 – XoXo

0

代わりにこれを試してみてください。あなたのケースでは、まず置換するアイテムのインデックス(fromPosition)を見つけてから、そのインデックスにtoPositionを追加する必要があります。 How to move specific item in array list to the first item

+0

ドラッグアンドドロップでアイテムの位置を変更できるパズルゲームを作っています。 – XoXo

関連する問題