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;
}
我的 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;
}