安卓中的数据适配器(Adapter)是连接数据源与视图层的核心组件,负责将数据映射到界面控件(如ListView、RecyclerView)的每一项,适配器通过Adapter
接口实现,核心功能包括:
convertView
)。适配器类型 | 特点 | 适用场景 |
---|---|---|
ArrayAdapter | 继承自BaseAdapter ,支持简单数据类型(如String数组、List | 静态文本列表 |
BaseAdapter | 抽象类,需重写getCount() 、getItem() 等方法 | 自定义简单列表 |
RecyclerView.Adapter | 支持视图复用、高效渲染,适配复杂布局 | 复杂列表、网格、瀑布流 |
public class User { private String name; private int age; // 构造方法、Getter/Setter }
<!-item_user.xml --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_name" ... /> <TextView android:id="@+id/tv_age" ... /> </LinearLayout>
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> { private List<User> userList; public UserAdapter(List<User> data) { this.userList = data; } // 创建ViewHolder @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user, parent, false); return new ViewHolder(view); } // 绑定数据 @Override public void onBindViewHolder(ViewHolder holder, int position) { User user = userList.get(position); holder.tvName.setText(user.getName()); holder.tvAge.setText(String.valueOf(user.getAge())); } @Override public int getItemCount() { return userList.size(); } // ViewHolder内部类 public static class ViewHolder extends RecyclerView.ViewHolder { TextView tvName, tvAge; public ViewHolder(View itemView) { super(itemView); tvName = itemView.findViewById(R.id.tv_name); tvAge = itemView.findViewById(R.id.tv_age); } } }
RecyclerView recyclerView = findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); UserAdapter adapter = new UserAdapter(userList); recyclerView.setAdapter(adapter);
原因:未调用notifyDataSetChanged()
或未正确修改数据源。
解决:在数据源变更后调用adapter.notifyDataSetChanged()
,
userList.add(newUser); adapter.notifyItemInserted(userList.size() 1);
原因:未启用视图复用或图片加载未优化。
解决:
RecyclerView
替代ListView
。onBindViewHolder
中复用ViewHolder
。方案:在getItemCount()
中返回0,或显示空视图:
if (userList.isEmpty()) { recyclerView.setVisibility(View.GONE); emptyView.setVisibility(View.VISIBLE); }
优化方向 | 具体措施 |
---|---|
减少对象创建 | 使用ViewHolder 缓存视图,避免重复调用findViewById() |
异步处理 | 图片加载、网络请求使用异步任务(如AsyncTask 、LiveData ) |
分页加载 | 配合RecyclerView 的PagedListAdapter 实现懒加载 |
DiffUtil | 使用DiffUtil.Callback 计算数据差异,局部刷新(Android 10+) |
解答:
List
添加元素,调用notifyItemInserted(position)
: userList.add(newUser); adapter.notifyItemInserted(userList.size() 1);
List
移除元素,调用notifyItemRemoved(position)
: userList.remove(position); adapter.notifyItemRemoved(position);
解答:
ViewHolder
中定义所有子视图(如ImageView btnDelete
)。onBindViewHolder
中设置点击监听: holder.btnDelete.setOnClickListener(v -> { removeUser(holder.getAdapterPosition()); });
Glide
或Picasso
异步加载图片,避免阻塞UI