【发布时间】:2016-11-09 08:11:20
【问题描述】:
我的情况似乎与谷歌上发现的 100 万个问题(与微调器有关)有点不同,其中主要解决方案只是为微调器项创建自定义 xml。
在我的应用程序中,我需要根据设备物理尺寸调整微调器项目的文本大小,例如它应该占屏幕高度/宽度的固定百分比,这意味着 Px 和 Dp 大小都无法帮助我。我应该注意,开发是在 API 15 上进行的。
Spinner mySpinner = FindViewById<Spinner>(Resource.Id.mySpinner);
List<string> languages = new List<string>();
Translation.LoadAvailableLanguages(out languages);
var adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleSpinnerItem, languages);
adapter.SetDropDownViewResource(Resource.Layout.spinner_item);
mySpinner.Adapter = adapter;
如您所见,我为选择显示使用默认微调器项目布局,为下拉列表使用自定义spinner_item。自定义布局不过是TextView。
我在应用程序启动时以编程方式计算布局组件的确切像素值,因此无论平板电脑/手机的 dpi、分辨率和物理尺寸如何,此应用程序看起来都一样。
问题出在微调器上。我似乎不知道如何更改选择和下拉列表的文本大小。
我在适配器对象中找到了一个函数:
adapter.GetDropDownView(int position, View convertView, ViewGroup parent);
文档说:
获取一个视图,在下拉菜单中显示数据集中指定位置的数据。
position int:我们想要查看的项目的索引。
convertView 视图: 如果可能的话,要重用旧视图。注意:你应该检查这个 view 在使用前是非空的并且是合适的类型。如果不是 可以转换此视图以显示正确的数据,此方法 可以创建一个新视图。
parent ViewGroup:这个视图的父级 最终会附在
position 对我来说很清楚。convertView 是个谜。我从哪里得到这个旧视图?这种观点究竟是什么?我应该为这个参数使用什么?parent 对我来说再次不清楚。它是什么?我认为下拉列表的父级是 Spinner。在最坏的情况下,父母也可能是一个活动,但是它们都不属于ViewGroup,所以我不明白这里实际需要什么?
EDIT1:
我也试过这个:
(mySpinner.GetChildAt(n) as TextView).SetTextSize(Android.Util.ComplexUnitType.Px, 100);
但事实证明,mySpinner.ChildCount 是 0 而adapter.Count 有 3 个项目。
EDIT2:解决方案
根据接受的答案,我已将适用于 Android 的 Java 代码转换为适用于 android 的 C#/Xamarin
class SpinnerStringAdapter: Android.Widget.ArrayAdapter {
/// <summary>
/// Array items' text height in screen pixels
/// </summary>
private int ActualTextSize = 20;
/// <summary>
/// Display items as bold text
/// </summary>
private bool IsBold = false;
/// <summary>
/// Creates array adapter with custom sized text.
/// </summary>
/// <param name="AContext">The current context.</param>
/// <param name="ALayoutID">The resource ID for a layout file containing a TextView to use when instantiating views.</param>
/// <param name="AStringList">The string objects to represent in the ListView.</param>
/// <param name="ADisplay">The display of the parent activity</param>
/// <param name="ATextSize">The size of a text for the array items. Size in percents of Display height</param>
public SpinnerStringAdapter(Context AContext, int ALayoutID, System.Collections.IList AStringList, Display ADisplay, double ATextSize, bool AIsBold):
base(AContext, ALayoutID, AStringList) {
Android.Graphics.Point size = new Android.Graphics.Point();
ADisplay.GetSize(size);
int width = size.X;
int height = size.Y;
ActualTextSize = Convert.ToInt32(height * ATextSize / 100); // Convert percent to fraction and calculate actual height
IsBold = AIsBold;
}
public override View GetDropDownView(int position, View convertView, ViewGroup parent) {
TextView tv = (LayoutInflater.From(Context).Inflate(Resource.Layout.spinner_item, parent, false) as TextView);
tv.SetTextSize(Android.Util.ComplexUnitType.Px, ActualTextSize);
tv.SetText(GetItem(position).ToString(), TextView.BufferType.Normal);
if ( IsBold ) {
tv.SetTypeface(null, Android.Graphics.TypefaceStyle.Bold);
}
return tv;
}
public override View GetView(int position, View convertView, ViewGroup parent) {
TextView tv = ( LayoutInflater.From(Context).Inflate(Resource.Layout.spinner_item, parent, false) as TextView );
tv.SetTextSize(Android.Util.ComplexUnitType.Px, ActualTextSize);
tv.SetText(GetItem(position).ToString(), TextView.BufferType.Normal);
if ( IsBold ) {
tv.SetTypeface(null, Android.Graphics.TypefaceStyle.Bold);
}
return tv;
}
}
【问题讨论】: