更改适配器中的业务对象
Changing a business object in an Adapter
我正在构建一个类似于 Facebook 的 android 应用程序(从 REST API 获取存储在数据库中的新闻源),我现在正在实现一个类似 reddit 的投票系统,其中每个 Feed 项都有一个存储在数据库中的投票状态(none、赞成、反对)。
当我检索新闻源 json 时,我将其 voteState 设置为 json 中的投票状态,然后通过新闻源适配器显示它。
但是如果我将新闻源适配器中的 voteState 设置为另一个值(基于 onClickListener),这个更改后的值不会到达实际的新闻源。
这是因为每次我滚动新闻源时,新闻源适配器都会获得一个新的新闻源实例,并且不关心我更改的值。
因此,我正在寻找从新闻源适配器永久修改新闻源投票状态的最佳方法(这可以推广到分配给 ArrayList 的任何变量,然后通过 ArrayListAdapter 显示)。
如果您有任何建议,请随时回复。
谢谢:)
编辑:
public class NewsfeedAdapter extends RecyclerView.Adapter<NewsfeedAdapter.ViewHolder> {
private Newsfeed newsfeed;
private FeedItem item;
public NewsfeedAdapter(..., Newsfeed newsfeed) {
...;
this.newsfeed = newsfeed;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
protected Button button_up/down....
public ViewHolder(View v) {
super(v);
button = findViewById ... (R.id.button);
...
}
}
// Create new views (invoked by the layout manager)
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
...
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final FeedItem item = newsfeed.get(position);
holder.button_up.setTag(position);
holder.button_up.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
changeVote(item, "up");
}
});
holder.button_down.setTag(position);
holder.button_down.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
changeVote(item, "down");
}
});
}
public void changeVote(FeedItem item, String flag) {
// Log.d(TAG, "State of vote :" + item.getVoteState());
if (item.getVoteState().equals(flag)) {
item.setVoteState("none");
Log.d(TAG, "Deleting vote :" + item.getVoteState());
new Connexion(activity, fragment, "vote", "Deleting vote...").execute(String.valueOf(item.getId()), flag, "delete");
}
else if (item.getVoteState().equals("none")){
item.setVoteState(flag);
Log.d(TAG, "Voting :" + item.getVoteState());
new Connexion(activity, fragment, "vote", "Voting...").execute(String.valueOf(item.getId()), flag, "insert");
} else {
item.invertVoteState(flag);
Log.d(TAG, "Inverting :" + item.getVoteState());
new Connexion(activity, fragment, "vote", "Voting...").execute(String.valueOf(item.getId()), flag, "invert");
}
} }
您有两个选择:
1) 每次更改一条数据时,向其余部分发送更新API。这真的很贵,而且不是你最想做的事情。
2) 在您的休息 API 和您的列表视图之间创建一个本地数据层 - 很可能是 SQLite 数据库或其他一些 ORM 库。这样你就可以在你的适配器中保存一个数据库的实例,每当一条数据发生变化时,你可以通过一个简单的数据库方法调用来更新它,然后定期将更新发送给其余的API,同时也检查从其余 API 获取新更新,然后将它们推送到数据库。
我强烈建议使用 SQLite 数据库,因为您可以在数据库代码中保留一个计数器,记录一定数量的更改或自上次同步以来经过的时间,并使用户看到的数据保持最新通过重复的网络调用来减少用户的数据使用量。
我正在构建一个类似于 Facebook 的 android 应用程序(从 REST API 获取存储在数据库中的新闻源),我现在正在实现一个类似 reddit 的投票系统,其中每个 Feed 项都有一个存储在数据库中的投票状态(none、赞成、反对)。
当我检索新闻源 json 时,我将其 voteState 设置为 json 中的投票状态,然后通过新闻源适配器显示它。
但是如果我将新闻源适配器中的 voteState 设置为另一个值(基于 onClickListener),这个更改后的值不会到达实际的新闻源。 这是因为每次我滚动新闻源时,新闻源适配器都会获得一个新的新闻源实例,并且不关心我更改的值。
因此,我正在寻找从新闻源适配器永久修改新闻源投票状态的最佳方法(这可以推广到分配给 ArrayList 的任何变量,然后通过 ArrayListAdapter 显示)。
如果您有任何建议,请随时回复。
谢谢:)
编辑:
public class NewsfeedAdapter extends RecyclerView.Adapter<NewsfeedAdapter.ViewHolder> {
private Newsfeed newsfeed;
private FeedItem item;
public NewsfeedAdapter(..., Newsfeed newsfeed) {
...;
this.newsfeed = newsfeed;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
protected Button button_up/down....
public ViewHolder(View v) {
super(v);
button = findViewById ... (R.id.button);
...
}
}
// Create new views (invoked by the layout manager)
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
...
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final FeedItem item = newsfeed.get(position);
holder.button_up.setTag(position);
holder.button_up.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
changeVote(item, "up");
}
});
holder.button_down.setTag(position);
holder.button_down.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
changeVote(item, "down");
}
});
}
public void changeVote(FeedItem item, String flag) {
// Log.d(TAG, "State of vote :" + item.getVoteState());
if (item.getVoteState().equals(flag)) {
item.setVoteState("none");
Log.d(TAG, "Deleting vote :" + item.getVoteState());
new Connexion(activity, fragment, "vote", "Deleting vote...").execute(String.valueOf(item.getId()), flag, "delete");
}
else if (item.getVoteState().equals("none")){
item.setVoteState(flag);
Log.d(TAG, "Voting :" + item.getVoteState());
new Connexion(activity, fragment, "vote", "Voting...").execute(String.valueOf(item.getId()), flag, "insert");
} else {
item.invertVoteState(flag);
Log.d(TAG, "Inverting :" + item.getVoteState());
new Connexion(activity, fragment, "vote", "Voting...").execute(String.valueOf(item.getId()), flag, "invert");
}
} }
您有两个选择:
1) 每次更改一条数据时,向其余部分发送更新API。这真的很贵,而且不是你最想做的事情。
2) 在您的休息 API 和您的列表视图之间创建一个本地数据层 - 很可能是 SQLite 数据库或其他一些 ORM 库。这样你就可以在你的适配器中保存一个数据库的实例,每当一条数据发生变化时,你可以通过一个简单的数据库方法调用来更新它,然后定期将更新发送给其余的API,同时也检查从其余 API 获取新更新,然后将它们推送到数据库。
我强烈建议使用 SQLite 数据库,因为您可以在数据库代码中保留一个计数器,记录一定数量的更改或自上次同步以来经过的时间,并使用户看到的数据保持最新通过重复的网络调用来减少用户的数据使用量。