我遇到了这个奇怪的问题,其中RecyclerView被击中或错过了向我展示我的结果。我正在使用Volley来在服务器上调用我的REST API,它返回一个json文件。 Log.i()向我显示我的结果每次都被抓取,但它们并不总是显示在屏幕上。我会说他们大约有30%的时间出现。
FragmentList
public class FragmentList extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_fragment_list, container, false);
RecyclerView recyclerView;
FoodAdapter adapter;
final List<Food> foodList = new ArrayList<>();
recyclerView = v.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
String url = "https://www.example.com";
StringRequest sr = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
Log.i(TAG, response);
JSONArray foodResp = new JSONArray(response);
for (int i = 0; i < foodResp.length(); i++) {
JSONObject foodObj = foodResp.getJSONObject(i);
foodList.add(
new Food(
1,
R.drawable.ic_launcher_background,
foodObj.getString("mealTitle"),
foodObj.getString("mealDesc"))
);
}
} catch (Exception e) {
Log.i(TAG, "Error: " + e.getMessage());
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.i(TAG, "err: " + error.toString());
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("data", "value");
return params;
}
};
Volley.newRequestQueue(getActivity()).add(sr);
adapter = new FoodAdapter(getActivity(), foodList);
recyclerView.setAdapter(adapter);
return v;
}
}
fragment_fragment_list.xml
<LinearLayout 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"
tools:context="com.localfridge.localfridge.FragmentList">
<!-- TODO: Update blank fragment layout -->
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
FoodAdapter只是加入
FoodAdapter.java
ublic class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.FoodViewHolder> {
private Activity mCtx;
private List<Food> foodList;
public FoodAdapter(Activity mCtx, List<Food> foodList) {
this.mCtx = mCtx;
this.foodList = foodList;
}
@Override
public FoodViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.list_item, null);
FoodViewHolder foodView = new FoodViewHolder(view);
return foodView;
}
@Override
public void onBindViewHolder(FoodViewHolder holder, int position) {
Food food = foodList.get(position);
holder.txtFoodTitle.setText(food.getFoodTitle());
holder.txtFoodDesc.setText(food.getFoodDesc());
holder.imageView.setImageDrawable(mCtx.getResources().getDrawable(food.getImage(), null));
}
@Override
public int getItemCount() {
return foodList.size();
}
class FoodViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView txtFoodTitle, txtFoodDesc, txtFoodLoc;
public FoodViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.foodImg);
txtFoodTitle = itemView.findViewById(R.id.foodTitle);
txtFoodDesc = itemView.findViewById(R.id.foodDesc);
}
}
}
答案 0 :(得分:2)
因为Volley Requests
是异步的。所以填写你的适配器并在得到结果时设置适配器,意味着调用onResponse
解决方案1
@Override
public void onResponse(String response) {
try {
Log.i(TAG, response);
JSONArray foodResp = new JSONArray(response);
for (int i = 0; i < foodResp.length(); i++) {
JSONObject foodObj = foodResp.getJSONObject(i);
foodList.add(
new Food(
1,
R.drawable.ic_launcher_background,
foodObj.getString("mealTitle"),
foodObj.getString("mealDesc"))
);
}
adapter = new FoodAdapter(getActivity(), foodList);
recyclerView.setAdapter(adapter);
} catch (Exception e) {
Log.i(TAG, "Error: " + e.getMessage());
}
}
<强>更新强>
解决方案2
正如评论中所建议的那样。您可以提前设置适配器,但在这种情况下,您必须通知适配器数据已更改
@Override
public void onResponse(String response) {
try {
Log.i(TAG, response);
JSONArray foodResp = new JSONArray(response);
for (int i = 0; i < foodResp.length(); i++) {
JSONObject foodObj = foodResp.getJSONObject(i);
foodList.add(
new Food(
1,
R.drawable.ic_launcher_background,
foodObj.getString("mealTitle"),
foodObj.getString("mealDesc"))
);
}
if(adapter!=null)
{
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
Log.i(TAG, "Error: " + e.getMessage());
}
}