Android自定義下拉列表——PopupWindow+ListView(單選模式)

最近在項(xiàng)目中使用android原生的Spinner發(fā)現(xiàn)其顯示效果沒有想象中的好耕赘,于是就動手寫了一個popuwindow的彈出框下拉列表名斟,在popuwindow中主要使用了ListView自帶的單選和多選模式跃巡。

listview中使用自帶的選擇框有兩種方式败明,第一種方式:

ListView lv = (ListView) findViewById(R.id.list_view);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

第二中方式:就是在listview布局中直接加液茎,建議使用第二種

android:choiceMode="singleChoice"

先書寫一個帶listview的布局歌殃,popuwindow_spinner布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="@mipmap/spinner_pop_bg">
 <TextView
    android:id="@+id/pop_title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="6dp"
    android:gravity="center"
    android:textSize="@dimen/title_size"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@color/grey_line"/>
    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:divider="#00000000"
        android:choiceMode="singleChoice"
        >
    </ListView>
    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@color/grey_line"/>
    <TextView
        android:id="@+id/pop_cancel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="6dp"
        android:text="@string/cancel"
        android:textColor="@color/orange"
        android:gravity="center"
        android:textSize="@dimen/title_size"/>
</LinearLayout>

其實(shí)在popuwindow中使用listview和在Activity中使用相同乔妈,具體實(shí)現(xiàn)代碼如下(具體使用看注釋):

  public class SpinnerPopuwindow extends PopupWindow{
  
    private View conentView;
    private ListView listView;
    private SpinnerPopAdapter adapter;
    private Activity context;
    private TextView pop_title;
    private TextView pop_cancel;
  /**
     * @param context 上下文
     * @param string 獲取到未打開列表時(shí)顯示的值
     * @param list 需要顯示的列表的集合
     * @param itemsOnClick listview在activity中的點(diǎn)擊監(jiān)聽事件
     */
    @SuppressLint("InflateParams")
    public SpinnerPopuwindow(final Activity context, final String string, final List<String> list, AdapterView.OnItemClickListener itemsOnClick) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.context =context;
        conentView = inflater.inflate(R.layout.popuwindow_spinner, null);
        // 設(shè)置SelectPicPopupWindow的View
        this.setContentView(conentView);
        // 設(shè)置SelectPicPopupWindow彈出窗體的寬
       this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
    //    this.setWidth(view.getWidth());
        // 設(shè)置SelectPicPopupWindow彈出窗體的高
        this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        // 設(shè)置SelectPicPopupWindow彈出窗體可點(diǎn)擊
        this.setFocusable(true);
        // 刷新狀態(tài)
        this.update();
        this.setOutsideTouchable(false);
        // 實(shí)例化一個ColorDrawable顏色為半透明
        ColorDrawable dw = new ColorDrawable(0000000000);
        // 點(diǎn)back鍵和其他地方使其消失,設(shè)置了這個才能觸發(fā)OnDismisslistener ,設(shè)置其他控件變化等操作
        this.setBackgroundDrawable(dw);
        this.setOnDismissListener(new OnDismissListener() {
            @Override
            public void onDismiss() {
                darkenBackground(1f);
            }
        });
        //解決軟鍵盤擋住彈窗問題
        this.setSoftInputMode(PopupWindow.INPUT_METHOD_NEEDED);
        this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

        // 設(shè)置SelectPicPopupWindow彈出窗體動畫效果
      //  this.setAnimationStyle(R.style.AnimationPreview);

        adapter = new SpinnerPopAdapter(context,list);
        listView = (ListView) conentView.findViewById(R.id.listView);
        listView.setOnItemClickListener(itemsOnClick);
        listView.setAdapter(adapter);
        // setAdapter是異步進(jìn)行的氓皱,為了使彈窗能即時(shí)刷新路召,所以使用post+Runnable
        listView.post(new Runnable() {
            @Override
            public void run() {
           //主要是為了比對未打開列表時(shí)顯示的值和列表中的值進(jìn)行默認(rèn)選中
                for(int j = 0;j<list.size();j++){
                    if(string.equals(list.get(j).toString())){
                        listView.setItemChecked(j, true);//listview自帶的方法
                    }else {
                        listView.setItemChecked(j, false);
                    }
                }
            }
        });

        pop_title = (TextView) conentView.findViewById(R.id.pop_title);
        pop_cancel = (TextView) conentView.findViewById(R.id.pop_cancel);

        pop_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
                darkenBackground(1f);
            }
        });
    }

  //給下拉列表的設(shè)置標(biāo)題,增加復(fù)用性
    public void setTitleText(String str){
        pop_title.setText(str);
    }
    //獲取選中列表中的數(shù)據(jù)所對應(yīng)的position
    public int getText(){
        return listView.getCheckedItemPosition();
    }

    /**
     * 顯示popupWindow
     *
     * @param parent
     */
    public void showPopupWindow(View parent) {
        if (!this.isShowing()) {
            // 以下拉方式顯示popupwindow
            //  this.showAsDropDown(parent);
           // this.showAsDropDown(parent,0,10);
            this.showAtLocation(parent, Gravity.BOTTOM|Gravity.CENTER, 0, 0);
            darkenBackground(0.9f);//彈出時(shí)讓頁面背景回復(fù)給原來的顏色降低透明度波材,讓背景看起來變成灰色
        }
    }
    /**
     * 關(guān)閉popupWindow
     */
    public void dismissPopupWindow() {
               this.dismiss();
              darkenBackground(1f);//關(guān)閉時(shí)讓頁面背景回復(fù)為原來的顏色

    }
    /**
     * 改變背景顏色股淡,主要是在PopupWindow彈出時(shí)背景變化,通過透明度設(shè)置
     */
    private void darkenBackground(Float bgcolor){
        WindowManager.LayoutParams lp = context.getWindow().getAttributes();
        lp.alpha = bgcolor;
        context.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        context.getWindow().setAttributes(lp);
    }
}

