Jas*_*ulo 34 arrays android imageview android-cardview android-recyclerview
我使用android.support.v7.widget.RecyclerView来显示包含文本的简单项目,在某些情况下还显示图像.基本上我从这里按照教程https://developer.android.com/training/material/lists-cards.html,只是将mDataset的类型从String []更改为JSONArray和ViewHolder的xml.我的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>
Run Code Online (Sandbox Code Playgroud)
在这个片段中,我将从Web服务器加载所有信息.收到信息后,我初始化RecyclerView中的项目.我使用了一个LinearLayoutManager,它在我的Fragment的onCreate方法中设置.添加适配器后,我在RecyclerView上调用setHasFixedSize(true)方法.我的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();
}
}
Run Code Online (Sandbox Code Playgroud)
和我的RecyclerView中的视图的xml:
<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>
Run Code Online (Sandbox Code Playgroud)
所以现在这是我的问题:一切正常.我的RecyclerView中正确显示了文本和图片.但是,如果我通过向下滚动并再次向上滚动到达列表的末尾,则图片将显示在不应包含图片的项目中.目前我有九件物品.最后两个包含一张图片.所以我向下滚动,只看到前七项中的文字.到达列表的末尾显示了我预期的两张图片.但如果我再次向上滚动,那些图片会出现在其他项目中.
向上和向下滚动会以相同的顺序更改图片:
我已经发现,每当一个项目再次出现在屏幕上时,就会调用onBindViewHolder(ViewHolder holder,int position)方法.我在mDataset中检查了位置和给定的信息.这里的一切都很好:位置是正确的,也是给定的信息.所有项目中的文本都不会更改,并始终正确显示.有没有人有任何这种问题,并知道一些解决方案?
Joe*_*Joe 47
我认为你需要在方法中else为你的if ( object.has("image") )语句添加一个子句onBindViewHolder(ViewHolder holder, int position),将image设置为null:
holder.image.setImageDrawable(null);
Run Code Online (Sandbox Code Playgroud)
我认为onBindViewHolder的文档最好地描述了为什么这是必要的:
由RecyclerView调用以在指定位置显示数据.此方法应更新itemView的内容以反映给定位置的项目.
你应该总是假设传入的ViewHolder需要完全更新:)
Lio*_*789 14
不确定人们是否仍有这方面的问题,但if语句对我不起作用.对我有用的是:
在适配器中使用此方法的覆盖
@Override
public int getItemViewType(int position) {
return position;
}
Run Code Online (Sandbox Code Playgroud)
然后在onBindViewHolder中为图像本身调用基于此的if语句,如下所示:
int pos = getItemViewType(position);
if(theList.get(pos).getPicture() == null) {
holder.picture.setVisibility(View.GONE);
} else {
Picasso.with(context).load(R.drawable.robot).into(holder.picture);
}
Run Code Online (Sandbox Code Playgroud)
我正在使用毕加索,但它应该适用于任何其他情况.希望这有助于某人!