版权声明:本文为HaiyuKing原创文章,转载请注明出处!

前言

对下拉菜单的文本区域和列表区域进行了封装。包括两种展现方式:popwindow(单选)、dialog(单选+多选)

因为该封装需要在Eclipse开发环境中使用,所以列表控件使用的是ListView。

效果图

代码分析

SpinnerViewPop:自定义RelativeLayout子类【popwindow(单选)、dialog(单选)

SpinnerViewMultiDialog:自定义RelativeLayout子类【dialog(多选)

PopWindowUtil:PopWindow的封装【popwindow(单选)

DialogUtil:dialog的封装【dialog(单选+多选)

MySpinnerPopListArrayAdapter:列表适配器【popwindow(单选)、dialog(单选)

MySpinnerPopMultListArrayAdapter:列表适配器【dialog(多选)

常用的方法:

  • setEditable —— 设置下拉菜单区域是否可点击(可编辑)【参考Demo中的第1个】
  • setHint —— 设置下拉菜单区域的提示语【参考Demo中的多选对话框】
  • setSpinnerType —— 用于区分popwindow(单选)、dialog(单选)【参考Demo中的第4个】
  • setHandedPopup ——设置下拉菜单区域是否执行点击事件的状态值,搭配OnSpinnerClickListener使用,实现点击下拉菜单区域触发事件,一般用来隐藏软键盘,或者网络请求,最后手动弹出下拉菜单【参考Demo中的第2个】
  • setData —— 设置数据源集合【初始化数据的时候调用】
  • setSelectedIndexAndText —— 设置单选情况下的指定选中列表项【初始化数据的时候调用,设置默认值】
  • setOnSpinnerClickListener —— 下拉菜单区域的点击事件监听器{一般用来隐藏软键盘,或者网络请求,最后手动弹出下拉菜单}
  • setOnSpinnerItemClickListener —— 单选情况下的列表项的点击事件监听器
  • setOnSpinnerConfirmClickListener —— 多选情况下的确定操作的点击事件监听器

使用步骤

一、项目组织结构图

注意事项:

1、导入类文件后需要change包名以及重新import R文件路径

2、 Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、导入步骤

将drawable、drawable-xxhdpi目录下的文件复制到项目中

将布局文件复制到项目中

在colors.xml文件中添加以下代码

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color> <!-- *********************popwindow样式下拉菜单************************* -->
<!-- popwindow样式下拉菜单文本选中状态的颜色 -->
<color name="spinnerpop_selected_text_color">#0365C5</color>
<!-- popwindow样式下拉菜单文本默认状态的颜色 -->
<color name="spinnerpop_normal_text_color">#191919</color>
<!-- popwindow样式下拉菜单可编辑的背景颜色 -->
<color name="spinnerpop_canedit_bg_color">#ffffff</color>
<!-- popwindow样式下拉菜单不可编辑的背景颜色 -->
<color name="spinnerpop_notedit_bg_color">#C5C5C5</color> </resources>

在dimens.xml中添加以下代码

<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen> <!-- *********************popwindow样式下拉菜单************************* -->
<!-- 下拉菜单文本大小 -->
<dimen name="spinnerpop_text_size">18sp</dimen>
<!-- 下拉菜单列表项的文本大小 -->
<dimen name="spinnerpop_listitem_text_size">18sp</dimen>
<!-- 下拉菜单列表项的内边距 -->
<dimen name="spinnerpop_listitem_padding">10dp</dimen>
<!-- 下拉菜单高度 -->
<dimen name="spinnerpop_height">42dp</dimen>
<!-- 下拉菜单按钮的外边距 -->
<dimen name="spinnerpop_confirm_margin">15dp</dimen> </resources>

在styles.xml文件中添加以下代码

<resources>

    <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style> <!-- *********************popwindow样式下拉菜单************************* -->
