2016-04-16 14 views
0

リストのように見えるシンプルなRecyclerViewがあり、それぞれのビューに異なるIDを設定しています。最初のビューをクリックしてビューを追加し、クリックしてください(最初のものを期待してください)。正しく動作しないのは、ビューを削除して別のビューを追加すると、新しいビューのIDがその注文を破棄することです。Android:リサイクルビューを削除して正しく追加する

アダプタ

public class AddEventsAdapter extends RecyclerView.Adapter<AddEventsAdapter.ViewHolder> { 

    private List<String> items = new ArrayList<>(); 

    public void addItem(String name) { 
     items.add(name); 
     notifyItemInserted(items.size() - 1); 
    } 

    public void removeItem(int position) { 
     items.remove(position); 
     notifyItemRemoved(position); 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 
     View view = inflater.inflate(R.layout.add_event_item, parent, false); 

     return new ViewHolder(view); 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
    } 

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

    static int i; 

    class ViewHolder extends RecyclerView.ViewHolder{ 

     public TextView eventName; 
     public RelativeLayout theLayout; 


     public ViewHolder(View itemView) { 
      super(itemView); 
      eventName = (TextView)itemView.findViewById(R.id.eventName); 
      theLayout = (RelativeLayout)itemView.findViewById(R.id.backgroundevent); 

      theLayout.setId(++i); 
      eventName.setText(String.format("", i)); 

      theLayout.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (v.getId() == 1){ 
        addItem(""); 
       }else { 
        removeItem(getAdapterPosition()); 
       } 
      } 
     }); 
     } 
    } 
} 

実装:

final AddEventsAdapter AddContainer = new AddEventsAdapter(); 
    AddEventsRecycler.setLayoutManager(new LinearLayoutManager(this)); 
    AddEventsRecycler.setAdapter(AddContainer); 
    AddEventsRecycler.setItemViewCacheSize(666); 

    AddContainer.addItem(""); 

すべての行のレイアウト:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:background="@drawable/event_clicked_ripple" 
    android:clickable="true" 
    android:id="@+id/backgroundevent" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:padding="10dp"> 

    <TextView 
     android:clickable="false" 
     android:id="@+id/eventName" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="something" 
     android:layout_centerVertical="true" 
     android:layout_toLeftOf="@+id/eventImage" 
     android:layout_toStartOf="@+id/eventImage" 
     android:layout_marginRight="10dp"/> 

    <ImageButton 
     android:clickable="false" 
     android:id="@+id/eventImage" 
     android:layout_alignParentEnd="true" 
     android:layout_alignParentRight="true" 
     android:layout_width="30dp" 
     android:layout_height="30dp" 
     android:background="@drawable/oval_shape"/> 

</RelativeLayout> 

私の問題は、5つのビューを追加して2番目を削除し、もう1つ追加すると6番目のisnteadをもう一度追加します。 ここでの質問は、ビューを削除してリサイクルしない方法ですと思いますか?

+0

?あなたのビュー所有者は自分自身を設定してはいけません。 –

+0

私はonBindViewHolderを使って各項目のテキストを設定するか、削除した後にビューをリサイクルしないようにする必要があると言っていますか? –

+0

'eventName.setText(String.format(" "、i));'作成時にビューホルダーにテキストを設定するだけです。これは明らかに再び呼び出されることはなく、問題につながります。あなたのオブジェクトを 'onBindViewHolder'で適切にバインドし、idが必要な場合は、そのIDをビューホルダーではなくモデルに追加してください。 –

答えて

1

RecyclerViewsの背後にある考え方は、あなたがonCreateViewHolder()で提供ビューの所有者が同じviewTypeの景色のために再利用することができるということです。この動作はRecyclerViewsを効率的にするものです。ビューを拡張するには高価で、findViewByIdを実行するには高価です。

あなたはRecyclerViewに1つのビュータイプしか持たないようにしました。つまり、多くのビューをスクロールしてビューを削除/追加すると、ViewHoldersを自由にリサイクルすることができます。

あなたのコードで何が起こっていますか?ビュー番号2を削除すると、ViewHolderはリサイクルされ、リサイクラビュープールに返されます。ビュー番号6を追加すると、リサイクラビューには番号2のリサイクルビューホルダが使用されます。したがって、onCreateViewHolderは呼び出されません(リサイクルするための余分なビューがあるため!)。しかし、onBindViewHolderは、と呼ばれています。

public void setData(final int position) { 
    eventName.setText(String.format("", position)); 
    theLayout.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (position == 1){ 
       addItem(""); 
      }else { 
       removeItem(position); 
      } 
     } 
} 

をしてonBindViewHolderでこのメソッドを呼び出します:だからViewHolderによって表示されるデータを更新するためのメソッドを追加し、それが意図されるだけで、適切 `onBindViewHolder`を使用してと間違って何

@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 
    holder.setData(position); 
} 
+0

私は論理を得る、それはまだ意図したように動作していないtho。私がビューを削除すると、それ以降のビューは、すでに追加したビューの数よりも優れた数字にIDを変更すると、奇妙な感じになります。 –

+0

ビューを削除してリサイクルしない方法はありませんか? –

+0

あなたの番号が増え続ける理由は、毎回増分し続ける静的なintとして 'i'を持っている可能性があります。 (onBindViewHolder'()から渡される)setDataに渡すpositionパラメータにビュー番号を設定する必要があります。 –

0

があなたのremoveItem(int position)

public void removeItem(int position) { 
    items.remove(position); 
    notifyItemRemoved(position); 
    notifyItemRangeChanged(position, items.size()); 
} 

を変更してみてくださいそれはおそらくあなたの問題を解決します

+0

それはまだ乱雑ですが、私は5つのビューを追加し、1つを削除すると、私は削除した後のすべてのビューは、あなたの 'RecyclerView'のために使用するレイアウト –

+0

乱数に自分のIDを変更しますか? – Max

+0

RelativeLayout、私はちょうど質問に追加しました –

関連する問題