Android Studio App开发中高级控件下拉列表Spinner的讲解及实战(附源码 超详细必看)

Posted showswoller

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Studio App开发中高级控件下拉列表Spinner的讲解及实战(附源码 超详细必看)相关的知识,希望对你有一定的参考价值。

运行有问题或需要源码请点赞关注收藏后评论区留言~~~

一、下拉框Spinner

Spinner是下拉框控件,它用于从一串列表中选择某项,其功能类似于单选按钮的组合,下拉列表的展示方式有两种,一种是在当前下拉框的正下方弹出列表框,另一种是在页面中部弹出列表对话框。 此外 在Java代码中 Spinner还可以调用下列四个方法

setPrompt 设置标题文字

setAdapter 设置列表项的数据适配器

setSelection 设置当前选中哪项

setOnItemSelectedListener 设置下拉列表的选择监听器

效果如下 点开后可实现选择功能  并且点击某项后,对话框消失 同时下拉框文字也变为刚选中的行星名称

 

 

 java类代码

package com.example.chapter08;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;

public class SpinnerDropdownActivity extends AppCompatActivity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_spinner_dropdown);
        initSpinnerForDropdown(); // 初始化下拉模式的列表框
    

    // 初始化下拉模式的列表框
    private void initSpinnerForDropdown() 
        // 声明一个下拉列表的数组适配器
        ArrayAdapter<String> starAdapter = new ArrayAdapter<String>(this,
                R.layout.item_select, starArray);
        // 从布局文件中获取名叫sp_dropdown的下拉框
        Spinner sp_dropdown = findViewById(R.id.sp_dropdown);
        // 设置下拉框的标题。对话框模式才显示标题,下拉模式不显示标题
        sp_dropdown.setPrompt("请选择行星");
        sp_dropdown.setAdapter(starAdapter); // 设置下拉框的数组适配器
        sp_dropdown.setSelection(0); // 设置下拉框默认显示第一项
        // 给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法
        sp_dropdown.setOnItemSelectedListener(new MySelectedListener());
    

    // 定义下拉列表需要显示的文本数组
    private String[] starArray = "水星", "金星", "地球", "火星", "木星", "土星";
    // 定义一个选择监听器,它实现了接口OnItemSelectedListener
    class MySelectedListener implements OnItemSelectedListener 
        // 选择事件的处理方法,其中arg2代表选择项的序号
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) 
            Toast.makeText(SpinnerDropdownActivity.this, "您选择的是" + starArray[arg2],
                    Toast.LENGTH_LONG).show();
        

        // 未选择时的处理方法,通常无需关注
        public void onNothingSelected(AdapterView<?> arg0) 
    


XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="下拉模式的列表框"
        android:textColor="@color/black"
        android:textSize="17sp" />

    <Spinner
        android:id="@+id/sp_dropdown"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:spinnerMode="dropdown" />"

</LinearLayout>

二、数组适配器ArrayAdapter

ArrayAdapter主要用于每行列表只展示的文本的情况

三、简单适配器SimpleAdapter

ArrayAdapter只能显示文本列表,显然不够美观,有时还想给列表加上图标。SimpleAdapter的实现过程略微复杂,它能够同时显示文本和图形。下面是使用简单适配器的效果

可以看出有文字有对应的图标显示 比较美观

 

 

 Java类代码

package com.example.chapter08;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.Toast;

