android5.1 FrameLayout源码浅析

5.4         FrameLayout

 

5.4.1         介绍

 

FrameLayout类的继承关系:

 

java.lang.Object

   ↳

android.view.View

 

   ↳

android.view.ViewGroup

 

 

   ↳

android.widget.FrameLayout

 

Known Direct Subclasses

AppWidgetHostView, BaseCardView, CalendarView, CardView, DatePicker, GestureOverlayView, HorizontalScrollView, MediaController, ScrollView, SearchOrbView, TabHost, TimePicker, ViewAnimator

AppWidgetHostView

Provides the glue to show AppWidget views. 

BaseCardView

A card style layout that responds to certain state changes. 

CalendarView

This class is a calendar widget for displaying and selecting dates. 

CardView

A FrameLayout with a rounded corner background and shadow. 

DatePicker

This class is a widget for selecting a date. 

GestureOverlayView

A transparent overlay for gesture input that can be placed on top of other widgets or contain other widgets. 

HorizontalScrollView

Layout container for a view hierarchy that can be scrolled by the user, allowing it to be larger than the physical display. 

MediaController

A view containing controls for a MediaPlayer. 

ScrollView

Layout container for a view hierarchy that can be scrolled by the user, allowing it to be larger than the physical display. 

SearchOrbView

A widget that draws a search affordance, represented by a round background and an icon. 

TabHost

Container for a tabbed window view. 

TimePicker

A view for selecting the time of day, in either 24 hour or AM/PM mode. 

ViewAnimator

Base class for a FrameLayout container that will perform animations when switching between its views. 

 

Known Indirect Subclasses

FragmentTabHost, ImageCardView, ImageSwitcher, SpeechOrbView, TextSwitcher, ViewFlipper, ViewSwitcher

 

FrameLayout类的属性分两种,自己特有的只有一个,另外是继承共用的,

 

特有的:

android:layout_gravity

Standard gravity constant that a child supplies to its parent. 

 

Defines how the child view should be positioned, on both the X and Y axes, within its enclosing layout.

Must be one or more (separated by '|') of the following constant values.

Constant

Value

Description

top

0x30

Push object to the top of its container, not changing its size.

bottom

0x50

Push object to the bottom of its container, not changing its size.

left

0x03

Push object to the left of its container, not changing its size.

right

0x05

Push object to the right of its container, not changing its size.

center_vertical

0x10

Place object in the vertical center of its container, not changing its size.

fill_vertical

0x70

Grow the vertical size of the object if needed so it completely fills its container.

center_horizontal

0x01

Place object in the horizontal center of its container, not changing its size.

fill_horizontal

0x07

Grow the horizontal size of the object if needed so it completely fills its container.

center

0x11

Place the object in the center of its container in both the vertical and horizontal axis, not changing its size.

fill

0x77

Grow the horizontal and vertical size of the object if needed so it completely fills its container.

clip_vertical

0x80

Additional option that can be set to have the top and/or bottom edges of the child clipped to its container's bounds. The clip will be based on the vertical gravity: a top gravity will clip the bottom edge, a bottom gravity will clip the top edge, and neither will clip both edges.

clip_horizontal

0x08

Additional option that can be set to have the left and/or right edges of the child clipped to its container's bounds. The clip will be based on the horizontal gravity: a left gravity will clip the right edge, a right gravity will clip the left edge, and neither will clip both edges.

start

0x00800003

Push object to the beginning of its container, not changing its size.

end

0x00800005

Push object to the end of its container, not changing its size.

 

 

继承的:

 

android:layout_height

Specifies the basic height of the view. 

android:layout_width

Specifies the basic width of the view. 

android:layout_marginBottom

setMargins(int,int,int,int)

Specifies extra space on the bottom side of this view. 

android:layout_marginEnd

setMarginEnd(int)

Specifies extra space on the end side of this view. 

android:layout_marginLeft

setMargins(int,int,int,int)

Specifies extra space on the left side of this view. 

android:layout_marginRight

setMargins(int,int,int,int)

Specifies extra space on the right side of this view. 

android:layout_marginStart

setMarginStart(int)

Specifies extra space on the start side of this view. 

android:layout_marginTop

setMargins(int,int,int,int)

Specifies extra space on the top side of this view

 

实际上,FrameLayout并非只有如上的属性可以设置,在事件中往往有如下设置:

      <FrameLayout

        android:id="@+id/MultiCallsFragmentContainer"

        android:layout_width="match_parent"

        android:layout_height="360dip"

        android:layout_below="@+id/call_title"

        android:elevation="@dimen/dialpad_elevation"

        android:visibility="gone">

 

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

    </FrameLayout>

    <FrameLayout

        android:id="@+id/progressSpinner"

        android:layout_below="@id/yl_primary_call_info_container"

        android:background="#63000000"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:layout_centerHorizontal="true"

        android:layout_centerVertical="true"

        android:visibility="gone">

 

可见它作为别的布局的子view,则可以使用其他相关的属性,另外还可以使用一些通用的属性。

 

 

5.4.2         绘制分析

FrameLayout继承自ViewGroup,属于view控件,因此也遵从view的绘制逻辑。

 

根据我们对view的理解,其绘制大体也是按measure—layout—draw的流程处理的。

 

 

5.4.2.1                            Measure过程

重载onMeasure,功能分3大部分:

遍历子view,完成每个子view的measure;

找到子view的最大尺寸,设置给FrameLayout,因为FrameLayout的说明里提到子view的最大尺寸就是FrameLayout的尺寸;

如果FrameLayout不是确定大小的模式,子view又是MATCH_PARENT属性的,则要单独为这些子view重新计算尺寸,重新measure。

 

从性能分析的角度看,单独重新measure MATCH_PARENT属性的view是耗时的,这个影响有多大,需要进行实验验证。如果对性能有一定影响,那么我们在设置FrameLayout属性和其子viewMATCH_PARENT属性时就要考虑是注重于性能,还是注重于布局的兼容性。

 

5.4.2.2                            Layout过程

这里重载了onLayout()方法,

其layout过程就是遍历所有子view的layout方法。

 

其执行流程是FrameLayout. onLayout--viewGroup.layout

--view.layout--FrameLayout的成员view.onLayout--…,这样就遍历完了FrameLayout节点下的整个view树。

 

在FrameLayout. onLayout里遍历每个成员view的时候,还根据gravity为成员view重新计算了坐标值。

 

从性能优化方面考虑,因为在代码里面gravity有默认值,所以FrameLayout的成员view是否设置gravity属性,并不影响其处理速度,同时,在onLayout里对gravity的处理并不是一个耗时流程。

 

 

5.4.2.3                            Draw过程

重载了draw方法,实现两个功能,第一是使用了父类的draw方法,绘制控件本身;第二是绘制Foreground,对于Foreground需要的时候再单独分析。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要自定义一个FrameLayout,需要继承FrameLayout类,并在子类中重写构造方法和一些必要的方法,例如onMeasure()方法、onLayout()方法等。 以下是一个简单的自定义FrameLayout的示例: ```java public class MyFrameLayout extends FrameLayout { public MyFrameLayout(Context context) { super(context); } public MyFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); } public MyFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 在这里可以对View的尺寸进行自定义 // 例如,设置View的宽高比为2:1 int width = MeasureSpec.getSize(widthMeasureSpec); int height = width / 2; int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, newHeightMeasureSpec); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); // 在这里可以对子View的位置进行自定义 // 例如,将第一个子View放置在左上角 View childView = getChildAt(0); childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight()); } } ``` 在上面的示例中,我们重写了onMeasure()方法,将View的高度设置为宽度的一半,并在onLayout()方法中将第一个子View放置在左上角。 可以在布局文件中使用自定义的MyFrameLayout,例如: ```xml <com.example.MyFrameLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/image" /> </com.example.MyFrameLayout> ``` 这样就可以在自定义的FrameLayout中放置子View,并对其尺寸和位置进行自定义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值