RecyclerView 直到 SearchView 交互才填充

RecyclerView not populated until SearchView interaction

我的 recyclerview 有一个自定义适配器的问题。问题是当 activity 打开时,recyclerview 是空的。当用户在 SearchView 的文本字段中键入任何内容时,recyclerview 会被填充并保持填充状态,不会出现任何问题。我试图改变一些代码的位置来解决这个问题,但没有成功。我在代码下方添加了当前和所需状态的屏幕截图。提前致谢。

添加课程活动:

public class AddCourseActivity extends AppCompatActivity{

private RecyclerView mRecyclerView;
private AddCourseAdapter mAdapter;
private List<AddCourseAdapter.AddCourseModel> mModels;
SearchView mSearchView;

@Override
protected void onCreate(Bundle savedInstance) {
    super.onCreate(savedInstance);
    setContentView(R.layout.activity_add_course);
    Kii.initialize(AppConstants.APP_ID, AppConstants.APP_KEY,
            AppConstants.APP_SITE);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setDisplayShowHomeEnabled(true);
    mRecyclerView = (RecyclerView) findViewById(R.id.addcourseRecyclerView);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    String[] courses = new String[]{
            "Math119",
            "Enve101",
            "Chem107",
            "Chem229",
            "Phys105",
            "Math120"};
    mModels = new ArrayList<>();
    mAdapter = new AddCourseAdapter(this, mModels);
    mSearchView = (SearchView) findViewById(R.id.searchView);
    mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }
        @Override
        public boolean onQueryTextChange(String newText) {
            final List<AddCourseAdapter.AddCourseModel> filteredModelList = filter(mModels, newText);
            mAdapter.animateTo(filteredModelList);
            mRecyclerView.scrollToPosition(0);
            return true;
        }
    });
    for (String course: courses) {
        mModels.add(new AddCourseAdapter.AddCourseModel(course));
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.notifyDataSetChanged();
    }
}

private List<AddCourseAdapter.AddCourseModel> filter(List<AddCourseAdapter.AddCourseModel> models, String query) {
    query = query.toLowerCase();
    final List<AddCourseAdapter.AddCourseModel> filteredModelList = new ArrayList<>();
    for (AddCourseAdapter.AddCourseModel model: models) {
        final String text = model.getText().toLowerCase();
        if (text.contains(query)) {
            filteredModelList.add(model);
        }
    }
    return filteredModelList;
}
}

添加课程适配器:

public class AddCourseAdapter extends RecyclerView.Adapter<AddCourseAdapter.AddCourseViewHolder> {
private final LayoutInflater mInflater;
private final List<AddCourseModel> mModels;
KiiUser user;
KiiObject object;
KiiBucket userBucket;
Context context;

public AddCourseAdapter(Context context, List<AddCourseModel> models) {
    mInflater = LayoutInflater.from(context);
    mModels = new ArrayList<>(models);
}

@Override
public AddCourseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    context = parent.getContext();
    final View itemView = mInflater.inflate(R.layout.list_item_add_course, parent, false);
    user = KiiUser.getCurrentUser();
    final String username = user.getUsername();
    userBucket = Kii.user().bucket(username);
    String id = "mycourses";
    object = userBucket.object(id);
    return new AddCourseViewHolder(itemView);
}

@Override
public void onBindViewHolder(final AddCourseViewHolder holder, int position) {
    final AddCourseModel model = mModels.get(position);
    holder.bind(model);
    holder.addButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final String value = holder.mTextView.getText().toString();
            object.refresh(new KiiObjectCallBack() {
                @Override
                public void onRefreshCompleted(int token, @NonNull KiiObject object, Exception exception) {
                    object.set(value, true);
                    object.saveAllFields(new KiiObjectCallBack() {
                        @Override
                        public void onSaveCompleted(int token, KiiObject object, Exception exception) {
                            Toast.makeText(context,
                                    "Added: " + value,
                                    Toast.LENGTH_SHORT)
                                    .show();
                        }
                    }, false);
                }
            });
            holder.addButton.setVisibility(View.GONE);
            holder.removeButton.setVisibility(View.VISIBLE);
        }
    });
    holder.removeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View v) {
            final String value = holder.mTextView.getText().toString();
            object.refresh(new KiiObjectCallBack() {
                @Override
                public void onRefreshCompleted(int token, @NonNull KiiObject object, Exception exception) {
                    object.set(value, false);
                    object.saveAllFields(new KiiObjectCallBack() {
                        @Override
                        public void onSaveCompleted(int token, @NonNull KiiObject object, Exception exception) {
                            Toast.makeText(context,
                                    "Removed: " + value,
                                    Toast.LENGTH_SHORT)
                                    .show();
                        }
                    }, false);
                }
            });

            holder.addButton.setVisibility(View.VISIBLE);
            holder.removeButton.setVisibility(View.GONE);
        }
    });
}

