引言

最近做的项目想仿做滴滴出行首页的悬浮框。

正文

效果参考滴滴出行;

工欲善其事,必先利其器!来......

Spinner详解

Spinner控件初始化时,会调用它的选择监听事件,默认选择第一个

一、Spinner比较好用的属性

Spinner的entries属性,就可以不用设置Spinner的Adapter,也可以填充数据

android:id="@+id/spCity"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:prompt="请选择城市"

android:entries="@array/cities"/>

Spinner的spinnerMode属性,Spinner显示为对话框或者是下拉框形式;

android:spinnerMode=["dialog"|"dropdown"]

prompt属性表示spinner列表上方的提示

spinnerMode="dialog"效果图,可以看到我们设置的提示符"请选择城市"

spinnerMode="dropdown"效果图

spinner_drop_item

二、设置spinner显示数据

使用Spinner布局文件使用的是系统默认的;使用创建ArrayAdapter两种方式,传入不同的数据源;

使用xml文件作为数据源

private void initView(){

city= (Spinner) findViewById(R.id.spCity);

SpinnerAdapter adapter=null;

adapter=ArrayAdapter.createFromResource(this,R.array.cities,android.R.layout.simple_spinner_dropdown_item);

city.setAdapter(adapter);

}

使用数组或者是List作为数据数据源

ArrayList list=new ArrayList();

SpinnerAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item,list);

三、spinner点击事件处理

city.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

@Override

public void onItemSelected(AdapterView> adapterView, View view, int i, long l) {

//这个方法里可以对点击事件进行处理

//i指的是点击的位置,通过i可以取到相应的数据源

}

@Override

public void onNothingSelected(AdapterView> adapterView) {

}

})

四、用代码来点击spinner

//选择Spinner里的第二个数据;

city.setSelection(1,true);

自定义Spinner

spinner就是下拉选择组件,系统自带的spinner使用起来非常方便,首先定义一个array(strings.xml),如下:

一年级

二年级

三年级

四年级

五年级

六年级

代码如下:

Spinner spinner = (Spinner) findViewById(R.id.spinner);

ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.grade, android.R.layout.simple_spinner_item);

spinner.setAdapter(adapter);

这样就实现了一个简单的spinner,显示如下:

但这并不是我想要的样式和效果,下面我们就一点点的来改造它。

(1)改变初始布局

spinner_layout.xml

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

xmlns:tools = "http://schemas.android.com/tools"

android:textColor = "#6d6d6d"

android:textSize = "15sp"

android:drawableRight = "@drawable/arrow"

android:drawablePadding = "5dp"

tools:text = "一年级" >

然后替换createFromResource中的即可,如下:

ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.grade, R.layout.spinner_layout);

这样还不够,因为还有一个带箭头的背景,将背景设置为透明即可,如下:

spinner.setBackgroundColor(0x0);

这样初始布局的展示就与spinner_layout一样了。

(2)改变列表item布局

经过上面的修改后,发现弹窗中列表item的布局也变成了spinner_layout,查看ArrayAdapter的构造函数可知有mResource和mDropDownResource两个变量,其中mResource就是初始布局,而mDropDownResource则是列表item的布局。

而createFromResource函数中,mResource和mDropDownResource赋值相同。但是ArrayAdapter还有一个setDropDownViewResource函数。

首先定义一个布局,如下:

spinner_layout.xml

android:layout_width="match_parent"

android:layout_height="wrap_content"

xmlns:tools="http://schemas.android.com/tools"

android:textColor="#6d6d6d"

android:textSize="15sp"

android:padding="8dp"

android:gravity="center_horizontal"

tools:text="一年级">

然后使用setDropDownViewResource函数即可,如下:

adapter.setDropDownViewResource(R.layout.spinner_item);

(3)改变弹窗背景及位置

在开始的动画中可以看到弹窗会遮挡住,我们想让弹窗处于下方,同时弹窗是圆角带箭头的。