SpinnerPopAdapter書寫方式是最基本的適配器寫法:

public class SpinnerPopAdapter extends BaseAdapter {
    private List<String> content;
    private Context context;
    private LayoutInflater mInflater;

    public SpinnerPopAdapter(Context context,List<String> content){
        this.context = context;
        this.content = content;
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return content == null ? 0 : content.size();
    }

    @Override
    public Object getItem(int position) {
        return content.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if(convertView == null){
            convertView = mInflater.inflate(R.layout.popuwindow_spinner_item,null);
            viewHolder = new ViewHolder();
            viewHolder.tv_spinner = (TextView) convertView.findViewById(R.id.tv_spinner);
            viewHolder.check = (CheckableLayout) convertView.findViewById(R.id.check);
            convertView.setTag(viewHolder);
        }else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        String spinnerText = content.get(position);
        viewHolder.tv_spinner.setText(spinnerText);
        return convertView;
    }
    public static class ViewHolder{
        TextView tv_spinner;
        public CheckableLayout check;
    }
}

adapter中布局各聘,其中要記得自定義選中布局CheckableLayout繼承自RelativeLayout并實(shí)現(xiàn)Checkable揣非,網(wǎng)上例子很多我就不在這兒寫了,popuwindow_spinner_item布局:

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

    <TextView
        android:id="@+id/tv_spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:duplicateParentState="true"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="30dp"
        android:gravity="center"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:duplicateParentState="true"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="20dp"
        android:src="@drawable/singlechoice_selector"/>

</com.goldenlink.credit.view.CheckableLayout>

最主要的是在Activity中的使用

public class NewTaskActivity extends Activity implements View.OnClickListener{

    public static final String TAG = "NewTaskActivity";

    private ImageView goback;
    private LinearLayout task_type;
    private TextView tv_type;
    private SpinnerPopuwindow mSpinnerPopuwindow;

