• 安卓基础学习 Day19|安卓高级控件------下拉列表


    目录

    下拉列表(spinner)

    下拉列表(数组适配器、列表框形式)

    1.提出要求

    2.主布局资源文件

    3.主界面 

    4.条目布局文件

    下拉列表(数组适配器、对话框形式) 

    1.提出要求

    2.主布局资源文件

    3.条目布局文件

    4.主界面

    下拉列表(简单适配器) 

    1.提出要求

    2.条目布局

    3.主布局资源文件

    4.主界面

    下拉列表(基本适配器)

    1.提出要求

    2.条目布局文件

    3.主布局资源文件

    4.适配器类 

    5.实体类

    6.主界面

    复用 convertView进行优化


    下拉列表(spinner)

    Spinner用于从一串列表中选择某项,功能类似于单选按钮的组合

    有两种展示的方式:列表框形式、对话框形式

    下拉列表(数组适配器、列表框形式)

    1.提出要求

    2.主布局资源文件

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. xmlns:tools="http://schemas.android.com/tools"
    4. android:layout_width="match_parent"
    5. android:layout_height="match_parent"
    6. android:orientation="vertical"
    7. tools:context=".MainActivity">
    8. <TextView
    9. android:layout_width="match_parent"
    10. android:layout_height="wrap_content"
    11. android:text="下拉模式的列表框"
    12. android:textSize="17sp" />
    13. <Spinner
    14. android:id="@+id/sp_dropdown"
    15. android:layout_width="match_parent"
    16. android:layout_height="wrap_content"
    17. android:spinnerMode="dropdown"/>
    18. </LinearLayout>

    效果

    3.主界面 

    声明变量

    声明变量(静态数组,要展示的选项内容)

    主界面完整代码

    1. import androidx.appcompat.app.AppCompatActivity;
    2. import android.os.Bundle;
    3. import android.view.View;
    4. import android.widget.AdapterView;
    5. import android.widget.ArrayAdapter;
    6. import android.widget.Spinner;
    7. import android.widget.Toast;
    8. public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
    9. private Spinner sp_dropdown;
    10. //定义下拉列表需要显示的文本数组
    11. private final static String[] starArray = {"水星", "金星", "地球", "火星", "木星", "土星", "天王星", "海王星"};
    12. @Override
    13. protected void onCreate(Bundle savedInstanceState) {
    14. super.onCreate(savedInstanceState);
    15. setContentView(R.layout.activity_main);
    16. sp_dropdown = findViewById(R.id.sp_dropdown);
    17. //声明一个下拉列表的数组适配器// 第一个参数:上下文,第二个参数:条目布局,第三个参数:要显示的数据
    18. ArrayAdapter<String> startAdapter = new ArrayAdapter<>(this, R.layout.item_select, starArray);
    19. //将适配器给Spinner
    20. sp_dropdown.setAdapter(startAdapter);
    21. //设置下拉框默认显示第一项
    22. sp_dropdown.setSelection(0);
    23. //给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法
    24. sp_dropdown.setOnItemSelectedListener(this);
    25. }
    26. @Override
    27. public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
    28. Toast.makeText(MainActivity.this, "你选择的是" + starArray[position], Toast.LENGTH_SHORT).show();
    29. }
    30. @Override
    31. public void onNothingSelected(AdapterView<?> adapterView) {
    32. }
    33. }

    新建条目布局(我这里根节点直接用的TestView)

    4.条目布局文件

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <TextView xmlns:android="http://schemas.android.com/apk/res/android"
    3. xmlns:tools="http://schemas.android.com/tools"
    4. android:layout_width="match_parent"
    5. android:layout_height="50dp"
    6. android:gravity="center"
    7. android:textColor="#0000ff"
    8. android:textSize="17sp"
    9. tools:text="火星" />

    添加适配器(Adapter)

    适配器作用:负责从数据集合中取出对应的数据显示到条目布局上

    数组适配器(ArrayAdapter):最简单的适配器,只展示一行文字

    实现步骤:

    (1)编写列表项的XML文件,内部布局只要一个TextView标签

    (2)调用ArrayAdapter的构造方法,填入待展现的字符串数组,以及列表项的XML文件(R。layout.item_select)

    (3)调用下拉控件的setAdapter方法,传入第二步得到的适配器实例

    声明数组适配器

     效果

     设置监听,一单选中弹出吐司

    效果

    下拉列表(数组适配器、对话框形式) 

    1.提出要求

    2.主布局资源文件

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. xmlns:tools="http://schemas.android.com/tools"
    4. android:layout_width="match_parent"
    5. android:layout_height="match_parent"
    6. android:orientation="vertical"
    7. tools:context=".MainActivity">
    8. <TextView
    9. android:layout_width="match_parent"
    10. android:layout_height="wrap_content"
    11. android:text="下拉模式的列表框"
    12. android:textSize="17sp" />
    13. <Spinner
    14. android:id="@+id/sp_dialog"
    15. android:layout_width="match_parent"
    16. android:layout_height="wrap_content"
    17. android:spinnerMode="dialog"/>
    18. </LinearLayout>

    3.条目布局文件

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <TextView xmlns:android="http://schemas.android.com/apk/res/android"
    3. xmlns:tools="http://schemas.android.com/tools"
    4. android:layout_width="match_parent"
    5. android:layout_height="50dp"
    6. android:gravity="center"
    7. android:textColor="#0000ff"
    8. android:textSize="17sp"
    9. tools:text="火星" />

    4.主界面

    1. package net.lzt.spinnerdialog;
    2. import androidx.appcompat.app.AppCompatActivity;
    3. import android.os.Bundle;
    4. import android.view.View;
    5. import android.widget.AdapterView;
    6. import android.widget.ArrayAdapter;
    7. import android.widget.Spinner;
    8. import android.widget.Toast;
    9. public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
    10. private Spinner sp_dialog;
    11. //定义下拉列表需要显示的文本数组
    12. private final static String[] starArray = {"水星", "金星", "地球", "火星", "木星", "土星", "天王星", "海王星"};
    13. @Override
    14. protected void onCreate(Bundle savedInstanceState) {
    15. super.onCreate(savedInstanceState);
    16. setContentView(R.layout.activity_main);
    17. sp_dialog = findViewById(R.id.sp_dialog);
    18. //声明一个下拉列表的数组适配器// 第一个参数:上下文,第二个参数:条目布局,第三个参数:要显示的数据
    19. ArrayAdapter<String> startAdapter = new ArrayAdapter<>(this, R.layout.item_select, starArray);
    20. //设置下拉框的标题。对话框模式才显示标题,下拉模式不显示标题
    21. sp_dialog.setPrompt("请选择行星");
    22. //将适配器给Spinner
    23. sp_dialog.setAdapter(startAdapter);
    24. //设置下拉框默认显示第一项
    25. sp_dialog.setSelection(0);
    26. //给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法
    27. sp_dialog.setOnItemSelectedListener(this);
    28. }
    29. @Override
    30. public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
    31. Toast.makeText(MainActivity.this, "你选择的是" + starArray[position], Toast.LENGTH_SHORT).show();
    32. }
    33. @Override
    34. public void onNothingSelected(AdapterView<?> adapterView) {
    35. }
    36. }

    两种方式的代码基本不变,但是对话框的可以显示一个标题

    效果

    下拉列表(简单适配器) 

    简单适配器(SimpleAdapter)

    简单适配器允许在列表项中同时展示文本与图片

    1.提出要求

    2.条目布局

    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="wrap_content"
    5. android:orientation="horizontal">
    6. <ImageView
    7. android:layout_width="0dp"
    8. android:layout_height="50dp"
    9. android:layout_weight="1"
    10. android:src="@mipmap/diqiu" />
    11. <TextView
    12. android:id="@+id/tv_name"
    13. android:layout_width="0dp"
    14. android:layout_height="match_parent"
    15. android:layout_weight="3"
    16. android:gravity="center"
    17. android:textColor="#ff0000"
    18. android:textSize="17sp"
    19. android:text="地球"/>
    20. </LinearLayout>

    实现效果

    3.主布局资源文件

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. xmlns:tools="http://schemas.android.com/tools"
    4. android:layout_width="match_parent"
    5. android:layout_height="match_parent"
    6. android:orientation="vertical"
    7. tools:context=".MainActivity">
    8. <TextView
    9. android:layout_width="match_parent"
    10. android:layout_height="wrap_content"
    11. android:text="简单适配器"
    12. android:textSize="17sp" />
    13. <Spinner
    14. android:id="@+id/sp_icon"
    15. android:layout_width="match_parent"
    16. android:layout_height="wrap_content"
    17. android:spinnerMode="dialog"/>
    18. </LinearLayout>

    效果

    4.主界面

    1. import androidx.appcompat.app.AppCompatActivity;
    2. import android.os.Bundle;
    3. import android.view.View;
    4. import android.widget.AdapterView;
    5. import android.widget.SimpleAdapter;
    6. import android.widget.Spinner;
    7. import android.widget.Toast;
    8. import java.util.ArrayList;
    9. import java.util.HashMap;
    10. import java.util.List;
    11. import java.util.Map;
    12. public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
    13. //定义下拉列表需要显示的行星图标数组
    14. private static final int[] iconArray = {
    15. R.mipmap.shuixing, R.mipmap.jinxing, R.mipmap.diqiu, R.mipmap.huoxing,
    16. R.mipmap.muxing, R.mipmap.tuxing, R.mipmap.tianwangxing, R.mipmap.haiwangxing
    17. };
    18. //定义下拉列表需要显示的行星名称数组
    19. private static final String[] starArray = {"水星", "金星", "地球", "火星", "木星", "土星", "天王星", "海王星"};
    20. @Override
    21. protected void onCreate(Bundle savedInstanceState) {
    22. super.onCreate(savedInstanceState);
    23. setContentView(R.layout.activity_main);
    24. //声明一个映射对象的列表,用于保存行星的图标与名称配对信息
    25. List<Map<String, Object>> List = new ArrayList<>();
    26. //iconArray是行星的图标数组,starArray是行星名称数组【这里遍历数组】
    27. for (int i = 0; i < iconArray.length; i++) {
    28. Map<String, Object> item = new HashMap<>();
    29. item.put("icon", iconArray[i]);
    30. item.put("name", starArray[i]);
    31. List.add(item);
    32. }
    33. //建立绑定关系,声明一个下拉列表的简单适配器,其中指定了图标与文本两组数据
    34. SimpleAdapter starAdapter = new SimpleAdapter(this, List,
    35. R.layout.item_simple, //条目布局
    36. new String[]{"icon", "name"}, //map中的key
    37. new int[]{R.id.iv_icon, R.id.tv_name}); //map中的值
    38. Spinner sp_icon = findViewById(R.id.sp_icon);
    39. sp_icon.setAdapter(starAdapter);
    40. sp_icon.setSelection(0); // 默认选中0
    41. sp_icon.setOnItemSelectedListener(this);
    42. }
    43. @Override
    44. public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
    45. Toast.makeText(MainActivity.this, "你选择的是" + starArray[position], Toast.LENGTH_SHORT).show();
    46. }
    47. @Override
    48. public void onNothingSelected(AdapterView<?> adapterView) {
    49. }
    50. }

     集合当中数据与条目布局的对应关系 

     运行效果

     【我的图片是我网上找的然后截的图,大小有点差别,如果还想好看整齐点儿可以找大小一致的照片】

    下拉列表(基本适配器)

    基本适配器(BaseAdapter)是一种适应性更强的基本适配器

    1.提出要求

    2.条目布局文件

    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="wrap_content"
    5. android:orientation="horizontal">
    6. <!--这里用于显示行星图片的视图-->
    7. <ImageView
    8. android:id="@+id/iv_icon"
    9. android:layout_width="0dp"
    10. android:layout_height="80dp"
    11. android:layout_weight="1"
    12. android:scaleType="fitCenter"
    13. android:src="@mipmap/diqiu" />
    14. <LinearLayout
    15. android:layout_width="0dp"
    16. android:layout_height="match_parent"
    17. android:layout_marginLeft="5dp"
    18. android:layout_weight="3"
    19. android:orientation="vertical">
    20. <!--显示行星名称的文本视图-->
    21. <TextView
    22. android:id="@+id/tv_name"
    23. android:layout_width="match_parent"
    24. android:layout_height="0dp"
    25. android:layout_weight="1"
    26. android:gravity="start|center"
    27. android:text="地球"
    28. android:textColor="#000000"
    29. android:textSize="20sp" />
    30. <TextView
    31. android:id="@+id/tv_desc"
    32. android:layout_width="match_parent"
    33. android:layout_height="0dp"
    34. android:layout_weight="2"
    35. android:gravity="start|center"
    36. android:text="地球是距太阳第三颗,也是太阳系第五大行星,地球是太阳系中密度最大的行星。"
    37. android:textColor="#000000"
    38. android:textSize="10sp" />
    39. </LinearLayout>
    40. </LinearLayout>

    3.主布局资源文件

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. xmlns:tools="http://schemas.android.com/tools"
    4. android:layout_width="match_parent"
    5. android:layout_height="match_parent"
    6. android:orientation="vertical"
    7. tools:context=".MainActivity">
    8. <TextView
    9. android:layout_width="match_parent"
    10. android:layout_height="wrap_content"
    11. android:text="基本适配器"
    12. android:textSize="17sp" />
    13. <Spinner
    14. android:id="@+id/sp_planet"
    15. android:layout_width="match_parent"
    16. android:layout_height="wrap_content"
    17. android:spinnerMode="dialog"/>
    18. </LinearLayout>

    4.适配器类 

     BaseAdapter是一个抽象类,无法直接使用所以需要创建一个适配器类

    1. import android.content.Context;
    2. import android.view.LayoutInflater;
    3. import android.view.View;
    4. import android.view.ViewGroup;
    5. import android.widget.BaseAdapter;
    6. import android.widget.ImageView;
    7. import android.widget.TextView;
    8. import java.util.List;
    9. //适配器
    10. public class PlanetBaseAdapter extends BaseAdapter {
    11. //定义成员属性
    12. private Context mContext;
    13. private List<Planet> mPlaneList; //行星信息的集合
    14. public PlanetBaseAdapter(Context mContext, List<Planet> mPlaneList) {
    15. this.mContext = mContext;
    16. this.mPlaneList = mPlaneList;
    17. }
    18. @Override
    19. public int getCount() { //告诉适配器集合中有多少个元素
    20. return mPlaneList.size();
    21. }
    22. @Override
    23. public Object getItem(int position) { //条目与数据对应的索引
    24. return mPlaneList.get(position);
    25. }
    26. @Override
    27. public long getItemId(int position) { //Planet对应的id,但是这里没有,所以直接返回position(不会重复)
    28. return position;
    29. }
    30. @Override
    31. public View getView(int position, View convertView, ViewGroup parent) { // 每个条目怎么来的
    32. // 根据布局文件item_list.xml生成转换视图对象(导入条目布局)
    33. View view = LayoutInflater.from(mContext).inflate(R.layout.item_list, null);
    34. ImageView iv_icon = view.findViewById(R.id.iv_icon);
    35. TextView tv_name = view.findViewById(R.id.tv_name);
    36. TextView tv_desc = view.findViewById(R.id.tv_desc);
    37. // 给控件设置好数据(拿到数据)
    38. Planet planet = mPlaneList.get(position);
    39. iv_icon.setImageResource(planet.image);
    40. tv_name.setText(planet.name);
    41. tv_desc.setText(planet.desc);
    42. return view;
    43. }
    44. }

    5.实体类

    这里主要是存放行星的图片、名称以及介绍的信息,方便后续导入

    这里关于各个行星的介绍网上复制即可,但是注意最好别太多

    1. import java.util.ArrayList;
    2. import java.util.List;
    3. //实体类
    4. public class Planet {
    5. public int image; // 行星图标
    6. public String name; //行星名称
    7. public String desc; //行星描述
    8. public Planet(int image, String name, String desc) {
    9. this.image = image;
    10. this.name = name;
    11. this.desc = desc;
    12. }
    13. //定义下拉列表需要显示的行星图标数组
    14. private static int[] iconArray = {R.mipmap.shuixing, R.mipmap.jinxing, R.mipmap.diqiu, R.mipmap.huoxing,
    15. R.mipmap.muxing, R.mipmap.tuxing, R.mipmap.tianwangxing, R.mipmap.haiwangxing};
    16. //定义下拉列表需要显示的行星名称数组
    17. private static final String[] nameArray = {"水星", "金星", "地球", "火星", "木星", "土星", "天王星", "海王星"};
    18. //定义下拉列表需要显示的行星描述数组
    19. private static final String[] descArray = {
    20. "水星最接近太阳 [3] ,是太阳系中体积和质量最小的行星。常和太阳同时出没,中国古代称之它为“辰星”。水星在直径上小于两个卫星——木卫三和土卫六。",
    21. "太阳系中第六大行星,太阳系中温度最高的行星,中国古代称之为太白或太白金星。它有时是晨星,黎明出现于东方天空,被称为“启明”;有时又是昏星,黄昏后出现西方天空,被称为“长庚”。",
    22. "地球是距太阳第三颗,也是太阳系第五大行星,地球是太阳系中密度最大的行星。地球,当然不需要飞行器即可被观测,然而我们直到二十世纪才有了整个行星的地图。",
    23. "为距太阳第四远,也是太阳系中第七大行星,在中国古代又称荧火,因为火星呈红色,荧荧像火,亮度常有变化;而且在天空中运动,有时从西向东,有时又从东向西。",
    24. "木星是离太阳第五颗行星,中国古代称为岁星,因为他公转一周正好是12年,也就是一地支,木星是太阳系行星中质量最大的一颗。",
    25. "土星是离太阳第六远的行星,也是八大行星中第二大的行星,中国古代称为“镇星”,是太阳系密度最小的行星,可以浮在水上。",
    26. "天王星是太阳系中离太阳第七远行星,也是太阳系中最冷的行星,从直径来看,是太阳系中第三大行星。天王星的体积比海王星大,质量却比其小。",
    27. "海王星是环绕太阳运行的第八颗行星,也是太阳系中第四大天体(直径上)。海王星在直径上小于天王星,但质量比它大。"
    28. };
    29. public static List<Planet> getDefaultList() {
    30. List<Planet> planetList = new ArrayList<>();
    31. for (int i = 0; i < iconArray.length; i++) {
    32. planetList.add(new Planet(iconArray[i], nameArray[i], descArray[i]));//根据上面的三个数组构建的集合
    33. }
    34. return planetList;
    35. }
    36. }

    6.主界面

    1. import androidx.appcompat.app.AppCompatActivity;
    2. import android.os.Bundle;
    3. import android.view.View;
    4. import android.widget.AdapterView;
    5. import android.widget.Spinner;
    6. import android.widget.Toast;
    7. import java.util.List;
    8. public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
    9. private List<Planet> planetList;
    10. @Override
    11. protected void onCreate(Bundle savedInstanceState) {
    12. super.onCreate(savedInstanceState);
    13. setContentView(R.layout.activity_main);
    14. Spinner sp_planet = findViewById(R.id.sp_planet);
    15. //创建一个集合,获取默认的行星列表
    16. planetList = Planet.getDefaultList();
    17. /**
    18. * 指定Spinner的适配器
    19. * BaseAdapter是一个抽象类,无法直接使用(创建一个适配器类)
    20. * 构建一个行星适配器
    21. */
    22. PlanetBaseAdapter adapter = new PlanetBaseAdapter(this, planetList);
    23. sp_planet.setAdapter(adapter);
    24. sp_planet.setSelection(0);
    25. //选中的监听
    26. sp_planet.setOnItemSelectedListener(this);
    27. }
    28. @Override
    29. public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
    30. Toast.makeText(MainActivity.this, "你选择的是" + planetList.get(position).name, Toast.LENGTH_SHORT).show();
    31. }
    32. @Override
    33. public void onNothingSelected(AdapterView<?> adapterView) {
    34. }
    35. }

    条目与数据集合对应关系

     运行结果

    复用 convertView进行优化

     当列表的item从上方滚出屏幕视角之外时:

     优化后

    1. @Override
    2. public View getView(int position, View convertView, ViewGroup parent) { // 每个条目怎么来的
    3. ViewHolder holder;
    4. if (convertView == null) {
    5. // 根据布局文件item_list.xml生成转换视图对象(导入条目布局)
    6. convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list, null);
    7. holder = new ViewHolder();
    8. holder.iv_icon = convertView.findViewById(R.id.iv_icon);
    9. holder.tv_name = convertView.findViewById(R.id.tv_name);
    10. holder.tv_desc = convertView.findViewById(R.id.tv_desc);
    11. //将试图持有者保存到转换视图中(将holder绑定到convertView)
    12. convertView.setTag(holder);
    13. } else {
    14. //重用上面的控件(将上面的控件打包好直接调用)
    15. holder = (ViewHolder) convertView.getTag();
    16. }
    17. // 给控件设置好数据(拿到数据)
    18. Planet planet = mPlaneList.get(position);
    19. holder.iv_icon.setImageResource(planet.image);
    20. holder.tv_name.setText(planet.name);
    21. holder.tv_desc.setText(planet.desc);
    22. return convertView;
    23. }
    24. public final class ViewHolder {
    25. public ImageView iv_icon;
    26. public TextView tv_name;
    27. public TextView tv_desc;
    28. }

    这里无论是if还是else都会刷新数据

    这样个写法更企业化,也更节省空间。

  • 相关阅读:
    苹果ios系统IPA包企业签名手机下载应用可以有几种方式可以下载到手机?
    报错 documentation/kbuild: is a directory. stop(Windows 内置Linux子系统WSL编译Linux内核)
    android adb工具命令大全
    简单的图片二维码制作教程,你感兴趣吗?
    怎么在电脑桌面上添加待办事项?
    【论文阅读】 Cola-Dif; An explainable task-specific synthesis network
    【新书推荐】大模型赛道如何实现华丽的弯道超车 —— 《分布式统一大数据虚拟文件系统 Alluxio原理、技术与实践》
    前缀和与差分
    Python 编程基础 | 第二章-基础语法 | 2.1、缩进规则
    图解Intel SM4-AES-NI实现方案
  • 原文地址:https://blog.csdn.net/m0_64018773/article/details/125597347