经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
Android listview
来源:cnblogs  作者:yooooooo  时间:2020/12/14 17:02:33  对本文有异议

ListView是Android中最常用的控件之一,几乎所有的应用程序都会用到它,因此学会运用它很重要。下面我们从一个例子中去理解ListView的用法,先看一下我们这个例子的项目结构图

image

这里我们先看Fruit,FruitAdapter 和fruit_item这三个文件

Fruit是作为ListView适配器的类型

FruitAdapter是继承ArrayAdapter的适配器

fruit_item是ListView的子项布局文件

那么问题就来了,为什么要有适配器?它的作用又是什么呢?

之所以要有适配器是因为我们的数据不能直接传递给ListView,因此我们需要借助适配器来完成数据的传递。而ArrayAdapter是android中比较好用的一种,可以通过泛型来指定要适配的数据类型,然后在构造函数中把要适配的数据传入

下面我们就来看一下各个部分的代码,首先我们来看一下MainActivity的代码

  1. package com.example.apple.listviewtest;
  2. import android.support.v7.app.AppCompatActivity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.widget.AdapterView;
  6. import android.widget.ListView;
  7. import android.widget.Toast;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. public class MainActivity extends AppCompatActivity {
  11. // fruitList用于存储数据
  12. private List<Fruit> fruitList=new ArrayList<>();
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. // 先拿到数据并放在适配器上
  18. initFruits(); //初始化水果数据
  19. FruitAdapter adapter=new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
  20. // 将适配器上的数据传递给listView
  21. ListView listView=findViewById(R.id.list_view);
  22. listView.setAdapter(adapter);
  23. // 为ListView注册一个监听器,当用户点击了ListView中的任何一个子项时,就会回调onItemClick()方法
  24. // 在这个方法中可以通过position参数判断出用户点击的是那一个子项
  25. listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  26. @Override
  27. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  28. Fruit fruit=fruitList.get(position);
  29. Toast.makeText(MainActivity.this,fruit.getName(),Toast.LENGTH_SHORT).show();
  30. }
  31. });
  32. }
  33. // 初始化数据
  34. private void initFruits(){
  35. for(int i=0;i<10;i++){
  36. Fruit a=new Fruit("a",R.drawable.a);
  37. fruitList.add(a);
  38. Fruit b=new Fruit("B",R.drawable.b);
  39. fruitList.add(b);
  40. Fruit c=new Fruit("C",R.drawable.c);
  41. fruitList.add(c);
  42. Fruit d=new Fruit("D",R.drawable.d);
  43. fruitList.add(d);
  44. }
  45. }
  46. }

代码也不复杂,我们直接看注释就好了

接下来看一看对应的activity_main.xml的代码

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. >
  6. <ListView
  7. android:id="@+id/list_view"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent"/>
  10. </LinearLayout>

这里的代码也很简单,就是用了一个ListView控件

然后我们就看一下适配器FruitAdapter的代码

  1. package com.example.apple.listviewtest;
  2. import android.content.Context;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import android.widget.ArrayAdapter;
  7. import android.widget.ImageView;
  8. import android.widget.TextView;
  9. import java.util.List;
  10. public class FruitAdapter extends ArrayAdapter<Fruit> {
  11. private int resourceId;
  12. // 适配器的构造函数,把要适配的数据传入这里
  13. public FruitAdapter(Context context, int textViewResourceId, List<Fruit> objects){
  14. super(context,textViewResourceId,objects);
  15. resourceId=textViewResourceId;
  16. }
  17. // convertView 参数用于将之前加载好的布局进行缓存
  18. @Override
  19. public View getView(int position, View convertView, ViewGroup parent){
  20. Fruit fruit=getItem(position); //获取当前项的Fruit实例
  21. // 加个判断,以免ListView每次滚动时都要重新加载布局,以提高运行效率
  22. View view;
  23. ViewHolder viewHolder;
  24. if (convertView==null){
  25. // 避免ListView每次滚动时都要重新加载布局,以提高运行效率
  26. view=LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
  27. // 避免每次调用getView()时都要重新获取控件实例
  28. viewHolder=new ViewHolder();
  29. viewHolder.fruitImage=view.findViewById(R.id.fruit_image);
  30. viewHolder.fruitName=view.findViewById(R.id.fruit_name);
  31. // 将ViewHolder存储在View中(即将控件的实例存储在其中)
  32. view.setTag(viewHolder);
  33. } else{
  34. view=convertView;
  35. viewHolder=(ViewHolder) view.getTag();
  36. }
  37. // 获取控件实例,并调用set...方法使其显示出来
  38. viewHolder.fruitImage.setImageResource(fruit.getImageId());
  39. viewHolder.fruitName.setText(fruit.getName());
  40. return view;
  41. }
  42. // 定义一个内部类,用于对控件的实例进行缓存
  43. class ViewHolder{
  44. ImageView fruitImage;
  45. TextView fruitName;
  46. }
  47. }

可以看到在FruitAdapter类中我们重写了父类的一组构造函数,用于将上下文、ListView子项布局的id和数据都传递进来。另外又重写了getView()方法,这个方法在每个子项被滚动到屏幕内的时候会被调用。ListView本身的运行效率是很低的,因此我们需要优化,具体的优化方法已经在代码中了,直接看代码注释就知道了

现在我们再看看Fruit的代码

  1. package com.example.apple.listviewtest;
  2. public class Fruit {
  3. private String name;
  4. private int imageId;
  5. public Fruit(String name,int imageId){
  6. this.name=name;
  7. this.imageId=imageId;
  8. }
  9. public String getName(){
  10. return name;
  11. }
  12. public int getImageId(){
  13. return imageId;
  14. }
  15. }

Fruit是ListView适配器的类型,即是数据传入到ListView中的类型。

  1. public class FruitAdapter extends ArrayAdapter<Fruit>

看这行FruitAdapter中的代码,我们把Fruit作为了适配器的类型

我们最后看一下fruit_item的代码

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent">
  6. <ImageView
  7. android:id="@+id/fruit_image"
  8. android:layout_width="50dp"
  9. android:layout_height="50dp" />
  10. <TextView
  11. android:id="@+id/fruit_name"
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"
  14. android:layout_gravity="center_vertical"
  15. android:layout_marginLeft="10dp"
  16. />
  17. </LinearLayout>

代码也不复杂,每个子项布局都显示一张图片和一段文字

最终效果图如下:

image

总结:
使用ListView,关键是在适配器与适配器的类型上,这两个方面掌握了,基本就可以定制出属于自己的ListView界面了。ListView虽然功能强大,但是它只能实现纵向滚动的效果,如果要实现横向滚动就有心无力了。

原文链接:http://www.cnblogs.com/linhaostudy/p/14119234.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号