从片段中的json获取值

Posted

技术标签:

【中文标题】从片段中的json获取值【英文标题】:Get values from json in fragment 【发布时间】:2021-07-06 21:35:36 【问题描述】:

我正在尝试从 JSON 获取信息到卡片视图中,我已经在一个单独的项目中制作了这个应用程序并且它可以工作,但现在我正在尝试将它与实际应用程序集成。我正在为实际应用程序使用片段。

package com.example.loginfirebase.news;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;

import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import com.example.loginfirebase.R;
import com.google.android.gms.common.api.Response;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class NewsFragment extends Fragment 
    RecyclerView recyclerView;
    List<Anunturi> anunturiLi;
    private static String JSON_URL = "";
    Adapter adapter;
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public NewsFragment() 
        // Required empty public constructor
    


    public static NewsFragment newInstance(String param1, String param2) 
        NewsFragment fragment = new NewsFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

    


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        if(container==null)
            Log.v("Container",": Containerul este null");
        
        // Inflate the layout for this fragment
        Context aplicationcontext = getActivity().getApplicationContext();
        //Context  thiscontext = container.getContext();
        RecyclerView recyclerView=container.findViewById(R.id.anunturiList);
        if (recyclerView==null)
            Log.v("recycler view value","is null");
        
        Context fragmentcontext=container.getContext();
        anunturiLi = new ArrayList<>();
        extractAnunturi(aplicationcontext,fragmentcontext);
        Log.v("Aplication context", String.valueOf(aplicationcontext));

        return inflater.inflate(R.layout.fragment_news, container, false);
    


//    public void onViewCreated(View view, Bundle savedInstanceState) 
//        super.onCreate(savedInstanceState);
//        RecyclerView recyclerView=view.findViewById(R.id.anunturiList);
//
//
//    

    private void extractAnunturi(Context aplicationcontext,Context fragmentcontext) 
        //TODO: FIX
        Context mContext;
        mContext = fragmentcontext;
        Log.v("Activity non null","activity:"+getActivity());
        RequestQueue queue = Volley.newRequestQueue(getActivity());
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, JSON_URL, null, new com.android.volley.Response.Listener<JSONArray>() 
            @Override
            public void onResponse(JSONArray response) 
                for (int i = 0; i < response.length(); i++) 
                    try 
                        JSONObject anunturiObject = response.getJSONObject(i);

                        Anunturi anunturi = new Anunturi();
                        anunturi.setTitle(anunturiObject.getString("titlu_anunt"));
                        Log.v("Tag anunturi title:",anunturi.getTitle());
                        anunturi.setAutor(anunturiObject.getString("autor_anunt".toString()));
                        Log.v("Tag anunturi title:",anunturi.getAutor());
                        anunturi.setCoverImage(anunturiObject.getString("cover_image"));
                        Log.v("Tag anunturi title:",anunturi.getCoverImage());
                        anunturi.setAnuntURL(anunturiObject.getString("url"));
                        Log.v("Tag anunturi title:",anunturi.getAnuntURL());
                        anunturi.setText_anunt(anunturiObject.getString("text_anunt"));
                        Log.v("Tag anunturi title:",anunturi.getText_anunt());
                        anunturiLi.add(anunturi);
                     catch (JSONException e) 
                        e.printStackTrace();
                    
                
//TODO FIX
                recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
                adapter = new Adapter(getApplicationContext(), anunturiLi);
                recyclerView.setAdapter(adapter);
            

        , new com.android.volley.Response.ErrorListener() 
            @Override
            public void onErrorResponse(VolleyError error) 
                //nimic
            
        );

        queue.add(jsonArrayRequest);

    

我得到了这个错误

F:\LoginFirebase\app\src\main\java\com\example\loginfirebase\news\NewsFragment.java:127: error: cannot find symbol
                recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
                                                                      ^
  symbol: method getApplicationContext()

我尝试将上下文作为参数传递并更改为:

recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
            adapter = new Adapter(getActivity().getApplicationContext(), anunturiLi);
            recyclerView.setAdapter(adapter);

但我得到了这个错误

2021-04-11 19:37:42.632 26960-26960/com.example.loginfirebase D/AndroidRuntime: Shutting down VM
2021-04-11 19:37:42.633 26960-26960/com.example.loginfirebase E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.loginfirebase, PID: 26960
    java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)' on a null object reference
        at com.example.loginfirebase.news.NewsFragment$1.onResponse(NewsFragment.java:127)
        at com.example.loginfirebase.news.NewsFragment$1.onResponse(NewsFragment.java:103)
        at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:90)
        at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

适配器代码:

package com.example.loginfirebase.news;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.loginfirebase.R;
import com.squareup.picasso.Picasso;

import java.util.List;

public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder>

    LayoutInflater inflater;
    List<Anunturi> anunturi;

    public Adapter(Context ctx, List<Anunturi> anunturi)
        this.inflater= LayoutInflater.from(ctx);
        this.anunturi=anunturi;
    

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
        View view=inflater.inflate(R.layout.custom_list_layout,parent,false);
        return new ViewHolder(view);
    

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) 
        //bind the data
        holder.titlu_anunt.setText(anunturi.get(position).getTitle());
        holder.autor_anunt.setText(anunturi.get(position).getAutor());
        Picasso.get().load(anunturi.get(position).getCoverImage()).into(holder.img_anunt);
        holder.text_anunt.setText(anunturi.get(position).getText_anunt());
    

    @Override
    public int getItemCount() 
        return anunturi.size();
    

    public class ViewHolder extends RecyclerView.ViewHolder
        TextView titlu_anunt,autor_anunt,text_anunt;
        ImageView img_anunt;
        public ViewHolder(@NonNull View itemView) 
            super(itemView);
            titlu_anunt=itemView.findViewById(R.id.anunt_title);
            autor_anunt=itemView.findViewById(R.id.anunt_autor);
            text_anunt=itemView.findViewById(R.id.txt_anunt);
            img_anunt=itemView.findViewById(R.id.anunt_image);

        
    

解决方案

必须将代码放在 onViewCreated 中

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) 
    super.onViewCreated(view, savedInstanceState);
    RecyclerView recyclerView=view.findViewById(R.id.anunturiList);
    //View view = inflater.inflate(R.layout.fragment_news, container, false);
    anunturiLi = new ArrayList<>();
    extractAnunturi();

【问题讨论】:

尝试在 Fragment 的 onAttach() 方法中初始化变量 aplicationcontext 【参考方案1】:

当你这样做时:

RecyclerView recyclerView=container.findViewById(R.id.anunturiList);

您将 Recycler View 分配给一个局部变量,因此您的 recyclerView 字段仍然为空。当你在下面使用它时,它会导致 NPE。

您必须将其分配给recyclerView 字段:

recyclerView=container.findViewById(R.id.anunturiList);

【讨论】:

将分配更改为您建议的内容,我仍然收到相同的错误,在我 setLayoutmanager 的行中可以使用 getActivity().getApplicationContext() 吗?

以上是关于从片段中的json获取值的主要内容,如果未能解决你的问题,请参考以下文章

具有获取 json 值的片段中的自定义适配器

如何从“活动”中的“编辑”文本中获取值并将其用于片段?

使用片段从另一个类获取值时出现 NullPointerException [重复]

如何从 JSON 数组中的 JSON 对象中的单个值获取数据?

无法从 Xcode 中的 JSON 获取最新值

如何从该片段中的 onItemSelectedListener 中获取微调器单击的项目?