使用 ScrollView 的大列表
Large list using ScrollView
我正在创建一个布局,其中我有大量要显示的项目,每个项目都包含一个具有 ImageView
、EditText
和 TextView
的布局。理想情况下,这是 ListView 的完美候选者,但是,由于我有一个 EditText
,当用户尝试键入某些内容时,我无法专注于它。在 SO 上阅读了很多关于此的帖子,似乎没有干净的解决方案来使用 ListView 实现此功能。
但是,我可能有 100 多个项目要显示,直接在 ScrollView
上渲染所有这些似乎不是一个明智的主意。是否有任何设计模式来处理这种情况?
您可以尝试使用RecycleView。它适用于大型数据集。
https://developer.android.com/training/material/lists-cards.html
"The RecyclerView widget is a more advanced and flexible version of ListView. This widget is a container for displaying large data sets that can be scrolled very efficiently by maintaining a limited number of views. Use the RecyclerView widget when you have data collections whose elements change at runtime based on user action or network events."
我想你需要的是新的RecyclerView that was recently added to the support library. A simple introduction is available here。
RecyclerView 特别有用,因为它没有 onItemClickListener
。人们往往会问 "but why doesn't it have one?"
它实际上非常聪明,正是因为您的 use-case:它不会窃取您对可点击项目的关注(如您所知,ListView 会这样做),而是将每个点击事件委托给children 的 onClickListener
s.
来自指定link的示例(来源是Antonio Leiva的博客):
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder> {
private List<ViewModel> items;
private int itemLayout;
public MyRecyclerAdapter(List<ViewModel> items, int itemLayout) {
this.items = items;
this.itemLayout = itemLayout;
}
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(itemLayout, parent, false);
return new ViewHolder(v);
}
@Override public void onBindViewHolder(ViewHolder holder, int position) {
ViewModel item = items.get(position);
holder.text.setText(item.getText());
holder.image.setImageBitmap(null);
Picasso.with(holder.image.getContext()).cancelRequest(holder.image);
Picasso.with(holder.image.getContext()).load(item.getImage()).into(holder.image);
holder.itemView.setTag(item);
}
@Override public int getItemCount() {
return items.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView image;
public TextView text;
public ViewHolder(View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.image);
text = (TextView) itemView.findViewById(R.id.text);
}
}
}
add
和 remove
上的位置:
public void add(ViewModel item, int position) {
items.add(position, item);
notifyItemInserted(position);
}
public void remove(ViewModel item) {
int position = items.indexOf(item);
items.remove(position);
notifyItemRemoved(position);
}
和初始化:
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.list);
recyclerView.setHasFixedSize(true); // use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setAdapter(new MyRecyclerAdapter(list, R.layout.item));
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
需要依赖项:
dependencies {
...
compile 'com.android.support:recyclerview-v7:21.0.+'
}
我正在创建一个布局,其中我有大量要显示的项目,每个项目都包含一个具有 ImageView
、EditText
和 TextView
的布局。理想情况下,这是 ListView 的完美候选者,但是,由于我有一个 EditText
,当用户尝试键入某些内容时,我无法专注于它。在 SO 上阅读了很多关于此的帖子,似乎没有干净的解决方案来使用 ListView 实现此功能。
但是,我可能有 100 多个项目要显示,直接在 ScrollView
上渲染所有这些似乎不是一个明智的主意。是否有任何设计模式来处理这种情况?
您可以尝试使用RecycleView。它适用于大型数据集。 https://developer.android.com/training/material/lists-cards.html
"The RecyclerView widget is a more advanced and flexible version of ListView. This widget is a container for displaying large data sets that can be scrolled very efficiently by maintaining a limited number of views. Use the RecyclerView widget when you have data collections whose elements change at runtime based on user action or network events."
我想你需要的是新的RecyclerView that was recently added to the support library. A simple introduction is available here。
RecyclerView 特别有用,因为它没有 onItemClickListener
。人们往往会问 "but why doesn't it have one?"
它实际上非常聪明,正是因为您的 use-case:它不会窃取您对可点击项目的关注(如您所知,ListView 会这样做),而是将每个点击事件委托给children 的 onClickListener
s.
来自指定link的示例(来源是Antonio Leiva的博客):
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder> {
private List<ViewModel> items;
private int itemLayout;
public MyRecyclerAdapter(List<ViewModel> items, int itemLayout) {
this.items = items;
this.itemLayout = itemLayout;
}
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(itemLayout, parent, false);
return new ViewHolder(v);
}
@Override public void onBindViewHolder(ViewHolder holder, int position) {
ViewModel item = items.get(position);
holder.text.setText(item.getText());
holder.image.setImageBitmap(null);
Picasso.with(holder.image.getContext()).cancelRequest(holder.image);
Picasso.with(holder.image.getContext()).load(item.getImage()).into(holder.image);
holder.itemView.setTag(item);
}
@Override public int getItemCount() {
return items.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView image;
public TextView text;
public ViewHolder(View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.image);
text = (TextView) itemView.findViewById(R.id.text);
}
}
}
add
和 remove
上的位置:
public void add(ViewModel item, int position) {
items.add(position, item);
notifyItemInserted(position);
}
public void remove(ViewModel item) {
int position = items.indexOf(item);
items.remove(position);
notifyItemRemoved(position);
}
和初始化:
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.list);
recyclerView.setHasFixedSize(true); // use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setAdapter(new MyRecyclerAdapter(list, R.layout.item));
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
需要依赖项:
dependencies {
...
compile 'com.android.support:recyclerview-v7:21.0.+'
}