android - 将微调器宽度设置为当前项目宽度

标签 android width spinner selection

默认情况下,微调器宽度设置为适合下拉列表中最大的项目,但我希望它与所选项目的宽度相同。

<android.widget.Spinner
    android:id="@+id/tab_spinner"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:entries="@array/countries" />

enter image description here

如您在右侧图片中所见,微调器太长了,因为列表中的项目很长。

如何将其调整为所选项目的宽度?

最佳答案

默认情况下,Spinner将尝试测量您的一些下拉 View 并使用找到的最大宽度。这发生在 Spinner#measureContentWidth() , 一个 protected Spinner的方法|调用 Spinner#onMeasure() .

解决此问题的一种方法是确保您的 SpinnerAdapter#getView()方法总是使用 Spinner#getSelectedItemPosition()为其position争论。

我可以想到两种可能的解决方案:

  1. 使用包装器适配器创建自定义微调器(我更喜欢这个解决方案)
  2. 或调整您的自定义适配器


<强>1。使用包装器适配器创建自定义微调器

确保在您的 xml 中使用它布局,而不是正常的 <Spinner> .

注意DynamicWidthSpinner#getAdapter()将返回 WrapperSpinnerAdapter ;使用它的 getBaseAdapter()访问适配器的方法。

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。调整您的自定义适配器

注意parentgetView()可能并不总是 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.
}

关于android - 将微调器宽度设置为当前项目宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40009955/

相关文章:

android - 我应该将 setOnClickListener 放在 RecyclerView 适配器的什么位置

css - 如何制作一个全宽的 wordpress 主题?

html - 图像的中心部分适合屏幕

java - 用房间数据库填充微调器

android - Snackbar 不会在滑动时关闭

android - 如何在 android 的 JSON 请求中传递 requestUrl 和其他参数中的一半参数?

android - 如何使用 Android 中的 Parcelable 接口(interface)通过 Intent 将包含可绘制参数的对象传递给另一个 Activity

css - 为什么 'padding' 有时会算在元素宽度内,有时不会?

Android OPEN 微调器,单击一次按钮

java - 微调器选择后填充 TextView