RecyclerView并不总是显示结果

时间:2018-01-18 08:04:57

标签: java android android-recyclerview android-volley

我遇到了这个奇怪的问题,其中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);
    }
}
}

1 个答案:

答案 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());
        }

    }