首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android (Java) RecyclerView在试图解析JSON时崩溃

Android (Java) RecyclerView在试图解析JSON时崩溃
EN

Stack Overflow用户
提问于 2021-12-15 21:10:09
回答 1查看 60关注 0票数 0

在过去的几天里,我一直试图在我的移动应用程序中实现一个回收视图,该应用程序可以用图片显示所有的结果。对于这个项目,我使用的是调羹API。我的问题是,每次我尝试运行它时,应用程序都会崩溃,下面的错误信息如下所示。在收到错误信息之前,我可以看到我得到了api的响应,但是回收器视图没有膨胀。

当我注释掉整个parseJSON()时,视图就会出现,但它显然只是一个空页面。

我也尝试过JsonObjectRequest stringRequest = new JsonObjectRequest(Request.Method.GET, uri.toString(), null, new Response.Listener<JSONObject>() {而不是当前的StringRequest

是我的解析JSON函数的问题,还是我看错地方了,而适配器导致了viewholder的问题?

Logcat消息:

代码语言:javascript
运行
复制
2021-12-15 20:34:32.138 28763-28763/com.example.foodapp D/AndroidRuntime: Shutting down VM
2021-12-15 20:34:32.142 28763-28763/com.example.foodapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.foodapp, PID: 28763
    android.content.res.Resources$NotFoundException: Resource ID #0x0
        at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:237)
        at android.content.res.Resources.loadXmlResourceParser(Resources.java:2400)
        at android.content.res.Resources.getLayout(Resources.java:1252)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:530)
        at com.example.foodapp.FoodsAdapter.onCreateViewHolder(FoodsAdapter.java:28)
        at com.example.foodapp.FoodsAdapter.onCreateViewHolder(FoodsAdapter.java:18)
        at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:7078)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6235)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
        at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1873)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1873)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at androidx.appcompat.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:536)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:784)
        at android.view.View.layout(View.java:22844)
        at android.view.ViewGroup.layout(ViewGroup.java:6389)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3470)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2938)
2021-12-15 20:34:32.142 28763-28763/com.example.foodapp E/AndroidRuntime:     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
        at android.view.Choreographer.doCallbacks(Choreographer.java:796)
        at android.view.Choreographer.doFrame(Choreographer.java:731)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

查询“鸡”一词的结果

