DrawerLayout与FragmentTabHost结合模仿oschina主界面

2023-11-17

1. DrawerLayout实现侧滑菜单

drawerlayout是官方出的侧滑菜单控件,使用起来非常方便。将它当作LinearLayout一样的布局控件,完成布局xml文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawerlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="fly.drawerandtab.ui.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <FrameLayout
            android:id="@+id/realtabcontent"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?attr/windows_bg">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="4dip">

                    <fly.drawerandtab.widget.MyFragmentTabHost
                        android:id="@+id/tabhost"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="4dip" />

                    <View
                        android:layout_width="match_parent"
                        android:layout_height="1px"
                        android:background="?attr/lineColor" />
                </RelativeLayout>

                <ImageView
                    android:id="@+id/quick_option_iv"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:clickable="true"
                    android:contentDescription="@null"
                    android:src="@drawable/btn_quickoption_selector" />
        </FrameLayout>
    </LinearLayout>

    <fragment
        android:id="@+id/left_fragment"
        android:name="fly.drawerandtab.fragment.LeftFragment"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        tools:layout="@layout/fragment_left" />

    <fragment
        android:id="@+id/right_fragment"
        android:name="fly.drawerandtab.fragment.RightFragment"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity="right"
        tools:layout="@layout/fragment_right" />
</android.support.v4.widget.DrawerLayout>

一个布局控件,这里用的是LinearLayout充满父容器,两个fragment分别代表左侧滑和右侧滑,android:layout_gravity属性代表左边还是右边。
左侧滑栏的fragment代码:

package fly.drawerandtab.fragment;

import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import fly.drawerandtab.R;

/**
 * Created by Fly on 2016/6/25.
 */
public class LeftFragment extends Fragment implements View.OnClickListener{
    private View mLeftView;
    private View first_item;
    private View second_item;
    private View third_item;
    private View forth_item;
    private View fifth_item;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mLeftView = inflater.inflate(R.layout.fragment_left, container, false);
        initView();

