2016-06-21 11 views
1

Ich habe einen Adapter für meine RecyclerView. Jeder Adapter hat ImageView und einen weiteren Adapter für RecyclerView, der auch ImageView für jedes Element hat. Ich muss auf Unterpunkt klicken und zu seiner Detailansicht gehen. Wenn ich in dieser Ansicht auf die Schaltfläche REMOVE klicke, muss diese Unterposition entfernt werden. So habe ich mehrere Probleme:Android Entfernen von Unterelementen von RecyclerView

  1. Ich habe Methode im Hauptadapter implementiert, die zwei Parameter hat: Position in der Hauptliste und Position in der Unterliste. So versuche ich es zu entfernen. Das Problem ist, dass, wenn ich eine Unterposition an einer Position lösche, dieselben Subelemente an anderen Positionen entfernt werden (ich verwende gefälschte Daten und einige von ihnen sind die gleichen).
  2. Nach dem Entfernen einer Unterposition, wenn ich versuche, die zweite zu entfernen, wird es nicht entfernt. Ich habe im Debug-Modus eingecheckt und gesehen, dass die Größe der Liste von Unterpunkten wie am Anfang ist.

Es gibt Code meines Adapters. Im Hauptteil habe ich innere Klasse für Adapter mit Subitems:

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

    private Context mContext; 
    private List<MediaWithDuplicatesTest> mTests; 
    private OnDuplicateClickListener mListener; 

    public PhotoWithDuplicatesAdapterTest(Context context, List<MediaWithDuplicatesTest> tests) { 
     mContext = context; 
     mTests = tests; 
    } 

    public interface OnDuplicateClickListener { 
     void onDuplicateClick(int photoPosition, int duplicatePosition); 
    } 

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

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     Picasso.with(mContext) 
       .load(mTests.get(position).getPhoto()) 
       .fit() 
       .centerCrop() 
       .into(holder.mPhotoImageView); 
     DuplicateAdapter adapter = new DuplicateAdapter(mContext, position, mTests.get(position).getDuplicates()); 
     adapter.setOnDuplicateClickListener(new DuplicateAdapter.OnDuplicateClickListener() { 
      @Override 
      public void onDuplicateClick(int photoPosition, int duplicatePosition) { 
       if (mListener != null) mListener.onDuplicateClick(photoPosition, duplicatePosition); 
      } 
     }); 
     LinearLayoutManager manager = new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false); 
     holder.mDuplicatesRecyclerView.setLayoutManager(manager); 
     holder.mDuplicatesRecyclerView.setAdapter(adapter); 
    } 

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

    public void setOnDuplicateClickListener(OnDuplicateClickListener listener) { 
     mListener = listener; 
    } 

    public void removeDuplicate(int photoPosition, int duplicatePosition) { 
     List<String> duplicates = mTests.get(photoPosition).getDuplicates(); 
     duplicates.remove(duplicatePosition); 
     if (duplicates.size() == 0) { 
      mTests.remove(photoPosition); 
      notifyItemRemoved(photoPosition); 
     } else notifyItemChanged(photoPosition); 
    } 

    public String getDuplicate(int photoPosition, int duplicatePosition) { 
     return mTests.get(photoPosition).getDuplicates().get(duplicatePosition); 
    } 

    public class ViewHolder extends RecyclerView.ViewHolder { 

     @Bind(R.id.iv_photo) SquareImageView mPhotoImageView; 
     @Bind(R.id.rv_duplicates) RecyclerView mDuplicatesRecyclerView; 

     public ViewHolder(View itemView) { 
      super(itemView); 
      ButterKnife.bind(this, itemView); 
     } 
    } 

    public static class DuplicateAdapter extends RecyclerView.Adapter<DuplicateAdapter.ViewHolder> { 

     private Context mContext; 
     private int mPhotoPosition; 
     private List<String> mDuplicates; 
     private OnDuplicateClickListener mListener; 

     public DuplicateAdapter(Context context, int photoPosition, List<String> duplicates) { 
      mContext = context; 
      mPhotoPosition = photoPosition; 
      mDuplicates = duplicates; 
     } 

     public interface OnDuplicateClickListener { 
      void onDuplicateClick(int photoPosition, int duplicatePosition); 
     } 

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

     @Override 
     public void onBindViewHolder(DuplicateAdapter.ViewHolder holder, int position) { 
      Picasso.with(mContext) 
        .load(mDuplicates.get(position)) 
        .fit() 
        .centerCrop() 
        .into(holder.mDuplicateImageView); 
     } 

     @Override 
     public int getItemCount() { 
      return mDuplicates == null ? 0 : mDuplicates.size(); 
     } 

     public void setOnDuplicateClickListener(OnDuplicateClickListener listener) { 
      mListener = listener; 
     } 

     public class ViewHolder extends RecyclerView.ViewHolder { 

      @Bind(R.id.iv_duplicate) SquareImageView mDuplicateImageView; 

      @OnClick(R.id.iv_duplicate) 
      void onDuplicateClick() { 
       if (mListener != null) mListener.onDuplicateClick(mPhotoPosition, getAdapterPosition()); 
      } 

      public ViewHolder(View itemView) { 
       super(itemView); 
       ButterKnife.bind(this, itemView); 
      } 
     } 
    } 
} 

Und das ist, wie ich von subitem Anruf zu entfernen (in Activity)