代码语言:javascript
运行
复制
{
    "results": [{
        "vegetarian": false,
        "vegan": false,
        "glutenFree": false,
        "dairyFree": false,
        "veryHealthy": true,
        "cheap": false,
        "veryPopular": false,
        "sustainable": false,
        "weightWatcherSmartPoints": 11,
        "gaps": "no",
        "lowFodmap": false,
        "aggregateLikes": 2,
        "spoonacularScore": 92.0,
        "healthScore": 90.0,
        "creditsText": "Foodista.com – The Cooking Encyclopedia Everyone Can Edit",
        "license": "CC BY 3.0",
        "sourceName": "Foodista",
        "pricePerServing": 168.12,
        "id": 654959,
        "title": "Pasta With Tuna",
        "readyInMinutes": 45,
        "servings": 4,
        "sourceUrl": "http://www.foodista.com/recipe/K6QWSKQM/pasta-with-tuna",
        "image": "https://spoonacular.com/recipeImages/654959-312x231.jpg",
        "imageType": "jpg",
        "summary": "Pasta With Tuna might be just the main course you are searching for. One serving contains <b>421 calories</b>, <b>24g of protein</b>, and <b>10g of fat</b>. For <b>$1.68 per serving</b>, this recipe <b>covers 28%</b> of your daily requirements of vitamins and minerals. 1 person were impressed by this recipe. Head to the store and pick up flour, onion, peas, and a few other things to make it today. It is a good option if you're following a <b>pescatarian</b> diet. All things considered, we decided this recipe <b>deserves a spoonacular score of 92%</b>. This score is excellent. Try <a href=\"https://spoonacular.com/recipes/pasta-and-tuna-salad-ensalada-de-pasta-y-atn-226303\">Pastan and Tuna Salad (Ensalada de Pasta y Atún)</a>, <a href=\"https://spoonacular.com/recipes/tuna-pasta-565100\">Tuna Pasta</a>, and <a href=\"https://spoonacular.com/recipes/tuna-pasta-89136\">Tuna Pasta</a> for similar recipes.",
        "cuisines": [],
        "dishTypes": ["lunch", "main course", "main dish", "dinner"],
        "diets": ["pescatarian"],
        "occasions": [],
        "analyzedInstructions": [{
            "name": "",
            "steps": [{
                "number": 1,
                "step": "Cook pasta in a large pot of boiling water until al dente.",
                "ingredients": [{
                    "id": 20420,
                    "name": "pasta",
                    "localizedName": "pasta",
                    "image": "fusilli.jpg"
                }, {
                    "id": 14412,
                    "name": "water",
                    "localizedName": "water",
                    "image": "water.png"
                }],
                "equipment": [{
                    "id": 404752,
                    "name": "pot",
                    "localizedName": "pot",
                    "image": "stock-pot.jpg"
                }]
            }, {
                "number": 2,
                "step": "Drain and return to warm pot. Put olive oil in saucepan and add onion.",
                "ingredients": [{
                    "id": 4053,
                    "name": "olive oil",
                    "localizedName": "olive oil",
                    "image": "olive-oil.jpg"
                }, {
                    "id": 11282,
                    "name": "onion",
                    "localizedName": "onion",
                    "image": "brown-onion.png"
                }],
                "equipment": [{
                    "id": 404669,
                    "name": "sauce pan",
                    "localizedName": "sauce pan",
                    "image": "sauce-pan.jpg"
                }, {
                    "id": 404752,
                    "name": "pot",
                    "localizedName": "pot",
                    "image": "stock-pot.jpg"
                }]
            }, {
                "number": 3,
                "step": "Saute until transparent. Stir in flour and cook for a few seconds and then whisk in milk. Stir constantly until this thickens.",
                "ingredients": [{
                    "id": 20081,
                    "name": "all purpose flour",
                    "localizedName": "all purpose flour",
                    "image": "flour.png"
                }, {
                    "id": 1077,
                    "name": "milk",
                    "localizedName": "milk",
                    "image": "milk.png"
                }],
                "equipment": [{
                    "id": 404661,
                    "name": "whisk",
                    "localizedName": "whisk",
                    "image": "whisk.png"
                }]
            }, {
                "number": 4,
                "step": "Add peas, tuna (shredded into chunks,) parsley, green onions, cheese and hot pepper sauce.",
                "ingredients": [{
                    "id": 6168,
                    "name": "hot sauce",
                    "localizedName": "hot sauce",
                    "image": "hot-sauce-or-tabasco.png"
                }, {
                    "id": 11291,
                    "name": "green onions",
                    "localizedName": "green onions",
                    "image": "spring-onions.jpg"
                }, {
                    "id": 11297,
                    "name": "parsley",
                    "localizedName": "parsley",
                    "image": "parsley.jpg"
                }, {
                    "id": 1041009,
                    "name": "cheese",
                    "localizedName": "cheese",
                    "image": "cheddar-cheese.png"
                }, {
                    "id": 11304,
                    "name": "peas",
                    "localizedName": "peas",
                    "image": "peas.jpg"
                }, {
                    "id": 10015121,
                    "name": "tuna",
                    "localizedName": "tuna",
                    "image": "canned-tuna.png"
                }],
                "equipment": []
            }, {
                "number": 5,
                "step": "Pour over pasta and stir gently to mix.",
                "ingredients": [{
                    "id": 20420,
                    "name": "pasta",
                    "localizedName": "pasta",
                    "image": "fusilli.jpg"
                }],
                "equipment": []
            }, {
                "number": 6,
                "step": "Serve at once.",
                "ingredients": [],
                "equipment": []
            }]
        }],
        "spoonacularSourceUrl": "https://spoonacular.com/pasta-with-tuna-654959"
    }, {
        "vegetarian": false,
        "vegan": false,
        "glutenFree": false,
        "dairyFree": false,
        "veryHealthy": false,
        "cheap": false,
        "veryPopular": false,
        "sustainable": false,
        "weightWatcherSmartPoints": 24,
        "gaps": "no",
        "lowFodmap": false,
        "aggregateLikes": 1,
        "spoonacularScore": 67.0,
        "healthScore": 28.0,
        "creditsText": "Pick Fresh Foods",
        "license": "CC BY 3.0",
        "sourceName": "Pick Fresh Foods",
        "pricePerServing": 274.82,
        "id": 511728,
        "title": "Pasta Margherita",
        "readyInMinutes": 45,
        "servings": 4,
        "sourceUrl": "http://pickfreshfoods.com/pasta-margherita/",
        "image": "https://spoonacular.com/recipeImages/511728-312x231.jpg",
        "imageType": "jpg",
        "summary": "Pasta Margherita might be just the main course you are searching for. One serving contains <b>809 calories</b>, <b>34g of protein</b>, and <b>34g of fat</b>. This recipe serves 4 and costs $2.75 per serving. 1 person has made this recipe and would make it again. If you have basil, linguine pasta, garlic clove, and a few other ingredients on hand, you can make it. To use up the olive oil you could follow this main course with the <a href=\"https://spoonacular.com/recipes/sauteed-banana-granola-and-yogurt-parfait-624619\">Sauteed Banana, Granolan and Yogurt Parfait</a> as a dessert. All things considered, we decided this recipe <b>deserves a spoonacular score of 69%</b>. This score is pretty good. Similar recipes include <a href=\"https://spoonacular.com/recipes/margherita-pizza-with-pesto-pasta-salad-31919\">Margherita Pizza With Pesto Pasta Salad</a>, <a href=\"https://spoonacular.com/recipes/pasta-margherita-with-rhubarb-and-apple-compote-613006\">Pasta margherita with rhubarb and apple compote</a>, and <a href=\"https://spoonacular.com/recipes/margherita-pizzette-516272\">Margherita Pizzette</a>.",
        "cuisines": [],
        "dishTypes": ["lunch", "main course", "main dish", "dinner"],
        "diets": [],
        "occasions": [],
        "analyzedInstructions": [{
            "name": "",
            "steps": [{
                "number": 1,
                "step": "Whisk oil, garlic, basil, salt together in large bowl.",
                "ingredients": [{
                    "id": 11215,
                    "name": "garlic",
                    "localizedName": "garlic",
                    "image": "garlic.png"
                }, {
                    "id": 2044,
                    "name": "basil",
                    "localizedName": "basil",
                    "image": "basil.jpg"
                }, {
                    "id": 2047,
                    "name": "salt",
                    "localizedName": "salt",
                    "image": "salt.jpg"
                }, {
                    "id": 4582,
                    "name": "cooking oil",
                    "localizedName": "cooking oil",
                    "image": "vegetable-oil.jpg"
                }],
                "equipment": [{
                    "id": 404661,
                    "name": "whisk",
                    "localizedName": "whisk",
                    "image": "whisk.png"
                }, {
                    "id": 404783,
                    "name": "bowl",
                    "localizedName": "bowl",
                    "image": "bowl.jpg"
                }]
            }, {
                "number": 2,
                "step": "Add tomatoes and mozzarella then gently toss to combine; set aside.Cook pasta according to package directions for al dente.",
                "ingredients": [{
                    "id": 1026,
                    "name": "mozzarella",
                    "localizedName": "mozzarella",
                    "image": "mozzarella.png"
                }, {
                    "id": 11529,
                    "name": "tomato",
                    "localizedName": "tomato",
                    "image": "tomato.png"
                }, {
                    "id": 20420,
                    "name": "pasta",
                    "localizedName": "pasta",
                    "image": "fusilli.jpg"
                }],
                "equipment": []
            }, {
                "number": 3,
                "step": "Drain well.",
                "ingredients": [],
                "equipment": []
            }, {
                "number": 4,
                "step": "Add pasta to tomato mixture and gently toss to combine.",
                "ingredients": [{
                    "id": 11529,
                    "name": "tomato",
                    "localizedName": "tomato",
                    "image": "tomato.png"
                }, {
                    "id": 20420,
                    "name": "pasta",
                    "localizedName": "pasta",
                    "image": "fusilli.jpg"
                }],
                "equipment": []
            }, {
                "number": 5,
                "step": "Serve immediately.",
                "ingredients": [],
                "equipment": []
            }]
        }],
        "spoonacularSourceUrl": "https://spoonacular.com/pasta-margherita-511728"
    }],
    "offset": 0,
    "number": 2,
    "totalResults": 211
}

我的RecyclerView片段

代码语言:javascript
运行
复制
public class RecyclerViewFragment extends Fragment {
    private RecyclerView mRecyclerView;
    private FoodsAdapter mFoodsAdapter;
    private ArrayList<FoodListItem> mFoodList = new ArrayList<FoodListItem>();
    private RequestQueue mRequestQueue;

    private static final String TAG = "RecyclerViewFragment";


    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    public static final String ARG_FOOD_NAME = "foodName";
    public static final String ARG_DIET_PLAN = "dietPlan";

    private String mFoodName;
    private String mDietPlan;

    public RecyclerViewFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param foodName the name of the food from user input.
     * @param dietPlan the diet plan selected on the spinner.
     * @return A new instance of fragment RecyclerViewFragment.
     */
    public static RecyclerViewFragment newInstance(String foodName, String dietPlan) {
        RecyclerViewFragment fragment = new RecyclerViewFragment();
        Bundle args = new Bundle();
        args.putString(ARG_FOOD_NAME, foodName);
        args.putString(ARG_DIET_PLAN, dietPlan);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mFoodName = getArguments().getString(ARG_FOOD_NAME);
            mDietPlan = getArguments().getString(ARG_DIET_PLAN);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_recycler_view, container, false);

        mRecyclerView = view.findViewById(R.id.rv_foodlist);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
        mRecyclerView.setAdapter(new FoodsAdapter(mFoodList));

        mFoodList = new ArrayList<>();

        mRequestQueue = Volley.newRequestQueue(view.getContext());
        return view;
    }

    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        parseJSON();
    }

    private void parseJSON() {
        Uri uri = Utils.buildUri("https://api.spoonacular.com/recipes/complexSearch?apiKey=5da441b5a0254a19a401525d92b6cd73", "query", mFoodName, "addRecipeInformation", "true","number", "2");

        StringRequest stringRequest = new StringRequest(Request.Method.GET, uri.toString(), new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.d(TAG, response);

                try {
                    // fetch JSONArray named results
                    JSONObject rootObject = new JSONObject(response);
                    JSONArray jsonArray = rootObject.getJSONArray("results");
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject result = jsonArray.getJSONObject(i);

                        mFoodList.add(new FoodListItem(result.getString("title"), result.getString("image"), result.getInt("readyInMinutes")));
                    }

                    mFoodsAdapter = new FoodsAdapter(mFoodList);
                    mRecyclerView.setAdapter(mFoodsAdapter);

                } catch (JSONException e) {
                    Toast.makeText(getActivity(), getString(R.string.toast_error_downloading_food), Toast.LENGTH_LONG);
                }

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
            }
        });

        mRequestQueue.add(stringRequest);
    }
}

我的RecyclerView适配器

代码语言:javascript
运行
复制
public class FoodsAdapter extends RecyclerView.Adapter<FoodsAdapter.RecyclerViewHolder> {
    private ArrayList<FoodListItem> mFoodList;

    public FoodsAdapter(ArrayList<FoodListItem> foodList){
        mFoodList = foodList;
    }

    @NonNull
    @Override
    public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
        return new RecyclerViewHolder(view);

    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
        FoodListItem currentItem = mFoodList.get(position);

        String imageUrl = currentItem.getImageUrl();
        String foodName = currentItem.getFoodName();
        int timeToMake = currentItem.getTimeToMake();

        holder.mTextViewFoodName.setText(foodName);
        holder.mTextViewTimeToMake.setText("Preparation time: " + timeToMake);
        Picasso.get().load(imageUrl).fit().centerInside().into(holder.mImageView);

    }

    @Override
    public int getItemCount() {
        if (mFoodList != null)
        return mFoodList.size();
        else
            return 0;
    }

    public class RecyclerViewHolder extends RecyclerView.ViewHolder{
        public ImageView mImageView;
        public TextView mTextViewFoodName;
        public TextView mTextViewTimeToMake;

        public RecyclerViewHolder(@NonNull View itemView) {
            super(itemView);
            mImageView = itemView.findViewById(R.id.iv_title_image);
            mTextViewFoodName = itemView.findViewById(R.id.tv_food_name);
            mTextViewTimeToMake = itemView.findViewById(R.id.tv_food_time_to_make);
        }
    }

}

FoodListItem.java

代码语言:javascript
运行
复制
public class FoodListItem {
    private String mImageUrl;
    private String mFoodName;
    private int mTimeToMake;

    public FoodListItem(String imageUrl, String foodName, int timeToMake) {
        mImageUrl = imageUrl;
        mFoodName = foodName;
        mTimeToMake = timeToMake;
    }

    public String getImageUrl(){
        return mImageUrl;
    }

    public void setFoodName(String inFoodName){
        this.mFoodName = inFoodName;

    }

    public String getFoodName(){
        return mFoodName;
    }

    public int getTimeToMake(){
        return mTimeToMake;
    }
}

Uri生成器

代码语言:javascript
运行
复制
    @NonNull
    public static Uri buildUri(String base, String paramName, String paramValue, String requestParamName, String requestParamValue, String numberOfItemsName, String numberOfItemsValue){
        Uri uri = Uri.parse(base);
        // create a URI Builder and add the parameter
        Uri.Builder uriBuilder = uri.buildUpon();
        uriBuilder.appendQueryParameter(paramName, paramValue).appendQueryParameter(requestParamName, requestParamValue).appendQueryParameter(numberOfItemsName, numberOfItemsValue);
        return uriBuilder.build();
    }
EN

回答 1

Stack Overflow用户

发布于 2021-12-17 10:28:06

正如我在适配器中看到的,请检查onBindViewHolder (),您必须用一个布局项代替viewType,下面的代码将根据您的要求运行。请运行以下代码

/我的RecyclerView片段/

代码语言:javascript
运行
复制
public class RecyclerViewFragment extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private FoodsAdapter mFoodsAdapter;
    private ArrayList<FoodListItem> mFoodList = new ArrayList<FoodListItem>();
    private RequestQueue mRequestQueue;

    private static final String TAG = "RecyclerViewFragment";
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    public static final String ARG_FOOD_NAME = "foodName";
    public static final String ARG_DIET_PLAN = "dietPlan";

    private String mFoodName = "foodName";
    private String mDietPlan = "dietPlan";

    private Uri buildUri(String base, String paramName, String paramValue, String requestParamName, String requestParamValue, String numberOfItemsName, String numberOfItemsValue) {
        Uri uri = Uri.parse(base);
        // create a URI Builder and add the parameter
        Uri.Builder uriBuilder = uri.buildUpon();
        uriBuilder.appendQueryParameter(paramName, paramValue).appendQueryParameter(requestParamName, requestParamValue).appendQueryParameter(numberOfItemsName, numberOfItemsValue);
        return uriBuilder.build();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycler_view_fragment);

        mRecyclerView = findViewById(R.id.rv_foodlist);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setAdapter(new FoodsAdapter(mFoodList));

        mFoodList = new ArrayList<>();

        mRequestQueue = Volley.newRequestQueue(this);

        parseJSON();
    }

    private void parseJSON() {
        Uri uri = buildUri("https://api.spoonacular.com/recipes/complexSearch?apiKey=5da441b5a0254a19a401525d92b6cd73", "query", "chicken", "addRecipeInformation", "true", "number", "2");

        StringRequest stringRequest = new StringRequest(Request.Method.GET, uri.toString(), new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.d(TAG, response);

                try {
                    // fetch JSONArray named results
                    JSONObject rootObject = new JSONObject(response);
                    JSONArray jsonArray = rootObject.getJSONArray("results");
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject result = jsonArray.getJSONObject(i);

                        mFoodList.add(new FoodListItem(result.getString("image"), result.getString("title"), result.getInt("readyInMinutes")));
                    }

                    mFoodsAdapter = new FoodsAdapter(mFoodList);
                    mRecyclerView.setAdapter(mFoodsAdapter);

                } catch (JSONException e) {
                    Toast.makeText(RecyclerViewFragment.this, getString(R.string.toast_error_downloading_food), Toast.LENGTH_LONG);
                }

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
            }
        });

        mRequestQueue.add(stringRequest);
    }
}

/我的RecyclerView适配器/

代码语言:javascript
运行
复制
public class FoodsAdapter extends RecyclerView.Adapter<FoodsAdapter.RecyclerViewHolder> {
    private ArrayList<FoodListItem> mFoodList;

    public FoodsAdapter(ArrayList<FoodListItem> foodList) {
        mFoodList = foodList;
    }

    @NonNull
    @Override
    public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.foods, parent, false);
        return new RecyclerViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
        FoodListItem currentItem = mFoodList.get(position);

        String imageUrl = currentItem.getImageUrl();
        String foodName = currentItem.getFoodName();
        int timeToMake = currentItem.getTimeToMake();

        holder.mTextViewFoodName.setText(foodName);
        holder.mTextViewTimeToMake.setText("Preparation time: " + timeToMake);
        Picasso.get().load(imageUrl).fit().centerInside().into(holder.mImageView);

    }

    @Override
    public int getItemCount() {
        if (mFoodList != null)
            return mFoodList.size();
        else
            return 0;
    }

    public class RecyclerViewHolder extends RecyclerView.ViewHolder {
        public ImageView mImageView;
        public TextView mTextViewFoodName;
        public TextView mTextViewTimeToMake;

        public RecyclerViewHolder(@NonNull View itemView) {
            super(itemView);
            mImageView = itemView.findViewById(R.id.iv_title_image);
            mTextViewFoodName = itemView.findViewById(R.id.tv_food_name);
            mTextViewTimeToMake = itemView.findViewById(R.id.tv_food_time_to_make);
        }
    }
}

/添加foods.xml s.xml/

代码语言:javascript
运行
复制
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="4dp">


    <ImageView
        android:id="@+id/iv_title_image"
        android:layout_width="60dp"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/whatsappchatbackground" />

    <TextView
        android:id="@+id/tv_food_name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="14sp"
        android:textAlignment="center"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/iv_title_image"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_food_time_to_make"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="14sp"
        android:textAlignment="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/iv_title_image" />
</androidx.constraintlayout.widget.ConstraintLayout>

/

代码语言:javascript
运行
复制
public class FoodListItem {
    private String mImageUrl;
    private String mFoodName;
    private int mTimeToMake;

    public FoodListItem(String imageUrl, String foodName, int timeToMake) {
        mImageUrl = imageUrl;
        mFoodName = foodName;
        mTimeToMake = timeToMake;
    }

    public String getImageUrl() {
        return mImageUrl;
    }

    public void setFoodName(String inFoodName) {
        this.mFoodName = inFoodName;

    }

    public String getFoodName() {
        return mFoodName;
    }

    public int getTimeToMake() {
        return mTimeToMake;
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70370337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档