问题描述
我的recyclerview遇到问题,它具有一个自定义适配器.问题是,当活动打开时,recyclerview为空.当用户在SearchView的文本字段上键入任何内容时,将填充recyclerview并保持填充状态,而不会出现任何问题.我试图更改一些代码的位置来解决此问题,但没有成功.我已在代码下方添加了当前状态和所需状态的屏幕截图.预先感谢.
I'm facing an issue with my recyclerview, which has a custom adapter. Issue is that when the activity opens, recyclerview is empty. When user types anything on SearchView's text field, recyclerview gets populated and stays populated without any problems. I tried to change place of some code to fix this issue, yet no success. I've added the current and desired state screenshots below the codes. Thanks in advance.
AddCourseActivity:
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;
}
}
AddCourseAdapter:
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构造函数中
The case is in your Adapter constructor
public AddCourseAdapter(Context context, List<AddCourseModel> models) {
mInflater = LayoutInflater.from(context);
mModels = new ArrayList<>(models);
}
您创建一个新的ArrayList,它最初是从模型列表中填充的(此刻为空).稍后,您将填充初始模型arraylist,而不是在适配器中创建的列表.
You create new ArrayList which initially populated from the models list (which is empty at this moment).Later you populate initial models arraylist, not the one created in adapter.
您可以:
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);
OR
b)将Adapter构造函数重写为
b) rewrite the Adapter constructor to
public AddCourseAdapter(Context context, List<AddCourseModel> models) {
mInflater = LayoutInflater.from(context);
mModels = models;
}
这篇关于在SearchView交互之前,不会填充RecyclerView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!