- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在我正在开发的应用程序中,有一个 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);
}
}
}
最佳答案
问题是这一行:
PersonDataAdapterClassList.add(GetPerDataModel);
您实际上是在列表末尾附加了整个响应。
相反,您应该更改存储数据的方式,可能是一个以 p_id 为键的映射,然后在解析响应时更新或创建。
您可以做的另一件事,更简单,但效率可能较低:您可以在处理响应之前清除整个列表:
public void PERSON_DATA_PROCESSING(JSONArray array) {
PersonDataAdapterClassList.clear();
for (...
通过在开始时这样做,它应该可以工作,并且您可以保留当前代码的其余部分。不过,这听起来是 map 的合理用例。
还有一个问题,如果一个元素在后续请求中停止显示,是否应该将其删除?如果是,清除数据是正确的做法,如果需要保留数据,则使用 map 。
还有一个提示,您可以通知适配器更新,而不是每次都重置适配器。通过重置适配器,recyclerview 可以重新创建所有 View 。
为此,您应该更改适配器的代码:
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);
}
}
关于android - 如何在 Volley 调用后为更改的数据更新 recyclerview 适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55204368/
我目前正在测试 Volley 库。但是当请求失败 (404) 时,它不会再次执行,或者至少没有错误。但是缺少数据。如果请求失败,这是重试请求的正确方法吗? 提前致谢 req.setRetryPolic
我是新来从事Volley和缓存工作的:P。尽管我已经看过许多与Volley进行图像缓存有关的文章和帖子,但是我仍然不清楚采用Volley进行图像缓存的最佳/首选方式。像磁盘缓存还是内存? Volley
我想使用 Volley 从我的 Android 应用发送请求。 我已经把它包含在 build.gradle 中了 dependencies { ... compile 'com.andr
我的目标是从另一个类调用 Volley,这是一种非常简洁、模块化的方式,即: VolleyListener newListener = new VolleyListener()
我的代码是: class MyService extends Service{ public void onCreate(){ new ImageLoader(mReque
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我需要帮助来解决 Volley 库错误。我已使用 nodejs api 向服务器发送一些凭据以进行用户注册。在成功的情况下,当我的所有凭据对于创建新用户帐户都是唯一的时,它会向我显示所有响应等的所有内
我正在尝试完善我的应用程序中的错误处理,但我找不到 Volley 触发某些错误的集中位置以及原因。例如,我想知道如果我的请求的状态代码是 500 或更大,它肯定会触发 ServerError,但我似乎
当我在调试器中运行该方法时,数据按预期显示,但是每当我尝试使用它执行任何操作时,parentObject 的值都会返回为 null。 我只是想从服务器获取响应并将其存储为 JSONObject 以便在
我正在使用 Android Volley 缓存请求,这在我使用 GET 时工作正常,但由于某些原因我改用 POST。现在我想用不同的 POST 数据缓存相同的 URL。 请求 1 -> URL1,PO
我的情况是使用 Android-volley至 POST我的 json 对象,我可以成功发布所有内容,我的数据在服务器中可见,但服务器响应为 String不像 json ,这就是出现错误的原因。 co
我正在使用 volley 从 REST api 解析电影详细信息,并将解析的数据保存在名为 detailsMovies 的对象数组列表中。但是我无法在 onResponse 方法之外访问 ArrayL
我想知道如何解决这个问题。已完成代码的研究和替换,但问题仍然存在。 这是我使用 volley 的代码。 private void Regist(){ loading.setVisibility
如何创建一个单独的类,在其中定义所有关于 volley在另一个 Activity 中,我们直接传递 URL、CONTEXT 和 Get Response... 最佳答案 首先在Activity中创建回
我正在使用 volley 库并以 XML 格式获取响应。我想知道我们如何使用/volley 库解析响应。谢谢。 最佳答案 StringRequest req = new StringReque
当我在android studio中搜索 Volley 时,同时获取com.mcxiaoke.volley:library:1.0.19和com.mcxiaoke.volley:library-aar
我是 volley 和 android 的新手,我已经用 gradle 安装了 volley 并做了与官方教程相同的操作。但是没有响应,这意味着 Errorlistener 和 Responselis
当我在 Volley 中发出请求时,我收到 com.android.volley.ServerError 和响应代码 400。 我正在做这样的事情(通用示例代码): final String para
我引用了http://www.androidhive.info/2016/02/android-push-notifications-using-gcm-php-mysql-realtime-chat
当我将以下行添加到依赖项的 build.gradle 行时,Android Studio 显示此错误消息:compile 'com.android.volley:volley:1.0.0' apply
我是一名优秀的程序员,十分优秀!