LIstView:
在应用成语中我们通常会用到使用列表的形式来展示一些内容,Listview就是一个专门用来进行列表布局的控件,
一个Listview通常有两个功能
1.将数据以列表的形式布局展示
2.当用户点击每一行时的点击操作
一个Listview创建的三元素
1.Listview中每一行的view (item)
2.所需要的数据,文字,图片等
3.连接数据与item的适配器 adpter
常用适配器
下面展示一个简单的ListView:
首先,第一步创建xml插入Listview控件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical"> <ListView android:id="@+id/main_listView" android:layout_width="match_parent" android:layout_height="wrap_content"> </ListView> </LinearLayout>
第二:创建item视图,当然这里比较简单,只有一个textview
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/item_txt" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:textSize="20sp" /> </LinearLayout>
第三;在Java中获取listview , 创建资源数据,创建adpter(将item与数据进行绑定) , 最后为listview设置适配器
public class SecondActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView listView = findViewById(R.id.main_listView); //使用for循环的方式创建5条数据 List<String> list= new ArrayList<>(); for (int i = 1; i < 50 ; i++) { list.add("这是第" + i + "行"); } //给listview添加自定义适配器 listView.setAdapter(new MyDapter(list)); } /** * 创建自定义适配器类,继承BaseAdapter * 以参数的形式传入数据 */ public class MyDapter extends BaseAdapter { //传入数据形式,自定义 List<String> list; public MyDapter(List<String> list) { this.list = list; } //获取列表中item的数量 @Override public int getCount() { return list.size(); } //获取当前位置的item @Override public Object getItem(int i) { return list.get(i); } //获取当前位置item的id @Override public long getItemId(int i) { return i; } //将数据与控件进行绑定 @Override public View getView(int i, View view, ViewGroup viewGroup) { //获取视图item LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.main_item,null); //获取item中要添加内容的控件 TextView textView = view.findViewById(R.id.item_txt); //为控件添加数据 textView.setText(list.get(i)); return view; } } }
效果图展示:
当然我们还可以为listview添加头部和尾部布局:
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); //参数1 为头部布局,仅有一张图片 View head = layoutInflater.inflate(R.layout.head_layout,null); //加载头部 listView.addHeaderView(head); //加载尾部 // listView.addFooterView();
效果图:
listview的优化问题
为什么需要优化呢?因为如果我们有上亿个(较多个)项目要显示怎么办?为每个项目创建一个新视图?这不可能,因为内存有限制。实际上Android为你缓存了视图。Android中有个叫做Recycler的构件,下图是他的工作原理:
当item1 滚出屏幕的时候,就缓存到了Recycler,此时需要加载item8,如果此时item8的结构与item1的结构相同那么直接将item1拿出,直接填充数据
不需要在重新创建视图,那么我们到底如何实现呢?
1.创建一个viewHolder类存放item中得控件
2.判断视图(view)是否为空 是:创建视图 否:则通过getTag直接获取视图
不多BB,直接上代码
// 获取每一个Item显示的内容 @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { viewHolder = new ViewHolder(); convertView = inflater.inflate(R.layout.item, null); viewHolder.imageView = (ImageView) convertView.findViewById(R.id.id_iv); viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.id_tvTitle); viewHolder.tvContent = (TextView) convertView.findViewById(R.id.id_tvContent); convertView.setTag(viewHolder);// 通过setTag将ViewHolder和convertView绑定 } else { viewHolder = (ViewHolder) convertView.getTag(); // 获取,通过ViewHolder找到相应的控件 } ItemBean itemBean = list.get(position); viewHolder.imageView.setImageResource(itemBean.ItemImageResid); viewHolder.tvTitle.setText(itemBean.ItemTitle); viewHolder.tvContent.setText(itemBean.ItemContent); return convertView; } class ViewHolder { ImageView imageView; TextView tvTitle; TextView tvContent; }
有了listview,再也不用一个一个的创建列表布局了