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的讲解及实战(附源码 超详细必看)的主要内容,如果未能解决你的问题,请参考以下文章
参加CSDN编程竞赛,赢取《Android Studio开发实战:从零基础到App上线(第3版)》 实体书
参加CSDN编程竞赛,赢取《Android Studio开发实战:从零基础到App上线(第3版)》 实体书