        return mLeftView;
    }

    private void initView(){
        first_item = mLeftView.findViewById(R.id.first_item);
        second_item = mLeftView.findViewById(R.id.second_item);
        third_item = mLeftView.findViewById(R.id.third_item);
        forth_item = mLeftView.findViewById(R.id.forth_item);
        fifth_item = mLeftView.findViewById(R.id.fifth_item);

        first_item.setOnClickListener(this);
        second_item.setOnClickListener(this);
        third_item.setOnClickListener(this);
        forth_item.setOnClickListener(this);
        fifth_item.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch(id){
            case R.id.first_item:
                Toast.makeText(getActivity(),"第一个",2000).show();
                break;
        }
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?attr/layout_bg_normal">

    <fly.drawerandtab.widget.CustomerScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <include layout="@layout/fragment_left_items"/>

    </fly.drawerandtab.widget.CustomerScrollView>
</LinearLayout>

2. FragmentTabHost实现底部菜单

  • 自定义一个类继承FragmentTabHost:
package fly.drawerandtab.widget;

import android.content.Context;
import android.support.v4.app.FragmentTabHost;
import android.util.AttributeSet;

/**
 * Created by Fly on 2016/6/26.
 */
public class MyFragmentTabHost extends FragmentTabHost {
    private String mCurrentTag;
    private String mNoTabChangedTag;

    public MyFragmentTabHost(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void onTabChanged(String tabId) {
        if(tabId.equals(mNoTabChangedTag)){
            setCurrentTabByTag(mCurrentTag);
        }else{
            super.onTabChanged(tabId);
            mCurrentTag = tabId;
        }
    }

    public void setNoTabChangedTag(String tag) {
        this.mNoTabChangedTag = tag;
    }
}
  • 放入布局文件中。(在第一部分)
  • 定义每一个Tab的内容,继承Fragment就好,这里贴上一个的代码:
package fly.drawerandtab.fragment;

import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import fly.drawerandtab.R;
import fly.drawerandtab.interf.OnTabReselectListener;

/**
 * Created by Fly on 2016/6/26.
 */
public class MeFragment extends Fragment implements OnTabReselectListener{
    private View mView;
    private TextView mTextView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mView = inflater.inflate(R.layout.fragment_me, container, false);
        mTextView = (TextView) mView.findViewById(R.id.me_txt);

        return mView;
    }


    @Override
    public void onTabReselect() {
        mTextView.setText(R.string.double_click);
    }
}
  • 存储Tab的信息:
package fly.drawerandtab.ui;

import fly.drawerandtab.R;
import fly.drawerandtab.fragment.ExploreFragment;
import fly.drawerandtab.fragment.MeFragment;
import fly.drawerandtab.fragment.NewsFragment;
import fly.drawerandtab.fragment.TweetFragment;

/**
 * Created by Fly on 2016/6/26.
 */
public enum MainTab {
    NEWS(0, R.string.main_tab_news, R.drawable.tab_icon_new, NewsFragment.class),

    TWEET(1, R.string.main_tab_tweet, R.drawable.tab_icon_tweet, TweetFragment.class),

    QUICK(2, R.string.main_tab_quick, R.drawable.tab_icon_new, null),

    EXPLORE(3, R.string.main_tab_explore, R.drawable.tab_icon_explore, ExploreFragment.class),

    ME(4, R.string.main_tab_me, R.drawable.tab_icon_me, MeFragment.class);

    private int index;
    private int resName;
    private int resIcon;
    private Class<?> clz;

    MainTab(int index, int resName, int resIcon, Class<?> clz) {
        this.index = index;
        this.resName = resName;
        this.resIcon = resIcon;
        this.clz = clz;

    }



    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public int getResIcon() {
        return resIcon;
    }

    public void setResIcon(int resIcon) {
        this.resIcon = resIcon;
    }

    public int getResName() {
        return resName;
    }

    public void setResName(int resName) {
        this.resName = resName;
    }

    public Class<?> getClz() {
        return clz;
    }

    public void setClz(Class<?> clz) {
        this.clz = clz;
    }
}
  • 在MainActivity中初始化自定义的FragmentTabHost:
package fly.drawerandtab.ui;

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TabHost;
import android.widget.TextView;

import fly.drawerandtab.R;
import fly.drawerandtab.interf.OnTabReselectListener;
import fly.drawerandtab.widget.MyFragmentTabHost;

public class MainActivity extends AppCompatActivity implements TabHost.OnTabChangeListener, View.OnTouchListener {

    private DrawerLayout mDrawerLayout = null;
    private MyFragmentTabHost mTabHost;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
    }

    private void initView() {

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout);

        mTabHost = (MyFragmentTabHost) findViewById(R.id.tabhost);

        mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
//        mTabHost.setup(this.getLocalActivityManager());
        if (android.os.Build.VERSION.SDK_INT > 10) {
            mTabHost.getTabWidget().setShowDividers(0);
        }
        initTabs();

        mTabHost.setCurrentTab(0);
        mTabHost.setOnTabChangedListener(this);
    }

    private void initTabs() {
        MainTab[] tabs = MainTab.values();
        final int size = tabs.length;
        for (int i = 0; i < size; i++) {
            MainTab mainTab = tabs[i];
            TabHost.TabSpec spec = mTabHost.newTabSpec(getString(mainTab.getResName()));
            View indicator = LayoutInflater.from(getApplicationContext()).inflate(R.layout.tab_indicator, null);
            TextView title = (TextView) indicator.findViewById(R.id.tab_title);
            Drawable drawable = this.getResources().getDrawable(mainTab.getResIcon());
            title.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null);
            if (i == 2) {
                indicator.setVisibility(View.INVISIBLE);
                mTabHost.setNoTabChangedTag(getString(mainTab.getResName()));
            }
            title.setText(getString((mainTab.getResName())));

            spec.setIndicator(indicator);
            spec.setContent(new TabHost.TabContentFactory() {
                @Override
                public View createTabContent(String tag) {
                    return new View(MainActivity.this);
                }
            });
            mTabHost.addTab(spec, mainTab.getClz(), null);
            mTabHost.getTabWidget().getChildAt(i).setOnTouchListener(this);
        }
    }

    @Override
    public void onTabChanged(String tabId) {
        final int size = mTabHost.getTabWidget().getTabCount();
        for (int i = 0; i < size; i++) {
            View v = mTabHost.getTabWidget().getChildAt(i);
            if (i == mTabHost.getCurrentTab()) {
                v.setSelected(true);
            } else {
                v.setSelected(false);
            }
        }

        supportInvalidateOptionsMenu();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        super.onTouchEvent(event);
        boolean consumed = false;
        // use getTabHost().getCurrentTabView to decide if the current tab is
        // touched again
        if (event.getAction() == MotionEvent.ACTION_DOWN
                && v.equals(mTabHost.getCurrentTabView())) {
            // use getTabHost().getCurrentView() to get a handle to the view
            // which is displayed in the tab - and to get this views context
            Fragment currentFragment = getCurrentFragment();
            if (currentFragment != null
                    && currentFragment instanceof OnTabReselectListener) {
                OnTabReselectListener listener = (OnTabReselectListener) currentFragment;
                listener.onTabReselect();
                consumed = true;
            }
        }
        return consumed;
    }

    private Fragment getCurrentFragment() {
        return getSupportFragmentManager().findFragmentByTag(
                mTabHost.getCurrentTabTag());
    }
}

