在Android中就提供了专门列表显示条目的控件,ListView控件,ListView控件不是一次性加载全部数据,他是只加载用户在屏幕看得到的数据,当用户滑动的过程中在去加载新的数据,同时会自动销毁之前加载过的数据
什么时候使用ListView ?
答:当很多条目Item,显示都内容不同,数据不同,但是存放的位置是相似的,并且动态变化的条目Item(和数据),就可以用ListView
ListView的使用:
1.在布局中定义ListVIew
<?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"> <!-- 定义ListView --> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="wrap_content"> </ListView> </RelativeLayout>
2.在Java代码中找到ListVIew,再设置适配器 setAdapter(ListAdapter的子类)
为何有BaseAdapter的出现 ?
答:无论是ArrayAdapter还是SimpleAdapter,都是都不够灵活,所以Android提供了BaseAdapter适配器,BaseAdapter可以自定义适配器。
BaseAdapter是 ArrayAdapter 和 SimpleAdapter 的父类,所以可以理解为:ArrayAdapter 和 SimpleAdapter 都去继承了BaseAdapter后进行了封装
ListView+BaseAdapter代码:
package liudeli.ui.all; import android.app.Activity; import android.app.AlertDialog; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; import liudeli.ui.all.adapter.MyBaseAdapter; import liudeli.ui.all.domain.Student; public class ListViewActivity2 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_listview2); ListView listView = findViewById(R.id.listview); // 组装数据 List<Student> students = new ArrayList<>(); for (int i=0; i< 50; i++) { students.add(new Student(i, "刘刘"+ i, 10 + 1)); } final ListAdapter listAdapter = new MyBaseAdapter(this, students); listView.setAdapter(listAdapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { /** * 获取点击条目的信息 * 还记得MyBaseAdapter里面的 public Object getItem(int position)方法吗 * 下面代码的listAdapter.getItem(position); 调用就是 public Object getItem(int position)方法 * 为什么能强制类型转换Student student =(Student),因为在BaseAdapter getItem()的类型是Student */ Student student =(Student) listAdapter.getItem(position); /** * 还记得MyBaseAdapter里面的 public long getItemId(int position)方法吗 * 下面代码的listAdapter.getItemId(position); 调用就是 public long getItemId(int position)方法 */ long itemId = listAdapter.getItemId(position); Toast.makeText(ListViewActivity2.this, "student.toString:" + student.toString() + " itemId:" + itemId , Toast.LENGTH_LONG).show(); new AlertDialog.Builder(ListViewActivity2.this) .setMessage("student.toString:" + student.toString() + " itemId:" + itemId) .setPositiveButton("我知道了", null) .create().show(); } }); } @Override protected void onDestroy() { super.onDestroy(); } }
Student.java
package liudeli.ui.all.domain; public class Student { private int id; private String name; private int age; public Student() { } public Student(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "id=" + id + ", name=" + name + ", age=" + age + '}'; } }
listview_item.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="wrap_content"> <ImageView android:id="@+id/iv_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@id/iv_icon" android:orientation="vertical" android:paddingLeft="20dp"> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20dp" android:textColor="@android:color/black" android:text="姓名" /> <TextView android:id="@+id/tv_age" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16dp" android:textColor="@android:color/black" android:text="年龄" /> </LinearLayout> <TextView android:id="@+id/tv_id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="ID" android:layout_centerVertical="true" android:layout_marginRight="20dp" android:textColor="@android:color/black" /> </RelativeLayout>
MyBaseAdapter代码:
package liudeli.ui.all.adapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import java.util.List; import liudeli.ui.all.R; import liudeli.ui.all.domain.Student; public class MyBaseAdapter extends BaseAdapter { private final String TAG = MyBaseAdapter.class.getSimpleName(); private Context context; private List<Student> students; // 布局加载器 private LayoutInflater layoutInflater; public MyBaseAdapter(Context context, List<Student> students) { this.context = context; this.students = students; layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } /** * 此方法是返回 Item条目都总数,此方法非常重要 * @return */ @Override public int getCount() { return students.size(); } /** * 这个方法是在listAdapter.getItem(position);调用 * 如果这个方法返回的是null,listAdapter.getItem(position)后使用就报错 * @param position * @return */ @Override public Object getItem(int position) { return students.get(position); } /** * 这个方法是在listAdapter.getItemId(position);调用 * @param position * @return */ @Override public long getItemId(int position) { return position + 10000; } /** * 此方法是返回 每一个条目Item的View,有十个条目Item就会执行此方法十次,此方法非常重要 * @param position * @param convertView * @param parent * @return */ @Override public View getView(int position, View convertView, ViewGroup parent) { /*Log.d(TAG, "调用了一次 getView position:" + position); TextView textView = new TextView(context); textView.setTextColor(Color.BLUE); textView.setTextSize(20); textView.setText("调用了一次 getView position:" + position); return textView;*/ View view = layoutInflater.inflate(R.layout.listview_item, null); // 取出布局加载器 加载等布局文件 控件ID TextView name = view.findViewById(R.id.tv_name); TextView age = view.findViewById(R.id.tv_age); TextView id = view.findViewById(R.id.tv_id); // 布局加载器 加载等布局文件 控件和数据绑定 name.setText(students.get(position).getName()); age.setText(students.get(position).getAge() + ""); id.setText(students.get(position).getId() + ""); return view; } }
结果: