1

我有一个正在制作的自定义表格行。我想使用 XML 文件来定义单行的外观。我想让一个类扩展 TableRow 并将自己定义为 XML 中定义的文件。XML 文件可能如下所示:

<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingRight="10dp"
        android:text="@string/loading"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:text="@string/loading"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</TableRow>

代码可能如下所示:

public class SpecialTableRow extends TableRow {

    public SpecialTableRow (Context context) {
        }
}   

我可以在构造函数中放入一些东西来让类假设它是整个 tableRow 吗?或者,是否有另一种效果更好的结构?我想出的最好的是:

    TableRow tr=(TableRow) LayoutInflater.from(context).inflate(R.layout.text_pair,null);
    TextView mFieldName=(TextView) tr.findViewById(R.id.label);
    TextView mValue=(TextView) tr.findViewById(R.id.data);
    tr.removeAllViewsInLayout();
    addView(mFieldName);
    addView(mValue);

但这会从 XML 中删除布局参数。外面有什么更好的吗?

4

3 回答 3

1

查看有关创建自定义视图的教程。您将希望继承 TableRow 并添加要显示的其他视图。然后,您可以直接在 XML 布局中使用新视图,并另外创建您可能需要的任何自定义属性。我已经包含了一个示例,该示例创建了一个名为 TextPairRow 的自定义 TableRow,使用两个 TextView 填充布局以在 TableRow 中显示,并添加显示/隐藏两个 TextView 的 showLabel 和 showData 自定义属性。最后,我介绍了如何在 XML 布局中直接使用新视图。

class TextPairRow extends TableRow {

    private TextView label, data;

     public TextPairRow (Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.getTheme().obtainStyledAttributes(
                                           attrs,
                                           R.styleable.TextPairRow, 0, 0);

        try {
            showLabel = a.getBoolean(R.styleable.TextPairRow_showLabel, false);
            showData = a.getBoolean(R.styleable.TextPairRow_showData, false);
        } finally {
            a.recycle();
        }

        initViews();
    }

    private void initViews(){

       // Here you can inflate whatever you want to be in your 
       // view or add views programatically.
       // In this example, we'll just assume you have a basic XML 
       // layout which defines a LinearLayout with two TextViews.
       LinearLayout mLayout = (LinearLayout) 
           LayoutInflater.from(getContext()).inflate(R.layout.textview_layout, this);

       label = (TextView) mLayout.findViewById(R.id.label);
       data = (TextView) mLayout.findViewById(R.id.data);

       if(showLabel)
           label.setVisibility(View.VISIBLE);
       else
           label.setVisibility(View.GONE); // can also use View.INVISIBLE 
                                           // depending on your needs

       if(showData){
           data.setVisibility(View.VISIBLE);
       else
           data.setVisibility(View.GONE); // can also use View.INVISIBLE 
                                           // depending on your needs
    }
}

这是您定义自定义 XML 属性的地方(找到或创建此文件:res/values/attrs.xml)

<resources>
   <declare-styleable name="TextPairRow">
       <attr name="showText" format="boolean" />
       <attr name="showLabel" format="boolean" />
   </declare-styleable>
</resources>

最后,要直接在 XML 布局中使用新视图:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto">
 <com.thefull.packageforyourview.TextPairRow    
     android:orientation="horizontal"
     custom:showData="true"
     custom:showLabel="true" />
</LinearLayout>

请注意,您可能需要xmlns:custom="http://schemas.android.com/apk/res/com.thefull.packageforyourview"根据您的自定义视图是否在库项目中来使用。无论如何,这或示例中的内容都将起作用。

于 2013-10-22T22:09:03.563 回答
1

这样做的真正诀窍实际上非常简单。使用inflate方法的第二个参数。事实上,最好的做法是:

LayoutInflater.from(context).inflate(R.layout.text_pair,this);

这会将 R.layout.text_pair 膨胀成这个,有效地使用整行。无需手动添加视图,Android 会为您处理。

于 2014-03-23T21:15:13.213 回答
0

我唯一能想到的就是使用静态方法而不是构造函数。例如:

public static void newInstance (Context context) {
    this = context.getLayoutInflater().inflate(R.layout.text_pair, null, null);
}

然后不要使用构造函数来初始化对象,调用这个方法。

于 2013-10-22T21:25:54.087 回答