简体   繁体   English

如何将ListView适配器转换为RecyclerView适配器?

[英]How do I convert my ListView adapter into RecyclerView adapter?

I am currently using a listview instead of a RecyclerView for my data. 我目前正在使用列表视图而不是RecyclerView来存储数据。 I was wondering if there's an easy way to convert a ListView adapter to a RecyclerView adapter and hence listview to RecyclerView . 我想知道是否有一种简单的方法可以将ListView适配器转换为RecyclerView适配器,从而将listview转换为RecyclerView

Here's my code so far for the ListView adapter: 到目前为止,这是我的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();
        }
    }
}

In my activity I am calling: 在我的活动中,我打电话给:

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);
    }
});

Any ideas on how to go about this? 关于如何解决这个问题的任何想法?

I am currently using my listview and updating items as I go, I would like to convert everything to RecyclerView for better efficiency. 我目前正在使用列表视图并随时更新项目,我想将所有内容都转换为RecyclerView以提高效率。

Thanks in advance! 提前致谢!

I think there is no shortcut which will convert your ListView adapter automatically into an adapter for your RecyclerView . 我认为没有快捷方式可以将ListView适配器自动转换为RecyclerView的适配器。 However, I tried to rewrite your adapter like the following and I hope that works. 但是,我试图像下面那样重写您的适配器,希望它能起作用。

Please note that I have not tested the code. 请注意,我尚未测试代码。 Please modify the code if necessary. 请根据需要修改代码。 I tried to put some comments in the code so that it helps to understand the overall procedure better. 我试图在代码中添加一些注释,以帮助更好地理解整个过程。

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();
        }
    }
}

Once you have the adapter, I think you already know how to set the adapter into your RecyclerView from your Activity . 一旦有了适配器,我想您已经知道如何从Activity中将适配器设置到RecyclerView In case you do not know, here is how. 如果您不知道,这里是方法。

recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new MyVisitorAdapterForRecyclerView(this, fitems);
recyclerView.setAdapter(mAdapter);

Hope that helps! 希望有帮助!

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何按字母顺序对 listView 的文件进行排序并集成列表适配器?我正在使用自定义适配器 - How do i sort alphabetically the files of my listView and integrate a list adapter?I'm using a custom adapter 将ListView适配器移植到RecyclerView适配器 - Porting a ListView adapter to a RecyclerView Adapter 如何在recyclerview适配器中将getItematposition()用作ListView - how to use getItematposition() in recyclerview adapter as ListView 如何检查RecyclerView适配器中的每个值? - How can I check every value in my RecyclerView adapter? 如何修复RecyclerView:未连接适配器; 跳过布局? - How do i fix RecyclerView: No adapter attached; skipping layout? 如何使用 AsyncTask、RecyclerView 和 RecyclerView.Adapter 将手机中的图像获取到 RecyclerView? - How can I use AsyncTask, RecyclerView, and a RecyclerView.Adapter to get images from my phone into my RecyclerView? 如何从sqlite数据库附加RecyclerView适配器 - How do I attach RecyclerView adapter from sqlite database 如何在 recyclerview 适配器中为 Activity 扩展上下文 - How do I extablish context for an Activity within a recyclerview adapter 如何在ListView适配器中缓存自定义视图? - How can I cache custom views in my ListView Adapter? Android-RecyclerView:是否需要为每个recyclerView使用适配器和ItemObject? 如何分别处理点击? - Android - RecyclerView: Do I need to use an adapter and an ItemObject for each recyclerView ?. How do I handle the clicks separately?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM