高端网站建设公司联系电话/免费观看短视频的app软件推荐
文章目录
- 1 自定义ListView列表项
- 1.1 自定义布局文件
- 1.2 自定义Adapter加载自定义布局
- 2 进行ListView进行适配
- 2.1 自定义JavaBean
- 2.2 自定义布局与ListIView绑定
- 2.2.1 主布局文件
- 2.2.2 获取自定义布局文件,填充主布局文件
- 3 对自定义布局的加载进行优化
- 3.1 对自定义列表适配器进行优化
- 3.2 完整优化代码
- 4 结果
1 自定义ListView列表项
- LIstView支持自定义列表项,此时需要自定义布局文件
- 在自定义布局文件需要使用类型数据的时候,此时需要自定义适配器
1.1 自定义布局文件
- 新建layout.xml文件
- 新建的layout布局是列表项的布局,相当于在列表项中进行自定义布局
<?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="wrap_content"><ImageViewandroid:layout_width="100dp"android:layout_height="80dp"android:id="@+id/fruit_image"android:src="@drawable/apple"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/fruit_name"android:text="name"android:textSize="30sp"android:textColor="#000000"android:layout_gravity="center_vertical"android:layout_marginLeft="20dp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/fruit_price"android:text="name"android:textSize="30sp"android:textColor="#ff0000"android:layout_gravity="center_vertical"android:layout_marginLeft="40dp"/></LinearLayout>
1.2 自定义Adapter加载自定义布局
- 自定义Adapter需要继承一个父类适配器,例如:ArrayAdapter, 并覆盖其中的构造方法与**getView()**方法
- 自定义构造方法:必须是有参构造方法
- 参数一:上下文环境,例如MainActivity.this
- 参数二:布局文件的ID,为R.layout.layout
- 参数三:为列表类型的数据源
// 参数1 为上下文, 参数2 为layout布局的id, 参数3 为数据源public FruitAdapter(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {super(context, resource, objects);}
- getView方法,填充自定义布局
使用步骤:
- 获取传入数组的数据项,数组或者列表在构造方法中传入
- 将自定义布局转化为View类型,使用 **inflate()**方法进行填充
LayoutInflater.from(getContext()).inflate(R.layout.fruit_layout, parent, false);
- 在view中获取其中的控件,填充其中的信息
- 最后返回布局view
// 屏幕滑动的时候,调用子项
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {//1. 得到当前fruit实例, 可见 fruit在适配器中Fruit fruit = getItem(position);// 2. 为子项加载布局, 传入到ViewGroup中View view = LayoutInflater.from(getContext()).inflate(R.layout.fruit_layout, parent, false);// 3. 获取View中的控件,并为控件赋值ImageView fruitImage = view.findViewById(R.id.fruit_image);TextView fruitName = view.findViewById(R.id.fruit_name);TextView fruitPrice = view.findViewById(R.id.fruit_price);// 4. 设置图片以及文件资源fruitImage.setImageResource(fruit.getImageID());fruitName.setText(fruit.getName());fruitPrice.setText("$" + fruit.getPrice() / 100 + "/KG");// 5. 返回设置好的布局return view;
}
2 进行ListView进行适配
2.1 自定义JavaBean
package com.hlq.sz_ch_listviewdemo02;public class Fruit {private int imageID;private String name;private long price;public void setImageID(int imageID) {this.imageID = imageID;}public void setName(String name) {this.name = name;}public void setPrice(long price) {this.price = price;}public int getImageID() {return imageID;}public String getName() {return name;}public long getPrice() {return price;}public Fruit(int imageID, String name, long price) {this.imageID = imageID;this.name = name;this.price = price;}public Fruit() {}
}
2.2 自定义布局与ListIView绑定
2.2.1 主布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><ListViewandroid:id="@+id/list_view"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>
2.2.2 获取自定义布局文件,填充主布局文件
- 在内存中新建自定义列表适配器,
new FruitAdapterEnhance(MainActivity.this, R.layout.fruit_layout, fruits);
- 绑定适配器,
listView.setAdapter(fruitAdapter);
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {// 内部对象private ListView listView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 1. 绑定控件listView = (ListView)findViewById(R.id.list_view);// 2. 准备数据List<Fruit> fruits = new ArrayList<>();for (int i = 0; i < 2; ++i) {Fruit pineApple = new Fruit(R.drawable.pineapple, "菠萝", 1690);fruits.add(pineApple);Fruit mango = new Fruit(R.drawable.mango, "芒果", 2990);fruits.add(mango);Fruit grape = new Fruit(R.drawable.grape, "葡萄", 1990);fruits.add(grape);Fruit pomegranate = new Fruit(R.drawable.pomegranate, "石榴", 1500);fruits.add(pomegranate);Fruit apple = new Fruit(R.drawable.apple, "苹果", 2000);fruits.add(apple);Fruit watermelon = new Fruit(R.drawable.watermelon, "西瓜", 2880);fruits.add(watermelon);Fruit orange = new Fruit(R.drawable.orange, "橘子", 1880);fruits.add(orange);}// 3. 设置子布局// 4. 定义适配器, 控件与数据的桥梁FruitAdapterEnhance fruitAdapter = new FruitAdapterEnhance(MainActivity.this, R.layout.fruit_layout, fruits);listView.setAdapter(fruitAdapter);// 5. 设置点击事件// 4 为列表适配器增加响应事件listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position , long i) {// 从View中获取信息, 此时的View为点击的ViewTextView textView = view.findViewById(R.id.fruit_name);String result = textView.getText().toString();Toast.makeText(MainActivity.this, "选择的选项为: " + result, Toast.LENGTH_SHORT).show();// 上下文必须指定为MainActivity.this}});}
}
3 对自定义布局的加载进行优化
- 优化思想:在用户进行滑动的时候,每一个列表项都需要重新加载,由于布局要加载到内存,造成ListView的性能下降
- 为了优化性能,可以将ListView的布局保存,不必重新加载,每一个列表项只是将数据填入到布局中
3.1 对自定义列表适配器进行优化
- 自定义内部类,包含列表项中的布局控件,此时为ViewHolder
- 第一次加载时,View的引用为null, 将ViewHolder内部类存储在view中,使用
view.setTag(viewHolder);
- 当view的引用不为null的时候,获取view布局,并获取其中的内部类进行布局的填充
view = convertView; viewHolder = (ViewHolder)view.getTag();
- 每一个项目的加载都需要设置信息,因此在ViewHolder内部类中填充信息。获取View控件,进行资源的设置,例如:
viewHolder.getFruitImage().setImageResource(fruit.getImageID());
viewHolder.getFruitName().setText(fruit.getName());
3.2 完整优化代码
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 androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.List;public class FruitAdapterEnhance extends ArrayAdapter<Fruit> {// 构造函数// 参数1 为上下文, 参数2 为layout布局的id, 参数3 为数据源public FruitAdapterEnhance(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {super(context, resource, objects);}// 屏幕滑动的时候,调用子项@NonNull@Overridepublic View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {//1. 得到当前fruit实例, 从适配的位置获取 使得控件与数据项一一对应Fruit fruit = getItem(position);// 1. 新增ViewHolderViewHolder viewHolder;View view;// 2. 是否加载了布局if (convertView == null) {// 2.1 没有加载布局的时候,使用子布局view = LayoutInflater.from(getContext()).inflate(R.layout.fruit_layout, parent, false);viewHolder = new ViewHolder();viewHolder.setFruitImage(view.findViewById(R.id.fruit_image));viewHolder.setFruitName(view.findViewById(R.id.fruit_name));viewHolder.setFruitPrice(view.findViewById(R.id.fruit_price));// 2.2 将viewHolder存储与view中view.setTag(viewHolder);} else {// 从新获取viewHolderview = convertView;viewHolder = (ViewHolder)view.getTag();}// 3. 设置viewGroup中的内容viewHolder.getFruitImage().setImageResource(fruit.getImageID());viewHolder.getFruitName().setText(fruit.getName());viewHolder.getFruitPrice().setText("$" + fruit.getPrice() / 100 + "/Kg");// // 2. 为子项加载布局, 传入到ViewGroup中
// View view = LayoutInflater.from(getContext()).inflate(R.layout.fruit_layout, parent, false);
//
// // 3. 获取View中的控件,并为控件赋值
// ImageView fruitImage = view.findViewById(R.id.fruit_image);
// TextView fruitName = view.findViewById(R.id.fruit_name);
// TextView fruitPrice = view.findViewById(R.id.fruit_price);
//
// // 4. 设置图片以及文件资源
// fruitImage.setImageResource(fruit.getImageID());
// fruitName.setText(fruit.getName());
// fruitPrice.setText("$" + fruit.getPrice() / 100 + "/KG");
//
// // 5. 返回设置好的布局return view;}// 3设置内部类,加载布局,只需提供数据,加快读取速度private class ViewHolder{ImageView fruitImage;TextView fruitName;TextView fruitPrice;public ImageView getFruitImage() {return fruitImage;}public TextView getFruitName() {return fruitName;}public TextView getFruitPrice() {return fruitPrice;}public void setFruitImage(ImageView fruitImage) {this.fruitImage = fruitImage;}public void setFruitName(TextView fruitName) {this.fruitName = fruitName;}public void setFruitPrice(TextView fruitPrice) {this.fruitPrice = fruitPrice;}}}