    /** 模擬的假數(shù)據(jù) */
    private List<String> testData;
    private String type;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_newtask);
        initView();
    }

    public void initView(){
        goback = (ImageView) findViewById(R.id.goback);
        goback.setOnClickListener(this);
        task_type = (LinearLayout) findViewById(R.id.task_type);
        task_type.setOnClickListener(this);
        tv_type = (TextView) findViewById(R.id.tv_type);
        TestData();
    }
    /**
     * 模擬假數(shù)據(jù)
     */
    private void TestData() {
        testData = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            String str = new String("數(shù)據(jù)" + i);
            testData.add(str);
        }
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.goback:
                this.finish();
                break;
            case R.id.task_type:
                type = tv_type.getText().toString();
                mSpinnerPopuwindow = new SpinnerPopuwindow(this,type,testData,itemsOnClick);
                mSpinnerPopuwindow.showPopupWindow(task_type);
                mSpinnerPopuwindow.setTitleText("類型");//給下拉列表設(shè)置標(biāo)題
                break;
        }
    }
    //SchedulePopuwindow為彈出窗口實(shí)現(xiàn)監(jiān)聽類
    private AdapterView.OnItemClickListener itemsOnClick = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String value = testData.get(mSpinnerPopuwindow.getText());
            tv_type.setText(value);
            mSpinnerPopuwindow.dismissPopupWindow();
        }
    };
}

Activity中的布局躲因,activity_newtask布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/title_height"
        android:background="@mipmap/title_bg" >
        <ImageView
            android:id="@+id/goback"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true"
            android:layout_centerInParent="true"
            android:layout_marginLeft="10dp"
            android:src="@mipmap/goback" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="@string/new_task"
            android:textColor="@color/white"
            android:textSize="@dimen/title_size" />
    </RelativeLayout>

    <LinearLayout
        android:id="@+id/ll_type"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:layout_gravity="center"
        android:background="@color/white"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="8dp"
            android:textSize="16sp"
            android:text="類型"/>
        <LinearLayout
            android:id="@+id/task_type"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
        <TextView
            android:id="@+id/tv_type"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:padding="8dp"
            android:text="請選擇類型"
            android:textSize="14sp"/>
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center|right"
            android:padding="8dp"
           android:src="@mipmap/spinner"
            />
            </LinearLayout>
    </LinearLayout>
 </LinearLayout>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末早敬,一起剝皮案震驚了整個濱河市忌傻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌搞监,老刑警劉巖水孩,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異琐驴,居然都是意外死亡俘种,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門绝淡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宙刘,“玉大人,你說我怎么就攤上這事牢酵⌒” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵馍乙,是天一觀的道長布近。 經(jīng)常有香客問我,道長丝格,這世上最難降的妖魔是什么撑瞧? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮显蝌,結(jié)果婚禮上预伺,老公的妹妹穿的比我還像新娘。我一直安慰自己琅束,他們只是感情好扭屁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著涩禀,像睡著了一般料滥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上艾船,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天葵腹,我揣著相機(jī)與錄音,去河邊找鬼屿岂。 笑死践宴,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的爷怀。 我是一名探鬼主播阻肩,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了烤惊?” 一聲冷哼從身側(cè)響起乔煞,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎柒室,沒想到半個月后渡贾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡雄右,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年空骚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片擂仍。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡囤屹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逢渔,到底是詐尸還是另有隱情牺丙,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布复局,位于F島的核電站,受9級特大地震影響粟判,放射性物質(zhì)發(fā)生泄漏亿昏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一档礁、第九天 我趴在偏房一處隱蔽的房頂上張望角钩。 院中可真熱鬧,春花似錦呻澜、人聲如沸递礼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脊髓。三九已至,卻和暖如春栅受,著一層夾襖步出監(jiān)牢的瞬間将硝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工屏镊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留依疼,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓而芥,卻偏偏與公主長得像律罢,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子棍丐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容