这就需要使用spinner的两个函数setPopupBackgroundResource和setDropDownVerticalOffset。

但是注意这两个函数都需要在android4.1版本及以上,鉴于目前4.1以下版本已经很少了,所以我们只考虑4.1以上即可,代码如下:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {

spinner.setPopupBackgroundResource(R.drawable.bg_spinner);

spinner.setDropDownVerticalOffset(dip2px(20));

}

另外有一种方式同样也可以达到效果,在这里记录一下:

(但是很粗糙,没能满足紧靠正下方的需求)

解决方案:这是因为spinner有一个属性:android:overlapAnchor=”false” 。

这个属性默认是true。改为false即可。但是不知道为什么这个属性在代码提示中是没有的。所以记录下来。

(4)添加选中效果

经过上面的处理,我们已经得到想要的样式。但是还差一点,弹窗列表中缺少选中的样式。比如说我当前选择“二年级”,在弹窗中,对应的item字体应该加深加粗。在spinner源码中搜寻了一遍,发现并没有对应的函数和解决方法,那么我们自己动手吧。

其实spinner是使用adapter来加载列表的,而我们使用createFromResource函数会自动创建了adapter,我们可以自定义一个adapter,如下:

public class SpinnerAdapter extends ArrayAdapter {

private int selectedPostion;

public void setSelectedPostion(int selectedPostion) {

this.selectedPostion = selectedPostion;

}

public SpinnerAdapter(@NonNull Context context, int resource, @NonNull T[] objects) {

super(context, resource, objects);

}

@Override

public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

View view = super.getDropDownView(position, convertView, parent);

TextView textView = (TextView) view;

if (selectedPostion == position) {

textView.setTextColor(0xff373741);

textView.getPaint().setFakeBoldText(true);

} else {

textView.setTextColor(0xff6d6d6d);

textView.getPaint().setFakeBoldText(false);

}

return view;

}

public static @NonNull

SpinnerAdapter createFromResource(@NonNull Context context, @ArrayRes int textArrayResId, @LayoutRes int textViewResId) {

final CharSequence[] strings = context.getResources().getTextArray(textArrayResId);

return new SpinnerAdapter<>(context, textViewResId, strings);

}

}

注意ArrayAdapter中的getDropDownView函数是获取弹窗item使用的view的,而不是getView函数。

同时我们要重新写一个createFromResource函数。

将之前使用的adapter替换成自定义这个,同时为spinner设置监听即可,更改后的完整代码如下:

Spinner spinner = (Spinner) findViewById(R.id.spinner);

adapter = SpinnerAdapter.createFromResource(this,R.array.grade,R.layout.spinner_layout);

adapter.setDropDownViewResource(R.layout.spinner_item);

spinner.setBackgroundColor(0x0);

if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.JELLY_BEAN){

spinner.setPopupBackgroundResource(R.drawable.bg_spinner);

spinner.setDropDownVerticalOffset(dip2px(20));

}

spinner.setAdapter(adapter);

spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){

@Override

public void onItemSelected (AdapterView < ? > parent, View view,int position,long id){

adapter.setSelectedPostion(position);

}

@Override

public void onNothingSelected (AdapterView < ? > parent){

}

});

