Я использую android.support.v7.widget.RecyclerView для отображения простых элементов, содержащих текст, а в некоторых случаях и изображений. В основном я следил за учебником здесь https://developer.android.com/training/material/lists-cards.html и просто изменил тип mDataset из String [] в JSONArray и xml ViewHolder. Мой 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>
В этом фрагменте я загружаю всю информацию с веб-сервера. После получения информации я инициализирую элементы в RecyclerView. Я использую LinearLayoutManager, который установлен в методе onCreate моего фрагмента. После добавления адаптера я вызываю метод setHasFixedSize (true) в моем RecyclerView. Класс My Adapter выглядит следующим образом:
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();
}
}
И мой xml для просмотра внутри моего 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>
Итак, вот моя проблема: все работает нормально. Текст и изображение отображаются правильно в моем RecyclerView. Однако, если я дойду до конца списка, прокрутив вниз и снова прокручивая изображение, изображения отображаются в элементах, которые не должны содержать изображения. На данный момент у меня есть девять предметов. Последние два из них содержат изображение. Поэтому я прокручиваю вниз и просто вижу текст в первых семи пунктах. Достижение конца списка показывает мне две картины, как ожидалось. Но если я снова прокручу страницу, эти картинки появятся в других предметах.
Прокрутка вверх и вниз меняет изображения всегда в том же порядке:
- Первая прокрутка (после однократного уменьшения) создает изображение во втором элементе.
- Скроллинг создает изображение в 7-м элементе.
- Прокрутка создает изображение в первом элементе.
- Скроллинг ничего не создает.
- Прокрутка создает изображение в третьем элементе, а изображение во втором элементе перезаписывается другим изображением.
- Прокрутка вниз создает изображение в 6-м элементе и позволяет снимку в 7-м элементе исчезнуть.
- И так далее...
Я уже обнаружил, что метод onBindViewHolder (ViewHolder, int position) вызывается каждый раз, когда элемент появляется снова на экране. Я проверил позицию и данные в моем mDataset. Здесь все прекрасно работает: позиция правильная и данная информация тоже. Текст во всех элементах не изменяется и всегда отображается правильно. Кто-нибудь есть какая-то проблема и знает какое-то решение? Любая помощь высоко ценится.:)