// implementing of DuplicatesFragment.OnRemoveListener 
@Override 
public void onRemove(int photoPosition, int duplicatePosition) { 
    fm.popBackStackImmediate(); 
    Fragment fragment = fm.findFragmentById(R.id.fragment_container); 
    if (fragment instanceof DuplicatesFragment) { 
     DuplicatesFragment duplicatesFragment = (DuplicatesFragment) fragment; 
     duplicatesFragment.removeDuplicate(photoPosition, duplicatePosition); 
    } 
} 

Und removeDuplicate Methode in DuplicatesFragment:

public void removeDuplicate(int photoPosition, int duplicatePosition) { 
    if (mAdapter != null) mAdapter.removeDuplicate(photoPosition, duplicatePosition); 
} 

mAdapter - Instanz von PhotoWithDuplicatesAdapterTest. Was mache ich falsch?

Das ist, wie es aussieht: enter image description here

Da ist MediaWithDuplicatesTest Objekt:

public class MediaWithDuplicatesTest { 

    private String mPhoto; 
    private List<String> mDuplicates; 

    public String getPhoto() { 
     return mPhoto; 
    } 

    public void setPhoto(String photo) { 
     mPhoto = photo; 
    } 

    public List<String> getDuplicates() { 
     return mDuplicates; 
    } 

    public void setDuplicates(List<String> duplicates) { 
     mDuplicates = duplicates; 
    } 
} 

Vielleicht wird es hilfreich sein, wenn ich auch den Code der Erstellung meiner Testdaten und Adapter schreiben:

private void populateRecyclerViewHolder() { 
    LinearLayoutManager manager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false); 
    mAdapter = new PhotoWithDuplicatesAdapterTest(getContext(), getFakeData()); 
    mAdapter.setOnDuplicateClickListener(this); 
    mViewHolder.mPhotosWithDuplicatesRecyclerView.setLayoutManager(manager); 
    mViewHolder.mPhotosWithDuplicatesRecyclerView.setAdapter(mAdapter); 
} 

private List<MediaWithDuplicatesTest> getFakeData() { 
    List<MediaWithDuplicatesTest> fakeData = new ArrayList<>(); 
    List<String> fakeDuplicates = getFakeDuplicates(); 
    for (String fakeDuplicate : fakeDuplicates) { 
     MediaWithDuplicatesTest fake = new MediaWithDuplicatesTest(); 
     fake.setPhoto(fakeDuplicate); 
     fake.setDuplicates(fakeDuplicates); 
     fakeData.add(fake); 
    } 
    return fakeData; 
} 

private List<String> getFakeDuplicates() { 
    return new ArrayList<String>() { 
     { 
      add("http://2.bp.blogspot.com/-CmBgofK7QzU/TVj3u3N1h2I/AAAAAAAADN8/OszBhGvvXRU/s640/tumblr_lg7h9gpbtP1qap9qio1_500.jpeg"); 
      add("http://www.newcastlewildflower.com.au/wp-content/uploads/2013/05/9fkUCY02te7bqobeZzdT9SEio1_500.jpg"); 
      add("http://img.ffffound.com/static-data/assets/6/51cc46900bf5fe574293d49c4d9939e0ebfc8ee3_m.jpg"); 
      add("http://2.bp.blogspot.com/-CmBgofK7QzU/TVj3u3N1h2I/AAAAAAAADN8/OszBhGvvXRU/s640/tumblr_lg7h9gpbtP1qap9qio1_500.jpeg"); 
      add("http://www.newcastlewildflower.com.au/wp-content/uploads/2013/05/9fkUCY02te7bqobeZzdT9SEio1_500.jpg"); 
      add("http://img.ffffound.com/static-data/assets/6/51cc46900bf5fe574293d49c4d9939e0ebfc8ee3_m.jpg"); 
     } 
    }; 
} 
+0

Uhm, können wir den Arbeitsablauf visuell darstellen? Es ist schwer vorstellbar, was Sie erreichen wollen. – GPuschka

+0

@GPuschka Ich habe meinen Beitrag bearbeitet. Wie Sie sehen können, haben wir auf dem Bildschirm eine Liste. Jedes Element der Liste repräsentiert: ImageView (in grauem Hintergrund) und eine andere Liste (rechts von ImageView) –

+0

Hmm, ich sehe nichts, was die Logik des bereitgestellten Codes brechen könnte. Außer vielleicht die Implementierung von MediaWithDuplicatesTest. Wie wird es umgesetzt? – GPuschka

Antwort

1

Alles klar, wir gehen. In der privaten Liste getFakeData() Methode übergeben Sie die gleiche Liste von fakeDuplicates an alle Elemente in für den Hauptadapter. Das bedeutet, dass sie die zugrunde liegenden Daten teilen. Änderungen daran spiegeln sich in allen Ansichten wider, die aus den Daten erstellt wurden. Setzen Sie die Instanziierung der Liste innerhalb der Schleife und sehen Sie, ob das hilft.

+0

Wow erstelle. Es hilft bei meinem ersten Problem. Vielen Dank! Aber das zweite Problem ist immer noch hier :( –

+0

Versuchen Sie zu beobachten, wann und wie die 'private void populateRecyclerViewHolder()' aufgerufen wird. Es sollte nur einmal aufgerufen werden, aber aus dem Code gesehen und die Beschreibung ist meine irgendwo dazwischen aufgerufen Entfernen eines Duplikats Ist die Detailansicht ein Vorgang? – GPuschka

+0

Nein.Detailansicht ist ein Fragment –