将XML布局用作View子类的视图?

9

我觉得我曾经知道如何做到这一点,但现在却一片空白。我有一个扩展自View的类(Card),并且我用XML为它编写了一个布局。我想做的是将Card的视图设置为构造函数中的XML视图,以便我可以使用Card中的方法来设置TextView等内容。有什么建议?下面是代码:

Card.java: (我在那里使用了View.inflate(context, R.layout.card_layout, null);作为我想要做的事情的示例,但它不起作用。我基本上希望该类成为 View 的接口,并且为此我需要以某种方式分配 XML 布局给 View。我是否要使用类似于 setContentView(View view) 的东西?虽然View类中没有这样的方法,但是否有类似的方法?)

public class Card extends View {

    TextView tv;

    public Card(Context context) {
        super(context);
        View.inflate(context, R.layout.card_layout, null);
        tv = (TextView) findViewById(R.id.tv);
    }

    public Card(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        View.inflate(context, R.layout.card_layout, null);
        tv = (TextView) findViewById(R.id.tv);
    }

    public Card(Context context, AttributeSet attrs) {
        super(context, attrs);
        View.inflate(context, R.layout.card_layout, null);
        tv = (TextView) findViewById(R.id.tv);
    }

    public void setText(String text) {
        tv.setText(text);
    }

}

card_layout.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="336dp"
    android:layout_height="280dp"
    android:layout_gravity="center"
    android:background="@drawable/card_bg"
    android:orientation="vertical" >


    <TextView
        android:id="@+id/tv"
        android:layout_height="fill_parent"
        android:layout_width="wrap_content"
        android:textSize="24dp"
    />

</LinearLayout>
2个回答

9
你现在的设置无法实现你想要的功能。一个 View(或者它的直接子类)代表了一个单独的视图,它没有子视图的概念,这就是你想要做的事情。简单的 View 类不能使用 LayoutInflater,因为它没有添加子视图的方法(如 addView() 方法)。
另一方面,正确的类应该是 ViewGroup(或者它的直接子类,如 LinearLayoutFrameLayout 等),它们可以接受添加 Views 或其他的 ViewGroups,通过提供 addView 方法。最终你的类应该是:
public class Card extends ViewGroup {

    TextView tv;

    public Card(Context context) {
        super(context);
        View.inflate(context, R.layout.card_layout, this);
        tv = (TextView) findViewById(R.id.tv);
    }

    public Card(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        View.inflate(context, R.layout.card_layout, this);
        tv = (TextView) findViewById(R.id.tv);
    }

    public Card(Context context, AttributeSet attrs) {
        super(context, attrs);
        View.inflate(context, R.layout.card_layout, this);
        tv = (TextView) findViewById(R.id.tv);
    }

    public void setText(String text) {
        tv.setText(text);
    }

}

如果我没记错的话,如果你扩展了ViewGroup,就必须重写onLayout。因此(根据您的布局文件),您应该考虑扩展LinearLayout并将xml布局中的LinearLayout替换为一个merge标签。

1
我曾考虑过让我的类扩展LinearLayout,但后来觉得这是个愚蠢的想法。在看到这条评论后,我尝试了一下,结果完美运行!非常感谢! - user766650

3
您应该能够在布局中使用您的类名。例如:
<your.package.name.Card 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="336dp"
    android:layout_height="280dp"
    ...

只需调用findViewById来获取子视图。

要使用您的Card类,您可以使用inflator获取一个实例,然后将其附加到父视图中。

LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
Card card = (Card) inflater.inflate(R.layout.card_layout, null);
parentView.addView(card);

点击此处查看更多信息。


1
但是,card_layout.xml 如何与 Card 类连接起来呢?当我按照你上面写的做时,什么也没有出现。 - user766650
1
我查看了文档,它提供了很多关于以编程方式绘制自定义视图的信息,但没有关于使用在XML中定义的视图的内容。我可以使用方法等来绘制所有内容,但这需要一些时间,因为它是一个相当详细的布局。 - user766650
您需要将Card的实例添加到另一个视图中,可以使用view.addView(card)setContentView(card)方法将其添加到Activity中。 - devnate
好的,我想你需要使用膨胀器。我会编辑我的答案来展示如何使用。 - devnate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接