Android開發之GridView實現彈出式選擇器

yungfan發表於2016-08-22
前段時間,寫了一個小專案,裡面有個介面如下圖所示,之前的版本是用Spinner來做,覺得不夠拉轟,所以採用GridView做了一個實現,效果還不錯,Mark一下。
img_4489fdcdd9cf91a2e840b3a304a260c7.png
彈出單選GridView.png
一、點選那個底部的綠色按鈕,彈出一個對話方塊,對話方塊裡面的內容是一個單選的GridView,關鍵程式碼如下:
//add_pay就是底部那個按鈕
add_pay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AlertDialog alertDialog = new AlertDialog.Builder(AddActivity.this)
                        .setView(getChoiceView(2))
                        .create();

                alertDialog.show();
            }
        });

上面的重點是那個getChoiceView(2),因為我有好幾個資料來源,所以就用一個int型別引數的type來區分一下,不同的type取不同的資料來源展示。

二、getChoiceView方法,主要是載入佈局,初始化GridView,然後設定Adapter和點選事件,比較簡單,關鍵程式碼如下:
   private View getChoiceView(final int type) {

        //R.layout.dialog_choice就是GridView所在的那個佈局,下面有介紹
        View view = LayoutInflater.from(AddActivity.this).inflate(R.layout.dialog_choice, null);
        GridView gv = (GridView) view.findViewById(R.id.gv);
        //GridView的資料來源,直接從strings.xml中載入過來
        List<String> data; 
        //自定義介面卡
        final MyAdapter adapter;
        //判斷型別,載入資料來源設定Adapter
        if (type == 1) {
            data = Arrays.asList(getResources().getStringArray(R.array.event));
            adapter = new MyAdapter(this, data);
            gv.setAdapter(adapter);
            //設定預設選中
            adapter.changeState(eventSelected);
        } else {
            data = Arrays.asList(getResources().getStringArray(R.array.pay));
            adapter = new MyAdapter(this, data);
            gv.setAdapter(adapter);
            adapter.changeState(paySelected);
        }

        //監聽點選事件,點選以後,之前的選中應該變為未選中
        gv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (type == 1) {
                    eventSelected = position;
                    //將選擇的內容設定到底部的按鈕上去
                    add_event.setText(eventArray.get(position).toString());
                } else {
                    paySelected = position;
                    add_pay.setText(payArray.get(position).toString());
                }
                alertDialog.dismiss();
                adapter.changeState(position);
            }
        });
        return view;
    }
三、dialog_choice 與 choice_item佈局,非常簡單

GridView所在的佈局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:gravity="center"
    android:orientation="vertical">

    <GridView
        android:id="@+id/gv_choice"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:horizontalSpacing="15dp"
        android:listSelector="@color/transparent"
        android:numColumns="2" //2列
        android:verticalSpacing="15dp"></GridView>

</LinearLayout>

GridView中每個item的佈局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_choice"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:button="@null"
        android:gravity="center"
        android:paddingBottom="10dp"
        android:paddingTop="10dp"
        android:textColor="@color/white" />

</LinearLayout>
四、MyAdapter繼承自BaseAdapter,關鍵是弄一個記錄選中與否的ArrayList,預設初始化的時候都是未選中,然後設定一個方法能修改選中項,在getView中根據選中與否,來設定背景色
@Override
public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder viewHolder = null;
        if (convertView == null) {
            viewHolder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.choice_item, null);
            viewHolder.title = (TextView) convertView.findViewById(R.id.tv_choice);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        if (!"".equals(data.get(position))) {
            viewHolder.title.setText(data.get(position));
        }
        if (list.get(position) == true) {
            viewHolder.title.setBackgroundDrawable(activity.getResources()
                    .getDrawable(R.drawable.choice_item_bg_selected));
        } else {
            viewHolder.title.setBackgroundDrawable(activity.getResources()
                    .getDrawable(R.drawable.choice_item_bg_default));
        }


        return convertView;
}

  /**
     * 修改選中時的狀態
     *
     * @param position
     */
public void changeState(int position) {
        if (lastPosition != -1) {
            list.set(lastPosition, false);// 取消上一次的選中狀態
        }
        list.set(position, !list.get(position));// 設定這一次的選中狀態
        lastPosition = position; // 記錄本次選中的位置
        notifyDataSetChanged(); // 通知介面卡進行更新
}

最終效果
img_e247ac9f0170730fce530dcf162436f2.gif
演示.gif


相關文章