<!-- 自定义loading dialog:列表对话框 -->
<style name="dialogutil_list_style" parent="@android:style/Theme.Dialog">
<!-- 边框 -->
<item name="android:windowFrame">@null</item>
<!-- 是否显示title -->
<item name="android:windowNoTitle">true</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 设置dialog的背景:#00000000透明色 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 半透明 -->
<item name="android:windowIsTranslucent">false</item>
<!-- 背景变灰:整个屏幕变灰,配合setCanceledOnTouchOutside(false) -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 边距 -->
<item name="android:paddingLeft">20dp</item>
<item name="android:paddingRight">20dp</item>
</style> </resources>

将spinner包中的文件复制到项目中

将bean包中的SpinnearBean复制到项目中。

至此,SpinnerViewPop集成到项目中了。

三、使用方法

在Activity布局文件中引用SpinnerViewPop布局类【注意:需要重新引用SpinnerViewPop类的完整路径】

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.why.project.spinnerviewpopdemo.MainActivity"> <!-- 列表弹出框(禁用的) -->
<com.why.project.spinnerviewpopdemo.views.spinner.SpinnerViewPop
android:id="@+id/spinnerView_pop0"
android:layout_width="match_parent"
android:layout_height="@dimen/spinnerpop_height"
android:background="@drawable/spinnerview_pop_box_bg_drawable"
android:layout_margin="10dp"
/> <!-- 列表弹出框(popwindow样式) -->
<com.why.project.spinnerviewpopdemo.views.spinner.SpinnerViewPop
android:id="@+id/spinnerView_pop1"
android:layout_width="match_parent"
android:layout_height="@dimen/spinnerpop_height"
android:background="@drawable/spinnerview_pop_box_bg_drawable"
android:layout_margin="10dp"
/> <!-- 列表弹出框(popwindow样式含背景色) -->
<com.why.project.spinnerviewpopdemo.views.spinner.SpinnerViewPop
android:id="@+id/spinnerView_pop2"
android:layout_width="match_parent"
android:layout_height="@dimen/spinnerpop_height"
android:background="@drawable/spinnerview_pop_box_bg_drawable"
android:layout_margin="10dp"
/> <!-- 列表弹出框(对话框样式【单选】) -->
<com.why.project.spinnerviewpopdemo.views.spinner.SpinnerViewPop
android:id="@+id/spinnerView_pop3"
android:layout_width="match_parent"
android:layout_height="@dimen/spinnerpop_height"
android:background="@drawable/spinnerview_pop_box_bg_drawable"
android:layout_margin="10dp"
/> <!-- 列表弹出框(对话框样式【多选】) -->
<com.why.project.spinnerviewpopdemo.views.spinner.SpinnerViewMultiDialog
android:id="@+id/spinnerView_pop4"
android:layout_width="match_parent"
android:layout_height="@dimen/spinnerpop_height"
android:background="@drawable/spinnerview_pop_box_bg_drawable"
android:layout_margin="10dp"
/> <TextView
android:id="@+id/tv_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="显示下拉菜单选中的内容"/> </LinearLayout>

在Activity中使用如下:

