SpinnerViewPop【PopWindow样式(单选)、Dialog样式(单选+多选)的下拉菜单】
版权声明:本文为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; } }
混淆配置
无
参考资料
暂时空缺