5

Android适配器RecyclerView.Adapter和ArrayAdapter的使用

 2 years ago
source link: http://www.lzhpo.com/article/153
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

适配器有什么用?

简单来说就是连接View和数据的桥梁。

如果用MVC模式来理解的话,可以这么理解:

Model(我们的数据) ---> Controller(适配器Adapter)---> View(Android用户界面)

RecyclerView.Adapter(RecyclerView)

Android 5.0时提供了RecyclerView这个列表元件,作为ListView的强化版,它提供更好的效能表现、更高的灵活性,博客有文章将其称为艺术般的元件。

RecyclerView要求必须使用ViewHolder模式,一般我们在使用过程中,都需要去建立一个新的ViewHolder然后作为泛型传入Adapter。

简单的Demo

先写一个MenuProgressAdapterRecyclerView适配器:

public class MenuProgressAdapter extends RecyclerView.Adapter<MenuProgressAdapter.ViewHolder> {    private Context context;    private List<MenuProgress> data;    private DebugTaskModel debugTask;    public MenuProgressAdapter(Context context, List<MenuProgress> data, DebugTaskModel debugTask) {        this.context = context;        this.data = data;        this.debugTask = debugTask;    }    @Override    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {        View view = LayoutInflater.from(parent.getContext())                .inflate(R.layout.common_item_list, parent, false);        return new ViewHolder(view);    }    @Override    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {        MenuProgress menuProgress = data.get(position);        holder.menuProgressItem = menuProgress;        holder.itemId.setText(data.get(position).getId());        holder.itemName.setText(data.get(position).getTitle());        if (menuProgress.isFinish()) {            holder.testFinish.setVisibility(View.VISIBLE);            holder.testTodo.setVisibility(View.GONE);        } else {            holder.testFinish.setVisibility(View.GONE);            holder.testTodo.setVisibility(View.VISIBLE);        }        // 为每个Item添加点击事件        holder.itemView.setOnClickListener(v -> {            if (DoubleClickUtil.doubleClick()) {                Toast.makeText(context, DOUBLE_CLICK_PROMPT, Toast.LENGTH_LONG).show();                return;            }            // 获取被点击之后的MenuProgress            MenuProgress item = data.get(position);            // 点击之后的业务逻辑...        });    }    @Override    public int getItemCount() {        if (data == null) {            return 0;        }        return data.size();    }    public void clear() {        if (data != null) {            data.clear();        }        notifyDataSetChanged();    }    public class ViewHolder extends RecyclerView.ViewHolder {        public final View mView;        public final ImageView testFinish;        public final ImageView testTodo;        public final TextView itemId;        public final TextView itemName;        public MenuProgress menuProgressItem;        public ViewHolder(View view) {            super(view);            this.mView = view;            this.testFinish = itemView.findViewById(R.id.testFinish);            this.testTodo = itemView.findViewById(R.id.testTodo);            this.itemId = itemView.findViewById(R.id.itemId);            this.itemName = itemView.findViewById(R.id.itemName);        }        @Override        public String toString() {            return "ViewHolder{" +                    "mView=" + mView +                    ", itemId=" + itemId +                    ", itemName=" + itemName +                    ", menuProgressItem=" + menuProgressItem +                    '}';        }    }}
private MenuProgressAdapter adapter;
// 通过构造器将我们的数据t.getData()和debugTaskData设置进去adapter = new MenuProgressAdapter(this, t.getData(), debugTaskData);// 设置LayoutManagerbinding.debugTaskList.setLayoutManager(new LinearLayoutManager(this));// 为debugTaskList视图设置适配器binding.debugTaskList.setAdapter(adapter);

ArrayAdapter

ArrayAdapter数组适配器用于绑定格式单一的数据,数据源可以是集合或者数组列表视图(ListView)以垂直的形式列出需要显示的列表项。

ArrayAdapter比较简单,通常会和ListView一起使用,但是现在我们已经很少使用ListView了,被废弃了,现在用的是RecyclerView。

简单的Demo(ListView)

定义CommonMenu的适配器ItemListAdapter

@Data@Builder@AllArgsConstructor@NoArgsConstructorpublic class CommonMenu {    private String id;    private String title;    // 是否完成此试验数据填写    private boolean finish;}
public class ItemListAdapter extends ArrayAdapter<CommonMenu> {    private int resourceId;    public ItemListAdapter(@NonNull Context context, int resource, @NonNull List<CommonMenu> objects) {        super(context, resource, objects);        resourceId = resource;    }    @NonNull    @Override    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {        CommonMenu item = getItem(position);        View view;        if (convertView == null) {            view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);        } else {            view = convertView;        }        TextView itemId = view.findViewById(R.id.itemId);        TextView itemName = view.findViewById(R.id.itemName);        itemId.setText(item.getId());        itemName.setText(item.getTitle());        return view;    }}

使用ItemListAdapter适配器:

private List<CommonMenu> menuList = new ArrayList<>();
// 在此之前,将从数据库中查询出来的menuList放置到适配器中。ItemListAdapter itemListAdapter = new ItemListAdapter(this, R.layout.common_item_list, menuList);// 将此ListView的View拿到ListView itemListView = findViewById(R.id.tap_switch_item_list_view);// 为ListView设置适配器itemListAdapteritemListView.setAdapter(itemListAdapter);// 为每个item设置监听器itemListView.setOnItemClickListener((parent, view, position, id) -> {    // parent:被点击的AdapterView    // view:被点击的View    // position:适配器中被点击的View的位置,可以通过menuList.get(position)可以获取到被点击的CommonMenu数据    // id:id单击的项目的行ID    // 点击某个item之后的业务逻辑...});

获取被点击的item数据,我举个例子,我先添加一个数据:

menuList.add(CommonMenu.builder()             .id("123456789")             .title("示例1")             .finish(true)             .build());
itemListView.setOnItemClickListener((parent, view, position, id) -> {    // 被点击的CommonMenu数据    CommonMenu commonMenu = menuList.get(position);});

OnItemClickListener的源码:

/** * Interface definition for a callback to be invoked when an item in this * AdapterView has been clicked. */public interface OnItemClickListener {    /**     * Callback method to be invoked when an item in this AdapterView has     * been clicked.     * <p>     * Implementers can call getItemAtPosition(position) if they need     * to access the data associated with the selected item.     *     * @param parent The AdapterView where the click happened.     * @param view The view within the AdapterView that was clicked (this     *            will be a view provided by the adapter)     * @param position The position of the view in the adapter.     * @param id The row id of the item that was clicked.     */    void onItemClick(AdapterView<?> parent, View view, int position, long id);}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK