我当前正在使用列表视图而不是RecyclerView
来存储数据。我想知道是否有一种简单的方法可以将ListView
适配器转换为RecyclerView
适配器,然后将列表视图转换为RecyclerView
。
到目前为止,这是我的ListView
适配器的代码:
public class MyVisitorAdapter extends ArrayAdapter<VisitorItem> implements Filterable {
public ArrayList<VisitorItem> original;
public ArrayList<VisitorItem> fitems;
private Filter filter;
private Context context;
//This whole class needs to be refactored to support binding with viewholders or add recyclerview. This was a trial run to check out
//how listview pans out, but forgot to remove and update it later
public MyVisitorAdapter(Context context, ArrayList<VisitorItem> items) {
super(context, 0, items);
this.original = new ArrayList<>();
this.original.addAll(items);
this.fitems = new ArrayList<>();
this.fitems.addAll(items);
this.context = context;
}
@Override
public void add(VisitorItem item) {
this.fitems.add(item);
this.original.add(item);
notifyDataSetChanged();
}
@Override
public void remove(VisitorItem item) {
this.fitems.remove(item);
this.original.remove(item);
notifyDataSetChanged();
}
@Override
public int getCount() {
return fitems.size();
}
@Override
public VisitorItem getItem(int position) {
return fitems.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.item_guest, null);
VisitorItem item = fitems.get(position);
if (item != null) {
TextView firstName = v.findViewById(R.id.firstName);
firstName.setText(item.firstName);
TextView lastName = v.findViewById(R.id.lastName);
lastName.setText(item.lastName);
TextView email = v.findViewById(R.id.email);
email.setText(item.email);
TextView phoneNumber = v.findViewById(R.id.phoneNumber);
phoneNumber.setText(item.phoneNumber);
View dividerView = v.findViewById(R.id.item_divider);
if (getContext() instanceof SubmitGuestsActivity) {
dividerView.setVisibility(View.GONE);
}
if (this.getContext() instanceof MyVisitorActivity) {
TextView clearButton = v.findViewById(R.id.item_delete_guest);
clearButton.setVisibility(View.VISIBLE);
clearButton.setOnClickListener(v1 -> new AlertDialog.Builder(getContext(), R.style.myDialogTheme)
.setCancelable(true)
.setTitle("Confirm delete")
.setMessage("Are you sure?")
.setPositiveButton("Yes", (dialog, which) -> {
VisitorItem itemToBeDeleted = getItem(position);
VisitorItem.delete(VisitorItem.class, itemToBeDeleted.getId());
remove(itemToBeDeleted);
fitems.remove(itemToBeDeleted);
Toast.makeText(getContext(), "Deleted", Toast.LENGTH_SHORT).show();
})
.setNegativeButton("No", (dialog, which) -> dialog.dismiss())
.create().show());
}
}
return v;
}
@Override
public Filter getFilter() {
if (filter == null) {
filter = new ItemsFilter();
}
return filter;
}
private class ItemsFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
String prefix = constraint.toString().toLowerCase();
if (prefix.length() == 0) {
ArrayList<VisitorItem> list = new ArrayList<>(original);
results.values = list;
results.count = list.size();
} else {
final ArrayList<VisitorItem> list = new ArrayList<>(original);
final ArrayList<VisitorItem> nlist = new ArrayList<>();
int count = list.size();
for (int i = 0; i < count; i++) {
final VisitorItem item = list.get(i);
final String firstName = item.firstName.toLowerCase();
final String lastName = item.lastName.toLowerCase();
final String email = item.email.toLowerCase();
if (firstName.contains(prefix) && lastName.contains(prefix) && email.contains(prefix)) {
nlist.add(item);
}
}
results.values = nlist;
results.count = nlist.size();
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
fitems = (ArrayList<VisitorItem>) results.values;
MyVisitorAdapter.this.notifyDataSetChanged();
}
}
}
在我的活动中,我打电话给
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(MyVisitorActivity.this, AddVisitorActivity.class);
i.putExtra("firstName", mRegisterAdapter.getItem(position).firstName);
i.putExtra("lastName", mRegisterAdapter.getItem(position).lastName);
i.putExtra("email", mRegisterAdapter.getItem(position).email);
i.putExtra("phoneNumber", mRegisterAdapter.getItem(position).phoneNumber);
i.putExtra("position", position);
startActivityForResult(i, 202);
}
});
关于如何解决这个问题的任何想法?
我目前正在使用列表视图并随时更新项目,我想将所有内容都转换为RecyclerView
,以提高效率。
谢谢!
答案 0 :(得分:2)
我认为没有快捷方式可以将您的ListView
适配器自动转换为您的RecyclerView
的适配器。但是,我试图像下面那样重写您的适配器,希望它能起作用。
请注意,我尚未测试代码。请根据需要修改代码。我试图在代码中添加一些注释,以帮助更好地理解整个过程。
public class MyVisitorAdapterForRecyclerView extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
public ArrayList<VisitorItem> original;
public ArrayList<VisitorItem> fitems;
private Filter filter;
private Context context;
public MyVisitorAdapterForRecyclerView(Context context, ArrayList<VisitorItem> items) {
this.original = new ArrayList<>();
this.original.addAll(items);
this.fitems = new ArrayList<>();
this.fitems.addAll(items);
this.context = context;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Otherwise populate normal views
View v = LayoutInflater.from(context).inflate(R.layout.list_item_normal, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
try {
MyViewHolder vh = (MyViewHolder) holder;
vh.bindView(position);
} catch (Exception e) {
e.printStackTrace();
}
}
// Similar to getCount function
@Override
public int getItemCount() {
if (fitems == null) return 0;
else return fitems.size();
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
public class MyViewHolder extends RecyclerView.ViewHolder {
// Declare the elements of your row here
TextView firstName;
TextView lastName;
TextView email;
TextView phoneNumber;
View dividerView;
TextView clearButton;
// Define elements of a row here
public MyViewHolder(View itemView) {
super(itemView);
// Get the view elements here
firstName = itemView.findViewById(R.id.firstName);
lastName = itemView.findViewById(R.id.lastName);
email = itemView.findViewById(R.id.email);
phoneNumber = itemView.findViewById(R.id.phoneNumber);
dividerView = itemView.findViewById(R.id.item_divider);
clearButton = itemView.findViewById(R.id.item_delete_guest);
}
public void bindView(int position) {
// This is the similar function as getView
VisitorItem item = fitems.get(position);
if (item != null) {
firstName.setText(item.firstName);
lastName.setText(item.lastName);
email.setText(item.email);
phoneNumber.setText(item.phoneNumber);
if (context instanceof SubmitGuestsActivity)
dividerView.setVisibility(View.GONE);
else dividerView.setVisibility(View.VISIBLE);
if (context instanceof MyVisitorActivity) {
clearButton.setVisibility(View.VISIBLE);
clearButton.setOnClickListener(v1 -> new AlertDialog.Builder(getContext(), R.style.myDialogTheme)
.setCancelable(true)
.setTitle("Confirm delete")
.setMessage("Are you sure?")
.setPositiveButton("Yes", (dialog, which) -> {
VisitorItem itemToBeDeleted = fitems.get(position);
VisitorItem.delete(VisitorItem.class, itemToBeDeleted.getId());
remove(itemToBeDeleted);
fitems.remove(itemToBeDeleted);
Toast.makeText(context, "Deleted", Toast.LENGTH_SHORT).show();
})
.setNegativeButton("No", (dialog, which) -> dialog.dismiss())
.create().show());
} else clearButton.setVisibility(View.GONE);
// Add the click listener here instead of your activity
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(context, AddVisitorActivity.class);
i.putExtra("firstName", fitems.get(position).firstName);
i.putExtra("lastName", fitems.get(position).lastName);
i.putExtra("email", fitems.get(position).email);
i.putExtra("phoneNumber", fitems.get(position).phoneNumber);
i.putExtra("position", position);
((MyVisitorActivity) context).startActivityForResult(i, 202);
}
});
}
}
}
// You do not have to override the add function.
// However, you can implement one of your own like the one you had earlier.
public void add(VisitorItem item) {
this.fitems.add(item);
this.original.add(item);
notifyDataSetChanged();
}
// You do not have to override the remove function either.
// However, you can implement one of your own like the one you had earlier.
public void remove(VisitorItem item) {
this.fitems.remove(item);
this.original.remove(item);
notifyDataSetChanged();
}
@Override
public Filter getFilter() {
if (filter == null) {
filter = new ItemsFilter();
}
return filter;
}
private class ItemsFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
String prefix = constraint.toString().toLowerCase();
if (prefix.length() == 0) {
ArrayList<VisitorItem> list = new ArrayList<>(original);
results.values = list;
results.count = list.size();
} else {
final ArrayList<VisitorItem> list = new ArrayList<>(original);
final ArrayList<VisitorItem> nlist = new ArrayList<>();
int count = list.size();
for (int i = 0; i < count; i++) {
final VisitorItem item = list.get(i);
final String firstName = item.firstName.toLowerCase();
final String lastName = item.lastName.toLowerCase();
final String email = item.email.toLowerCase();
if (firstName.contains(prefix) && lastName.contains(prefix) && email.contains(prefix)) {
nlist.add(item);
}
}
results.values = nlist;
results.count = nlist.size();
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
fitems = (ArrayList<VisitorItem>) results.values;
notifyDataSetChanged();
}
}
}
一旦有了适配器,我想您已经知道如何从RecyclerView
将适配器设置到Activity
中。如果您不知道,这里是方法。
recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new MyVisitorAdapterForRecyclerView(this, fitems);
recyclerView.setAdapter(mAdapter);
希望有帮助!
答案 1 :(得分:0)
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private String[] mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class MyViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView textView;
public MyViewHolder(TextView v) {
super(v);
//initialize all view
textView = v;
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
TextView v = (TextView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
...
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
//put all code of getView start VisitorItem item = fitems.get(position);
holder.textView.setText(mDataset[position]);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.length;
}
}
// add all other method just remove @override