在Volley通话后,如何为更改后的数据更新recyclerview适配器

时间:2019-03-17 06:15:56

标签: android android-recyclerview android-adapter recycler-adapter

在我正在开发的应用程序中,有一个API被重复调用以在recyclerview中显示数据。每次服务器返回相同的数据集,直到task_status被“完成”。如果任何字段有变化,请务必刷新显示的卡,这一点很重要。此外,如果添加了新的数据集,它将添加新的卡。现在的问题是,即使在任何字段中没有更改或没有新的数据集的情况下,每次调用API时都会添加一组新的卡。

JSON数组

[
{
    p_id: "011",
    m_status: "deliveryon",
    p_name: "Alfred Kusher",
    p_position: "Delivery Optimiser",
    p_location: "Vancuver"
},
{
    p_id: "021",
    m_status: "intask",
    p_name: "Wilson Divachik",
    p_position: "Driver",
    p_location: "Ontario"
},
{
    p_id: "014",
    task_status: "enroute",
    p_name: "Dalvin Petter",
    p_position: "Driver",
    p_location: "Lunenbrg"
},
{
    p_id: "244",
    task_status: "intask",
    p_name: "Maria Laoumi",
    p_position: "Assistant Marketing Manager",
    p_location: "Ottawa"
},
{
    p_id: "004",
    task_status: "active",
    p_name: "Linda Jefferson",
    p_position: "Sales Lead",
    p_location: "Quebec"
},
{
    p_id: "055",
    task_status: "active",
    p_name: "Dimitar Kurmanov",
    p_position: "Senior Manager",
    p_location: "Nova Scotia"
}
]

例如,根据上面的示例JSON响应,它应在调用API时第一次添加6张卡片,并且仅在任何字段有任何更改(例如p_location时,才更改显示的数据或task_status)。此外,如果有新数据集,请添加新卡。

APICall.Java

 public void PERSON_DATA_WEB_CALL() {

    String HTTP_SERVER_URL = String.format("http://myURL.com/%1$s", LoginID);

    JsonArrayRequest jsArrRequest = new JsonArrayRequest
            (Request.Method.GET, HTTP_SERVER_URL, null, new Response.Listener<JSONArray>() {

                @Override
                public void onResponse(JSONArray response) {

                    PERSON_DATA_PROCESSING(response);

                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    // TODO Auto-generated method stub
                }
            }) {

    };
    requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(jsArrRequest);
}


public void PERSON_DATA_PROCESSING(JSONArray array) {

    for (int i = 0; i < array.length(); i++) {

        PersonDataModel GetPerDataModel = new PersonDataModel();
        JSONObject json = null;
        try {
            json = array.getJSONObject(i);
            GetPerDataModel.setID(json.getString("p_id"));
            GetPerDataModel.setTaskStatus(json.getString("task_status"));
            GetPerDataModel.setName(json.getString("p_name"));
            GetPerDataModel.setPosition(json.getString("p_position"));
            GetPerDataModel.setLoction(json.getString("p_location"));

        } catch (JSONException e) {

            e.printStackTrace();
        }

        PersonDataAdapterClassList.add(GetPerDataModel);

    }

    if (array.length() != 0) {
        recyclerViewAdapter = new PersonRecyclerAdapter(PersonDataAdapterClassList, this);
        recyclerView.setAdapter(recyclerViewAdapter);
    } 

}

Adapter.java

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

Context context;
public List<PersonDataModel> dataModels;
private static int currentPosition = 0;
public PersonRecyclerAdapter(List<PersonDataModel> getDataAdapter, Context context) {
    super();
    this.dataModels = getDataAdapter;
    this.context = context;
}
public PersonDataModel dataAdapter;

@Override
public PersonRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.person, parent, false);
    PersonRecyclerAdapter.ViewHolder viewHolder = new PersonRecyclerAdapter.ViewHolder(view);
    return viewHolder;
}

