• 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() + "
    ");
                    }
                    tv_show.setText(tv_show.getText() + "
    =====================
    " + 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() + "
    ");
                    }
                    tv_show.setText(tv_show.getText() + "
    =====================
    " + 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() + "
    ");
                    }
                    tv_show.setText(tv_show.getText() + "
    =====================
    " + 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() + "
    ");
                        }
                    }
                    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() + "
    ");
                    }
                    tv_show.setText(tv_show.getText() + "=====================
    " + 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

  • 相关阅读:
    爬虫练习
    爬取豆瓣电影top250
    简单爬虫
    正则提取子域名和ip
    用户体验培训总结
    测试经验总结
    项目管理知识总结
    读书笔记——《留住好员工:爱他们,还是失去他们?》
    ISTQB学习笔记
    数据结构和算法with Python
  • 原文地址:https://www.cnblogs.com/whycxb/p/7251720.html
Copyright © 2020-2023  润新知