APP学习5(ListView和Adapter)
1. ListView
ListView是以列表的形式展示数据内容,并且能够根据列表的高度自适应屏幕显示。
2. 常用数据适配器(Adapter)
BaseAdapter是基本的适配器,实际上是一个抽象类,通常在自定义适配器时回继承BaseAdapter。
3. 例子
3.1 自己编写(不推荐)
实现结果:
注意点:就是设置名称的时候比较麻烦。而且需要两个layout文件。
layout_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="购物商城" android:gravity="center" android:textSize="50sp" android:textColor="@color/black" android:background="#00BCD4" ></TextView> <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/mylist" ></ListView> </LinearLayout>
itemlayout.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="20dp" > <ImageView android:layout_width="120dp" android:layout_height="90dp" android:id="@+id/iv" android:layout_centerVertical="true" ></ImageView> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv1" android:text="标题" android:layout_toRightOf="@+id/iv" android:layout_alignBottom="@+id/iv" android:layout_marginBottom="50dp" android:layout_marginLeft="10dp" ></TextView> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv2" android:text="内容" android:layout_toRightOf="@+id/iv" android:layout_alignBottom="@+id/iv" android:layout_marginBottom="20dp" android:layout_marginLeft="10dp" android:textColor="#FF9800" ></TextView> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv3" android:text="价格" android:layout_toRightOf="@+id/tv2" android:layout_alignBottom="@+id/tv2" android:layout_marginLeft="5dp" android:textColor="#FF9800" ></TextView> </RelativeLayout>
MainActivity.java
package com.example.myapp; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private ImageView iv; private TextView tv1,tv3;//标题,价格 //1.定义适配器中的数组内容 //图片资源,存的id号 private int[] imgs = {R.drawable.apple,R.drawable.straw,R.drawable.mitao,R.drawable.water}; //标题资源要和上面数组对应 private String[] title = {"苹果","草莓","水蜜桃","西瓜"}; //价格 private String[] price={"20","30","40","50"}; ListView mylist=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mylist=findViewById(R.id.mylist); //造一个适配器,创建一个inner class(内部类) MyAdapter md = new MyAdapter(); //给listview添加适配器 mylist.setAdapter(md); } //适配器要进行继承 private class MyAdapter extends BaseAdapter { @Override public int getCount() {//获取数量 return imgs.length; } @Override public Object getItem(int position) {//position记录当前的序号,从0开始 return title[position];//获取某个item } @Override public long getItemId(int position) {//获取选中的编号 return position; } @Override public View getView(int position, View converView, ViewGroup viewGroup) { //用于配置listview要加载的内容,包括视图和数据项 //1.将item的布局文件解析成为view对象,就是将itemlayout这个文件转换为一个View对象 View view1=View.inflate(MainActivity.this,R.layout.itemlayout,null); //这里时要在view1(即itemlayout)里面找对象,与平时直接findViewById不同。 tv1 = view1.findViewById(R.id.tv1);//标题 tv3 = view1.findViewById(R.id.tv3);//价格 iv = view1.findViewById(R.id.iv);//图片 //position指的是item的序号 tv1.setText(title[position]); iv.setBackgroundResource(imgs[position]); tv3.setText(price[position]); return view1; } } }
存在的问题:
当item的内容过多时候,就会出现问题。
3.2 优化方法
view只有一份,即不会发生改变,但是加载的holder视图一直在改变。
优点:当视图不停增加的时候,view可以重复使用,减少开销。
package com.example.myapp; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private ImageView iv; private TextView tv1,tv3;//标题,价格 //1.定义适配器中的数组内容 //图片资源,存的id号 private int[] imgs = {R.drawable.apple,R.drawable.straw,R.drawable.mitao,R.drawable.water}; //标题资源要和上面数组对应 private String[] title = {"苹果","草莓","水蜜桃","西瓜"}; //价格 private String[] price={"20","30","40","50"}; ListView mylist=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mylist=findViewById(R.id.mylist); //造一个适配器,创建一个inner class(内部类) MyAdapter md = new MyAdapter(); //给listview添加适配器 mylist.setAdapter(md); } //适配器要进行继承 private class MyAdapter extends BaseAdapter { @Override public int getCount() {//获取数量 return imgs.length; } @Override public Object getItem(int position) {//position记录当前的序号,从0开始 return title[position];//获取某个item } @Override public long getItemId(int position) {//获取选中的编号 return position; } @Override public View getView(int position, View converView, ViewGroup viewGroup) { // //用于配置listview要加载的内容,包括视图和数据项 // //1.将item的布局文件解析成为view对象,就是将itemlayout这个文件转换为一个View对象 // View view1=View.inflate(MainActivity.this,R.layout.itemlayout,null); // //这里时要在view1(即itemlayout)里面找对象,与平时直接findViewById不同。 // tv1 = view1.findViewById(R.id.tv1);//标题 // tv3 = view1.findViewById(R.id.tv3);//价格 // iv = view1.findViewById(R.id.iv);//图片 // //position指的是item的序号 // tv1.setText(title[position]); // iv.setBackgroundResource(imgs[position]); // tv3.setText(price[position]); // return view1; //优化方案 // ViewHolder holder=null; //converView用于缓存ithem视图的一个对象 if(converView==null){//如果没有的情况下,直接new一个。 converView = View.inflate(MainActivity.this,R.layout.itemlayout,null); holder=new ViewHolder(); holder.tv1 = converView.findViewById(R.id.tv1); holder.tv3 = converView.findViewById(R.id.tv3); holder.iv = converView.findViewById(R.id.iv); converView.setTag(holder); }else{//有的话直接转载 holder = (ViewHolder) converView.getTag(); } holder.iv.setBackgroundResource(imgs[position]); holder.tv1.setText(title[position]); holder.tv3.setText(price[position]); return converView; } } static class ViewHolder{ TextView tv1;//标题 TextView tv3;//价格 ImageView iv; } }