@Override
public void onBindViewHolder(final PersonRecyclerAdapter.ViewHolder viewHolder, final int position) {

    dataAdapter = dataModels.get(position);
    viewHolder.id.setText(dataAdapter.getID());
    viewHolder.location.setText(dataAdapter.getLocation());
    viewHolder.taskStatus.setText(dataAdapter.getMStatus());
    viewHolder.name.setText(dataAdapter.getName());
    viewHolder.p_position.setText(dataAdapter.getPPosition());

}

@Override
public int getItemCount() {

    return dataModels.size();
}

class ViewHolder extends RecyclerView.ViewHolder {

    public TextView id;
    public TextView taskStatus;
    public TextView location;
    public TextView name;
    public TextView p_position;
    public ViewHolder(View itemView) {
        super(itemView);
        id = (TextView) itemView.findViewById(R.id.textViewPID);
        taskStatus = (TextView) itemView.findViewById(R.id.textViewTaskStatus);
        location = (TextView) itemView.findViewById(R.id.textViewLocation);
        name = (TextView) itemView.findViewById(R.id.textViewName);
        p_position = (TextView) itemView.findViewById(R.id.textViewPosition);
    }
}
}

1 个答案:

答案 0 :(得分:2)

问题是这一行:

PersonDataAdapterClassList.add(GetPerDataModel); 

您实际上是将整个响应添加到列表的末尾。

相反,您应该更改存储数据的方式(可能是以p_id为键的映射),然后在解析响应时进行更新或创建。

您可以做的另一件事是,更轻松,但效率可能更低:您可以在处理响应之前擦除整个列表:

public void PERSON_DATA_PROCESSING(JSONArray array) {
    PersonDataAdapterClassList.clear();
    for (...

通过在开始时执行此操作,它应该可以工作,并且您可以保留当前代码的其余部分。不过,这听起来是地图的合理用例。

还有一个问题,如果一个元素停止在后续请求中显示,是否应该将其删除?如果是,则清除数据是正确的方法,如果需要保留数据,请使用地图。

另一个提示,您不必每次都可以将更新通知适配器而不必重置适配器。通过重置适配器,recyclerview可以重新创建所有视图。

为此,您应该更改适配器的代码:

public class PersonRecyclerAdapter extends RecyclerView.Adapter<PersonRecyclerAdapter.ViewHolder> {
    private Context context; 
    private final List<PersonDataModel> dataModels;
    private static int currentPosition = 0;

    public PersonRecyclerAdapter(Context context) { 
        super();
        this.context = context;
        this.dataModels = new ArrayList<PersonDataModel>();
    }

    public void updateModels(List<PersonDataModel> newModels) {
        dataModels.clear();
        dataModels.adAll(newModels);
        notifyDataSetChaged();
    }
    ...

现在,当您创建recyclerview时,应该在此处创建适配器,并保留对其的引用

recyclerview = findViewById...
recyclerViewAdapter = new PersonRecyclerAdapter(this);
recyclerview.setAdaper(recyclerViewAdapter);

然后在您的api调用中:

public void PERSON_DATA_PROCESSING(JSONArray array) {
    List<PersonDataModel> newModels = new ArrayList<>();
    for (int i = 0; i < array.length(); i++) {
        PersonDataModel GetPerDataModel = new PersonDataModel();
        JSONObject json = null; 
        try {
            json = array.getJSONObject(i);
            GetPerDataModel.setID(json.getString("p_id"));
            GetPerDataModel.setTaskStatus(json.getString("task_status"));
            GetPerDataModel.setName(json.getString("p_name"));
            GetPerDataModel.setPosition(json.getString("p_position"));
            GetPerDataModel.setLoction(json.getString("p_location"));

            newModels.add(GetPerDataModel);
        } catch (JSONException e) {
            e.printStackTrace();
        }    
    }

    if (array.length() != 0) { 
        recyclerViewAdapter.updateModels(newModels);
    } 
}