有没有更好的方法在使用 volley 获取数据的同时在片段中填充 listView?

Is there a better way to populate a listView in a fragment while getting the data with volley?

我正在做一个练习,我必须通过 Volley 库从服务器获取一个 JSONArray 对象。然后用该数据填充一个 listView。我已经做到了,但我认为必须有更好的方法。我想出的唯一方法是在我发送给 volley 的 JSONArrayRequest 的 onResponse 方法中设置适配器。

是否可以在fragment的onCreateView方法中设置适配器?

这是我的代码:

public class UserListFragment extends Fragment {

    private static final String USERS_URL = "https://raw.githubusercontent.com/users.json";
    public static final String TAG = UserListFragment.class.getSimpleName();
    private ListView listView;
    private VolleyManager volleyManager;
    private List<User> users;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_user_list, null);

        listView = (ListView) view.findViewById(R.id.list_view);
        Button obtain_data_btn = (Button) view.findViewById(R.id.user_list_obtain_btn);
        obtain_data_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getUsersListData();
            }
        });

        return view;
    }

    private void getUsersListData() {
        JsonArrayRequest jsonArrayRqst = new JsonArrayRequest(
                USERS_URL,
                new Response.Listener<JSONArray>(){
                    @Override
                    public void onResponse(JSONArray response) {
                        users = parseUserList(response.toString());
                        listView.setAdapter(new UsersAdapter(getActivity(), R.layout.list_item, users));
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.d(TAG, error.getMessage());
                }
                }
        );

        volleyManager = VolleyManager.getInstance(getActivity());
        volleyManager.addToRequestQueue(jsonArrayRqst);
    }

    /**
     * Parses a users json array into a users list.
     *
     * @param jsonArray
     *
     * @return Users list
     */
    private List<User> parseUserList(String jsonArray) {
        Gson gson = new Gson();

        // Declares the list type
        Type listType = new TypeToken<List<User>>() {}.getType();

        List<User> userList = gson.fromJson(jsonArray, listType);

        return userList;
    }

    private class UsersAdapter extends ArrayAdapter<User> {

        public UsersAdapter(Context context, int itemResourceId) {
            super(context, itemResourceId);
        }

        public UsersAdapter(Context context, int resource, List<User> users) {
            super(context, resource, users);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            View listItemView = convertView;

            if (listItemView == null) {
                LayoutInflater layoutInflater;
                layoutInflater = LayoutInflater.from(getContext());
                listItemView = layoutInflater.inflate(R.layout.list_item, null);
            }

            User user = getItem(position);

            TextView userNameTV = (TextView) listItemView.findViewById(R.id.userName_userList);
            TextView userLastNameTV = (TextView) listItemView.findViewById(R.id.userLastName_userList);
            TextView userAgeTV = (TextView) listItemView.findViewById(R.id.userAge_userList);

            userNameTV.setText(user.getName());
            userLastNameTV.setText(user.getLastName());
            userAgeTV.setText(Integer.toString(user.getAge()));

            return listItemView;
        }

    }
}

是的,我在当前项目片段的 onCreateView 中将我的适配器设置为 ExpandableListView。这样做应该没有问题。

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

      View parentThis = (LinearLayout)inflater.inflate(R.layout.tab_exlv, container, false);


      exlvTabHistory = (ExpandableListView)parentThis.findViewById(R.id.exlvTabHistory);
      exlvTabHistory.setAdapter(setupEXLVAdapter());
    }

是的,有更好的方法。创建对您的 Adapter 的引用作为 Fragment 的成员变量,这允许您在数据进来后调用 notifyDataSetChanged()

有一点需要注意,您不能更改数据源的引用,即 users 列表。所以,当数据进来的时候,使用addAll()添加数据,不用重新分配数据源引用。

你的代码应该是这样的:

public class UserListFragment extends Fragment {

    private static final String USERS_URL = "https://raw.githubusercontent.com/users.json";
    public static final String TAG = UserListFragment.class.getSimpleName();
    private ListView listView;
    private VolleyManager volleyManager;
    private List<User> users;

    UsersAdapter adapter; //added

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_user_list, null);

        listView = (ListView) view.findViewById(R.id.list_view);

        //added:
        adapter = new UsersAdapter(getActivity(), R.layout.list_item, users);
        listView.setAdapter(adapter);


        Button obtain_data_btn = (Button) view.findViewById(R.id.user_list_obtain_btn);
        obtain_data_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getUsersListData();
            }
        });

        return view;
    }

    private void getUsersListData() {
        JsonArrayRequest jsonArrayRqst = new JsonArrayRequest(
                USERS_URL,
                new Response.Listener<JSONArray>(){
                    @Override
                    public void onResponse(JSONArray response) {
                        //modified:
                        users.addAll(parseUserList(response.toString()));
                        adapter.notifyDataSetChanged();
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.d(TAG, error.getMessage());
                }
                }
        );

        volleyManager = VolleyManager.getInstance(getActivity());
        volleyManager.addToRequestQueue(jsonArrayRqst);
    }

    //.........