android spinner布局,重拾Android之路之Spinner相关推荐

  1. android子view获取父布局,Android获取布局父ID(Android get layout parent id)

    Android获取布局父ID(Android get layout parent id) 我想知道View和ViewParent有什么区别? 我想获取ImageView父级的Id,但我不能这样做: m ...

  2. 重拾Android之路(三)手机适配

    随着android智能手机的发展和普及,各种各样的大小和尺寸的android智能机不断的退出,通过各种各样的设备机型,我们能够让自己的APP接触到广大的用户.为了能在各种android平台上使用,我们 ...

  3. 重拾Android之路(五)RxJava和RxAndroid

    现在RxJava和RxAndroid越来越火爆,自己在业余时间也学习了一下,感觉确实很好用,之前 为了完成页面刷新,数据请求,组件信息传递的时候,要使用handler,真的是逻辑思路很强,稍微不注意, ...

  4. Android延伸布局到状态栏,Android 状态栏透明

    前言:最近项目大量用到状态栏透明,网上也出现很多库可以直接拿来用,个人认为没有必要那么重引用到一个库(有木有同学和我有一样的想法),所以研究了一番,在此做个记录加强记忆也便后期查阅,如果无意中有幸能帮 ...

  5. android 3d布局轮播,android 图片/视频混合轮播控件banner

    android 图片/视频混合轮播控件banner 在youth5201314的图片轮播控件做的修改 原作者github地址:https://github.com/youth5201314/banne ...

  6. android 微信布局 字体,【Android】底部Tab+ViewPager(仿微信界面)

    感谢 github的作者:wuyexiong 效果图(图片和文字都有渐变效果) 实现 主要用到自定义一个LinearLayout和ImageView 1.BottomIconView继承自ImageV ...

  7. android五大布局的作用,Android五大布局与实际应用详解

    Android总体有五大布局: 线性布局(LiearLayout): 屏幕垂直或水平方向布局. 帧布局(FrameLayout):控件从屏幕左上角开始布局. 相对布局(RelativeLayout): ...

  8. android layout布局 有哪些,Android 常用布局 介绍与使用

    读前思考 学习一门技术或者看一篇文章最好的方式就是带着问题去学习,这样才能在过程中有茅塞顿开.灯火阑珊的感觉,记忆也会更深刻. 有哪些常用的布局? 每一种布局有何特点与不同? 布局上如何优化? 1. ...

  9. android线性布局控制间隙,Android线性布局(Linear Layout)

    Android 中常用布局 [1] 线性布局 [2] 相对布局 [3] 帧布局  -- FrameLayout [4] 表格布局 -- !!!一个 tabrow 就代表一行 [5] 绝对布局   -- ...

最新文章

  1. 【Leetcode | easy】有效的括号
  2. 获取一个目录下文件扩展名为txt或htm或html的文件的几种方法
  3. 从零实现一个简易jQuery框架之一—jQuery框架概述
  4. linux date 小写h,linux date 命令详解[转载]
  5. 沉默已久的华为突然宣告杀入无人驾驶领域,司机将全部失业!
  6. 计算机组成要素一:布尔逻辑:门结构
  7. 网络工程属于计算机哪一类,网络工程专业属于什么门类
  8. pdftk的使用介绍
  9. 监控 MySQL的多种方法
  10. react router 4
  11. 跟着锅子一步步学习32位汇编(3)---MOV和XCHG指令
  12. 【C语言】实现简易计算器
  13. 多种嵌入式文件系统移植集合
  14. 叮咚:分享一款超棒的模组:IDO-SOM6Y08
  15. 电脑qq微信等软件可以上网,浏览器无法上网,电脑浏览器提示代理服务器连接失败
  16. 有哪些比较好的企业内部管理软件?公认的5个高效管理软件介绍
  17. docker 容器启动提示,ipv4不能被使用
  18. 可以一键去除水印的工具哪个好
  19. Property description must be an object
  20. 21-《电子入门趣谈》第四章_自己制作电路板-4.2洞洞板的介绍和经典案例使用教程

热门文章

  1. 计算机行业人员的护肤宝典(女生篇)
  2. window cmd 用法简介
  3. 什么是ATM,TDM
  4. 地面互动投影的投影距离多少比较好?
  5. android吹裙子的实现代码
  6. 微型计算机原理的9h是什么意思,钢化玻璃膜中9H是什么意思?
  7. Ubuntu:u盘作系统启动盘
  8. Golang 基础知识(十一.struct结构体)
  9. Windows系统中睡眠、休眠、待机、混合睡眠的解释说明
  10. html/css/Bootstrap/Font Awesome