我正在尝试编写一个自定义视图组,我目前在我的布局文件中复制很多。这是一个非常简单的文本框,两个文本框放置在一个垂直方向和一些填充的线性布局中。值得一提的是,我使用Xamarin来开发这个应用程序,但我不认为这个问题是特定于Xamarin的。我的实现如下:
[Register("qube.AppListItem")]
class AppListItem : LinearLayout
{
private string m_Label;
private string m_Value;
private int m_LabelSize;
private int m_ValueSize;
private int m_HorizontalPadding;
private int m_VerticalPadding;
private ValueType m_ValueType;
private TextView m_LabelView;
private TextView m_ValueView;
public AppListItem(Context context) : this(context, null)
{
}
public AppListItem(Context context, IAttributeSet attrs) : this(context, attrs, 0)
{
}
public AppListItem(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
{
Initialize(context, attrs);
}
private void Initialize(Context context, IAttributeSet attrs)
{
var a = context.ObtainStyledAttributes(attrs, Resource.Styleable.AppListItem, 0, 0);
m_Label = a.GetString(Resource.Styleable.AppListItem_label);
m_Value = a.GetString(Resource.Styleable.AppListItem_value);
m_LabelSize = a.GetDimensionPixelOffset(Resource.Styleable.AppListItem_labelSize, Resource.Dimension.font_small);
m_ValueSize = a.GetDimensionPixelOffset(Resource.Styleable.AppListItem_valueSize, Resource.Dimension.font_medium);
m_HorizontalPadding = a.GetDimensionPixelOffset(Resource.Styleable.AppListItem_horizontalPadding, Resource.Dimension.row_padding);
m_VerticalPadding = a.GetDimensionPixelOffset(Resource.Styleable.AppListItem_verticalPadding, Resource.Dimension.info_list_padding);
m_ValueType = (ValueType)a.GetInt(Resource.Styleable.AppListItem_valueType, (int)ValueType.STRING);
a.Recycle();
Orientation = Orientation.Vertical;
Clickable = true;
SetPadding(m_HorizontalPadding, m_VerticalPadding, m_HorizontalPadding, m_VerticalPadding);
if (Build.VERSION.SdkInt >= BuildVersionCodes.Honeycomb)
{
// If we're running on Honeycomb or newer, then we can use the Theme's
// selectableItemBackground to ensure that the View has a pressed state
TypedValue outValue = new TypedValue();
Context.Theme.ResolveAttribute(Android.Resource.Attribute.SelectableItemBackground, outValue, true);
SetBackgroundResource(outValue.ResourceId);
}
BuildView();
}
private void BuildView()
{
m_LabelView = new TextView(Context);
m_LabelView.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
m_LabelView.TextSize = m_LabelSize;
m_LabelView.Text = m_Label;
AddView(m_LabelView);
if (m_ValueType == ValueType.EDITTEXT)
m_ValueView = new EditText(Context);
else
m_ValueView = new TextView(Context);
m_ValueView.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
m_ValueView.TextSize = m_ValueSize;
m_ValueView.Text = m_Value;
AddView(m_ValueView);
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
}
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
base.OnLayout(changed, l, t, r, b);
}
public string Label
{
get { return m_Label; }
set
{
m_Label = value;
m_LabelView.Text = value;
Invalidate();
RequestLayout();
}
}
public string Value
{
get { return m_ValueView.Text; }
set
{
m_ValueView.Text = value;
m_Value = value;
Invalidate();
RequestLayout();
}
}
public enum ValueType
{
STRING, EDITTEXT
}
}
如上所述,预期的行为是两个堆叠在一起的文本框,但实际行为是高度为0的视图(如果android:layout_height="wrap_content"
)。手动将layout_height
设置为20dp
只会显示该高度的空白视图。
答案 0 :(得分:0)
好吧,我犯的错误是愚蠢的,这是可以预料的。当我从typedarray获取维度时,我传入的默认值是资源ID而不是与这些id相关联的实际值。例如:
m_LabelSize = a.GetDimensionPixelOffset(Resource.Styleable.AppListItem_labelSize, Resource.Dimension.font_small);
应该是
m_LabelSize = a.GetDimensionPixelOffset(Resource.Styleable.AppListItem_labelSize, Resources.GetDimensionPixelOffset(Resource.Dimension.font_small));