Spinner背景问题

问题

遇到一个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 extends ArrayAdapter {

        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 createFromResource(@NonNull Context context,
                                                        CharSequence[] items, @LayoutRes int textViewResId) {
            return new SpinnerAdapter<>(context, textViewResId, items);
        }
    }

layout_spinner_pop_selectable_item.xml



    
    

但是我发现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背景问题)