APP学习5(ListView和Adapter)

1. ListView

ListView是以列表的形式展示数据内容,并且能够根据列表的高度自适应屏幕显示。

 

 

 2. 常用数据适配器(Adapter)

BaseAdapter是基本的适配器,实际上是一个抽象类,通常在自定义适配器时回继承BaseAdapter。

 

 

 

3. 例子

3.1 自己编写(不推荐)

实现结果:

 

 注意点:就是设置名称的时候比较麻烦。而且需要两个layout文件。

layout_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"
    android:orientation="vertical"
    >
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="购物商城"
        android:gravity="center"
        android:textSize="50sp"
        android:textColor="@color/black"
        android:background="#00BCD4"
        ></TextView>

    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/mylist"
        ></ListView>
</LinearLayout>

itemlayout.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="match_parent"
    android:padding="20dp"
    >
    <ImageView
        android:layout_width="120dp"
        android:layout_height="90dp"
        android:id="@+id/iv"
        android:layout_centerVertical="true"
        ></ImageView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv1"
        android:text="标题"
        android:layout_toRightOf="@+id/iv"
        android:layout_alignBottom="@+id/iv"
        android:layout_marginBottom="50dp"
        android:layout_marginLeft="10dp"
        ></TextView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv2"
        android:text="内容"
        android:layout_toRightOf="@+id/iv"
        android:layout_alignBottom="@+id/iv"
        android:layout_marginBottom="20dp"
        android:layout_marginLeft="10dp"
        android:textColor="#FF9800"
        ></TextView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv3"
        android:text="价格"
        android:layout_toRightOf="@+id/tv2"
        android:layout_alignBottom="@+id/tv2"
        android:layout_marginLeft="5dp"
        android:textColor="#FF9800"
        ></TextView>
</RelativeLayout>

MainActivity.java

package com.example.myapp;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity {
    private ImageView iv;
    private TextView tv1,tv3;//标题,价格
    //1.定义适配器中的数组内容
    //图片资源,存的id号
    private int[] imgs = {R.drawable.apple,R.drawable.straw,R.drawable.mitao,R.drawable.water};
    //标题资源要和上面数组对应
    private  String[] title = {"苹果","草莓","水蜜桃","西瓜"};
    //价格
    private String[] price={"20","30","40","50"};
    ListView mylist=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mylist=findViewById(R.id.mylist);
        //造一个适配器,创建一个inner class(内部类)
        MyAdapter md = new MyAdapter();
        //给listview添加适配器
        mylist.setAdapter(md);
    }
//适配器要进行继承
    private class MyAdapter extends BaseAdapter {

    @Override
    public int getCount() {//获取数量
        return imgs.length;
    }

    @Override
    public Object getItem(int position) {//position记录当前的序号,从0开始
        return title[position];//获取某个item
    }

    @Override
    public long getItemId(int position) {//获取选中的编号
        return position;
    }

    @Override
    public View getView(int position, View converView, ViewGroup viewGroup) {
        //用于配置listview要加载的内容,包括视图和数据项
        //1.将item的布局文件解析成为view对象,就是将itemlayout这个文件转换为一个View对象
        View view1=View.inflate(MainActivity.this,R.layout.itemlayout,null);
        //这里时要在view1(即itemlayout)里面找对象,与平时直接findViewById不同。
        tv1 = view1.findViewById(R.id.tv1);//标题
        tv3 = view1.findViewById(R.id.tv3);//价格
        iv = view1.findViewById(R.id.iv);//图片
        //position指的是item的序号
        tv1.setText(title[position]);
        iv.setBackgroundResource(imgs[position]);
        tv3.setText(price[position]);
        return view1;
    }
}
}

 

存在的问题:

当item的内容过多时候,就会出现问题。

3.2 优化方法

view只有一份,即不会发生改变,但是加载的holder视图一直在改变。

优点:当视图不停增加的时候,view可以重复使用,减少开销。

package com.example.myapp;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity {
    private ImageView iv;
    private TextView tv1,tv3;//标题,价格
    //1.定义适配器中的数组内容
    //图片资源,存的id号
    private int[] imgs = {R.drawable.apple,R.drawable.straw,R.drawable.mitao,R.drawable.water};
    //标题资源要和上面数组对应
    private  String[] title = {"苹果","草莓","水蜜桃","西瓜"};
    //价格
    private String[] price={"20","30","40","50"};
    ListView mylist=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mylist=findViewById(R.id.mylist);
        //造一个适配器,创建一个inner class(内部类)
        MyAdapter md = new MyAdapter();
        //给listview添加适配器
        mylist.setAdapter(md);
    }
//适配器要进行继承
    private class MyAdapter extends BaseAdapter {

    @Override
    public int getCount() {//获取数量
        return imgs.length;
    }

    @Override
    public Object getItem(int position) {//position记录当前的序号,从0开始
        return title[position];//获取某个item
    }

    @Override
    public long getItemId(int position) {//获取选中的编号
        return position;
    }

    @Override
    public View getView(int position, View converView, ViewGroup viewGroup) {
//        //用于配置listview要加载的内容,包括视图和数据项
//        //1.将item的布局文件解析成为view对象,就是将itemlayout这个文件转换为一个View对象
//        View view1=View.inflate(MainActivity.this,R.layout.itemlayout,null);
//        //这里时要在view1(即itemlayout)里面找对象,与平时直接findViewById不同。
//        tv1 = view1.findViewById(R.id.tv1);//标题
//        tv3 = view1.findViewById(R.id.tv3);//价格
//        iv = view1.findViewById(R.id.iv);//图片
//        //position指的是item的序号
//        tv1.setText(title[position]);
//        iv.setBackgroundResource(imgs[position]);
//        tv3.setText(price[position]);
//        return view1;

        //优化方案
        //
        ViewHolder holder=null;
        //converView用于缓存ithem视图的一个对象
        if(converView==null){//如果没有的情况下,直接new一个。
            converView = View.inflate(MainActivity.this,R.layout.itemlayout,null);
            holder=new ViewHolder();
            holder.tv1 = converView.findViewById(R.id.tv1);
            holder.tv3 = converView.findViewById(R.id.tv3);
            holder.iv = converView.findViewById(R.id.iv);
            converView.setTag(holder);
        }else{//有的话直接转载
            holder = (ViewHolder) converView.getTag();
        }
        holder.iv.setBackgroundResource(imgs[position]);
        holder.tv1.setText(title[position]);
        holder.tv3.setText(price[position]);
        return converView;
     }
    }
    static class ViewHolder{
        TextView tv1;//标题
        TextView tv3;//价格
        ImageView iv;
    }
}

 

posted on 2023-03-05 17:44  201812  阅读(46)  评论(0编辑  收藏  举报