Android在PopWindow中使用Spinner的心路历程

2019-07-25 16:04:58 浏览数 (2)

前言

最近在开发的项目程序中用到了PopWindow,结果在里面需要加一个点击选择的列表,于是就准备使用Spinner放在PopWindow,期间经历了几个问题,最后都一一解决了,这篇文章就介绍一下Spinner怎么在PopWindow中使用。

视频效果

按照惯例,我们先上最终实现的效果视频

代码演示

程序中我们点击组托弹出一个PopWindow,用于选择当前托盘号及单据类型,如下图

ppw_storelocation.xml

代码语言:javascript复制
<?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/seesimilarcolorThistle4"
    android:orientation="vertical"
    android:padding="10dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/seesimilarcolorThistle3"
        android:orientation="vertical"
        android:padding="10dp">


        <TextView
            android:id="@ id/ppw_storelocation_title"
            android:layout_width="match_parent"
            android:layout_height="35dp"
            android:gravity="center"
            android:text="扫描或输入库位信息"
            android:textColor="@color/seesimilarcolorGhostWhite"
            android:textSize="14dp" />


        <EditText
            android:id="@ id/ppw_storelocation_edt"
            android:layout_width="match_parent"
            android:layout_height="35dp"
            android:layout_marginTop="5dp"
            android:background="@color/seesimilarcolorGhostWhite"
            android:gravity="center"
            android:hint="扫描或输入库位码"
            android:textColor="@color/seesimilarcolorThistle4" />

        <TextView
            android:id="@ id/ppw_storelocation_typetitle"
            android:layout_width="match_parent"
            android:layout_height="35dp"
            android:gravity="center"
            android:text="入库类型"
            android:textColor="@color/seesimilarcolorGhostWhite"
            android:textSize="14dp" />


        <Spinner
            android:id="@ id/ppw_storelocation_spinner"
            android:layout_width="match_parent"
            android:layout_height="35dp"
            android:layout_marginTop="5dp"
            android:background="@color/seesimilarcolorGhostWhite"
            android:gravity="center"
            android:textAlignment="center" />


        <Button
            android:id="@ id/ppw_storelocation_btntmpstore"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:background="@drawable/shape"
            android:text="取消"
            android:textColor="@color/seesimilarcolorGhostWhite" />

    </LinearLayout>

</LinearLayout>

在PopWindow里面加入Spinner的显示

OnIteSelectedListener的事件内容可以自己写,我这里是程序中用到的。


到上面这样我本来觉得就可以结束了,可是在调试的过程中发现一点击Spinner框程序直接崩掉了,如下图

报错为Unable to add window -- token android.view.ViewRootImpl$W@538d624c is not valid; is your activity running? 出现这个问题后在度娘上查了一下,说是在PopWindow中加入Spinner默认的下拉列表是不行的,如果用对话框的方式可以实现,那我们就改一下对话框方法

如上图加上红框中的这一句后,我们再看看效果


关于Spinner中选择对齐的问题

上面这样我们就完美解决了在PopWindow中使用Spinner的问题,不过看上面的动图会发现,Spinner中的选项字体在最左边,这样并不好看,但是我们在Spinner中明明设置了gravity=center,如下图

查找资料后发现我们用系统自带的Simple_spinner_item这样的方法,使用字体居中不起作用

想要解决这个问题,需要我们重写ArrayAdapter里面的方法,下面是这个的核心方法

代码语言:javascript复制
         private View setCentered(View view) {
                TextView textView = view.findViewById(android.R.id.text1);
                textView.setGravity(Gravity.CENTER);
                return view;
            }

通过这们来我们就如视频刚开始一样,完美解决了Spinner字体居中的问题

最后放一下显示PopWindow的那一段完整代码

InitStorePopWindow

代码语言:javascript复制
    //组托的界面
    private void InitStorePopWindow() {
        //popup的显示View
        final View popupWindowView=getLayoutInflater().inflate(R.layout.ppw_storelocation, null);
        //定义popupwindow
        final PopupWindow popstore=new PopupWindow(popupWindowView, 600, 550, true);
        //设定可以选择及显示位置
        popstore.setFocusable(true);
        popstore.showAtLocation(fragwhinhead.getView(), Gravity.CENTER, 0, 0);
        popstore.showAsDropDown(fragwhinhead.getView());

        popupWindowView.setFocusable(true);
        popupWindowView.setFocusableInTouchMode(true);
        //返回键关闭popwindow
        popupWindowView.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    popstore.dismiss();
                    return true;
                }
                return false;
            }
        });

        //文本框事件
        EditText edtinput=popupWindowView.findViewById(R.id.ppw_storelocation_edt);
        edtinput.setInputType(InputType.TYPE_CLASS_TEXT);
        edtinput.requestFocusFromTouch();
        edtinput.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (KeyEvent.KEYCODE_BACK == event.getKeyCode()) {
                    popstore.dismiss();
                    return true;
                }
                return false;
            }
        });
        edtinput.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                //检测到回车键后进入事件
                if (KeyEvent.KEYCODE_ENTER == event.getKeyCode()) {
                    switch (event.getAction()) {
                        case KeyEvent.ACTION_UP:
                            String code=v.getText().toString();
                            if (code.equals("")) {
                                return true;
                            }

                            //检测库位是否正常
                            //todo 网络检测条码
                            whinretrofitApi api=new whinretrofitApi();
                            api.setbase(WhInActivity.this, mSysCfg);
                            api.setInfCallBack(WhInActivity.this);
                            api.setretrofittype(PostValue.StoreLocation);
                            api.execute(code);


                            popstore.dismiss();

                            return true;
                        default:
                            return true;
                    }
                }
                return false;
            }
        });


        //入库类型
        Spinner spinner=popupWindowView.findViewById(R.id.ppw_storelocation_spinner);
        String[] spinneritem={"生产入库", "采购入库", "调拨入库", "退货入库"};
        ArrayAdapter<String> spinnerAdapter=new ArrayAdapter<String>(WhInActivity.this,
                android.R.layout.simple_spinner_item, spinneritem){

            private View setCentered(View view) {
                TextView textView = view.findViewById(android.R.id.text1);
                textView.setGravity(Gravity.CENTER);
                return view;
            }

            @NonNull
            @Override
            public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                return setCentered(super.getView(position, convertView, parent));
            }

            @Override
            public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                return setCentered(super.getDropDownView(position, convertView, parent));
            }
        };
        //下拉样式
        spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(spinnerAdapter);
        spinner.setSelection(ordersel);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                ordersel=position;
                nowPallet.Remark=parent.getItemAtPosition(position).toString();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                ordersel=1;
                parent.setSelection(ordersel);
                nowPallet.Remark=parent.getSelectedItem().toString();
            }
        });

        //临时托盘按钮
        Button btn=popupWindowView.findViewById(R.id.ppw_storelocation_btntmpstore);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popstore.dismiss();
            }
        });

    }

-END-

1 人点赞