Sto usando android.support.v7.widget.RecyclerView per mostrare elementi semplici contenenti testo e in alcuni casi anche immagini. Fondamentalmente ho seguito il tutorial da qui https://developer.android.com/training/material/lists-cards.html e ho appena cambiato il tipo di mDataset da String [] a JSONArray e l'xml di ViewHolder. Il mio RecyclerView si trova in un semplice frammento:Strano comportamento delle immagini in RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
android:id="@+id/my_hopps_recycler_view"
android:scrollbars="vertical"
android:layout_centerInParent="true"
android:layout_width="200dp"
android:layout_height="wrap_content"/>
</RelativeLayout>
In questo frammento sto caricando tutte le informazioni da un server web. Dopo aver ricevuto le informazioni, inizializzo gli elementi in RecyclerView. Io uso un LinearLayoutManager che è impostato nel metodo onCreate del mio frammento. Dopo aver aggiunto l'adattatore, chiamo il metodo setHasFixedSize (true) sul mio RecyclerView. La mia classe Adapter si presenta così:
import android.graphics.BitmapFactory;
import android.support.v7.widget.RecyclerView;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.apache.commons.lang3.StringEscapeUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import saruul.julian.MyFragment;
import saruul.julian.R;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
/**
* Fragment holding the RecyclerView.
*/
private MyFragment myFragment;
/**
* The data to display.
*/
private JSONArray mDataset;
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView text;
ImageView image;
public ViewHolder(View v) {
super(v);
text = (TextView) v.findViewById(R.id.my_view_text);
image = (ImageView) v.findViewById(R.id.my_view_image);
}
}
public MyAdapter(MyFragment callingFragment, JSONArray myDataset) {
myFragment = callingFragment;
mDataset = myDataset;
}
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_view, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
try {
JSONObject object = mDataset.getJSONObject(position);
if (object.has("image")){
if (!hopp.getString("image").equals("")){
try {
byte[] decodedString = Base64.decode(StringEscapeUtils.unescapeJson(object.getString("image")), Base64.DEFAULT);
holder.image.setImageBitmap(BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length));
holder.image.setVisibility(View.VISIBLE);
} catch (Exception e){
e.printStackTrace();
}
}
}
if (object.has("text")){
holder.text.setText(object.getString("text"));
}
} catch (Exception e){
e.printStackTrace();
}
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.length();
}
}
E il mio xml per una vista all'interno del mio RecyclerView:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="@dimen/activity_horizontal_margin">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/my_hopp_people_reached"/>
<ImageView
android:id="@+id/my_hopp_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:adjustViewBounds="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/my_hopp_text"/>
<ImageButton
android:id="@+id/my_hopp_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:src="@drawable/ic_action_discard"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
Così ora qui è il mio problema: tutto funziona bene. Testo e immagine sono visualizzati correttamente nel mio RecyclerView. Tuttavia, se raggiungo la fine dell'elenco scorrendo verso il basso e scorrendo di nuovo verso l'alto, le immagini vengono visualizzate in voci che non devono contenere immagini. Al momento ho nove articoli. Gli ultimi due contengono un'immagine. Quindi scorro verso il basso e vedo solo il testo nei primi sette elementi. Raggiungere la fine della lista mi mostra due immagini come previsto. Ma se faccio scorrere verso l'alto, quelle immagini appaiono in altri oggetti.
scorrere su e giù cambia le immagini sempre nello stesso ordine:
- Il primo scorrendo verso l'alto (dopo essere stato giù una volta) crea un quadro nella seconda voce.
- Lo scorrimento verso il basso crea un'immagine nel settimo elemento.
- Lo scorrimento verso l'alto crea un'immagine nel primo elemento.
- Lo scorrimento verso il basso non crea nulla.
- Lo scorrimento verso l'alto crea un'immagine nel terzo elemento e l'immagine nel secondo elemento è stata sovrascritta con l'altra immagine.
- Lo scorrimento verso il basso crea un'immagine nel sesto elemento e fa scomparire l'immagine nel settimo elemento.
- E così via ...
ho già scoperto che il metodo onBindViewHolder (ViewHolder titolare, int position) è chiamato ogni volta che un oggetto appare di nuovo sullo schermo. Ho controllato la posizione e le informazioni fornite nel mio mDataset. Tutto funziona bene qui: la posizione è giusta e anche le informazioni fornite. Il testo in tutte le voci non cambia e viene sempre visualizzato correttamente. Qualcuno ha qualche tipo di questo problema e conosce qualche soluzione?
Questo sembra fare il trucco! Ho messo una clausola else alla mia istruzione if (! Hopp.getString ("image"). Equals ("")) perché ci sarà sempre un campo immagine in JSONObjects. Ho provato la stessa cosa ma ho usato holder.image.setImageBitmap (null) che ovviamente non ha funzionato o l'ho inserito anche nell'istruzione if errata. Non importa perché hai salvato la mia giornata. :) –
Grazie. Ho modificato in 'holder.image.setImageResource (R.drawable.image);' – zackygaurav
Non funziona con volley – delive