package com.why.project.spinnerviewpopdemo;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast; import com.why.project.spinnerviewpopdemo.bean.SpinnearBean;
import com.why.project.spinnerviewpopdemo.views.spinner.listener.OnSpinnerClickListener;
import com.why.project.spinnerviewpopdemo.views.spinner.listener.OnSpinnerConfirmClickListener;
import com.why.project.spinnerviewpopdemo.views.spinner.listener.OnSpinnerItemClickListener;
import com.why.project.spinnerviewpopdemo.views.spinner.SpinnerViewMultiDialog;
import com.why.project.spinnerviewpopdemo.views.spinner.SpinnerViewPop; import org.json.JSONArray;
import org.json.JSONObject; import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList; import static com.why.project.spinnerviewpopdemo.R.id.spinnerView_pop0;
import static com.why.project.spinnerviewpopdemo.R.id.spinnerView_pop1;
import static com.why.project.spinnerviewpopdemo.R.id.spinnerView_pop2;
import static com.why.project.spinnerviewpopdemo.R.id.spinnerView_pop3; public class MainActivity extends AppCompatActivity { private SpinnerViewPop spinnerView_notEditable; private SpinnerViewPop spinnerView_pop;
/**下拉菜单列表集合*/
private ArrayList<SpinnearBean> mSpinner1List; private SpinnerViewPop spinnerView_pop_bgcolor;
/**下拉菜单列表集合*/
private ArrayList<SpinnearBean> mSpinner2List; private SpinnerViewPop spinnerView_radioDialog;
/**下拉菜单列表集合*/
private ArrayList<SpinnearBean> mSpinner3List; private SpinnerViewMultiDialog spinnerView_multDialog;
/**下拉菜单列表集合*/
private ArrayList<SpinnearBean> mSpinner4List; private TextView tv_show; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initViews();
initDatas();
initEvents();
} private void initViews() { spinnerView_notEditable = (SpinnerViewPop) findViewById(spinnerView_pop0);
spinnerView_notEditable.setEditable(false);//禁用下拉菜单区域 spinnerView_pop = (SpinnerViewPop) findViewById(spinnerView_pop1);
spinnerView_pop.setHandedPopup(true);//实现点击下拉菜单区域触发事件,一般用来隐藏软键盘,或者网络请求,最后手动弹出下拉菜单 spinnerView_pop_bgcolor = (SpinnerViewPop) findViewById(spinnerView_pop2); spinnerView_radioDialog = (SpinnerViewPop) findViewById(spinnerView_pop3);
spinnerView_radioDialog.setSpinnerType(SpinnerViewPop.TYPE_DIALOG);//设置对话框样式,默认为popwindow样式 spinnerView_multDialog = (SpinnerViewMultiDialog) findViewById(R.id.spinnerView_pop4); tv_show = (TextView) findViewById(R.id.tv_show); } private void initDatas() {
/*==============================普通下拉菜单列表项=========================================*/
mSpinner1List = new ArrayList<SpinnearBean>();
//模拟获取数据集合
try{
mSpinner1List = parseJsonArray("spinners.txt");
}catch (Exception e) {
e.printStackTrace();
}
//设置下拉菜单显示的列表项文本
if (mSpinner1List != null && mSpinner1List.size() > 0){
spinnerView_pop.setData(mSpinner1List);//设置下拉菜单列表集合源
spinnerView_pop.setSelectedIndexAndText(0);//更改下拉菜单选中的列表项下标值
}
/*==============================下拉菜单列表项带有背景颜色=========================================*/
mSpinner2List = new ArrayList<SpinnearBean>();
//模拟获取数据集合
try{
mSpinner2List = parseJsonArray("spinners2.txt");
}catch (Exception e) {
e.printStackTrace();
}
//设置下拉菜单显示的列表项文本
if (mSpinner2List != null && mSpinner2List.size() > 0){
spinnerView_pop_bgcolor.setData(mSpinner2List);//设置下拉菜单列表集合源
spinnerView_pop_bgcolor.setSelectedIndexAndText(0);//更改下拉菜单选中的列表项下标值
} /*==============================下拉菜单列表项单选对话框=========================================*/
mSpinner3List = new ArrayList<SpinnearBean>();
//模拟获取数据集合
try{
mSpinner3List = parseJsonArray("spinners3.txt");
}catch (Exception e) {
e.printStackTrace();
}
//设置下拉菜单显示的列表项文本
if (mSpinner3List != null && mSpinner3List.size() > 0){
spinnerView_radioDialog.setData(mSpinner3List);//设置下拉菜单列表集合源
spinnerView_radioDialog.setSelectedIndexAndText(0);//更改下拉菜单选中的列表项下标值
} /*==============================下拉菜单列表项多选对话框=========================================*/
mSpinner4List = new ArrayList<SpinnearBean>();
//模拟获取数据集合
try{
mSpinner4List = parseJsonArray("spinners4.txt");
}catch (Exception e) {
e.printStackTrace();
}
//设置下拉菜单显示的列表项文本
if (mSpinner4List != null && mSpinner4List.size() > 0){
spinnerView_multDialog.setData(mSpinner4List);//设置下拉菜单列表集合源
spinnerView_multDialog.setHint("选择你的爱好");
} } private void initEvents() { //下拉菜单区域的点击事件监听
spinnerView_pop.setOnSpinnerClickListener(new OnSpinnerClickListener() {
@Override
public void OnFinished() {
//KeyboardUtil.hideKeyboard(MainActivity.this);//隐藏软键盘
spinnerView_pop.PopupListDialog();
}
});
//下拉菜单列表的列表项的点击事件监听
spinnerView_pop.setOnSpinnerItemClickListener(new OnSpinnerItemClickListener() {
@Override
public void OnFinished(int position) {
tv_show.setText(mSpinner1List.get(position).getParaName() + ":" + mSpinner1List.get(position).getParaValue());
StringBuffer str = new StringBuffer();
for(int i=0;i<mSpinner1List.size();i++){
str.append(mSpinner1List.get(i).getParaName() + ":" + mSpinner1List.get(i).isSelectedState() + "\n");
}
tv_show.setText(tv_show.getText() + "\n=====================\n" + str);
}
}); //下拉菜单列表的列表项的点击事件监听
spinnerView_pop_bgcolor.setOnSpinnerItemClickListener(new OnSpinnerItemClickListener() {
@Override
public void OnFinished(int position) {
tv_show.setText(mSpinner2List.get(position).getParaName() + ":" + mSpinner2List.get(position).getParaValue());
StringBuffer str = new StringBuffer();
for(int i=0;i<mSpinner2List.size();i++){
str.append(mSpinner2List.get(i).getParaName() + ":" + mSpinner2List.get(i).isSelectedState() + "\n");
}
tv_show.setText(tv_show.getText() + "\n=====================\n" + str);
}
}); //下拉菜单列表的列表项的点击事件监听
spinnerView_radioDialog.setOnSpinnerItemClickListener(new OnSpinnerItemClickListener() {
@Override
public void OnFinished(int position) {
tv_show.setText(mSpinner3List.get(position).getParaName() + ":" + mSpinner3List.get(position).getParaValue());
StringBuffer str = new StringBuffer();
for(int i=0;i<mSpinner3List.size();i++){
str.append(mSpinner3List.get(i).getParaName() + ":" + mSpinner3List.get(i).isSelectedState() + "\n");
}
tv_show.setText(tv_show.getText() + "\n=====================\n" + str);
}
}); //下拉菜单列表的列表项的点击事件监听
spinnerView_multDialog.setOnSpinnerConfirmClickListener(new OnSpinnerConfirmClickListener() {
@Override
public void OnConfirmed(ArrayList<Boolean> selecteIndexList) {
StringBuffer str1 = new StringBuffer();
for(int i=0;i<selecteIndexList.size();i++){
if(selecteIndexList.get(i)){//如果为true,则执行下面的代码
str1.append(mSpinner4List.get(i).getParaName() + ":" + mSpinner4List.get(i).getParaValue() + "\n");
}
}
tv_show.setText(str1); StringBuffer str = new StringBuffer();
for(int i=0;i<mSpinner4List.size();i++){
str.append(mSpinner4List.get(i).getParaName() + ":" + mSpinner4List.get(i).isSelectedState() + "\n");
}
tv_show.setText(tv_show.getText() + "=====================\n" + str);
}
});
} /*===========读取assets目录下的js字符串文件(js数组和js对象),然后生成List集合===========*/
public static final String LISTROOTNODE = "spinnerList";
public static final String KEY_LISTITEM_NAME = "paraName";
public static final String KEY_LISTITEM_VALUE = "paraValue";
public static final String KEY_LISTITEM_CHECKCOLOR = "checkColor"; /**
* 解析JSON文件的简单数组
*/
private ArrayList<SpinnearBean> parseJsonArray(String fileName) throws Exception{ ArrayList<SpinnearBean> itemsList = new ArrayList<SpinnearBean>(); String jsonStr = getStringFromAssert(MainActivity.this, fileName);
if(jsonStr.equals("")){
return null;
}
JSONObject allData = new JSONObject(jsonStr); //全部内容变为一个项
JSONArray jsonArr = allData.getJSONArray(LISTROOTNODE); //取出数组
for(int x = 0;x<jsonArr.length();x++){
SpinnearBean model = new SpinnearBean();
JSONObject jsonobj = jsonArr.getJSONObject(x);
model.setParaName(jsonobj.getString(KEY_LISTITEM_NAME));
model.setParaValue(jsonobj.getString(KEY_LISTITEM_VALUE));
if(jsonobj.has(KEY_LISTITEM_CHECKCOLOR)){
model.setCheckColor(jsonobj.getString(KEY_LISTITEM_CHECKCOLOR));
}
model.setSelectedState(false);
itemsList.add(model);
model = null;
}
return itemsList;
} /**
* 访问assets目录下的资源文件,获取文件中的字符串
* @param filePath - 文件的相对路径,例如:"listdata.txt"或者"/www/listdata.txt"
* @return 内容字符串
* */
public String getStringFromAssert(Context mContext, String filePath) { String content = ""; // 结果字符串
try {
InputStream is = mContext.getResources().getAssets().open(filePath);// 打开文件
int ch = 0;
ByteArrayOutputStream out = new ByteArrayOutputStream(); // 实现了一个输出流
while ((ch = is.read()) != -1) {
out.write(ch); // 将指定的字节写入此 byte 数组输出流
}
byte[] buff = out.toByteArray();// 以 byte 数组的形式返回此输出流的当前内容
out.close(); // 关闭流
is.close(); // 关闭流
content = new String(buff, "UTF-8"); // 设置字符串编码
} catch (Exception e) {
Toast.makeText(mContext, "对不起,没有找到指定文件!", Toast.LENGTH_SHORT)
.show();
}
return content;
}
}

