133

我目前正在开发的 Android 应用程序的主要活动已经变得非常大。这主要是因为它包含一个TabWidget带有 3 个选项卡的选项卡。每个选项卡都有很多组件。该活动必须同时控制所有这些组件。所以我想你可以想象这个 Activity 有 20 个字段(几乎每个组件都有一个字段)。它还包含很多逻辑(单击侦听器、填充列表的逻辑等)。

我通常在基于组件的框架中所做的是将所有内容拆分为自定义组件。然后,每个自定义组件都有明确的责任。它将包含它自己的一组组件以及与该组件相关的所有其他逻辑。

我试图弄清楚如何做到这一点,并且我在 Android 文档中找到了他们喜欢称之为“复合控件”的东西。(请参阅http://developer.android.com/guide/topics/ui/custom-components.html#compound并滚动到“复合控件”部分)我想基于定义视图结构。

在文档中它说:

请注意,就像使用 Activity 一样,您可以使用声明性(基于 XML)的方法来创建包含的组件,也可以在代码中以编程方式嵌套它们。

嗯,这是个好消息!基于 XML 的方法正是我想要的!但它没有说明如何做,只是它“就像一个活动”......但我在一个活动中所做的是调用setContentView(...)从 XML 中膨胀视图。如果您例如 subclass ,则该方法不可用LinearLayout

所以我尝试像这样手动扩展 XML:

public class MyCompoundComponent extends LinearLayout {

    public MyCompoundComponent(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.my_layout, this);
    }
}

LinearLayout这有效,除了我正在加载的 XML 已声明为根元素这一事实。这导致膨胀LinearLayout的成为一个孩子,MyCompoundComponent它本身已经是一个LinearLayout!! 所以现在我们在它们之间有一个冗余的 LinearLayoutMyCompoundComponent和它实际需要的视图。

有人可以为我提供一种更好的方法来解决这个问题,避免冗余LinearLayout实例化吗?

4

2 回答 2

102

使用合并标记作为您的 XML 根

<merge xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Your Layout -->
</merge>

检查这篇文章。

于 2009-09-25T11:07:57.397 回答
0

我认为你应该这样做的方式是使用你的类名作为 XML 根元素:

<com.example.views.MyView xmlns:....
       android:orientation="vertical" etc.>
    <TextView android:id="@+id/text" ... />
</com.example.views.MyView>

然后让您的类从您要使用的任何布局派生。请注意,如果您使用此方法,则不要在此处使用布局充气器。

public class MyView extends LinearLayout
{
    public ConversationListItem(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }
    public ConversationListItem(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }


    public void setData(String text)
    {
        mTextView.setText(text);
    }

    private TextView mTextView;

    @Override
    protected void onFinishInflate()
    {
        super.onFinishInflate();

        mTextView = (TextView)findViewById(R.id.text);
    }
}

然后您可以照常在 XML 布局中使用您的视图。如果你想以编程方式制作视图,你必须自己膨胀它:

MyView v = (MyView)inflater.inflate(R.layout.my_view, parent, false);

不幸的是,这不会让你这样做v = new MyView(context),因为似乎没有办法解决嵌套布局问题,所以这并不是一个完整的解决方案。您可以添加这样的方法MyView来使它更好一点:

public static MyView create(Context context)
{
    return (MyView)LayoutInflater.fromContext(context).inflate(R.layout.my_view, null, false);
}

免责声明:我可能是在胡说八道。

于 2012-10-22T15:53:23.403 回答