Set spinner width to current item width

后端 未结 3 753
栀梦
栀梦 2020-12-16 04:32

By default the spinner width is set to fit the largest item in the dropdown but I want it to be the same width as the selected item.



        
相关标签:
3条回答
  • 2020-12-16 05:07
      ViewGroup.LayoutParams spinnerLayoutParams = spinner.getLayoutParams();
        spinnerLayoutParams.width -= 1;
       spinner.setLayoutParams(spinnerLayoutParams);
    

    Do this is on item selected

    0 讨论(0)
  • 2020-12-16 05:25

    By default, Spinner will try to measure some of your dropdown views and use the max width found. This happens in Spinner#measureContentWidth(), a protected method of Spinner called in Spinner#onMeasure().

    One way to solve the issue is to make sure your SpinnerAdapter#getView() method always uses Spinner#getSelectedItemPosition() for its position argument.

    I can think of two possible solutions:

    1. Creating a custom spinner with a wrapper adapter (I prefer this solution)
    2. Or adapting your custom adapter


    1. Creating a custom spinner with a wrapper adapter

    Make sure to use this in your xml layout, instead of a normal <Spinner>.

    Be careful that DynamicWidthSpinner#getAdapter() will return a WrapperSpinnerAdapter; use its getBaseAdapter() method to access to your adapter.

    public class DynamicWidthSpinner extends Spinner {
    
        public DynamicWidthSpinner(Context context) {
            super(context);
        }
    
        public DynamicWidthSpinner(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public DynamicWidthSpinner(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
    
        public void setAdapter(SpinnerAdapter adapter) {
            super.setAdapter(adapter != null ? new WrapperSpinnerAdapter(adapter) : null);
        }
    
    
        public final class WrapperSpinnerAdapter implements SpinnerAdapter {
    
            private final SpinnerAdapter mBaseAdapter;
    
    
            public WrapperSpinnerAdapter(SpinnerAdapter baseAdapter) {
                mBaseAdapter = baseAdapter;
            }
    
    
            public View getView(int position, View convertView, ViewGroup parent) {
                return mBaseAdapter.getView(getSelectedItemPosition(), convertView, parent);
            }
    
            public final SpinnerAdapter getBaseAdapter() {
                return mBaseAdapter;
            }
    
            public int getCount() {
                return mBaseAdapter.getCount();
            }
    
            public View getDropDownView(int position, View convertView, ViewGroup parent) {
                return mBaseAdapter.getDropDownView(position, convertView, parent);
            }
    
            public Object getItem(int position) {
                return mBaseAdapter.getItem(position);
            }
    
            public long getItemId(int position) {
                return mBaseAdapter.getItemId(position);
            }
    
            public int getItemViewType(int position) {
                return mBaseAdapter.getItemViewType(position);
            }
    
            public int getViewTypeCount() {
                return mBaseAdapter.getViewTypeCount();
            }
    
            public boolean hasStableIds() {
                return mBaseAdapter.hasStableIds();
            }
    
            public boolean isEmpty() {
                return mBaseAdapter.isEmpty();
            }
    
            public void registerDataSetObserver(DataSetObserver observer) {
                mBaseAdapter.registerDataSetObserver(observer);
            }
    
            public void unregisterDataSetObserver(DataSetObserver observer) {
                mBaseAdapter.unregisterDataSetObserver(observer);
            }
        }
    }
    


    2. Adapting your custom adapter

    Be careful that parent in getView() might not always be a Spinner.

    private class SimpleSpinnerAdapter extends BaseAdapter {
    
        private LayoutInflater mInflater;
        private int mResource;
    
    
        public SimpleSpinnerAdapter(Context context, int resource) {
            mInflater = LayoutInflater.from(context);
            mResource = resource;
        }
    
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return createViewFromResource(
                    mInflater,
                    ((Spinner) parent).getSelectedItemPosition(),
                    convertView,
                    parent,
                    mResource);
        }
    
        @Override
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            return createViewFromResource(
                    mInflater,
                    position,
                    convertView,
                    parent,
                    mResource);
        }
    
        protected View createViewFromResource(LayoutInflater inflater, int position, 
                                              View convertView, ViewGroup parent,
                                              int resource) {
            View view;
            if (convertView == null) {
                view = inflater.inflate(resource, parent, false);
            } else {
                view = convertView;
            }
    
            bindView(position, view);
    
            return view;
        }
    
        protected void bindView(int position, View view) {
            // Bind your view.
        }
    
        // getCount(), getItem(), and getItemId() methods.
    }
    
    0 讨论(0)
  • 2020-12-16 05:32

    Setting the spinners XML to:

    android:layout_width="wrap_content"
    

    worked for me.

    0 讨论(0)
提交回复
热议问题