【问题标题】:notifyDataSetChanged method on RecyclerViewRecyclerView 上的 notifyDataSetChanged 方法
【发布时间】:2017-07-25 07:47:29
【问题描述】:

我正在尝试通过创建简单的应用程序来从 nodejs 服务器发送和接收推文来练习 RecyclerView。在主要活动中,我只列出响应,在第二个活动中,我向服务器发送一条简单的推文。我的主要活动中有一个 RecyclerView,它的工作是将接收到的数据显示为列表。我确实配置 RecyclerView 如下:

        //config recycler view
    mRyTweets = (RecyclerView) findViewById(R.id.ry_tweets);
    mRyTweets.setLayoutManager(new LinearLayoutManager(this));
    mAdapter = new TweetAdapter(this, new TweetAdapter.TweetEventHandler() {
        @Override
        public void onEditTweet(String tweetId, int position) {

        }

        @Override
        public void onDeleteTweet(String tweetId, int position) {

        }
    });
    mRyTweets.setAdapter(mAdapter);

及其布局:

    <android.support.v7.widget.Toolbar
    android:id="@+id/default_toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/colorPrimary"
    android:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

<android.support.v7.widget.RecyclerView
    android:id="@+id/ry_tweets"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/default_toolbar"/>
</RelativeLayout>

这是我从简单的 nodejs 服务器接收响应的地方:

   private void getTweetsFromServer() {
    Call<List<TweetModel>> call = mTService.getTweets();
    call.enqueue(new Callback<List<TweetModel>>() {
        @Override
        public void onResponse(Call<List<TweetModel>> call, Response<List<TweetModel>> response) {

            if (response.isSuccessful()) {
                //update the adapter data
                mAdapter.updateAdapterData(response.body());
                mAdapter.notifyDataSetChanged();
            } else {
                ErrorModel errorModel = ErrorUtils.parseError(response);
                Toast.makeText(getBaseContext(), "Error Type is: " + errorModel.type + " , description "
                        + errorModel.description, Toast.LENGTH_SHORT).show();
            }
        }

在这一行mAdapter.updateAdapterData(response.body()); 我将来自服务器的响应添加到我的适配器

public class TweetAdapter extends RecyclerView.Adapter<TweetAdapter.TweetViewHolder> {

private Context mContext;
private LayoutInflater mLayoutInflater;
private List<TweetModel> mData = Collections.emptyList();
private TweetEventHandler mTweetEventHandler;

public TweetAdapter(Context context, TweetEventHandler tweetEventHandler) {
    this.mContext = context;
    this.mLayoutInflater = LayoutInflater.from(context);
    this.mTweetEventHandler = tweetEventHandler;
}

public void updateAdapterData(List<TweetModel> data) {
    this.mData = data;
}

在第二个活动中,我有一个发送推文的菜单:

           TweetModel tweetModel = new TweetModel();
        //assign tweet model values
        tweetModel.body = mETxTweetBody.getText().toString();
        tweetModel.feel = mSelectedMode;

        //create call generic class to send request to server
        Call<TweetModel> call = mTService.createNewTweet(tweetModel);
        //Async request
        //NOTE: you should always Async request since the sync request cause the crash of your app
        call.enqueue(new Callback<TweetModel>() {
            @Override
            public void onResponse(Call<TweetModel> call, Response<TweetModel> response) {

                if (response.isSuccessful()) {
//
                    Toast.makeText(getApplicationContext(), "Successfully post tweet" + response.body().created_at
                            , Toast.LENGTH_SHORT).show();

                    finish();

                } 

一切都很好,但是当我在主要活动中发送新推文时,新推文不会立即显示在我的列表中,我必须退出应用程序并再次运行。我不知道为什么mAdapter.notifyDataSetChanged(); 不起作用? 你有什么建议??

【问题讨论】:

  • 问题:您的新推文会进入服务器中的数据库吗?或者它是否添加到现有模型中?如果您将其添加到现有模型中,通知数据集更改就足够了。但是,如果您将它发送到服务器,那么您将不会得到它。由于连接未打开。
  • @aa_oo 它只是保存在简单的 json 文件中。我的服务器是本地的。并通知数据集更改不起作用!
  • 对不起,我忙于工作。

标签: android node.js android-recyclerview


【解决方案1】:

感谢大家。 我通过

解决了我的问题
startActivityForResult(postNewTweetIntent,Constants.CREATE_OR_EDIT_TWEET_REQUEST_CODE);

在我发送推文时在 MainActivity 和 setResult(RESULT_OK); 中。然后在活动中:

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == Constants.CREATE_OR_EDIT_TWEET_REQUEST_CODE &&
            resultCode == RESULT_OK) {
        getTweetsFromServer();
    }
    super.onActivityResult(requestCode, resultCode, data);
}

在这个方法getTweetsFromServer();我收到来自服务器的响应,然后我调用notifyDataSetChanged()更新我的列表:

mAdapter.updateAdapterData(response.body());
mAdapter.notifyDataSetChanged();

【讨论】:

    【解决方案2】:

    首先,Collections.emptyList(); 返回一个不可变列表。请参阅this

    使用: List&lt;Model&gt; mData = new ArrayList&lt;&gt;();

    那你为什么不在你身上试试这个update

    public void updateAdapterData(List<TweetModel> data) {
      // instead of this  this.mData = data;
      this.mData.addAll(data);
      notifyDataSetChanged();
    }
    

    它应该可以正常工作!如果您需要解释,请回复!

    【讨论】:

    • 是的,我的错,忘了你使用Collections.emptyList();,它返回一个不可变的列表。使用mData = new ArrayList(); 参考:Check this stack post
    • 数据不再立即显示在列表中,我必须重新启动我的应用程序。
    • 也有这个解决方案? (即没有重新初始化列表的位置)对吗?只有一次?你能在帖子中编辑更新方法吗?
    • 是的,此解决方案不起作用。当我添加推文时,服务器响应数据和 updateAdapterData(response.body());onResponse 方法将重新初始化列表。
    • 是的,那么这就是你的问题,不应该重新初始化列表。它应该只初始化一次。为什么不使用旧方式,在其构造函数中将列表传递给适配器。然后不使用update 方法,而是使用list.addAll 方法,然后调用notifyDataSetChanged 方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多