【问题标题】:Response of a REST API into Fragment - Android StudioREST API 对 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 并返回了所需的数据

感谢您的帮助!

【问题讨论】:

    标签: android android-fragments android-adapter rest


    【解决方案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 调用中调用适配器构造函数,你应该很高兴......(并删除第一个调用来构造适配器)
    猜你喜欢
    • 2022-01-17
    • 1970-01-01
    • 2014-09-24
    • 2019-02-20
    • 2019-02-21
    • 2019-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多