问题
我正在开发的Android应用程序的主要活动已经变得非常大。这主要是因为它包含带有3个选项卡的aTabWidget
。每个选项卡都有很多组件。活动必须立即控制所有这些组件。所以我认为你可以想象这个Activity有20个字段(几乎每个组件都有一个字段)。它还包含许多逻辑(单击侦听器,填充列表的逻辑等)。
我通常在基于组件的框架中做的是将所有内容拆分为自定义组件。然后,每个自定义组件都有明确的责任。它将包含它自己的一组组件以及与该组件相关的所有其他逻辑。
我试图弄清楚如何做到这一点,我在Android文档中发现了他们喜欢称之为"复合控制"的东西。 (请参阅http://developer.android.com/guide/topics/ui/custom-components.html#compound并滚动到"复合控件"部分)我想基于定义视图结构的XML文件创建这样的组件。
在文档中它说:
请注意,就像使用Activity一样,你可以使用声明式(基于XML)方法来创建包含的组件,也可以从代码中以编程方式嵌套它们。
嗯,这是个好消息!基于XML的方法正是我想要的!但它没有说明如何做到这一点,除了它"像一个活动"...但我在一个活动中做的是调用setContentView(...)
从XML扩展视图。如果你是例如subclassLinearLayout
,则该方法不可用。
所以我尝试像这样手动扩充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
声明为根元素的事实。这导致inflatedLinearLayout
的孩子为MyCompoundComponent
,其本身已经是aLinearLayout
!!所以现在我们在MyCompoundComponent
之间有一个冗余的LinearLayout和它实际需要的视图。
有人可以为我提供一个更好的方法来解决这个问题,避免实现冗余LinearLayout
吗?
#1 热门回答(99 赞)
Use合并tag作为你的XML根目录
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Your Layout -->
</merge>
#2 热门回答(0 赞)
我认为你应该这样做的方法是使用你的类名作为XML根元素:
<com.example.views.MyView xmlns:....
android:orientation="vertical" etc.>
<TextView android:id="@+id/text" ... />
</com.example.views.MyView>
然后让你的类派生自你想要使用的任何布局。请注意,如果你使用此方法,则不要在此处使用布局inflater。
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);
}
免责声明:我可能正在谈论完整的bollocks。