zoukankan      html  css  js  c++  java
  • Android listview

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

    image

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

    Fruit是作为ListView适配器的类型

    FruitAdapter是继承ArrayAdapter的适配器

    fruit_item是ListView的子项布局文件

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

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

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

    package com.example.apple.listviewtest;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ListView;
    import android.widget.Toast;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
    
        // fruitList用于存储数据
        private List<Fruit> fruitList=new ArrayList<>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 先拿到数据并放在适配器上
            initFruits(); //初始化水果数据
            FruitAdapter adapter=new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
    
            // 将适配器上的数据传递给listView
            ListView listView=findViewById(R.id.list_view);
            listView.setAdapter(adapter);
    
            // 为ListView注册一个监听器,当用户点击了ListView中的任何一个子项时,就会回调onItemClick()方法
            // 在这个方法中可以通过position参数判断出用户点击的是那一个子项
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Fruit fruit=fruitList.get(position);
                    Toast.makeText(MainActivity.this,fruit.getName(),Toast.LENGTH_SHORT).show();
                }
            });
        }
    
        // 初始化数据
        private void initFruits(){
            for(int i=0;i<10;i++){
                Fruit a=new Fruit("a",R.drawable.a);
                fruitList.add(a);
                Fruit b=new Fruit("B",R.drawable.b);
                fruitList.add(b);
                Fruit c=new Fruit("C",R.drawable.c);
                fruitList.add(c);
                Fruit d=new Fruit("D",R.drawable.d);
                fruitList.add(d);
            }
        }
    }
    
    

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

    接下来看一看对应的activity_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"
        >
    
        <ListView
            android:id="@+id/list_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>
    

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

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

    package com.example.apple.listviewtest;
    
    
    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;
        }
    
        // convertView 参数用于将之前加载好的布局进行缓存
        @Override
        public View getView(int position, View convertView, ViewGroup parent){
            Fruit fruit=getItem(position); //获取当前项的Fruit实例
    
            // 加个判断,以免ListView每次滚动时都要重新加载布局,以提高运行效率
            View view;
            ViewHolder viewHolder;
            if (convertView==null){
    
                // 避免ListView每次滚动时都要重新加载布局,以提高运行效率
                view=LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
    
                // 避免每次调用getView()时都要重新获取控件实例
                viewHolder=new ViewHolder();
                viewHolder.fruitImage=view.findViewById(R.id.fruit_image);
                viewHolder.fruitName=view.findViewById(R.id.fruit_name);
    
                // 将ViewHolder存储在View中(即将控件的实例存储在其中)
                view.setTag(viewHolder);
            } else{
                view=convertView;
                viewHolder=(ViewHolder) view.getTag();
            }
    
            // 获取控件实例,并调用set...方法使其显示出来
            viewHolder.fruitImage.setImageResource(fruit.getImageId());
            viewHolder.fruitName.setText(fruit.getName());
            return view;
        }
    
        // 定义一个内部类,用于对控件的实例进行缓存
        class ViewHolder{
            ImageView fruitImage;
            TextView fruitName;
        }
    }
    

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

    现在我们再看看Fruit的代码

    package com.example.apple.listviewtest;
    
    public class Fruit {
        private String name;
        private int imageId;
    
        public Fruit(String name,int imageId){
            this.name=name;
            this.imageId=imageId;
        }
    
        public String getName(){
            return name;
        }
    
        public int getImageId(){
            return  imageId;
        }
    }
    

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

    public class FruitAdapter extends ArrayAdapter<Fruit>
    
    

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

    我们最后看一下fruit_item的代码

    <?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">
    
        <ImageView
            android:id="@+id/fruit_image"
            android:layout_width="50dp"
            android:layout_height="50dp" />
    
        <TextView
            android:id="@+id/fruit_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="10dp"
            />
    </LinearLayout>
    

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

    最终效果图如下:

    image

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

  • 相关阅读:
    软件体系架构复习要点
    Operating System on Raspberry Pi 3b
    2019-2020 ICPC North-Western Russia Regional Contest
    2019 ICPC ShenYang Regional Online Contest
    2019 ICPC XuZhou Regional Online Contest
    2019 ICPC NanChang Regional Online Contest
    2019 ICPC NanJing Regional Online Contest
    Codeforces Edu Round 72 (Rated for Div. 2)
    Codeforces Round #583 (Div.1+Div.2)
    AtCoder Beginning Contest 139
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/14119234.html
Copyright © 2011-2022 走看看