REST API 对 Fragment 的响应 - Android Studio

Posted

技术标签:

【中文标题】REST API 对 Fragment 的响应 - Android Studio【英文标题】:Response of a REST API into Fragment - Android Studio 【发布时间】:2021-11-25 19:33:27 【问题描述】:

我是在 android 中开发 APP 的新手。我想开发一个分片的APP,每个分片都填充了调用REST API获得的数据。

我遵循了不同的教程,但我遇到了这个问题:片段没有显示任何内容。

我从 android studio 中的“Tabbed Activity”开始我的项目:

这是我的片段(我称之为 api):

public class Calendar extends Fragment 

private static final String baseUrl = "https://xxx";
private static final String events = "/wp-json/sportspress/v2/events";
EventsJsonObjectToMatchesConverter converter;

ArrayList<Matches> matches = new ArrayList<>();

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

    View rootView = inflater.inflate(R.layout.calendar_layout,container, false);
    return rootView;


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

    this.getEvents();

    ListView lv = (ListView)view.findViewById(R.id.matches);

    MatchesAdapter adapter = new MatchesAdapter(this.getContext(),
            R.layout.matches_layout,
            matches);

    lv.setAdapter(adapter);


private void getEvents() 

    // Instantiate the RequestQueue.
    RequestQueue queue = Volley.newRequestQueue(getActivity().getApplicationContext());
    String url =getString(R.string.baseUrl) + getString(R.string.eventsEndpoit);

    // Request a string response from the provided URL.
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() 
                @Override
                public void onResponse(String response) 
                    // Display the first 500 characters of the response string.
                    Matches match = new Matches();
                    match.setHomeTeam("simone");
                    match.setAwayTeam("gaspa");
                    match.setResultHome(2);
                    match.setResultAway(1);
                    match.setDate("05/10/2021 - 10:00");
                    matches.add(match);

                    System.out.println(matches.size());
                
            , new Response.ErrorListener() 
        @Override
        public void onErrorResponse(VolleyError error) 

        
    )
        //This is for Headers If You Needed
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError 
            Map<String, String> params = new HashMap<String, String>();
            params.put("Content-Type", "application/json; charset=UTF-8");
            params.put(
                    "Authorization",
                    String.format("Basic %s", Base64.encodeToString(
                            String.format("%s:%s", getString(R.string.user), getString(R.string.password)).getBytes(), Base64.DEFAULT)));
            return params;
        


    ;

    // Add the request to the RequestQueue.
    queue.add(stringRequest);






这里是我的适配器:

public class MatchesAdapter extends ArrayAdapter<Matches> 

private ArrayList<Matches> matchList;

public MatchesAdapter(Context context, int matches_layout, ArrayList<Matches> matches) 
    super(context, matches_layout);
    this.matchList = matches;


@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) 
    int phraseIndex  = position;

    if(convertView == null)
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.matches_layout,parent, false);
    

    TextView home = convertView.findViewById(R.id.squadra_casa);
    TextView away = convertView.findViewById(R.id.squadra_trasferta);
    TextView home_result = convertView.findViewById(R.id.risultato_casa);
    TextView away_result = convertView.findViewById(R.id.risultato_trasferta);
    TextView group = convertView.findViewById(R.id.girone);
    TextView date = convertView.findViewById(R.id.data_ora);

    home.setText(matchList.get(position).getHomeTeam());
    away.setText(matchList.get(position).getAwayTeam());
    home_result.setText(matchList.get(position).getResultHome());
    away_result.setText(matchList.get(position).getResultAway());
    group.setText(matchList.get(position).getGroup());
    date.setText(matchList.get(position).getDate());

    return convertView;


我运行了应用程序,但我什么也没看到:

注意:我在 onResponse() 方法中模拟了对象 Match 来测试代码。我已经看到正确调用了 Rest API 并返回了所需的数据

感谢您的帮助!

【问题讨论】:

【参考方案1】:

从简短的代码来看,它似乎写得很好。您缺少的要点是 API 调用是异步的,并且在 API 返回任何结果之前填充了适配器。尝试在您的 StringRequest 调用的 OnResponse 回调中填充适配器,如下所示(抱歉,我没有尝试运行它,但我认为给您一个提示可能会有所帮助):

StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
        new Response.Listener<String>() 
            @Override
            public void onResponse(String response) 
                matches = ParseTextResultToMatchesObjects(response);
                adapter = new MatchesAdapter(this.getContext(),
                    R.layout.matches_layout,
                    matches);
            
        , new Response.ErrorListener() 
    @Override
    public void onErrorResponse(VolleyError error) 

    
    ...

编辑: 对于将来担心这一点的任何人:整个操作都放在 onViewCreated 中,而不是 onCreateView 中,这导致了更多的复杂性(不知道为什么),但是我写的关于操作的异步性和错误地填充适配器的内容时间到了……

【讨论】:

P.s.:提供的代码可能是错误的,但我很确定,错误来自我描述的 ASYNC 行为。希望对您有所帮助。 P.s.s.:在 MatchesAdapter 构造函数和 OnResponse 回调中放置断点,看看哪个先触发 ;) 我试过像你一样伤心,但结果是一样的。进入调试,如果我尝试你的解决方案,第一个断点“触发”在 onResponse 方法中,然后在 adpater 的构造函数中,我的代码是反之亦然 使用我的代码,应用程序首先执行 onViewCreated 方法(在 listView 中创建和设置适配器),然后调用 onResponse 方法 嗯,就是这样...您正在填充没有数据的列表,这就是您看到空白页面的原因。在 onResponse 调用中调用适配器构造函数,你应该很高兴......(并删除第一个调用来构造适配器)

以上是关于REST API 对 Fragment 的响应 - Android Studio的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 Node.js API REST 应用程序对高 CPU/RAM 使用率无响应?

iOS:如何从 REST SwiftUi 访问和使用 API 响应数据

反序列化 Facebook Workplace SCIM Rest API 响应

使用 TFS 2015 REST API 进行队列构建的 409 冲突响应

如何在 Spring Boot Rest api 响应的 ResponseEntity 中添加自定义属性

Bitbucket REST Api:如何通过调用 rest api 按日期 desc 对所有分支进行排序?