简体   繁体   English

在Android中滑动刷新后如何保持UI更改

[英]How do I keep UI changes after swiping to refresh in Android

So, I have this getView method in my CommentsAdapter class, and it basically allows the user to upvote or downvote a comment in the comments section while displaying the upvote count. 因此,我在CommentsAdapter类中具有此getView方法,它基本上允许用户在显示upvote计数的同时,在comment部分中对一个注释进行upvote或downvote。 I am able to upvote (and undo the upvote) with the corresponding UI change (blue button for un-upvoted and orange for upvoted). 我能够使用相应的UI更改进行投票(并撤消更改)(蓝色按钮代表未投票,橙色按钮代表已投票)。

However, once I refresh the screen, the button will always revert to blue regardless if it was upvoted or not and the vote count back to the original count. 但是,一旦刷新屏幕,无论该按钮是否被投票,该按钮将始终恢复为蓝色,并且投票数恢复为原始计数。 I did check the database and the correct upvote count and action were logged. 我确实检查了数据库,并记录了正确的upvote计数和操作。 Any tips? 有小费吗?

public class CommentsAdapter extends ArrayAdapter<Post> { 
  private int layout;
  private Context context;
  private ArrayList<Post> postList = new ArrayList<>();

  public CommentAdapter(@NonNull Context cont, @LayoutRes int textViewResourceId, @NonNull ArrayList<Post> objects) {
    super(cont, textViewResourceId, objects);
    layout = textViewResourceId;
    context = cont;
    postList = objects;
  }

  public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
      final ViewHolder v;
      final Post comment = postList.get(position);
      final String mimeType = "text/html";
      final String encoding = "UTF-8";
      final SharedPreferences prefs = context.getSharedPreferences("user_session", MODE_PRIVATE);
      final String sessionKey = prefs.getString("session_key", "");
      String htmlData = "<link rel=\"stylesheet\" type=\"text/css\" href=\"comments.css\" />" + comment.content;

      if (convertView == null) {
          v = new ViewHolder();
          LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          convertView = inflater.inflate(layout, parent, false);

          v.upvotedIcon = convertView.findViewById(R.id.navbar_upvoted_icon);
          v.upvoteIcon = convertView.findViewById(R.id.navbar_upvote_icon);
          v.upvotedText = convertView.findViewById(R.id.navbar_upvoted_text);
          v.upvoteText = convertView.findViewById(R.id.navbar_upvote_text);

          v.upvoteButton = convertView.findViewById(R.id.navbar_upvote_button);
          v.upvotedButton = convertView.findViewById(R.id.navbar_upvoted_button);

          v.upvotedIcon.setTypeface(fontAwesome);
          v.upvoteIcon.setTypeface(fontAwesome);
          v.upvotedText.setTypeface(opensans);
          v.upvoteText.setTypeface(opensans);

          convertView.setTag(v);
      } else {
          v = (ViewHolder) convertView.getTag();
      }

      v.upvoteText.setText(String.format(Locale.ENGLISH, "%d", comment.stats.upvotes));
      v.upvotedText.setText(String.format(Locale.ENGLISH, "%d", comment.stats.upvotes + 1));

      if (comment.hasReacted) {
          v.upvoteButton.setVisibility(View.GONE);
          v.upvotedButton.setVisibility(View.VISIBLE);
      } else {
          v.upvotedButton.setVisibility(View.GONE);
          v.upvoteButton.setVisibility(View.VISIBLE);
      }

      v.upvoteButton.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              setButtonState(true, comment, v);
              Call<JsonObject> call = MyApi.endpoint().upVotePost(sessionKey, comment.id);
              call.enqueue(new Callback<JsonObject>() {
                  @Override
                  public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
                      if(response.code() != 200) {
                          // show upvote icon
                          setButtonState(false, comment, v);
                          Toast.makeText(context, "Cannot upvote for the moment, try again later.", Toast.LENGTH_SHORT).show();
                      }
                  }

                  @Override
                  public void onFailure(Call<JsonObject> call, Throwable t) {
                      // show upvote icon
                      setButtonState(false, comment, v);
                      Toast.makeText(context, "Cannot connect to the server, try again later.", Toast.LENGTH_SHORT).show();
                  }
              });
          }


      });

      v.upvotedButton.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              // show upvote icon
              setButtonState(false, comment, v);
              Call<JsonObject> call = MyApi.endpoint().downVotePost(sessionKey, comment.id);
              call.enqueue(new Callback<JsonObject>() {
                  @Override
                  public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
                      if(response.code() != 200) {
                          // show upvoted icon
                          setButtonState(true, comment, v);
                          Toast.makeText(context, "Cannot undo your upvote for the moment, try again later.", Toast.LENGTH_SHORT).show();
                      }
                  }

                  @Override
                  public void onFailure(Call<JsonObject> call, Throwable t) {
                      // show upvoted icon
                      setButtonState(true, comment, v);
                      Toast.makeText(context, "Cannot connect to the server, try again later.", Toast.LENGTH_SHORT).show();
                  }
              });
          }
      });

      return convertView;
  }
}

You should add a property to your model that is a status, with values like "upvoted", "downvoted", etc., or {empty string}. 您应该在模型中添加一个状态属性,其属性值为“ upvoted”,“ downvoted”等或{empty string}。 Then when your data is acted on set that status accordingly. 然后,当您对数据进行操作时,请相应地设置该状态。 Then when the data is reloaded check your model for that status and display using the proper icon for each status. 然后,当重新加载数据时,请检查模型中的该状态,并使用适合每个状态的图标显示。 (I am simply using strings for the status values, but you could do something more elegant). (我只是在状态值中使用字符串,但是您可以做一些更优雅的操作)。

Edit: 编辑:

As several users have pointed out, make sure that you are calling notifyDataSetChanged after modifying you database values. 正如几个用户指出的那样,请确保在修改数据库值之后正在调用notifyDataSetChanged Also if you are pulling your data from a remote server, make sure you have updated the upvote/downvote values before you do the reload, (or at least properly merge remote data with your local data). 另外,如果要从远程服务器提取数据,请确保在重新加载之前已更新upvote / downvote值(或至少将远程数据与本地数据正确合并)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在存储过程进行更改后刷新hibernate对象 - How do I refresh hibernate object after changes made by stored procedure 如何在android中设备方向更改后保持listview项的突出显示 - How to keep highlight of listview item after device orientation changes in android 刷新后在 ListView 中保留数据 - Android Studio - Keep data in ListView after refresh - Android Studio 如何在Android中出现条件后停止左右滑动 - How to stop left and right swiping after a condition in android 在Android中关闭提醒对话框后,如何在活动调用中刷新TextView? - How do I refresh TextView on activity calling after closing alert dialog in Android? 如何跟踪更改以重新启动android中的活动? - how to keep track of changes to restart the activitiy in android? 如何刷新需要从数据库加载的Android活动? - How do I refresh an Android activity that needs to load from the database? 如何在Android Studio中立即刷新recyclerview的组件? - How Do I instantly refresh a component of a recyclerview in android studio? android轮换后如何保持RecyclerView? - How can I keep my RecyclerView after android rotation? 如何防止 CFEXECUTE 在 PrintStackTrace 之后挂起 - How do I keep CFEXECUTE from hanging after a PrintStackTrace
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM