Framelayout布局中嵌套多个布局layout的显示

2015已经来了快半月了,始终还是没感受到一点新年的气氛,但是终归是还没过年这对于我们来说好像也确实正常。

目前来说自我感觉还是沉浸在年末的那种气氛中,那就暂且年末吧。年末因为部分原因再次需要接触Launcher的代码了,记得14年最开始的时候就看过一部分Launcher2的代码,现在重新回头来看却发现感触颇多,竟然不知不觉忘掉了很多,也在看了许久之后又有点重新认识的感觉。

回归正题,此次不仅仅是要修改launcher2的源码部分,还要加一点自己的东西,因为还是依托于原生的launcher2的原因,只是想在固有launcher2的UI架构上增加一点自己的东西,关于launcher2的UI架构部分,我也就啰嗦下再次重温下,毕竟之前应该是没有记录过的。

首先最直观的是UI界面部分的大概分类。简单截张图算是凑合看看

之所以我区分为三个区域也是出于这三个部分已经占据了UI布局的大部分,分别是从左到右 搜索框/删除框所占区域,应用图标/窗口小部件所占区域,快捷功能键所占区域。如果按布局文件launcher.xml区分就得更为细致了。在此可以借鉴下网友解析的代码段

<com.android.launcher2.DragLayer
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
    android:id="@+id/drag_layer"
	...
    >

    <!-- Keep these behind the workspace so that they are not visible when
         we go into AllApps -->
    <include
        android:id="@+id/dock_divider"
	layout="@layout/workspace_divider"
        ...
	 />

    <!-- 分页指示器 -->
    <include
        android:id="@+id/paged_view_indicator"
        layout="@layout/scroll_indicator"
        ...
	 />

    <!-- The workspace contains 5 screens of cells -->
    <com.android.launcher2.Workspace
        android:id="@+id/workspace"
        ...
        >

		<!-- 五个分屏,默认显示cell3 -->
        <include android:id="@+id/cell1" layout="@layout/workspace_screen" />
        <include android:id="@+id/cell2" layout="@layout/workspace_screen" />
        <include android:id="@+id/cell3" layout="@layout/workspace_screen" />
        <include android:id="@+id/cell4" layout="@layout/workspace_screen" />
        <include android:id="@+id/cell5" layout="@layout/workspace_screen" />
    </com.android.launcher2.Workspace>

	<!-- 搜索框/删除框 -->
    <include
        android:id="@+id/qsb_bar"
        layout="@layout/qsb_bar" />

	<!-- 显示具体全部应用的界面,包括APPS、WIGHETS的tab标签,以及显示ALL APP的页面和现实APP WIGHETS的页面 -->
    <include layout="@layout/apps_customize_pane"
        android:id="@+id/apps_customize_pane"
        ..
	/>

	<!-- WorkSpace最下面的五个快捷位置 -->
    <include layout="@layout/hotseat"
        android:id="@+id/hotseat"
        ..
	 />

	<!-- 刚启动的时候显示的指导页 -->
    <include layout="@layout/workspace_cling"
        android:id="@+id/workspace_cling"
        ...
	/>

	<!-- 是第一次进入全部应用之后显示的指导页 -->
    <include layout="@layout/folder_cling"
        android:id="@+id/folder_cling"
        ...
	/>
</com.android.launcher2.DragLayer>

上面部分的解析已经非常清楚明了了,不再解释什么了。

对于launcher2的修改也就是从上面几个地方下手了。可以看出整个launcher的布局都是包含在com.android.launcher2.DragLayer中的,再详细看这部分java代码就会明白之前一直在说对于framelayout这个布局的最佳实例就是launcher这话并没错,因为launcher的源码才是将这个布局的各个特点发挥的淋漓尽致了。可想而知Framelayout做出来的launcher在安卓这个平台作为门面展示给所有人的将会有多么全面了。

之前一直想法是要在这个固有分区的基础上增加一个自己的分区来增加一点自己的功能,于是果断修改了launcher.xml布局,并将DragLayer的外层增加了一层LinearLayout同时在这个布局左边增加一个LinearLayout来显示自己的一点东西。但是这个简单的改动编译时有错误,log显示

Workspace can only be used in EXACTLY mode.

跟进到PageeView.java代码中找到这句异常提示

        if (widthMode != MeasureSpec.EXACTLY) {
            throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
        }

不知道出于什么考虑要将workspace区域设置为EXACTLY模式,查了下这个模式的资料貌似必须指定width或者height的具体数据或者fill_parent,match_parent才能判定为那个模式,因为时间问题暂时就没考虑直接注释,果断编译通过,剩下的工作就是计算自己区域的宽度将剩余区域分给workspace并指定合理的图标排布数量launcher就基本正常了。

再回到自己的Framelayout,因为想在自己的区域来根据不同情况显示不同的view,因此首先想到过Fragment,但是随后考虑再三决定不采用这个方法,因为Fragment的切换需要将调用Fragment显示的主Activity继承自FragmentAcitivity,显然我感觉对于一个简单的修改去改动Launcher.java的继承关系有点过于复杂,因此想了下用FrameLayout的方式就再简单不过了。于是在自己的LinearLayout中做了简单的测试,首先是要在launcher布局中加入这样的测试布局

           <LinearLayout
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:orientation="horizontal" >
              <FrameLayout android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:id="@+id/myframelayout"
                  >
                  <include android:id="@+id/view1" layout="@layout/mylayout1"></include>
                  <include android:id="@+id/view2" layout="@layout/mylayout2"></include>
              </FrameLayout>
           </LinearLayout>

加完这些,还需重新做另外两个简单的布局,因为仅仅是测试,所以仅需要每个layout中加一个TextView即可,能区分就够了。

然后是在Launcher中的操作

	LayoutInflater minflater;
	View myview1;
	View myview2;
	FrameLayout myframelayout;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		minflater = getLayoutInflater();
		myview1 = (View)minflater.inflate(R.layout.mylayout1, null);
		myview2 = (View)minflater.inflate(R.layout.mylayout2, null);
		myframelayout = (FrameLayout) findViewById(R.id.myframelayout);
........
}

此处给出了部分最终的代码,我之前说的view切换也就是这中嵌套的layout 的切换,我开始的做法是直接调用myview1.setVisibility(View.GONE)这种办法使其隐藏或者显示,但是我发现始终是无效的,可能如一个网友说的framelayout的特性就是分层叠加,后面的布局会逐层叠加上去,即使View.GONE了但是依然达不到显示另一个的效果。所以最后经过尝试还是采用了上述代码在需要显示其中一个view的时候,

myframelayout.removeAllViews();

myframelayout.addView(myview2);

这种方法的原理很简答就是每次需要重新显示一个view的时候先将framelayout中的所有嵌入view都清除,然后重新将索要显示的view显示出来。

后续如果需要监听嵌入layout布局中的按键响应,可以用类似myview2.findViewById(R.id.xxx)的方法找到相应id的按键去重写监听。

到此起码我最初想的是简单实现了,具体的效率和隐患因为时间关系暂时没测试,后续会继续测试和关注。

时间: 2024-09-29 14:05:22

Framelayout布局中嵌套多个布局layout的显示的相关文章

ScrollView中嵌套ListView时,listview高度显示的问题

方法一:直接更改listview的控件高度,动态获取(根据条目和每个条目的高度获取) 前几天因为项目的需要,要在一个ListView中放入另一个ListView,也即在一个ListView的每个ListItem中放入另外一个ListView.但刚开始的时候,会发现放入的小ListView会显示不完全,它的高度始终有问题.上网查了下,发现别人也有遇到这样的问题,而大多数人都不推荐这样的设计,因为默认情况下Android是禁止在ScrollView中放入另外的ScrollView的,它的高度是无法计

android布局中显示隐藏动画

android 在布局中提供属性,能简单的添加动画效果,如下: <LinearLayout ... animateLayoutChanges="true" ... /> 当对布局中的view添加删除,隐藏或显示, 都会有一个淡入淡出,和位移动画. 除了在XML布局文件中使用animateLayoutChanges 属性.也可以创建 LayoutTransition 对象通过 setLayoutTransition() 方法设置进去.源码如下: private ViewGro

解决ScrollView中嵌套Listview,Listview中嵌套Listview显示不完整和滑动冲突的问题

在一个滑动控件或者是布局里面,添加另外一个可以滑动的控件,通常会造成一些莫名其妙的问题.今天主要介绍在工作中遇到的,在ScrollView布局中嵌套Listview显示不正常,和在Listview中嵌套Listview的滑动冲突的问题. 1.ScrollView布局中嵌套Listview显示不正常的解决方案 目前来说,解决这个问题有好几种解决方案,这里只介绍其中两种比较简单易行的其中两种. (1)自定义一个Listview,继承自Listview,代码如下: public class ListV

Android 布局中的include标签使用

Android 布局中的include标签使用 最近在布局时,有好多页面都是有共同特点的,比如标题:一个同样的样式! 如下图所示: 如果给每个页面都单独的写一个标题的布局那就太麻烦了,如果能写一个标题布局,其它页面重用该多好! 这个时候,<include> 就隆重登场了! 写一个标题的布局 title.xml: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:an

android 布局中 gravity 和 layout_gravity 属性

gravity 这个英文单词是重心的意思,在这里就表示停靠位置的意思. android:gravity 和 android:layout_gravity 的区别: android:gravity 是设置该view里面的内容相对于该view的位置,例如设置button里面的text相对于view的靠左,居中等位置.(也可以在Layout布局属性中添加,设置Layout中组件的位置). android:layout_gravity 是用来设置该view相对与父view的位置,例如设置button在l

Android 中使用代码动态布局

Android 中使用代码动态布局 本文介绍在android中使用代码动态布局,有时候根据不同的需求,比如需要根据服务器上的条目个数来决定app中页面布局控件(显示个数,图标等).此处介绍通过java代码进行动态布局. 一.效果图: 图片随便找的,将就将就吧 二.给出xml文件布局 <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schema

【转】在Android布局中使用include和merge标签

内容转自:http://fengweipeng1208.blog.163.com/blog/static/21277318020138229754135/ 在我们开发android布局时,经常会有很多的布局是相同的,这个时候我们可以通过<include/>和<merge/>标签实现将复杂的布局包含在需要的布局中,减少重复代码的编写. 1. 创建一个可以重复使用的布局: 如下代码描述在应用中每个acitivity都出现的顶栏titlebar.xml 1 <FrameLayout

android 在布局中动态添加控件

第一步 Java代码 final LayoutInflater inflater = LayoutInflater.from(this); 第二步:获取需要被添加控件的布局 Java代码 final LinearLayout lin = (LinearLayout) findViewById(R.id.LinearLayout01); 第三步:获取需要添加的布局(控件) Java代码 LinearLayout layout = (LinearLayout) inflater.inflate( R

在界面布局中使用ShareActionProvider

Android在ICS版本中提供了一个 ShareActionProvider 用来创建分享菜单,并且会根据用户选择分享来源的频度自动调整菜单顺序.使用起来不错. 如果您的设计需要在界面上使用分享功能,而不是在ActionBar上,那么能否使用该分享控件呢?如下图所示: 在界面使用分享控件 下面来看看如何实现这个需求: ShareActionProvider 类有个函数 onCreateActionView, 这个函数会返回分享菜单的View,这个View是可以放到其他界面地方的.所以获取到该V