将微调器宽度设置为当前项目宽度
Set spinner width to current item width
默认情况下,微调器宽度设置为适合下拉列表中最大的项目,但我希望它与所选项目的宽度相同。
<android.widget.Spinner
android:id="@+id/tab_spinner"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:entries="@array/countries" />
正如您在右侧图片中看到的那样,微调器太长了,因为列表中的项目很长。
如何将其调整为所选项目的宽度?
将微调器 XML 设置为:
android:layout_width="wrap_content"
对我有用。
默认情况下,Spinner
将尝试测量您的某些下拉视图并使用找到的最大宽度。这发生在 Spinner#measureContentWidth()
中,在 Spinner#onMeasure()
中调用了 Spinner
的 protected
方法。
解决此问题的一种方法是确保您的 SpinnerAdapter#getView()
方法始终使用 Spinner#getSelectedItemPosition()
作为其 position
参数。
我可以想到两种可能的解决方案:
- 使用包装器适配器创建自定义微调器(我更喜欢这个解决方案)
- 或调整您的自定义适配器
1。使用包装器适配器创建自定义微调器
确保在您的 xml
布局中使用它,而不是正常的 <Spinner>
。
注意DynamicWidthSpinner#getAdapter()
会return一个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。调整您的自定义适配器
请注意 getView()
中的 parent
可能并不总是 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.
}
ViewGroup.LayoutParams spinnerLayoutParams = spinner.getLayoutParams();
spinnerLayoutParams.width -= 1;
spinner.setLayoutParams(spinnerLayoutParams);
在所选项目上执行此操作
默认情况下,微调器宽度设置为适合下拉列表中最大的项目,但我希望它与所选项目的宽度相同。
<android.widget.Spinner
android:id="@+id/tab_spinner"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:entries="@array/countries" />
正如您在右侧图片中看到的那样,微调器太长了,因为列表中的项目很长。
如何将其调整为所选项目的宽度?
将微调器 XML 设置为:
android:layout_width="wrap_content"
对我有用。
默认情况下,Spinner
将尝试测量您的某些下拉视图并使用找到的最大宽度。这发生在 Spinner#measureContentWidth()
中,在 Spinner#onMeasure()
中调用了 Spinner
的 protected
方法。
解决此问题的一种方法是确保您的 SpinnerAdapter#getView()
方法始终使用 Spinner#getSelectedItemPosition()
作为其 position
参数。
我可以想到两种可能的解决方案:
- 使用包装器适配器创建自定义微调器(我更喜欢这个解决方案)
- 或调整您的自定义适配器
1。使用包装器适配器创建自定义微调器
确保在您的 xml
布局中使用它,而不是正常的 <Spinner>
。
注意DynamicWidthSpinner#getAdapter()
会return一个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。调整您的自定义适配器
请注意 getView()
中的 parent
可能并不总是 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.
}
ViewGroup.LayoutParams spinnerLayoutParams = spinner.getLayoutParams();
spinnerLayoutParams.width -= 1;
spinner.setLayoutParams(spinnerLayoutParams);
在所选项目上执行此操作