public class SpinnerIconActivity extends AppCompatActivity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_spinner_icon);
        initSpinnerForSimpleAdapter(); // 初始化下拉框,演示简单适配器
    

    // 初始化下拉框,演示简单适配器
    private void initSpinnerForSimpleAdapter() 
        // 声明一个映射对象的列表,用于保存行星的图标与名称配对信息
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        // iconArray是行星的图标数组,starArray是行星的名称数组
        for (int i = 0; i < iconArray.length; i++) 
            Map<String, Object> item = new HashMap<String, Object>();
            item.put("icon", iconArray[i]);
            item.put("name", starArray[i]);
            list.add(item); // 把行星图标与名称的配对映射添加到列表
        
        // 声明一个下拉列表的简单适配器,其中指定了图标与文本两组数据
        SimpleAdapter starAdapter = new SimpleAdapter(this, list,
                R.layout.item_simple, new String[]"icon", "name",
                new int[]R.id.iv_icon, R.id.tv_name);
        // 设置简单适配器的布局样式
        starAdapter.setDropDownViewResource(R.layout.item_simple);
        // 从布局文件中获取名叫sp_icon的下拉框
        Spinner sp_icon = findViewById(R.id.sp_icon);
        sp_icon.setPrompt("请选择行星"); // 设置下拉框的标题
        sp_icon.setAdapter(starAdapter); // 设置下拉框的简单适配器
        sp_icon.setSelection(0); // 设置下拉框默认显示第一项
        // 给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法
        sp_icon.setOnItemSelectedListener(new MySelectedListener());
    

    // 定义下拉列表需要显示的行星图标数组
    private int[] iconArray = R.drawable.shuixing, R.drawable.jinxing, R.drawable.diqiu,
            R.drawable.huoxing, R.drawable.muxing, R.drawable.tuxing;
    // 定义下拉列表需要显示的行星名称数组
    private String[] starArray = "水星", "金星", "地球", "火星", "木星", "土星";

    // 定义一个选择监听器,它实现了接口OnItemSelectedListener
    class MySelectedListener implements OnItemSelectedListener 
        // 选择事件的处理方法,其中arg2代表选择项的序号
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) 
            Toast.makeText(SpinnerIconActivity.this, "您选择的是" + starArray[arg2], Toast.LENGTH_LONG).show();
        

        // 未选择时的处理方法,通常无需关注
        public void onNothingSelected(AdapterView<?> arg0) 
    


XML文件代码

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="行星的简单适配器"
        android:textColor="@color/black"
        android:textSize="17sp" />

    <Spinner
        android:id="@+id/sp_icon"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:spinnerMode="dialog" />"

</LinearLayout>

创作不易 觉得有帮助请点赞关注收藏~~~

《移动项目实践》实验报告——Android高级控件

实验目的

1、熟悉App开发常用的一些高级控件及相关工具,主要包括日期时间控件的用法、列表类视图及其适配器的用法、翻页类视图及其适配器的用法、碎片及其适配器的用法等;
2、熟悉四大组件之一广播Broadcast的基本概念与常见用法;

实验内容

1、万年历:最简单的时间功能仅能查看当前的年月日、时分秒,若要拓展它的功能,则可由日历变月历,在年月日之外补充星期几,再添加节假日描述。进一步升级扩展,由月历变年历,分别按公历与农历纪年,便成了万年历;
万年历的界面效果

2、日程表(日程提醒采用手机震动的方式):日程表不但支持基本的日历信息展示,而且支持用户设定每天的日程安排,还支持日程提醒时间。

日程表的主页面

日程安排/详情页面

实验过程(实验的设计思路、关键源代码等)

源代码:https://gitee.com/shentuzhigang/mini-project/tree/master/android-calendar

package io.shentuzhigang.demo.calendar

import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Bundle
import android.util.TypedValue
import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.PagerTabStrip
import androidx.viewpager.widget.ViewPager
import io.shentuzhigang.demo.calendar.util.DateUtil
import io.shentuzhigang.demo.calendar.widget.MonthPicker
import io.shentuzhigang.demo.calendar.adapter.CalendarPagerAdapter
@SuppressLint("SetTextI18n")
class CalendarActivity : AppCompatActivity(), View.OnClickListener {
    private var ll_calendar_main // 声明一个万年历区域的线性布局对象
            : LinearLayout? = null
    private var ll_month_select // 声明一个月份选择区域的线性布局对象
            : LinearLayout? = null
    private var mp_month // 声明一个月份选择器对象
            : MonthPicker? = null
    private var vp_calendar // 声明一个翻页视图对象
            : ViewPager? = null
    private var tv_calendar // 声明一个选中年份的文本视图对象
            : TextView? = null
    private var isShowSelect = false // 是否显示月份选择器
    private var mSelectedYear = 2000 // 当前选中的年份
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_calendar)
        ll_calendar_main = findViewById(R.id.ll_calendar_main)
        ll_month_select = findViewById(R.id.ll_month_select)
        // 从布局文件中获取名叫mp_month的月份选择器
        mp_month = findViewById<MonthPicker>(R.id.mp_month)
        // 从布局文件中获取名叫pts_calendar的翻页标题栏
        findViewById<View>(R.id.btn_ok).setOnClickListener(this)
        val pts_calendar = findViewById<PagerTabStrip>(R.id.pts_calendar)
        pts_calendar.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17f)
        pts_calendar.setTextColor(Color.BLACK)
        // 从布局文件中获取名叫vp_calendar的翻页视图
        vp_calendar = findViewById(R.id.vp_calendar)
        tv_calendar = findViewById(R.id.tv_calendar)
        with(tv_calendar){
            this?.setOnClickListener(this@CalendarActivity)
        }
        // 万年历默认显示当前年月的月历
        showCalendar(DateUtil.nowYear, DateUtil.nowMonth)
    }

    // 显示指定年月的万年历
    private fun showCalendar(year: Int, month: Int) {
        // 如果指定年份不是上次选中的年份,则需重新构建该年份的年历
        if (year != mSelectedYear) {
            tv_calendar!!.text = year.toString() + "年"
            // 构建一个指定年份的年历翻页适配器
            val adapter = CalendarPagerAdapter(supportFragmentManager, year)
            // 给vp_calendar设置年历翻页适配器
            vp_calendar!!.adapter = adapter
            mSelectedYear = year
        }
        // 设置vp_calendar默认显示指定月份的月历页
        vp_calendar!!.currentItem = month - 1
    }

    override fun onClick(v: View) {
        if (v.id == R.id.tv_calendar) { // 点击了年份文本
            // 重新选择万年历的年月
            resetPage()
        } else if (v.id == R.id.btn_ok) { // 点击了确定按钮
            // 根据月份选择器上设定的年月,刷新万年历的显示界面
            showCalendar(mp_month!!.getYear(), mp_month!!.getMonth() + 1)
            resetPage()
        }
    }

    // 重置页面。在显示万年历主页面和显示月份选择器之间切换
    private fun resetPage() {
        isShowSelect = !isShowSelect
        ll_calendar_main!!.visibility = if (isShowSelect) View.GONE else View.VISIBLE
        ll_month_select!!.visibility = if (isShowSelect) View.VISIBLE else View.GONE
    }

    companion object {
        private const val TAG = "CalendarActivity"
    }
}
package io.shentuzhigang.demo.calendar

import android.content.*
import android.graphics.Color
import android.os.*
import android.util.Log
import android.util.TypedValue
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.viewpager.widget.PagerTabStrip
import androidx.viewpager.widget.ViewPager
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
import io.shentuzhigang.demo.calendar.adapter.SchedulePagerAdapter
import io.shentuzhigang.demo.calendar.calendar.SpecialCalendar
import io.shentuzhigang.demo.calendar.util.DateUtil

