Android:扩展LinearLayout的自定义复合类认为它是LinearLayout

时间:2014-05-13 23:56:40

标签: java android android-linearlayout layout-inflater

我正在创建一个自定义复合布局,它包含一个包含ImageView和两个TextView的可单击水平LinearLayout。最终,我希望能够使用单个字段引用整个事物,并根据用户活动对我的活动进行添加,减去和编辑。我正在使用我在构造函数中膨胀的XML资源。但是我的手机认为我正在创建一个LinearLayout,当我尝试实现自定义类时出现以下错误:

D/ConnectionButton﹕ Ready to inflate
D/ConnectionButton﹕ constructor 2
D/AndroidRuntime﹕ Shutting down VM
W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x417be898)
E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.exampleapp.app/com.exampleapp.app.ManageFriends}: android.view.InflateException: Binary XML file line #3: Error inflating class com.exampleapp.utils.ConnectionButton

我在设置NameText时出错。如果我离开那条线它运行但我后来的Log告诉我android认为它是LinearLayout,而不是ConnectionButton

所以这是我的定义类 ConnectionButton:

public class ConnectionButton extends LinearLayout {
    ImageView IconView;
    TextView  NameView;
    TextView  StatusView;

    public ConnectionButton(Context context) {
        super(context);
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        Log.d("ConnectionButton","Ready to inflate");
        addView(inflater.inflate(R.layout.connection_row, null));
        Log.d("ConnectionButton","Inflated");
        IconView = (ImageView) findViewById(R.id.icon);
        NameView = (TextView) findViewById(R.id.name);
        StatusView = (TextView) findViewById(R.id.status);
    }

    public ConnectionButton (Context context, AttributeSet attrs) {
        super(context, attrs);
        Log.d("ConnectionButton","constructor 2");
/*        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        Log.d("ConnectionButton","Ready to inflate");
        addView(inflater.inflate(R.layout.connection_row, null));
        Log.d("ConnectionButton","Inflated");*/
        IconView = (ImageView) this.findViewById(R.id.icon);
        NameView = (TextView) this.findViewById(R.id.name);
        StatusView = (TextView) this.findViewById(R.id.status);
        NameView.setText("From Constructor 2");
    }
}

这是我的XML资源:

<com.exampleapp.utils.ConnectionButton xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:orientation="horizontal"
    android:clickable="true"
    style="@android:style/Widget.Button">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="left"
            android:adjustViewBounds="true"
            android:paddingRight="5dp"
            android:id="@+id/icon"/>
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:layout_weight="2"
            android:id="@+id/name"/>
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:layout_weight="1"
            android:id="@+id/status"/>
</com.exampleapp.utils.ConnectionButton>

这是我创建它的地方:( N.B。ConnectionList是应该包含这些对象的现有垂直LinearLayout)

    LinearLayout box = (LinearLayout)findViewById(R.id.ConnectionList);
    LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    Log.d("ConnectionButton","Ready to inflate");
    View CBv = inflater.inflate(R.layout.connection_row, box);
    Log.d("CBv class",CBv.getClass().toString());

2 个答案:

答案 0 :(得分:2)

您正在做出错误的假设,即inflater.inflate会返回新视图。根据它返回的文档:

  

膨胀层次结构的根视图。如果提供了root,那就是   根视图;否则它是膨胀的XML文件的根。

所以在你的情况下,CBv是一个LinearLayout,因为那是父亲的。要访问您的视图,只需使用findViewById。

答案 1 :(得分:0)

我认为您试图在ConnectionButton的构造函数内部膨胀ConnectionButton,这会构成递归问题。

我建议您更改ConnectionButton以使其继承自FrameLayout(因为您只有一个root子)并将其XML布局内容的根类型更改为LinearLayout。然后,您的控件将是一个扩展FrameLayout,其中包含一个LinearLayout