混淆配置

参考资料

暂时空缺

项目demo下载地址

https://github.com/haiyuKing/SpinnerViewPopDemo

SpinnerViewPop【PopWindow样式(单选)、Dialog样式(单选+多选)的下拉菜单】的更多相关文章

  1. html-4, form 表单 输入、传文件、单选、多选、下拉菜单、文本描述、重置、submit、按钮限制输入

    <!-- form HTTP协议 action:提交的服务器网址 method:get(默认)| post(应用:登录注册.上传文件) 页面中的a img link 默认是get请求 input ...

  2. Bootstrap之样式风格与下拉菜单

    背景颜色 bg-primary 字体颜色 text-primary 文字居中 text-center 按钮 btn btn-primary btn-default默认 btn-link链接 按钮大小 ...

  3. [k]自定义样式下拉菜单

    自定义样式下拉菜单-1 <!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> & ...

  4. 更改SharePoint 2010 顶部导航为下拉菜单样式

      更改SharePoint 2010 顶部导航为下拉菜单样式 最后的效果图: 假如一个网站集顶级站点下面有子网站:sub site1,该子站点下面又有两个子站点:sub site1_1,sub si ...

  5. 黄聪:TinyMCE 4 增强 添加样式、按钮、字体、下拉菜单和弹出式窗口

    我最喜欢 WordPress 3.9 的更新是使用了 TinyMCE 4.0 编辑器.新的 TinyMCE 看起来看起来更整洁(真正匹配WP仪表板),它有一些非常不错的附加功能.我的很多老主题和插件必 ...

  6. JavaScript---网络编程(11)--DHTML技术演示(4)-单选框/下拉菜单/添加文件

    本节讲述单选框/下拉菜单/添加文件,综合css,html和JavaScript. 单选框: 实现的功能是:(类似平时的性格测试) 先隐藏一部分页面,然后通过点击单选框来显示. 再通过选项的选择-(每个 ...

  7. JQuery对单选框,复选框,下拉菜单的操作

    JSP <%@ page language="java" import="java.util.*" pageEncoding="utf-8&qu ...

  8. flask中单选、多选、下拉框的获取

    1.单选: source = request.form.get('source') 2.多选:   joy = request.form.getlist('joy')    或者   joy = re ...

  9. [deviceone开发]-多种样式下拉菜单demo

    一.简介 该demo主要展示了3种下拉菜单. 一.仿QQ弹出菜单 主要实现原理是通过add一个ui,然后通过点击事件控制其visible属性来显示或者隐藏. 二.组合下拉菜单 主要用到的控件是do_A ...

随机推荐

  1. 运用BT在centos下搭建一个博客论坛

    在日常的工作和学习中,我们都很希望有自己的工作站,就是自己的服务器,自己给自己搭建一个博客或者是论坛,用于自己来写博客和搭建网站论坛.现在我们就用一个简单的方法来教大家如何30分钟内部署一个博客网站. ...

  2. php一些需要注意的点

    1,类的自动加载: spl_autoload_register(function ($class_name) { require_once $class_name . '.php';}); autol ...

  3. Swift 结构体的使用

    Swift 结构体是构建代码所用的一种通用且灵活的构造体. 我们可以为结构体定义属性(常量.变量)和添加方法,从而扩展结构体的功能. 与 C 和 Objective C 不同的是: 结构体不需要包含实 ...

  4. [Usaco2005 dec]Layout 排队布局 差分约束

    填坑- 差分约束一般是搞一个不等式组,求xn-x1的最大最小值什么的,求最大值就转化成xa<=xb+w这样的,然后建图跑最短路(这才是最终约束的),举个例子 x1<=x0+2x2<= ...

  5. bzoj 1485 [HNOI2009]有趣的数列 卡特兰数

    把排好序的序列看成一对对括号,要把他们往原数列里塞,所以就是括号序合法方案数 即为卡特兰数 f(n)=Cn2nn+1 求的时候为避免除法,可以O(n)计算每个素数出现次数,最后乘起来,打完之后发现其实 ...

  6. Spark学习之数据读取与保存总结(一)

    一.动机 我们已经学了很多在 Spark 中对已分发的数据执行的操作.到目前为止,所展示的示例都是从本地集合或者普通文件中进行数据读取和保存的.但有时候,数据量可能大到无法放在一台机器中,这时就需要探 ...

  7. Java语言编程 - Java第一个程序HelloWorld

    3.1 新建Java文件 首先新建一个文件夹,用于存放写的Java程序,例如我存放Java程序的位置为” D:\Files\code\java”. 在该文件夹中,右键新建一个文本文档 将文件名重命名为 ...

  8. 图解Java线程的生命周期,看完再也不怕面试官问了

    文章首发自个人微信公众号: 小哈学Java https://www.exception.site/java-concurrency/java-concurrency-thread-life-cycle ...

  9. SQL优化指南

    慢查询日志 开启撒网模式 开启了MySQL慢查询日志之后,MySQL会自动将执行时间超过指定秒数的SQL统统记录下来,这对于搜罗线上慢SQL有很大的帮助. SHOW VARIABLES LIKE 's ...

  10. matplotlib种类

    matplotlib模板: 1:线图 plot()单线段图 2:多个线图 subplot()Multiple axes (i.e. subplots) are created with the sub ...