开篇唠嗑

本来说早上要学一会儿英语,为了能够读出那些没见过的专业名词,后来发现我的积累简直太少了,实在不知道要学啥,看来得下载一个单词APP了,不怪得我四级低分飘过…害,被高中英语老师知道了怕是会抓着我揍一顿。好吧好吧,还是赶紧学习。

ListView

用处

ListView可以为我们提供一个列表外加纵向滚动的功能,在现实生活中很多时候都会用到,比如使用微信时,在联系人那一栏便是一个类似ListView一样的列表(不知道是不是,反正看起来像),它的使用可以说带给我们很大便利,但是真正想要用起来却没那么简单

用法

我的思路就是,每一个组件都可以分为布局代码两块
在布局这块,使用ListView首先需要在布局中引用ListView这个控件,并指定它的属性,而后还要创建一个子布局文件,用来确定列表的每一项的布局。
在代码这块,首先需要一个实体类,然后就是创建一个适配器,重写了里面的构造函数和getView()方法之后,就在活动中创建实例然后分配适配器就可以使用了。
听起来似乎很简单?但是做起来要是不熟练还是会翻车的

我的例子

想了想,感觉用到这个控件的APP有很多,我自己就随随便便弄了个通讯录。
第一步:引入控件并写好子项布局。
activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/list_view">

    </ListView>

</LinearLayout>

son_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/image_view"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/name_text"
            android:gravity="center"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/number_text"
            android:gravity="center"/>
    </LinearLayout>

</LinearLayout>

就是很简单的嵌套布局,左边是图片,右边是上下两部分,上面是名字,下面是电话号码。

第二步:创建实体类
Connection.java

package com.example.simpleapp1;

import android.media.Image;

public class Connection {
    private String name;
    private String number;
    private int imageId;

    public Connection(String a, String s, int i) {
        name = a;
        number = s;
        imageId = i;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public int getImageId() {
        return imageId;
    }

    public void setImageId(int imageId) {
        this.imageId = imageId;
    }
}

简简单单的三个属性:名字,电话号码,图片。

第三步:创建适配器。
ConnectionAdapter.java

package com.example.simpleapp1;

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 ConnectionAdapter extends ArrayAdapter<Connection> {
    private int resourceId;

    public ConnectionAdapter(Context context, int resourceId,List<Connection> objects ) {
        super(context, resourceId, objects);
        this.resourceId = resourceId;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Connection connection = getItem(position);
        View view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
        ImageView connectionImage = (ImageView)view.findViewById(R.id.image_view);
        TextView nameText = (TextView)view.findViewById(R.id.name_text);
        TextView numberText = (TextView)view.findViewById(R.id.number_text);
        connectionImage.setImageResource(connection.getImageId());
        nameText.setText(connection.getName());
        numberText.setText(connection.getNumber());
        return view;
    }
}

首先继承了ArrayAdapter,然后将泛型指定为Connection,之后重写构造函数,把上下文、数据、子项布局的id传进来,然后重写getView()方法,加载布局。

第四步,在活动中使用。
MainActivity.java

package com.example.simpleapp1;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
        private List<Connection> connectionList = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initConnection();
        ConnectionAdapter adapter = new ConnectionAdapter(MainActivity.this,R.layout.son_layout,connectionList);
        ListView listView = (ListView)findViewById(R.id.list_view);
        listView.setAdapter(adapter);

    }

    private void initConnection() {
        for (int i = 5;i>=0;i--){
            Connection a = new Connection("a","110", R.drawable.juzi);
            connectionList.add(a);
            Connection b = new Connection("b","119", R.drawable.xigua);
            connectionList.add(b);
            Connection c = new Connection("c","120", R.drawable.pingguo);
            connectionList.add(c);
        }
    }
}

就是创建适配器对象,然后实例化ListView,并指定适配器就好啦,因为还没弄数据库,所以就自己瞎弄了点数据上去。

最终效果:
在这里插入图片描述
啊 人没了 这也太…好吧好吧,还是有时间要学学界面的美化。。。

优化

每一个控件肯定都会有好处和坏处,ListView的缺点就在于他的运行效率在快速滑动的时候会有限制,而且只支持纵向滚动,并且设置点击事件的时候,不能具体到子项布局中的控件。
解决运行效率,可以从两个方面入手
第一个方面:在getView()方法中,由于每次都会重新加载布局,所以会使得效率变慢。但是getView()方法有一个convertView参数,他会缓存布局,所以我们只需要加一个判断语句,假如convertView为空,就加载布局,假如不为空,就使用convertView里缓存的布局。
第二个方面:在getView()方法中,每次View都会调用findViewById()方法获取实例,我们要做的同样是把实例缓存下来直接使用。在这里需要用到ViewHolder。
修改一下getView()方法,并增加一个内部类ViewHolder.

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Connection connection = getItem(position);
        View view;
        ViewHolder viewHolder;
        if(convertView == null){
            view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
            viewHolder = new ViewHolder();
            viewHolder.image = (ImageView)view.findViewById(R.id.image_view);
            viewHolder.name = (TextView)view.findViewById(R.id.name_text);
            viewHolder.number = (TextView)view.findViewById(R.id.number_text);
            view.setTag(viewHolder);
        }
        else{
          view = convertView;
          viewHolder = (ViewHolder)view.getTag();
        }
        viewHolder.image.setImageResource(connection.getImageId());
        viewHolder.number.setText(connection.getNumber());
        viewHolder.name.setText(connection.getName());
        return view;
    }
    class ViewHolder{
        ImageView image;
        TextView name;
        TextView number;
    }
}

啊,经过两步优化后,其实效率已经挺好的啦!

碎碎念

也不知道每天就这么复习,够不够时间让我复习完参加秋招,但是我总觉得复习不能急,要踏实稳妥,不然很容易忘。
啊,今天七夕啊,真好呢,看到大家都有甜甜的恋爱,心里也是有着一丝悸动,但是怎么说呢,也许只有在看到别人甜甜的恋爱的时候,我才会有这种感觉吧,大多数时候还是享受孤独的,毕竟恋爱是酸甜苦辣咸都有的勒。无论如何,还是希望天下有情人终成眷属,幸福美满不分开!
至于今天晚上要看的文,已经想好啦,就看海子的《面朝大海,春暖花开》吧!
“给每一条河每一座山取一个温暖的名字
陌生人,我也为你祝福
愿你有一个灿烂的前程
愿你有情人终成眷属
愿你在尘世获得幸福
我只愿面朝大海,春暖花开”

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