在我的应用程序中,我从Web服务器接收一些数据。此数据将发送到RecyclerView
。首先,所有数据都显示正常。但是,当我尝试刷新它时,数据不再显示。数据从Web服务到达(使用Logcat验证)。
ArrayList<FoodItem> allFood = response.body();
if(foodAdapter != null) {
foodAdapter.swap(allFood);
} else {
foodAdapter = new FoodAdapter(FoodViewForCustomerActivity.this, allFood);
}
photoCollectionView.setAdapter(foodAdapter);
RecyclerView
适配器public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.ViewHolder> {
Context mContext;
ArrayList<FoodItem> foodItems;
public FoodAdapter(Context context, ArrayList<FoodItem> foodItems) {
this.mContext = context;
this.foodItems = foodItems;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.food_item_row, parent, false);
return new ViewHolder(view);
}
public void swap(ArrayList<FoodItem> newFoods) {
foodItems.clear();
foodItems.addAll(newFoods);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
}, 500);
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
FoodItem foodItem = foodItems.get(position);
String stringPicture = foodItem.getPhoto();
byte[] decodedPictureStringArray = Base64.decode(stringPicture, Base64.DEFAULT);
Bitmap bitmapPhoto = BitmapFactory.decodeByteArray(decodedPictureStringArray, 0, decodedPictureStringArray.length);
Uri photoUri = getImageUri(mContext, bitmapPhoto);
Picasso.with(mContext).load(photoUri).resize(300, 300)
.centerCrop().into(holder.foodImage);
holder.foodItemNameText.setText(foodItem.getFoodItemName());
holder.foodPriceText.setText(foodItem.getUnitPrice() + " / " + foodItem.getUnitType());
}
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 10, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
@Override
public int getItemCount() {
return foodItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ImageView foodImage;
public TextView foodItemNameText;
public TextView foodPriceText;
public ViewHolder(View itemView) {
super(itemView);
foodImage = (ImageView) itemView.findViewById(R.id.foodPhoto);
foodItemNameText = (TextView) itemView.findViewById(R.id.foodItemNameText);
foodPriceText = (TextView) itemView.findViewById(R.id.foodPriceText);
}
}
}
RelativeLayout
和Toolbar
RecyclerView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".FoodViewForCustomerActivity">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar"
/>
<android.support.v7.widget.RecyclerView
android:layout_below="@id/toolbar"
android:id="@+id/photoCollectionView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f8f8f8"
android:divider="@null"
android:listSelector="@android:color/transparent"/>
</RelativeLayout>
答案 0 :(得分:2)
抱歉,回答我自己的问题。我按照solution provided here解决了我的问题。我的问题的主要原因是当我试图刷新它时,RecyclerView没有调用onCreateViewHolder或onBindView。
答案 1 :(得分:1)
foodAdapter=new FoodAdapter(FoodViewForCustomerActivity.this,allFood);
更改以上行。 在适配器构造函数中发送foodItems arraylist引用而不是allFood
正确的行
foodAdapter=new FoodAdapter(FoodViewForCustomerActivity.this,foodItems);
答案 2 :(得分:1)
从评论讨论来看。您的RecyclerView
似乎正在从您的来源提供正确的数据。
但是,当数据计数为1时,它将隐藏在其他UI元素下面。
您需要确保RecyclerView
不被其他UI元素遮挡,例如Toolbar
。
有多种方法可以做到这一点。
marginTop
添加?attr/actionBarSize
RecyclerView
。ConstraintLayout
,类似于android:layout_constraintTop_toBottomOf ="@id/toolbar"
。RelativeLayout
,类似于android:layout_below="@id/toolbar"
。您刷新数据的代码有点奇怪:
ArrayList<FoodItem> allFood = response.body();
if(foodAdapter != null) {
foodAdapter.swap(allFood);
} else {
foodAdapter = new FoodAdapter(FoodViewForCustomerActivity.this, allFood);
}
photoCollectionView.setAdapter(foodAdapter);
通常,每次数据更改时都不要设置适配器。您在初始化时设置一次,然后使用notify方法刷新数据。
请将结构分开如下:
,而不是您拥有的内容 FoodViewForCustomerActivity
的成员变量:
private ArrayList<FoodItem> mAllFood = new ArrayList<>();
在onCreate()
:
foodAdapter = new FoodAdapter(FoodViewForCustomerActivity.this, mAllFood);
photoCollectionView.setAdapter(foodAdapter);
在您的数据收集方法中:
ArrayList<FoodItem> food = response.body();
if(foodAdapter != null) {
Log.e(TAG, "Data retrieved (size="+food.size()+"), sending it to Adapter.");
foodAdapter.swap(food);
} else {
Log.e(TAG, "Data retrieved (size="+food.size()+"), but Adapter is null!");
}
答案 3 :(得分:0)
好的,你也可以改变
allFood.clear();
allFood.addAll(newFoods);
notifyDataSetChanged();
答案 4 :(得分:0)
更改此类代码
public void swap(ArrayList<FoodItem> newFoods){
foodItems.clear();
foodItems.addAll(newFoods);
foodAdapter.notifyDataSetChanged();
}