将微调器宽度设置为当前项目宽度
Posted
技术标签:
【中文标题】将微调器宽度设置为当前项目宽度【英文标题】:Set spinner width to current item width 【发布时间】:2017-02-21 22:12:58 【问题描述】:默认情况下,微调器宽度设置为适合下拉列表中最大的项目,但我希望它与所选项目的宽度相同。
<android.widget.Spinner
android:id="@+id/tab_spinner"
android:layout_
android:layout_
android:entries="@array/countries" />
正如您在右侧图片中看到的那样,微调器太长了,因为列表中的项目很长。
如何将其调整为所选项目的宽度?
【问题讨论】:
【参考方案1】:默认情况下,Spinner
将尝试测量您的一些下拉视图并使用找到的最大宽度。这发生在Spinner#measureContentWidth()
中,Spinner
的protected
方法在Spinner#onMeasure()
中调用。
解决此问题的一种方法是确保您的 SpinnerAdapter#getView()
方法始终使用 Spinner#getSelectedItemPosition()
作为其 position
参数。
我能想到两种可能的解决方案:
-
使用包装适配器创建自定义微调器(我更喜欢这种解决方案)
或调整您的自定义适配器
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.调整您的自定义适配器
注意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.
【讨论】:
第一个选项是最灵活的一个 第一个选项对我不起作用。当我实现它时(我不得不针对 kotlin 和getView
函数中的缺失代码对其进行调整)微调器不响应点击事件并且下拉箭头消失了。我将把我当前的代码放在下面的回复中。我正在使用自定义 TextView 作为微调器项
@jpmcosta 我把我的代码放在一个新的 SO 问题中:***.com/questions/56998198/…【参考方案2】:
ViewGroup.LayoutParams spinnerLayoutParams = spinner.getLayoutParams();
spinnerLayoutParams.width -= 1;
spinner.setLayoutParams(spinnerLayoutParams);
在所选项目上执行此操作
【讨论】:
值“-1”是 MATCH_PARENT 。为什么会有帮助?【参考方案3】:将微调器 XML 设置为:
android:layout_
为我工作。
【讨论】:
抱歉忘记发布我的代码,但它已经是这样了,对我没有任何改变......以上是关于将微调器宽度设置为当前项目宽度的主要内容,如果未能解决你的问题,请参考以下文章