14

Questo è il mio primo tentativo di associazione dati con un RecyclerView ma non il mio primo utilizzo di RecyclerView.RecyclerView e Data Binding non funzionanti

Per qualche motivo, nessuno dei metodi dell'adattatore viene chiamato - nemmeno getItemCount(). Potrebbe essere uno stupido problema con il mio RecyclerView e niente a che fare con l'associazione dati, ma non riesco a vedere nulla di sbagliato.

 View rootview = inflater.inflate(R.layout.fragment_profile_first, container, false); 
    // Initialize recycler view 

    RecyclerView badgesRV = (RecyclerView) rootview.findViewById(R.id.badgesRV); 
    LinearLayoutManager llm = new LinearLayoutManager(getActivity()); 
    llm.setOrientation(LinearLayoutManager.HORIZONTAL); 
    badgesRV.setLayoutManager(llm); 

    BadgeAdapter badgeAdapter = new BadgeAdapter(profileObject.badgesEntity.badges); 
    badgesRV.setAdapter(badgeAdapter); 

Adapter:

public class BadgeAdapter extends RecyclerView.Adapter<BadgeAdapter.BadgeBindingHolder>{ 

    private static final int MAX_BADGES_TO_DISPLAY = 5; 
    private BadgeObject[] badges; 

    public BadgeAdapter(BadgeObject[] badges){ 
     this.badges = badges; 
    } 

    @Override 
    public BadgeBindingHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View v = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.profile_badge_row, parent, false); 
     BadgeBindingHolder holder = new BadgeBindingHolder(v); 
     return holder; 
    } 

    @Override 
    public void onBindViewHolder(BadgeBindingHolder holder, int position) { 
     final BadgeObject badgeObject = badges[position]; 
     holder.getBinding().setVariable(BR.badge, badgeObject); 
     holder.getBinding().executePendingBindings(); 

    } 

    @Override 
    public int getItemCount() { 
     Log.d(TAG, "item count = " + Math.min(MAX_BADGES_TO_DISPLAY, badges.length)); 
     return Math.min(MAX_BADGES_TO_DISPLAY, badges.length); 
    } 

    public class BadgeBindingHolder extends RecyclerView.ViewHolder{ 
     private ViewDataBinding binding; 

     public BadgeBindingHolder(View rowView) { 
      super(rowView); 
      binding = DataBindingUtil.bind(rowView); 
     } 
     public ViewDataBinding getBinding() { 
      return binding; 
     } 
    } 
} 

profile_badge_row.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto"> 

<data> 
    <variable name="badge" type="parseJsonEntities.requestObjects.BadgeObject"/> 
</data> 

<LinearLayout 
    android:orientation="vertical" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <ImageView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@{badge.badgeImage}"/> 

</LinearLayout> 

Ho controllato e non è sicuramente dei dati lì. Cosa mi sono perso?

=====================

Aggiornamento:

Da quello che posso dire RecyclerView semplicemente non funziona all'interno di un Data Binding disposizione. Ho creato un layout separato con solo il mio camper e ha funzionato perfettamente. Non appena l'ho incluso nel mio layout principale, ha smesso di funzionare.

Non sono sicuro se si tratta di un bug o di una funzionalità.

Quindi, ho pensato che forse, se avessi fatto una visualizzazione personalizzata, forse funzionerà e lo farà. Il mio problema è che non so come passare un valore nella mia vista personalizzata.

Ho cercato here ma non riuscivo a capire esattamente cosa intendesse. Questo è il mio codice nella visualizzazione personalizzata.

LayoutInflater inflater = (LayoutInflater) 
      context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View view = inflater.inflate(R.layout.profile_badges_layout, this, true); 
    ProfileBadgesLayoutBinding binding = ProfileBadgesLayoutBinding.inflate(inflater); 

    RecyclerView badgesRV = (RecyclerView) view.findViewById(R.id.badgesRV); 

    LinearLayoutManager llm = new LinearLayoutManager(context); 
    llm.setOrientation(LinearLayoutManager.HORIZONTAL); 
    badgesRV.setLayoutManager(llm); 

    BadgeAdapter badgeAdapter = new BadgeAdapter(null); 
    badgesRV.setAdapter(badgeAdapter); 

Questo dà un messaggio che ProfileBadgesLayoutBinding non è stato trovato.

+0

dov'è il tuo xml frammento ?? –

+0

'RecyclerView' funziona perfettamente con' DataBinding', poiché molti altri lo stanno usando senza problemi. Puoi pubblicare il tuo layout dove si trova il tuo 'RecyclerView'? Forse qualche strano comportamento con altre viste a scorrimento. – yennsarah

+1

Inoltre, che cos'è 'badge.badgeImage'? Un 'ID risorsa', un 'Disegnabile' ..? – yennsarah

risposta

14

Nel vostro onCreateViewHolder:

@Override 
public BadgeBindingHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    ProfileBadgeRowBinding binding = DataBindingUtil.inflate(inflater, R.layout.profile_badge_row, parent, false); 
    BadgeBindingHolder holder = new BadgeBindingHolder(binding.getRoot(), binding); 
    return holder; 
} 

E aggiungere il legame nel vostro elemento Mostra

public class BadgeBindingHolder extends RecyclerView.ViewHolder{ 
    private ProfileBadgeRowBinding binding; 

    public BadgeBindingHolder(View rowView, ProfileBadgeRowBinding binding) { 
     super(rowView); 
     this.binding = binding; 
    } 

    ... 

} 

E nel bindToViewHolder impostare la variabile

@Override 
public void bindToViewHolder(RecyclerView.ViewHolder viewHolder) { 
    ProfileBadgeRowBinding binding = ((BadgeBindingHolder) viewHolder).binding; 
    binding.setVariable(BR.badge, badge); 
    binding.executePendingBindings(); // This line is important, it will force to load the variable in a custom view 
} 

Se si desidera accedere a una vista, aggiungere un ID a una vista nel proprio xml.

<layout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto"> 

    <data> 
     <variable name="badge" type="parseJsonEntities.requestObjects.BadgeObject"/> 
    </data> 

    <LinearLayout 
     android:orientation="vertical" android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <ImageView 
      android:id="@+id/image" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" /> 

    </LinearLayout> 
</layout> 

E allora si può accedere all'ID nella vostra bindToViewHolder

@Override 
public void bindToViewHolder(RecyclerView.ViewHolder viewHolder) { 
    ProfileBadgeRowBinding binding = ((BadgeBindingHolder) viewHolder).binding; 
    binding.setVariable(BR.badge, badge); 
    binding.executePendingBindings(); 

    binding.image.setImage(...); 
} 

più su visualizzazioni personalizzate https://developer.android.com/topic/libraries/data-binding/index.html#dynamic_variables

+2

Grazie! Il mio problema era che non ho usato binding.executePendingBindings(); Non mi sembrava così ovvio. Grazie mille !!!! – Jack

+0

salvagente. +1 questo ha funzionato bene per me. – TharakaNirmana