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;
    }
}

 

混淆配置

參考資料

暫時空缺

項目demo下載地址

https://github.com/haiyuKing/SpinnerViewPopDemo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM