自定義Spinner——使用listView和PopupWindow實現

1.建立用於spinner顯示選框的佈局文件sp_select_view.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:id="@+id/compound"
    android:background="@drawable/sp_select_item" >
    <TextView
        android:id="@+id/text"
        android:layout_width="76dp"
        android:layout_height="32dp"
        android:paddingLeft="10dp"
        android:text="文本文字"
        android:gravity="center_vertical"
        android:textSize="14sp"
        android:padding="5dp"
        android:singleLine="true" />
    <ImageView
        android:id="@+id/btn"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:layout_toRightOf="@+id/text"
        android:src="@mipmap/img_sp_downbtn"
        android:padding="5dp"
        android:layout_centerVertical="true"
        android:gravity="center"/>
</RelativeLayout>

2.建立用於顯示下拉列表的佈局文件sp_dropdown_list.xml

<?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" >
    <ListView
        android:id="@+id/listView"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:divider="#666666"
        android:dividerHeight="1dp"/>
</LinearLayout>

3.建立下拉列表的每一列的佈局文件sp_dropdown_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_container"
    android:background="@drawable/sp_select_item"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="5dp"
    android:paddingRight="5dp">
    <TextView
        android:id="@+id/tv_sp_listitem"
        android:layout_width="match_parent"
        android:layout_height="32dp"
        android:gravity="center_vertical"
        android:textSize="16sp"
        android:textColor="#000000"/>
</LinearLayout>

4.在drawable文件夾下建立下拉列表的每一列的背景樣式佈局和顯示選框的背景樣式佈局sp_select_item.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@color/colorPrimary"/>
    <item android:drawable="@color/colorPrimaryDark"/>
</selector>

5.建立自定義Spinner控件類的實現類

package com.htkrail.railgrinding.view;

import java.util.ArrayList;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

/**
 * 下拉列表框控件
 * Created by Administrator on 2020-04-15.
 */
public class MySpinner extends LinearLayout{

    private TextView editText;
    private ImageView imageView;
    private PopupWindow popupWindow = null;
    private ArrayList<String> dataList =  new ArrayList<String>();
    private View mView;
    public MySpinner(Context context) {
        this(context,null);
        // TODO Auto-generated constructor stub
    }
    public MySpinner(Context context, AttributeSet attrs) {
        this(context, attrs,0);
        // TODO Auto-generated constructor stub
    }
    public MySpinner(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
        initView();
    }

    public void initView(){
        String infServie = Context.LAYOUT_INFLATER_SERVICE;
        LayoutInflater layoutInflater;
        layoutInflater =  (LayoutInflater) getContext().getSystemService(infServie);
        View view  = layoutInflater.inflate(R.layout.sp_select_view, this,true);
        editText= (TextView)findViewById(R.id.text);
        imageView = (ImageView)findViewById(R.id.btn);
        this.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if(popupWindow == null ){
                    showPopWindow();
                }else{
                    closePopWindow();
                }
            }
        });
    }
    /**
     * 打開下拉列表彈窗
     */
    private void showPopWindow() {
        // 加載popupWindow的佈局文件
        String infServie = Context.LAYOUT_INFLATER_SERVICE;
        LayoutInflater layoutInflater;
        layoutInflater =  (LayoutInflater) getContext().getSystemService(infServie);
        View contentView  = layoutInflater.inflate(R.layout.sp_dropdown_list, null,false);
        ListView listView = (ListView)contentView.findViewById(R.id.listView);

        listView.setAdapter(new XCDropDownListAdapter(getContext(), dataList));
        popupWindow = new PopupWindow(contentView,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        popupWindow.setBackgroundDrawable(getResources().getDrawable(R.color.transparent));
        popupWindow.setOutsideTouchable(true);
        popupWindow.showAsDropDown(this);
    }
    /**
     * 關閉下拉列表彈窗
     */
    private void closePopWindow(){
        popupWindow.dismiss();
        popupWindow = null;
    }
    /**
     * 設置數據
     * @param list
     */
    public void setItemsData(ArrayList<String> list){
        dataList = list;
        editText.setText(list.get(0).toString());
    }

    /**
     *
     */
    public String getItemData(){
        return editText.getText().toString().trim();
    }
    /**
     * 數據適配器
     * @author caizhiming
     *
     */
    class XCDropDownListAdapter extends BaseAdapter{

        Context mContext;
        ArrayList<String> mData;
        LayoutInflater inflater;
        public XCDropDownListAdapter(Context ctx,ArrayList<String> data){
            mContext  = ctx;
            mData = data;
            inflater = LayoutInflater.from(mContext);
        }
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return mData.size();
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            // 自定義視圖
            ListItemView listItemView = null;
            if (convertView == null) {
                // 獲取list_item佈局文件的視圖
                convertView = inflater.inflate(R.layout.sp_dropdown_list_item, null);

                listItemView = new ListItemView();
                // 獲取控件對象
                listItemView.tv = (TextView) convertView
                        .findViewById(R.id.tv_sp_listitem);

                listItemView.layout = (LinearLayout) convertView.findViewById(R.id.layout_container);
                // 設置控件集到convertView
                convertView.setTag(listItemView);
            } else {
                listItemView = (ListItemView) convertView.getTag();
            }

            // 設置數據
            listItemView.tv.setText(mData.get(position).toString());
            final String text = mData.get(position).toString();
            listItemView.layout.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    editText.setText(text);
                    closePopWindow();
                }
            });
            return convertView;
        }

    }
    private static class ListItemView{
        TextView tv;
        LinearLayout layout;
    }

}

6.使用自定義的Spinner和使用普通的自帶的控件一樣
(1)首先需要在佈局文件中引用該控件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
        <com.htkrail.railgrinding.view.MySpinner
            android:id="@+id/sp_model"
            android:layout_marginTop="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true" />
    </RelativeLayout>

(2)其次,就是在代碼中使用該控件:

package com.htkrail.railgrinding;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import com.htkrail.railgrinding.view.MySpinner;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    private MySpinner spModel;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        spModel = (MySpinner)findViewById(R.id.sp_model);
        ArrayList<String> list = new ArrayList<String>();
        for(int i = 0;i< 6;i++){
            list.add("下拉列表項"+(i+1));
        }
        spModel.setItemsData(list);
    }
}

7.最終樣式
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章