我正在使用 android.support.v7.widget.RecyclerView 来显示包含文本的简单项目,在某些情况下还包括图像。基本上我按照这里的教程https://developer.android.com/training/material/lists-cards.html只是将 mDataset 的类型从 String[] 更改为 JSONArray 和 ViewHolder 的 xml。我的 RecyclerView 位于一个简单的 Fragment 中:
<?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 中的项目。我使用在我的 Fragment 的 onCreate 方法中设置的 LinearLayoutManager。添加 Adapter 后,我在 RecyclerView 上调用 setHasFixedSize(true) 方法。我的适配器类如下所示:
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 holder, int position) 方法。我检查了我的 mDataset 中的位置和给定信息。这里一切正常:位置正确,给定的信息也正确。所有项目中的文本都不会更改,并且始终正确显示。有没有人有任何这种问题并且知道一些解决方案?