这里写了一个接口,是为了判断是否再次点了当前的tab:

package fly.drawerandtab.interf;

/**
 * Created by Fly on 2016/7/17.
 */
public interface OnTabReselectListener {
    void onTabReselect();
}

源码地址:GitHub地址
CSDN地址

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DrawerLayout与FragmentTabHost结合模仿oschina主界面 的相关文章

  • Google Map Android API v2 无法在 Play 商店应用程序中显示地图

    我正在与Google Map Android API v2在 Android 应用程序中 它可以很好地与未签名的应用程序在不同的设备上 但是 当我签署 apk 并将应用程序上传到 Play 商店时 下载的应用程序显示白屏而不是地图 您使用什
  • 在 Java/Android 中检查字符串是否包含 URL 的最佳方法是什么?

    在 Java Android 中检查字符串是否包含 URL 的最佳方法是什么 最好的方法是检查字符串是否包含 com net org info 其他 或者有更好的方法吗 url 输入到 Android 中的 EditText 中 它可以是粘
  • 停止在列表视图中滚动

    我的活动中有一个列表视图和一个图像按钮 当我单击图像按钮时 我想转到列表中的特定位置 我通过调用列表上的 setSelection intposition 来实现此目的 当用户滑动列表视图然后单击图像按钮时会出现问题 列表将转到指定位置但继
  • phonestateintentreceiver.notifyPhoneCallState 的用途是什么?

    谁能告诉我有什么用phonestateintentreceiver notifyPhoneCallState 我知道现在在这里发布答案为时已晚 可能对将来参考此问题的人有所帮助 如果您的应用程序希望收到有关来电的通知 则必须调用notify
  • 如何在android中使用Mediaprojection库捕获屏幕并转换为mp4文件?

    从 android 5 0 开始 他们提供了媒体投影库来捕获屏幕内容 但他们提供的示例演示应用程序尚不清楚 你可以找到示例应用程序here https github com googlesamples android ScreenCaptu
  • 使用动画来滑动视图

    我有一个可以识别滑动手势 向上和向下 的 FrameLayout 例如 如果执行向上滑动 我应该对当前视图 即 MATCH PARENT x MATCH PARENT 进行动画处理 使其向上移动 同时新视图来自底部 我可以用动画来实现这一点
  • 重置首选项的默认值

    我正在使用 CheckBoxPreference 作为设置屏幕 XML 是
  • Room - LiveData 观察器在数据库更新时不会触发

    我试图在下面的代码中找出 为什么在我用新数据填充数据库后 Room 的 LiveData observable 不会给我新的转变 这是放在我的活动的 onCreate 方法中 shiftsViewModel ViewModelProvide
  • 为什么大多数 Android 设备不像典型操作系统那样有交换区域?

    现在有 Android 支持交换区域来提高性能吗 出于哪些考虑 大多数 Android 设备放弃了该功能 现在有 Android 支持交换区域吗 Quoting 黛安 哈克伯恩 https groups google com d msg a
  • Kotlin 协程阻塞 Android 中的主线程

    我是 Kotlin 和协程的新手 我有一个fun在我的活动及其内部 检查User用户名和密码 如果为真 则返回Users object 一切都好 但是当我按下按钮时 我的活动被阻止并等待响应Users login 我用这个有趣的 priva
  • setOnTouchListener() 给我一个错误

    button setOnTouchListener new OnTouchListener public void onClick View v Toast makeText MainActivity this YOUR TEXT 5000
  • 带有可点击区域的 Android 图像

    我需要建议如何在 Android 下实现以下功能 我需要一个表示类似于图形 来自离散数学 的图像 具有顶点和边缘 我可以在其中单击每个顶点或边缘并触发不同的操作 请告诉我如何实现这一目标 也许与imagebuttons 或另一种表示此功能的
  • Android Studio 3.0 - 设置未保存

    我已将 文件 gt 设置 gt 编辑器 gt 代码样式 中的 右边距 列 从默认的 100 增加到 140 不幸的是 每次重新启动 Android Studio 后 该边距都会重置 我还尝试导出和导入我的设置 但这并不能阻止重置右边距 希望
  • 如何在打开导航抽屉时使背景 Activity 变小?

    我想做我的背景Activity打开时稍微小一点Navigation Drawer 模拟存在的效果Airbnb应用 我想最好的解释是截图 但重点不是让 View 变小 而是让它成为与 Drawer 打开 关闭动画同步的动画 因此 如果您开始打
  • IllegalStateException:无法更改片段的标签,以前是 android:switcher,现在是 android:switcher

    我的活动使用TabLayout ViewPager 这里的选项卡和页面的数量是动态的 具体取决于从服务器获取的数据 崩溃是通过 Crashlytics 报告的 我无法复制它 我的活动代码 Override protected void on
  • 设置 LinearLayout 的最大宽度

    如何设置水平线的最大宽度LinearLayout 因此 如果内容较短 例如某些文本 布局会缩小 如果内容较长 则布局不会扩展超过某个最大宽度值 我更喜欢在 XML 级别执行此操作 这就是我所需要的超出了之前答案中的建议 https stac
  • 如何使用Android Invalidate()

    在我的主要活动中 我定义了两个视图和一个菜单 浏览次数 1 自定义视图游戏 2 按钮btn 菜单 1 打开项目用于打开文件 菜单布局在不同的活动中定义 基本上 当主活动启动时 它会绘制没有任何内容的自定义视图和按钮 然后我使用菜单中的 打开
  • OnSwipe 方法在 RecyclerView 中不起作用

    我正在开发一个用于播放音频文件的应用程序 创建了包含 2 个选项卡的选项卡布局 两者中都使用了片段RecyclerView两者都被使用 该片段名为LibraryFragment有这个RecycleView其物品在刷卡时必须传递给HomeFr
  • 如何在 Android 上设置 Google Drive API?

    我一直在尝试将 Google Drive 功能集成到我的应用程序中 但我无法使用任何内置功能 因此我相信我要么错过了一个步骤 要么做得不正确 我正在遵循官方的 Google 开发者指南 https developers google com
  • 智能手机可以通过 3G/4G 进行点对点通信吗?

    我正在尝试编写一个应用程序 将数据从一个 Android 设备传输到另一个 Android 设备 但这些设备很可能位于城市 州或国家的不同部分 直接的方法是拥有一台中央服务器 或任何类型的服务器 但我试图避免使用中央服务器 我试图传递的数据

随机推荐

  • 使用XMind解决问题?只需4个简单步骤!

    我们每天都在解决问题并做出决定 从我应该穿什么到学校的小问题到如何找工作或上大学等等的问题 我们面临的问题可能或大或小 或简单或复杂 无论它是什么 我们都必须解决它 解决问题和决策是商业和生活的重要技能 我们生活中非常重要的一部分是找到解决
  • UE4_积分相同排名显示问题

    找了一下ue4 rank 函数相关 没找到合适的 自己简单写了个 解决积分相同时名次要一样 之后顺位排序 中国式排名 蓝图实现 c 原理一样 1 2 3 4 5
  • 编译 QT4.6.3 出现 derefIfNotNull 未定义 解决

    使用高版本的编译工具编译QT4 6 3 出现错误 derefIfNotNull 未定义 找到 RefPtr h文件 在WFT 的 public 里面增加 两个函数的定义 void derefIfNotNull T ptr if LIKELY
  • CS从头配置电脑清单(软件篇)

    CS从头配置电脑清单 软件篇 假设你电脑丢了 重新搞了一台 怎么从头配置 迅速可以进行高效产出 假设你是Linux ubuntu系统 安装zoom 安装slack 进行其他设备的信息发送 自己给自己发 项目交流 安装截图软件 推荐flame
  • 【Java】QueryWrapper方法解释

    继承自 AbstractWrapper 自身的内部属性 entity 也用于生成 where 条件 及 LambdaQueryWrapper 可以通过 new QueryWrapper lambda 方法获取 queryWrapper lt
  • 加解密

    目录 一 加密基础知识 1 加密函数 密钥 反函数 2 加密 解密 3 对称加密 4 非对称加密 公钥私钥 二 非对称加密 1 大素数分解问题类 1 RSA 2 Rabin 3 Pollard s rho 素数分解算法 2 离散对数问题类
  • 论文笔记-深度估计(5)Unsupervised Monocular Depth Estimation with Left-Right Consistency

    ECCV2016 Unsupervised Monocular Depth Estimation with Left Right Consistency 本文采用无监督学习 没有ground truth 的方法来估计深度 基本思路是匹配好左
  • Graph Neural Network-Based Anomaly Detection in Multivariate Time Series 代码配置及解析

    可以在GPU上跑通的代码 含数据集 我已经放到了以下链接 链接 https pan baidu com s 1gM4KTbRNHzfbGEGgvEjXAw 提取码 e7wu 在服务器上跑 先创建一个虚拟环境 conda create n G
  • 算法——B树,B-树,B+树,B*树全面解析笔记

    算法 B树 B 树 B 树 B 树全面解析笔记 https www cnblogs com lianzhilei p 11250589 html http blog codinglabs org articles theory of mys
  • 【QT】混合UI设计

    虽然利用Designer和代码的设计方式都可以开发GUI 但是毫无疑问的是最有效的开发方式是利用两者进行混合开发 下面这个实验例子来自 QT5 9 C 开发指南 我做了小部分修改 最终效果是这样 图标导入 这次我们要开发的是一个有工具栏 菜
  • 哈希表——哈希表的概念,哈希表的实现(闭散列,开散列)详细解析

    作者 努力学习的少年 个人简介 双非大二 一个正在自学c 和linux操作系统 写博客是总结知识 方便复习 目标 进大厂 如果你觉得文章可以的话 麻烦你给我点个赞和关注 感谢你的关注 种一颗树最好是10年前 其次是现在 目录 哈希概念 哈希
  • 实战怎么用u盘重装系统

    当电脑系统出现故障问题无法进系统的情况下 我们可以通过制作u盘启动盘进pe系统进行修复或者重装系统解决 不过很多网友不知道怎么用u盘重装系统 今天小编就给大家分享一个简单易操作的u盘重装系统教程 具体的步骤如下 1 先在一台可用的电脑上下载
  • nodejs服务后台持续运行三种方法

    网上看到的 用了第二种方式OK的 自己备份保存下 一 利用 forever forever是一个nodejs守护进程 完全由命令行操控 forever会监控nodejs服务 并在服务挂掉后进行重启 1 安装 forever npm inst
  • 微信小程序之内嵌网页(webview)

    微信小程序提供了新的开放能力 它终于开放了在小程序中内嵌HTML页面的功能 从微信小程序基础库1 6 4开始 我们就可以在小程序内放置一个
  • 蓝桥杯大赛— —每日一题(6、走方格)

    走方格 题目描述 在平面上有一些二维的点阵 这些点的编号就像二维数组的编号一样 从上到下依次为第 1 至第 n 行 从左到右依次为第 1 至第 m 列 每一个点可以用行号和列号来表示 现在有个人站在第 1 行第 1 列 要走到第 n 行第
  • Redis可以代替MySQL作为数据库吗

    Redis可以代替MySQL作为数据库吗 当使用Redis作为数据库时 以下是一些基本的代码示例 1 连接到Redis服务器 2 存储和获取数据 3 列表操作 4 有序集合操作 6 键过期和删除 Redis作为数据库时 下面是一些更复杂的代
  • 如何基于G6进行双树流转绘制?

    1 背景 业务背景 CRM系统随着各业务条线对线索精细化分配的诉求逐渐增加 各个条线的流向规则会越来越复杂 各个条线甚至整个CRM的线索流转规则急需一种树形的可视化的图来表达 技术背景 在开发之前考虑了三种方案 原生canvas fabri
  • STM32 同个定时器 采用2个通道输入捕获

    工作中遇到 做点总结 之前看CSDN 找到一种写法 就是 把中断中的 CAPTURE VAL 的值 变成 date1 date2 去保存 但是我的写法不成功 一位大佬帮忙改成功了 总结我的写法错误之处 主函数区别 我把date1 清0 放后
  • java longlong_java Long long

    在Java中执行如下的代码 long number 26012402244 编译的时候会出现一个错误 提示 过大的整数 32322355744 如果在Eclipse中书写上面的代码 提示的是 The literal 26012402244
  • DrawerLayout与FragmentTabHost结合模仿oschina主界面

    1 DrawerLayout实现侧滑菜单 drawerlayout是官方出的侧滑菜单控件 使用起来非常方便 将它当作LinearLayout一样的布局控件 完成布局xml文件