【问题标题】:How to create a generic Android XML layout for all activities如何为所有活动创建通用的 Android XML 布局
【发布时间】:2012-10-21 04:25:02
【问题描述】:

我有一个应用程序需要在每个屏幕中使用相同的项目 [5 个按钮作为选项卡]。是否可以创建一个具有这 5 个按钮的“基本 XML 布局”,然后让所有其他 XML 文件以某种方式从基本布局扩展,这样我就不必拥有最终具有相同功能的多个按钮.

API 9 是否有更好的方法来解决这个问题

【问题讨论】:

    标签: android android-layout


    【解决方案1】:

    为您的基本活动创建一个通用布局。然后使用 <include> 标记将该布局包含在所有布局中,您想要这样做。

    之后创建一个抽象活动,然后处理此活动中按钮和代码的所有点击,然后将此活动扩展到您包含基本布局的所有其他活动中。

    例如

    常用按钮 xml 布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/tabhost_bg"
        android:gravity="center"
        android:orientation="horizontal" 
        android:weightSum="3">
    
        <Button
            android:id="@+id/btnHome"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/bottom_btn_active" 
            android:layout_weight="1"
            android:text="@string/label_home"
            style="@style/bottom_tab_btn"/>
    
        <Button
            android:id="@+id/btnSetting"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/bottom_btn_active" 
            android:layout_weight="1"
            android:text="@string/label_settings"
            style="@style/bottom_tab_btn"/>
    
        <Button
            android:id="@+id/btnMore"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/bottom_btn_active" 
            android:layout_weight="1"
            android:text="@string/label_more"
            style="@style/bottom_tab_btn"/>
    
    </LinearLayout>
    

    这是一个 xml 布局,您可以在其中包含上述 XML 文件

    <include
            android:id="@+id/bottombar"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            layout="@layout/bottom_bar" />
    

    这里 android:layout_width 和 android:layout_height 和 layout 是强制属性

    现在这里是一个处理公共控件点击的基本活动

    public abstract class BottomBar extends Activity implements OnClickListener {
    
        protected Button btnHome;
        Button btnSetting, btnMore;
        private Activity mActivity;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mActivity = this;
        }
    
        protected void mappingWidgets() {
    
            btnHome = (Button) findViewById(R.id.btnHome);
            btnSetting = (Button) findViewById(R.id.btnSetting);
            btnMore = (Button) findViewById(R.id.btnMore);
    
            btnHome.setOnClickListener(this);
            btnSetting.setOnClickListener(this);
            btnMore.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            if (v == null)
                throw new NullPointerException(
                        "You are refering null object. "
                                + "Please check weather you had called super class method mappingWidgets() or not");
            if (v == btnHome) {
    
            } else if (v == btnSetting) {
    
            }else if(v == btnMore) {
    
            }
        }
    
        protected void handleBackgrounds(View v) {
            if (v == btnHome) {
                btnHome.setBackgroundResource(R.drawable.bottom_btn_hover);
                btnSetting.setBackgroundResource(R.drawable.bottom_btn_active);
                btnMore.setBackgroundResource(R.drawable.bottom_btn_active);
    
            } else if (v == btnSetting) {
                btnHome.setBackgroundResource(R.drawable.bottom_btn_active);
                btnSetting.setBackgroundResource(R.drawable.bottom_btn_hover);
                btnMore.setBackgroundResource(R.drawable.bottom_btn_active);
    
            } else if (v == btnMore) {
                btnHome.setBackgroundResource(R.drawable.bottom_btn_active);
                btnSetting.setBackgroundResource(R.drawable.bottom_btn_active);
                btnMore.setBackgroundResource(R.drawable.bottom_btn_hover);
            }
        }
    
    }
    

    现在剩下的一步是在您的所有活动中扩展此基本活动。

    您可以使用 extends 关键字在 Activity 中扩展 Base Activity。 例如

    public class MyActivity extends BottomBar
    

    注意:您必须从子活动中调用基类的超级方法来处理对基本布局的公共控件的点击。

    因此,您可以在单个活动中实现多个通用布局。

    希望这会对您有所帮助。 享受!!

    【讨论】:

    • 有没有办法在实现它的布局中访问基本布局的 ID?
    • 我认为没有必要访问宿主布局中包含的布局的组件。如果你真的想访问,那么 afaik 你可以使用它。
    • 非常有帮助的帖子!!:)
    【解决方案2】:

    You may want to look in to the &lt;include&gt; tag. 它有效地获取您创建的 xml 并将其复制并粘贴到您的其他布局中。

    所以你要做的就是用你的按钮创建一个单一的布局。将它们放在&lt;merge&gt; 标签之间,这样它们就不会创建FrameLayout 来放置。然后使用&lt;include&gt; 标签在其他布局中使用相同的布局。

    注意:在使用&lt;include&gt; 标记时,请始终覆盖layout_widthlayout_height 属性。即使您在使用相同值时覆盖它们也是如此。以前版本的 Android 中存在一个错误,如果您也没有覆盖这些属性,它会忽略某些属性。

    【讨论】:

      【解决方案3】:

      包含将是要走的路,但我自己从来没有让这个可靠地工作。也许我做错了什么,但编译器并不总是在合并布局中获取 id。

      【讨论】:

        最近更新 更多