@Override
public int getItemCount() {
    return mModels.size();
}

public void animateTo(List<AddCourseModel> models) {
    applyAndAnimateRemovals(models);
    applyAndAnimateAdditions(models);
    applyAndAnimateMovedItems(models);
}

private void applyAndAnimateRemovals(List<AddCourseModel> newModels) {
    for (int i = mModels.size() - 1; i >= 0; i--) {
        final AddCourseModel model = mModels.get(i);
        if (!newModels.contains(model)) {
            removeItem(i);
        }
    }
}

private void applyAndAnimateAdditions(List<AddCourseModel> newModels) {
    for (int i = 0, count = newModels.size(); i < count; i++) {
        final AddCourseModel model = newModels.get(i);
        if (!mModels.contains(model)) {
            addItem(i, model);
        }
    }
}

private void applyAndAnimateMovedItems(List<AddCourseModel> newModels) {
    for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) {
        final AddCourseModel model = newModels.get(toPosition);
        final int fromPosition = mModels.indexOf(model);
        if (fromPosition >= 0 && fromPosition != toPosition) {
            moveItem(fromPosition, toPosition);
        }
    }
}

public AddCourseModel removeItem(int position) {
    final AddCourseModel model = mModels.remove(position);
    notifyItemRemoved(position);
    return model;
}

public void addItem(int position, AddCourseModel model) {
    mModels.add(position, model);
    notifyItemInserted(position);
}

public void moveItem(int fromPosition, int toPosition) {
    final AddCourseModel model = mModels.remove(fromPosition);
    mModels.add(toPosition, model);
    notifyItemMoved(fromPosition, toPosition);
}

public class AddCourseViewHolder extends RecyclerView.ViewHolder {
    private final TextView mTextView;
    private final ImageButton addButton;
    private final ImageButton removeButton;

    public AddCourseViewHolder(View itemView) {
        super(itemView);
        mTextView = (TextView) itemView.findViewById(R.id.addCourseTV);
        addButton = (ImageButton) itemView.findViewById(R.id.addButton);
        removeButton = (ImageButton) itemView.findViewById(R.id.removeButton);
    }

    public void bind(AddCourseModel model) {
        mTextView.setText(model.getText());
    }
}

public static class AddCourseModel {
   private final String mText;

   public AddCourseModel(String text) {
       this.mText = text;
   }

   public String getText() {
       return mText;
   }
}
}

当前初始状态:

期望的初始状态:

案例在您的 Adapter 构造函数中

public AddCourseAdapter(Context context, List<AddCourseModel> models) {
    mInflater = LayoutInflater.from(context);
    mModels = new ArrayList<>(models);
}

您创建了最初从模型列表(此时为空)填充的新 ArrayList。 稍后您填充初始模型数组列表,而不是在适配器中创建的数组列表。

您可以:

a) 移动

for (String course: courses) {
        mModels.add(new AddCourseAdapter.AddCourseModel(course));
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.notifyDataSetChanged();
    }

在这些线之间

mModels = new ArrayList<>();
mAdapter = new AddCourseAdapter(this, mModels);

制作成这样

mModels = new ArrayList<>();

for (String course: courses) {
  mModels.add(new AddCourseAdapter.AddCourseModel(course));
}
mAdapter = new AddCourseAdapter(this, mModels);
mRecyclerView.setAdapter(mAdapter);

b) 将 Adapter 构造函数重写为

public AddCourseAdapter(Context context, List<AddCourseModel> models) {
        mInflater = LayoutInflater.from(context);
        mModels = models;
    }