美文网首页
Spinner背景问题

Spinner背景问题

作者: 小马要加油 | 来源:发表于2022-03-28 15:43 被阅读0次

    问题

    遇到一个spinner 背景的问题,记录一下.
    我在xml中定义了一个spinner

                    android:id="@+id/tracking_mode_spinner"
                    android:layout_width="wrap_content"
                    android:layout_height="33dp"
                    android:spinnerMode="dropdown"
                    android:background="@drawable/corner_white_bg_nor"
                    android:popupBackground="@drawable/spinner_pop_bg"/>
    

    在java中调用:

    mSpinner = findViewById(R.id.layout_spinner);
    mSpinner.setDropDownVerticalOffset(mContext.getResources()
                   .getDimensionPixelSize(R.dimen.spinner_offset));
    mSpinner.setDropDownWidth(mContext.getResources()
                   .getDimensionPixelSize(R.dimen.spinner_width));
    mSpinner.setAnimation(null);
           SpinnerAdapter adapter = SpinnerAdapter.createFromResource(mContext,
                   CameraFramingMode.createFramingModeEntries(true, false), R.layout.layout_spinner_pop_selectable_item);
           mSpinner.setAdapter(adapter);
           mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
               @Override
               public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                   adapter.setSelectedPosition(position);
                   updateView();
               }
    
               @Override
               public void onNothingSelected(AdapterView<?> parent) {
    
               }
           });
    

    adapter 是这样使用:

      SpinnerAdapter adapter = SpinnerAdapter.createFromResource(mContext,
                    CameraFramingMode.createFramingModeEntries(true, false), R.layout.layout_spinner_pop_selectable_item);
    
    

    SpinnerAdapter 定义成这个

        public static class SpinnerAdapter<T> extends ArrayAdapter<T> {
    
            private int selectedPosition;
    
            void setSelectedPosition(int selectedPosition) {
                this.selectedPosition = selectedPosition;
            }
    
            SpinnerAdapter(@NonNull Context context, int resource, @NonNull T[] objects) {
                super(context, resource, R.id.text, objects);
            }
    
            @Override
            public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                View view = super.getDropDownView(position, convertView, parent);
                TextView icon = view.findViewById(R.id.icon);
                if (selectedPosition == position) {
                    FontsUtils.setTypeface(icon);
                    icon.setText(FontIcons.OK);
                    icon.setVisibility(View.VISIBLE);
                } else {
                    icon.setVisibility(View.INVISIBLE);
                }
                return view;
            }
    
            static @NonNull
            SpinnerAdapter<CharSequence> createFromResource(@NonNull Context context,
                                                            CharSequence[] items, @LayoutRes int textViewResId) {
                return new SpinnerAdapter<>(context, textViewResId, items);
            }
        }
    

    layout_spinner_pop_selectable_item.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="wrap_content"
        android:background="@drawable/selector_spinner_item_bg"
        android:gravity="center_vertical"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/text"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:background="@android:color/transparent"
       />
        <TextView
            android:id="@+id/icon"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
       />
    </LinearLayout>
    

    但是我发现spinner 设置的bg会被item的bg覆盖selector_spinner_item_bg.
    抓取控件树发现,spinner的显示会把下拉框一个item作为显示的内容.


    image.png

    这样子会有问题,当item的布局样式和spinner不一样时,spinner的样式会被覆盖.
    举个例子:当item背景要红色,spinner背景要黑色时,spinner设置了黑色背景无用.

    原因

    spinner源码中:makeView 获取view是通过Adapter#getView的方式获取的

    /**
         * Obtain a view, either by pulling an existing view from the recycler or
         * by getting a new one from the adapter. If we are animating, make sure
         * there is enough information in the view's layout parameters to animate
         * from the old to new positions.
         *
         * @param position Position in the spinner for the view to obtain
         * @param addChild true to add the child to the spinner, false to obtain and configure only.
         * @return A view for the given position
         */
        private View makeView(int position, boolean addChild) {
            View child;
    
            if (!mDataChanged) {
                child = mRecycler.get(position);
                if (child != null) {
                    // Position the view
                    setUpChild(child, addChild);
    
                    return child;
                }
            }
    
            // Nothing found in the recycler -- ask the adapter for a view
            child = mAdapter.getView(position, null, this);
    
            // Position the view
            setUpChild(child, addChild);
    
            return child;
        }
    

    DropDownAdapter#getView,这个方法不是抽象,所以当我们没有重写此方法时,他返回的就是item的view.

     public View getView(int position, View convertView, ViewGroup parent) {
                return getDropDownView(position, convertView, parent);
            }
    

    修改

    知道原因了就好修改了,我们重写getView重新设置一个view即可.

    相关文章

      网友评论

          本文标题:Spinner背景问题

          本文链接:https://www.haomeiwen.com/subject/qbupjrtx.html