2017-08-15 2 views
1

Ich versuche, eine benutzerdefinierte Viewgroup zu schreiben, die ich derzeit viel über meine Layout-Dateien duplizieren. Es ist ein wirklich einfaches, zwei Textboxen, die in einem linearen Layout mit einer vertikalen Ausrichtung und etwas Polsterung platziert sind. Es ist erwähnenswert, dass ich Xamarin verwende, um diese Anwendung zu entwickeln, aber ich glaube nicht, dass das Problem Xamarin-spezifisch ist. Meine Implementierung ist wie folgt: Android benutzerdefinierte Viewgroup nicht Rendering Kinder

[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 
    } 
} 

Das erwartete Verhalten ist, wie gesagt, zwei gestapelte Textbox auf dem jeweils anderen, jedoch das tatsächliche Verhalten ist eine Ansicht mit der Höhe 0 (wenn android:layout_height="wrap_content"). Wenn Sie layout_height manuell auf 20dp setzen, wird nur eine leere Ansicht dieser Höhe angezeigt.

Antwort

0

Okay, der Fehler, den ich gemacht habe, war ein dummer, der zu erwarten war. Wenn ich die Dimensionen aus dem typeDarray abrufe, ist der Standardwert, den ich übergebe, Ressourcen-IDs anstelle der tatsächlichen Werte, die diesen IDs zugeordnet sind. Zum Beispiel:

m_LabelSize = a.GetDimensionPixelOffset(Resource.Styleable.AppListItem_labelSize, Resource.Dimension.font_small); 

sollte

m_LabelSize = a.GetDimensionPixelOffset(Resource.Styleable.AppListItem_labelSize, Resources.GetDimensionPixelOffset(Resource.Dimension.font_small)); 
Verwandte Themen