如何为Android Layout文件创建可重用的xml包装器

我有几个大致相同的布局文件,除了一个部分。 有没有办法让我可以在一个地方拥有共同的XML; 而不是复制/粘贴,并且当我想要进行1次更改时必须更新一堆文件?

我知道我可以包含来自其他XML文件的XML,但是公共代码不是内部控件; 它是外包装; 所以包括不起作用。 基本上,我有一堆文件,看起来像这样:

     

基本上,我想做ASP.Net对Master Pages的处理。 这有什么选择吗?

解决方案非常简单。

您需要将onCreate()函数SetContentView中的“ Activity ”类扩展为基本xml布局,还需要覆盖基本Activity类中的setContentView

例如:

base_layout.xml使用以下代码创建base_layout.xml

         
  1. 创建BaseActivity.java
 public class BaseActivity extends Activity { ImageView image; LinearLayout baseLayout; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.base_layout); this.image = (ImageView) this.findViewById(R.id.image_view_01); this.baseLayout = (LinearLayout) this.findViewById(R.id.base_layout); this.image.setImageResource(R.drawable.header); } @Override public void setContentView(int id) { LayoutInflater inflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(id, this.baseLayout); } } 

SomeActivity.java

 public class SomeActivity extends BaseActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.some_layout); //rest of code } } 

到目前为止我唯一注意到的是当请求进度条(requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS))时,这需要在调用super.onCreate之前完成。 我想这是因为在调用这个函数之前还没有任何东西可以绘制。

这对我很有用,希望你会发现这对你自己的编码很有用。

也许您可以使用一个主布局XML文件,然后根据需要通过代码动态添加/删除其他小部件。

我试图做到这一点 – 我想要一个左侧有一个按钮,右侧有一个按钮的视图,但中间可能有任意内容(取决于谁包括它)。 基本上是一个自定义视图组,它可以在XML布局中具有子视图,并将使用另一个XML布局包装这些子视图。 我是这样做的:

top_bar.xml:这表示包装内容的通用布局。 请注意具有ID“addChildrenHere”的LinearLayout(可以是任何布局) – 稍后会引用它。

       

main.xml:主要布局。 这包括一个带有几个孩子的自定义视图组(WrappedLayout)。 请注意它如何声明自定义XML命名空间,并在WrappedLayout标记上设置两个自定义属性(这些属性表示用于包装子项的布局,以及该布局中应放置此节点的子项的位置)。

        

attrs.xml:这是res / values。 这定义了上面XML中使用的自定义XML属性。

        

最后,WrappedLayout.java:它处理读取自定义属性,并做一些hackery使addView()实际上在不同的地方添加视图。

 package karl.test; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; public class WrappedLayout extends FrameLayout { ///Attempts to add children to this layout will actually get forwarded through to mChildContainer. ///This would be final, but it's actually used indirectly by the constructor before it's initialised. private ViewGroup mChildContainer; public WrappedLayout(Context context, AttributeSet attrs) { super(context, attrs); //read the custom attributes final int layoutToInflate; final int childContainerID; { final TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.WrappedLayout); layoutToInflate = styledAttributes.getResourceId(R.styleable.WrappedLayout_layoutToInflate, 0); childContainerID = styledAttributes.getResourceId(R.styleable.WrappedLayout_childContainerID, 0); styledAttributes.recycle(); } if(layoutToInflate == 0 || childContainerID == 0) { Log.e("Error", "WrappedLayout.WrappedLayout(): Error reading custom attributes from XML. layoutToInflate = " + layoutToInflate + ", childContainerID =" + childContainerID); } else { //inflate the layout and (implicitly) add it as a child view final View inflatedLayout = View.inflate(context, layoutToInflate, this); //grab the reference to the container to pass children through to mChildContainer = (ViewGroup)inflatedLayout.findViewById(childContainerID); } } ///All the addView() overloads eventually call this method. @Override public void addView(View child, int index, ViewGroup.LayoutParams params) { if(mChildContainer == null) { //still inflating - we're adding one of the views that makes up the wrapper structure super.addView(child, index, params); } else { //finished inflating - forward the view through to the child container mChildContainer.addView(child, index, params); } } } 

据我所知,这是有效的。 Eclipse布局编辑器不能很好地工作(我不太确定问题是什么),但你可以很好地查看布局。 更改WrappedLayout的子项似乎需要手动编辑XML。

你看过应用样式和主题吗?