[英]How to update recyclerview adapter for the changed data after Volley call
在我正在開發的應用程序中,有一個 API 被重復調用以在回收視圖中顯示數據。 每次服務器返回相同的數據集,直到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
)有任何更改時才更改顯示的數據. 此外,如果有一組新數據,請添加一張新卡。
調用API
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);
}
}
適配器.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);
}
}
}
問題是這一行:
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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.