Android-编写自定义(复合)组件

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

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

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

文件中写道:

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

真是好消息!基于 XML 的方法正是我想要的!但是它并没有说明如何做到这一点,只是说它“类似于一个活动”... ... 但是我在一个活动中所做的是调用 setContentView(...)来从 XML 扩展视图。如果例如子类 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);
}
}

这是可行的,只是我加载的 XML 将 LinearLayout声明为根元素。这导致了充气的 LinearLayout是一个 MyCompoundComponent的孩子,它本身已经是一个 LinearLayout! !所以现在我们在 MyCompoundComponent和它实际需要的视图之间有一个冗余的 LinearLayout。

有没有人能给我提供一个更好的方法来解决这个问题,避免使用冗余的 LinearLayout实例化?

30286 次浏览

使用 合并标记作为 XML 根

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

看看这篇文章。

我认为您应该这样做,使用您的类名作为 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);
}

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