Android之ListView的使用
来源:互联网 发布:玉和颜去黑头 知乎 编辑:程序博客网 时间:2024/06/06 20:25
前言
在实现列表的技术里,Android有一个稍微古老的ListView,之所以古老是现在有一个叫 RecyclerView 的方法更加实用和强大,以致于现在基本上很少用 ListView 。但是这是题外话,本章内容虽然讲的是 ListView 但是它也有值得我们学的价值,正所谓技多不压身嘛~
什么是 ListView?
由于手机屏幕有限,我们不可能把所有想要展示的内容全部放在一个界面,这就需要一个列表,列表里每个Item里面在放置内容,听起来是会相比 Button TextView这些控件要难得多,而事实上操作起来确实也比较复杂,接下来由我细细讲解
首先我们建立一个 ListView 的 activity_main.xml 文件,表明我们要开始做列表了
<?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"> <ListView android:id="@+id/list_item" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView></LinearLayout>
这第一步有了做列表的决心,我们就应该思考列表的每一项应该怎么展示,那么我们又应该写一个Item的布局文件,这里我以学生列表为例,所以命名为 student.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="horizontal" > <ImageView android:id="@+id/imageview" android:src="@drawable/iconfont_user" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/textview" android:layout_width="wrap_content" android:layout_height="wrap_content" /></LinearLayout>
从代码可以看出每个Item 由一张图片和文字组成,水平放置,很常规的一种布局,一看就懂的。
之后呢?写好了布局,我们就应该思考怎么把 Item 加到 ListView 里面去,并且每个 Item 都要赋予内容吧,先想想怎么装内容吧,没有内容的 Item 装进去了也是空白列表,就像建房子总要住活人吧 ,装了内容的 Item 才是有生命力的活人,那么问题来了怎么装?读者不妨可以思考一下~~~~
本文例子一直是以学生为对象(ps:因为博主也是学生哈)。所以内容我们就装学生吧,那我们就建一个学生类,如下
public class Student { private String name; private int image; public Student(String name,int image){ this.name = name; this.image = image; } //问题1:这里为什么要get方法而不用set方法 public int getImage() { return image; } public String getName() { return name; }}
看了代码里面的问题1大家可以思考一下,稍后会解答,好了,有了学生这个对象,我们是不是得对号入座呢。把对应的学生放在对应的座位上去,但是这些是小学生,是需要老师指导去坐哪个座位的,这个老师就是一个中间者,即每个 Item 与 对象之间需要一个适配器 Adapter,接下来我们就创建一个 StudentAdapter 记得要继承自 ArrayAdapter
StudentAdapter.java
package com.example.hanlertest.listview2;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.ImageView;import android.widget.TextView;import java.util.List;public class StudentAdapter extends ArrayAdapter<Student> { private int resourceId;//接收布局文件Id public StudentAdapter(Context context, int textViewResourceId, List<Student> objects) { super(context, textViewResourceId, objects); resourceId = textViewResourceId;//将传过来的布局文件赋给resoureceId } @Override public View getView(int position, View convertView, ViewGroup parent) { View view; //将布局文件连接到View view = LayoutInflater.from(getContext()).inflate(resourceId,null); //获取当前的Item Student stu = getItem(position); ViewHolder viewHolder = new ViewHolder(); //获取对应的实例 viewHolder.imageView = (ImageView) view.findViewById(R.id.imageview); viewHolder.textView = (TextView) view.findViewById(R.id.textview); viewHolder.imageView.setImageResource(stu.getImage()); viewHolder.textView.setText(stu.getName()); return view; } //问题2:为什么要建这个内部类 private class ViewHolder { ImageView imageView; TextView textView; }}
同样这里留了个问题2,大家可以思考看看,代码中的 getView 方法可能新手朋友会陌生,我们来看看API
public View getView(int position, View convertView,ViewGroup parent)Get a View that displays the data at the specified position in the data set. You can either create a View manually or inflate it from an XML layout file. When the View is inflated, the parent View (GridView, ListView...) will apply default layout parameters unless you use LayoutInflater.inflate(int, android.view.ViewGroup, boolean) to specify a root view and to prevent attachment to the root.
简单的说,这个方法就是展示(display)Item 数据的方法,在手动滑动列表或者当列表出现在手机屏幕中时就会调用此方法,所以我们在这个方法中编写代码赋予数据。
顺便回答下问题1,这就是为什么我们要写get 方法的原因,因为在这里赋予数据的时候我们需要获取到 Item 的对象数据。
最后我们就在 MainActivity里面将所有的 Item 写进列表
MainActivity.java
package com.example.hanlertest.listview2;import android.app.Activity;import android.content.Context;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.ListView;import java.net.FileNameMap;import java.util.ArrayList;import java.util.List;public class MainActivity extends Activity { public List<Student> stuList = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initStudent();//初始化数据 StudentAdapter stuadapter = new StudentAdapter(MainActivity.this,R.layout.student,stuList);//实例化Adapter并调用构造方法传入布局ID,本例中没有对stuList操作 ListView listview = (ListView) findViewById(R.id.list_item); listview.setAdapter(stuadapter); listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override //点击Item事件 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Student stu = stuList.get(position); Toast.makeText(MainActivity.this,stu.getName(),Toast.LENGTH_SHORT).show(); } }); } private void initStudent() { for (int i = 0 ; i < 10 ; i++){ Student stu = new Student("学生"+i,R.drawable.iconfont_user); stuList.add(stu); } }}
下面贴上结果图
还记得问题2吗?为什么在Adapter要建一个 ViewHolder内部类,事实上 ListView 之所以难用,还因为它有很多细节有待优化,因为在 getView()方法里面每次都要将布局重新加载一边,就这么一拉上拉下就浪费了很多资源,那么怎么优化呢,在 getView()参数列表里还有一个 convertView 参数,这个参数的作用就是将之前已经加载好的东西进行缓存,具体代码看以下修改:
package com.example.administrator.listview;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.ImageView;import android.widget.TextView;import java.util.List;public class FruitAdapter extends ArrayAdapter<Fruit> { private int resourceId; public FruitAdapter(Context context, int textViewResourceId,List<Fruit> objects) { super(context, textViewResourceId,objects); resourceId = textViewResourceId; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view; Fruit fruit = getItem(position); ViewHolder viewHolder = new ViewHolder(); if(convertView == null){ //第一次加载的时候 view = LayoutInflater.from(getContext()).inflate(resourceId, null); viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image); viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name); view.setTag(viewHolder); }else{ view = convertView; viewHolder = (ViewHolder) view.getTag(); } viewHolder.fruitImage.setImageResource(fruit.getImageId()); viewHolder.fruitName.setText(fruit.getName()); return view; } private class ViewHolder { ImageView fruitImage; TextView fruitName; }}
好了,关于ListView的介绍大概如此,看了博主的文章,有没有收获那么一点点呢?或者是有什么指点建议之类的欢迎指出,共勉thanks!!!
- Android之ListView的使用
- android之ListView使用
- Android之使用ListView
- Android杂谈--ListView之BaseAdapter的使用
- Android杂谈--ListView之BaseAdapter的使用
- Android杂谈--ListView之SimpleAdapter的使用
- Android杂谈--ListView之BaseAdapter的使用
- Android ListView之BaseAdapter的使用
- android之ListView的Adapter使用
- Android:ListView之notifyDataSetChanged的使用
- Android之ListView与SimpleAdapter的使用
- Android杂谈--ListView之BaseAdapter的使用
- Android杂谈--ListView之SimpleAdapter的使用
- Android杂谈--ListView之BaseAdapter的使用
- Android杂谈--ListView之SimpleAdapter的使用
- Android--ListView之SimpleAdapter的使用(转)
- Android杂谈--ListView之SimpleAdapter的使用
- android ListView之BaseAdapter的使用方式
- MFC-PlaySound
- Android线程池使用
- 【转】程序员技术练级攻略
- IO-字节流
- React-Native Android 环境搭建
- Android之ListView的使用
- LeetCode *** 6. ZigZag Conversion
- Androd用WebView播放gif动画
- 嵌入式Linux使用Busybox init进程启动过程分析
- 跳台阶问题-----递归算法
- 接触php遇到的小问题
- SDUT 2152 Balloons(DFS 四面+八面) 2010年山东省第一届ACM大学生程序设计竞赛
- Java经典设计模式(1):五大创建型模式(附实例和详解)
- JSTL标签用法 详解