2017-04-11 68 views
0

我使用RecyclerView它支持拖放面臨setOnCheckedChangeListener位置值的問題。我的列表項有一行有兩個TextView,CheckBox,ImageView用於拖動行。在RecyclerView的Android

我用的輔助類以下鏈接: https://github.com/iPaulPro/Android-ItemTouchHelper-Demo/tree/master/app/src/main/java/co/paulburke/android/itemtouchhelperdemo/helper

arrTaxStatus的價值觀是正確的,當我拖行。 arrTaxStatus的

價值觀是正確的,當我啓用/禁用的複選框。

但我面臨的問題時,我啓用/禁用一些複選框,拖幾行,然後再啓用/禁用一些複選框。該位置在setOnCheckedChangeListener中受到干擾。即使我點擊第一行,我得到一個不同的「位置」

請告訴我怎樣才能獲得點擊複選框的正確位置。下面

代碼:

public class RecyclerListFragment extends AppCompatActivity implements OnStartDragListener { 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.create_tax_group); 

    arrTaxStatus = new ArrayList<Boolean>(); 
    HashMap<String, Object> temp; 
    taxAccounts = new ArrayList<HashMap<String, Object>>(); 
    Cursor cursor = dh.getDetailsFromTaxGivenTaxCategory(); 
    if (cursor.moveToFirst()) { 
     do { 
      temp = new HashMap<String, Object>(); 
      temp.put("taxName", cursor.getString(cursor.getColumnIndex("scheme_name"))); 
      temp.put("taxPercent", numberFormat.format(cursor.getDouble(cursor.getColumnIndex("percentage")))); 
      taxAccounts.add(temp); 
      arrTaxStatus.add(false); 
     } while (cursor.moveToNext()); 
    } 
    cursor.close(); 

    RecyclerListAdapter adapter = new RecyclerListAdapter(this, taxAccounts); 

    RecyclerView recyclerView = (RecyclerView) findViewById(android.R.id.list); 
    recyclerView.setHasFixedSize(true); 
    recyclerView.setAdapter(adapter); 
    recyclerView.setLayoutManager(new LinearLayoutManager(this)); 

    ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(adapter); 
    mItemTouchHelper = new ItemTouchHelper(callback); 
    mItemTouchHelper.attachToRecyclerView(recyclerView); 
} 

@Override 
public void onStartDrag(RecyclerView.ViewHolder viewHolder) { 
    mItemTouchHelper.startDrag(viewHolder); 
} 

public class RecyclerListAdapter extends RecyclerView.Adapter<RecyclerListAdapter.ItemViewHolder> 
     implements ItemTouchHelperAdapter { 
    private final OnStartDragListener mDragStartListener; 

    public RecyclerListAdapter(OnStartDragListener dragStartListener, ArrayList<HashMap<String, Object>> taxAccounts) { 
     mDragStartListener = dragStartListener; 
    } 

    @Override 
    public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.create_tax_group_row, parent, false); 
     ItemViewHolder itemViewHolder = new ItemViewHolder(view); 
     return itemViewHolder; 
    } 

    @Override 
    public void onBindViewHolder(final ItemViewHolder holder, final int position) { 
     holder.taxName.setText(taxAccounts.get(position).get("taxName").toString()); 
     holder.taxPercent.setText(taxAccounts.get(position).get("taxPercent").toString()); 
     holder.handleView.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) { 
        mDragStartListener.onStartDrag(holder); 
       } 
       return false; 
      } 
     }); 

     holder.taxStatus.setOnCheckedChangeListener(null); 
     holder.taxStatus.setChecked(arrTaxStatus.get(position)); 
     holder.taxStatus.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
       Log.i("arrTaxStatus pos|checked", position + "|" + isChecked); 
       arrTaxStatus.set(position, isChecked); 
       Log.i("arrTaxStatus onCheckedChanged", arrTaxStatus.toString()); 
      } 
     }); 
    } 

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

    @Override 
    public boolean onItemMove(int fromPosition, int toPosition) { 
     Collections.swap(taxAccounts, fromPosition, toPosition); 
     Collections.swap(arrTaxStatus, fromPosition, toPosition); 
     Log.i("arrTaxStatus onItemMove", arrTaxStatus.toString()); 
     notifyItemMoved(fromPosition, toPosition); 
     return true; 
    } 

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

    /** 
    * Simple example of a view holder that implements {@link ItemTouchHelperViewHolder} and has a 
    * "handle" view that initiates a drag event when touched. 
    */ 
    public class ItemViewHolder extends RecyclerView.ViewHolder implements 
      ItemTouchHelperViewHolder { 

     public final TextView taxName, taxPercent; 
     public final CheckBox taxStatus; 
     public final ImageView handleView; 

     public ItemViewHolder(View itemView) { 
      super(itemView); 
      taxName = (TextView) itemView.findViewById(R.id.childname); 
      taxPercent = (TextView) itemView.findViewById(R.id.balance); 
      taxStatus = (CheckBox) itemView.findViewById(R.id.check_status); 
      handleView = (ImageView) itemView.findViewById(R.id.handle); 
     } 

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

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

回答

0

你需要在你的數據模型e.g或器isChecked的IsEnabled創建一個變量。然後當你啓用/禁用它們。只需更新您用來填充列表的數組。 然後onBindViewHoder檢查變量值並啓用/禁用複選框。

概念是行回收,一旦你向上/向下移動。所以複選框不會保留這些值。所以你需要保留數組中的值。然後填充它們。

0

而不是讓從位置onbindviewholder設置標籤,就可以佈局持有排的位置,當你改變onchangelistner

0

可以使用notifyItemChanged(int position)方法從RecyclerView.Adapter class.從文檔使用該標記值:

通知任何註冊的觀察者該位置的物品已更改。相當於調用notifyItemChanged(position, null);.

這是一個項目的變化事件,而不是一個結構變化事件。它表明任何對位置數據的反映都是過時的,應該更新。位置上的物品保留相同的身份。 因爲你已經有了這個職位,所以應該適合你。

0

你需要保持一個標誌爲您的適配器如下:

private boolean onViewHolderBind; 

public ViewHolder(View itemView) { 
    super(itemView); 
    mCheckBox = (CheckBox) itemView.findViewById(R.id.checkboxId); 
    mCheckBox.setOnCheckChangeListener(this); 
} 

@Override 
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
    if(!onViewHolderBind) { 
     // perform your process when checkbox changed 
     notifyDataSetChanged(); 
    } 
} 

... 

@Override 
public void onBindViewHolder(YourAdapter.ViewHolder viewHolder, int position) { 
    // process other views 
    // ... 

    onViewHolderBind = true; 
    viewHolder.mCheckBox.setChecked(trueOrFalse); 
    onViewHolderBind = false; 
} 
0

我想你是痛苦的問題是,通過適配器內部控制的項目不符合你的陣列同步,問題是那Collections.swap(…)不會做什麼適配器執行圖形。 A swap()將交換數組中兩個項目的位置,但範圍內的項目保持原位。但是,當用戶從最後一個位置拖動一個項目到第一個位置時,範圍內的所有項目位置都會變爲

我開始使用此代碼自己和通過用下面的代碼(差異)替換swap()呼叫固定它:

 override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean { 
-  Collections.swap(items, fromPosition, toPosition) 
+  val temp = items[fromPosition] 
+  items.removeAt(fromPosition) 
+  items.add(toPosition, temp) 
      notifyItemMoved(fromPosition, toPosition) 
      return true 
     } 

爲了說明視覺上的缺陷,我添加了一個dump()呼叫是否顯示的內容適配器每條拖相互作用後,然後創建的適配器具有七個元件,方便地放於字母順序:

Adapter: did load 7 
Adapter: Dumping 7 items 
Adapter: …0 SharingItem(uri=content://FIRST, kind=Image) 
Adapter: …1 SharingItem(uri=content://B, kind=Image) 
Adapter: …2 SharingItem(uri=content://C, kind=Image) 
Adapter: …3 SharingItem(uri=content://D, kind=Audio) 
Adapter: …4 SharingItem(uri=content://E, kind=Audio) 
Adapter: …5 SharingItem(uri=content://F, kind=Video) 
Adapter: …6 SharingItem(uri=content://LAST, kind=Audio) 

在2×4網格顯示這些項目,我拖着的最後一個項目到所述第一positio ñ。當我拖着手指,該項目將採取拖拽移動,這是由轉儲適配器接收每個互動強調在地方在收集的不同部分:

Adapter: Move from 6 to 4 
Adapter: Dumping 7 items 
Adapter: …0 SharingItem(uri=content://FIRST, kind=Image) 
Adapter: …1 SharingItem(uri=content://B, kind=Image) 
Adapter: …2 SharingItem(uri=content://C, kind=Image) 
Adapter: …3 SharingItem(uri=content://D, kind=Audio) 
Adapter: …4 SharingItem(uri=content://LAST, kind=Audio) 
Adapter: …5 SharingItem(uri=content://F, kind=Video) 
Adapter: …6 SharingItem(uri=content://E, kind=Audio) 
Adapter: Move from 4 to 2 
Adapter: Dumping 7 items 
Adapter: …0 SharingItem(uri=content://FIRST, kind=Image) 
Adapter: …1 SharingItem(uri=content://B, kind=Image) 
Adapter: …2 SharingItem(uri=content://LAST, kind=Audio) 
Adapter: …3 SharingItem(uri=content://D, kind=Audio) 
Adapter: …4 SharingItem(uri=content://C, kind=Image) 
Adapter: …5 SharingItem(uri=content://F, kind=Video) 
Adapter: …6 SharingItem(uri=content://E, kind=Audio) 
Adapter: Move from 2 to 0 
Adapter: Dumping 7 items 
Adapter: …0 SharingItem(uri=content://LAST, kind=Audio) 
Adapter: …1 SharingItem(uri=content://B, kind=Image) 
Adapter: …2 SharingItem(uri=content://FIRST, kind=Image) 
Adapter: …3 SharingItem(uri=content://D, kind=Audio) 
Adapter: …4 SharingItem(uri=content://C, kind=Image) 
Adapter: …5 SharingItem(uri=content://F, kind=Video) 
Adapter: …6 SharingItem(uri=content://E, kind=Audio) 

更換後在上面的實現中調用swap()時,日誌顯示交互期間內部的更好圖片:

Adapter: did load 7 
Adapter: Dumping 7 items 
Adapter: …0 SharingItem(uri=content://FIRST, kind=Image) 
Adapter: …1 SharingItem(uri=content://B, kind=Image) 
Adapter: …2 SharingItem(uri=content://C, kind=Image) 
Adapter: …3 SharingItem(uri=content://D, kind=Audio) 
Adapter: …4 SharingItem(uri=content://E, kind=Audio) 
Adapter: …5 SharingItem(uri=content://F, kind=Video) 
Adapter: …6 SharingItem(uri=content://LAST, kind=Audio) 
Adapter: Move from 6 to 4 
Adapter: Dumping 7 items 
Adapter: …0 SharingItem(uri=content://FIRST, kind=Image) 
Adapter: …1 SharingItem(uri=content://B, kind=Image) 
Adapter: …2 SharingItem(uri=content://C, kind=Image) 
Adapter: …3 SharingItem(uri=content://D, kind=Audio) 
Adapter: …4 SharingItem(uri=content://LAST, kind=Audio) 
Adapter: …5 SharingItem(uri=content://E, kind=Audio) 
Adapter: …6 SharingItem(uri=content://F, kind=Video) 
Adapter: Move from 4 to 2 
Adapter: Dumping 7 items 
Adapter: …0 SharingItem(uri=content://FIRST, kind=Image) 
Adapter: …1 SharingItem(uri=content://B, kind=Image) 
Adapter: …2 SharingItem(uri=content://LAST, kind=Audio) 
Adapter: …3 SharingItem(uri=content://C, kind=Image) 
Adapter: …4 SharingItem(uri=content://D, kind=Audio) 
Adapter: …5 SharingItem(uri=content://E, kind=Audio) 
Adapter: …6 SharingItem(uri=content://F, kind=Video) 
Adapter: Move from 2 to 0 
Adapter: Dumping 7 items 
Adapter: …0 SharingItem(uri=content://LAST, kind=Audio) 
Adapter: …1 SharingItem(uri=content://FIRST, kind=Image) 
Adapter: …2 SharingItem(uri=content://B, kind=Image) 
Adapter: …3 SharingItem(uri=content://C, kind=Image) 
Adapter: …4 SharingItem(uri=content://D, kind=Audio) 
Adapter: …5 SharingItem(uri=content://E, kind=Audio) 
Adapter: …6 SharingItem(uri=content://F, kind=Video)