【问题标题】:How do I convert my ListView adapter into RecyclerView adapter?如何将我的 ListView 适配器转换为 RecyclerView 适配器?
【发布时间】:2019-04-23 18:10:02
【问题描述】:

我目前正在为我的数据使用列表视图而不是 RecyclerView。我想知道是否有一种简单的方法可以将 ListView 适配器转换为 RecyclerView 适配器,从而将 listview 转换为 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 以提高效率。

提前致谢!

【问题讨论】:

    标签: java android android-recyclerview android-listview android-adapter


    【解决方案1】:

    我认为没有捷径可以将您的ListView 适配器自动转换为您的RecyclerView 的适配器。但是,我尝试如下重写您的适配器,我希望它有效。

    请注意,我没有测试过代码。如有需要请修改代码。我尝试在代码中加入一些 cmets,以便更好地理解整个过程。

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

    一旦你有了适配器,我想你已经知道如何将适配器从你的Activity 设置到你的RecyclerView。如果你不知道,这里是如何。

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

    希望对您有所帮助!

    【讨论】:

    • 很高兴知道我可以提供帮助。不客气。 :)
    • 很棒的解决方案。这也解决了我的一个问题!谢谢大家!
    • 很高兴知道这有帮助!
    • @Reaz 或 Marissa 可以帮助我解决这个骨架加载问题:stackoverflow.com/questions/56012218/…。我有它的赏金
    【解决方案2】:
    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-11
      • 2021-03-24
      • 1970-01-01
      • 1970-01-01
      • 2016-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多