class ScheduleActivity : AppCompatActivity() {
    private var ll_schedule // 声明一个日程表区域的线性布局对象
            : LinearLayout? = null
    private var vp_schedule // 声明一个翻页视图对象
            : ViewPager? = null
    private var mSelectedWeek // 当前选中的星期
            = 0
    private var mFestivalResid = 0 // 节日图片的资源编号
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_schedule)
        // 从布局文件中获取名叫pts_schedule的翻页标题栏
        val pts_schedule = findViewById<PagerTabStrip>(R.id.pts_schedule)
        pts_schedule.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17f)
        pts_schedule.setTextColor(Color.BLACK)
        ll_schedule = findViewById(R.id.ll_schedule)
        // 从布局文件中获取名叫vp_schedule的翻页视图
        vp_schedule = findViewById(R.id.vp_schedule)
        val tv_schedule = findViewById<TextView>(R.id.tv_schedule)
        tv_schedule.setText(DateUtil.nowYearCN + " 日程安排")
        // 获取今天所处的星期在一年当中的序号
        mSelectedWeek = SpecialCalendar.todayWeek
        // 构建一个日程表的翻页适配器
        val adapter = SchedulePagerAdapter(supportFragmentManager)
        // 给vp_schedule设置日程表翻页适配器
        with(vp_schedule) {
            // 给vp_schedule设置日程表翻页适配器
            this?.setAdapter(adapter)
            // 设置vp_schedule默认显示当前周数的日程页
            this?.setCurrentItem(mSelectedWeek - 1)
            // 给vp_schedule添加页面变化监听器
            this?.addOnPageChangeListener(SheduleChangeListener())
        }
        // 延迟50毫秒再执行任务mFirst
        mHandler.postDelayed(mFirst, 50)
    }

    private val mHandler = Handler() // 声明一个处理器对象

    // 声明一个首次打开页面需要延迟执行的任务
    private val mFirst = Runnable {
        sendBroadcast(mSelectedWeek) // 发送广播,表示当前是在第几个星期
    }

    // 发送当前周数的广播
    private fun sendBroadcast(week: Int) {
        // 创建一个广播事件的意图
        val intent = Intent(ACTION_FRAGMENT_SELECTED)
        intent.putExtra(EXTRA_SELECTED_WEEK, week)
        // 通过本地的广播管理器来发送广播
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
    }

    public override fun onStart() {
        super.onStart()
        // 创建一个节日图片的广播接收器
        festivalReceiver = FestivalControlReceiver()
        // 注册广播接收器,注册之后才能正常接收广播
        LocalBroadcastManager.getInstance(this)
            .registerReceiver(festivalReceiver!!, IntentFilter(ACTION_SHOW_FESTIVAL))
    }

    public override fun onStop() {
        super.onStop()
        // 注销广播接收器,注销之后就不再接收广播
        LocalBroadcastManager.getInstance(this).unregisterReceiver(festivalReceiver!!)
    }

    override fun onResume() {
        super.onResume()
        if (mFestivalResid != 0) { // 在横屏和竖屏之间翻转时,不会重新onCreate,只会onResume
            ll_schedule!!.setBackgroundResource(mFestivalResid)
        }
    }

    // 声明一个节日图片的广播接收器
    private var festivalReceiver: FestivalControlReceiver? = null

    // 定义一个广播接收器,用于处理节日图片事件
    private inner class FestivalControlReceiver : BroadcastReceiver() {
        // 一旦接收到节日图片的广播,马上触发接收器的onReceive方法
        override fun onReceive(context: Context, intent: Intent) {
            if (intent != null) {
                // 从广播消息中取出节日图片的资源编号
                mFestivalResid = intent.getIntExtra(EXTRA_FESTIVAL_RES, 1)
                // 把页面背景设置为广播发来的节日图片
                ll_schedule!!.setBackgroundResource(mFestivalResid)
            }
        }
    }

    // 定义一个页面变化监听器,用于处理翻页视图的翻页事件
    inner class SheduleChangeListener : OnPageChangeListener {
        // 在翻页结束后触发
        override fun onPageSelected(position: Int) {
            Log.d(TAG, "onPageSelected position=$position, mSelectedWeek=$mSelectedWeek")
            mSelectedWeek = position + 1
            sendBroadcast(mSelectedWeek)
        }

        // 在翻页过程中触发
        override fun onPageScrolled(
            position: Int,
            positionOffset: Float,
            positionOffsetPixels: Int
        ) {
        }

        // 翻页状态改变时触发
        override fun onPageScrollStateChanged(arg0: Int) {}
    }

    companion object {
        private const val TAG = "ScheduleActivity"

        // 声明一个碎片选中事件的标识串
        var ACTION_FRAGMENT_SELECTED = "io.shentuzhigang.demo.calendar.ACTION_FRAGMENT_SELECTED"

        // 声明一个选择星期参数的标识串
        var EXTRA_SELECTED_WEEK = "selected_week"

        // 声明一个显示节日事件的标识串
        var ACTION_SHOW_FESTIVAL = "io.shentuzhigang.demo.calendar.ACTION_SHOW_FESTIVAL"

        // 声明一个节日图片参数的标识串
        var EXTRA_FESTIVAL_RES = "festival_res"
    }
}

实验结果(实验最终作品截图说明)


实验心得

1、熟悉App开发常用的一些高级控件及相关工具,主要包括日期时间控件的用法、列表类视图及其适配器的用法、翻页类视图及其适配器的用法、碎片及其适配器的用法等;
2、熟悉四大组件之一广播Broadcast的基本概念与常见用法;

参考项目

参考文章

以上是关于Android Studio App开发中高级控件下拉列表Spinner的讲解及实战(附源码 超详细必看)的主要内容,如果未能解决你的问题,请参考以下文章

Android studio实现网上订餐app

RecyclerView高级控件-附实例android专题

参加CSDN编程竞赛,赢取《Android Studio开发实战:从零基础到App上线(第3版)》 实体书

参加CSDN编程竞赛,赢取《Android Studio开发实战:从零基础到App上线(第3版)》 实体书

参加CSDN编程竞赛,赢取《Android Studio开发实战:从零基础到App上线(第3版)》 实体书

《移动项目实践》实验报告——Android高级控件