首页 > 系统 > Android > 正文

Android面试宝典总结 --第二章:Android布局

2019-11-09 18:35:59
字体:
来源:转载
供稿:网友

         本文对Android面试宝典的面试题目做一点总结和记录,希望对大家面试或简单复习有帮助。

一.Android中的布局

(一)请说出Android的六中布局,并简单介绍它的作用。

在Android中,共有六种布局方式,分别是:LinearLayout (线性布局),RelativeLayout(相对布局),FrameLayout(帧布局),AbsoluteLayout(绝对布局),TableLayout(表格布局),GridLayou(网格布局)。 1.线性布局LinearLayout,可以指定子控件的排列方式,比如垂直方向或水平方向。 2.绝对布局Relavitelayout,可以指定子控件的相对位置,比如上下左右、居中等,也可以指定一个控件相对另一个控件的相对位置。 3.帧布局FrameLayout,显示的View都是一层一层地往上加,显示的是最上面的一层。应用在动态显示碎片Fragment也是比较多的。上面三种布局相对来说应用是比较多的。下面的三种应用就少一点了。 4.绝对布局AbsoluteLayout,View的显示要定义具体的单位长度px。这个局限性比较多,不能匹配多种屏幕,基本已经不使用了。 5.表格布局TableLayout,是线性布局的子类,显示据一般是一行一行的,一行可以有多列,列与列对齐是很方便的。 6.表格布局GridLayout,作为android 4.0 后新增的一个布局,与前面介绍过的TableLayout(表格布局)其实有点大同小异;如果是显示类似网格效果的多个控件是非常方便的。

(二)http://schemas.android.com/apk/res/android” …>中的xmlns:android是什么意思?xmlns:android的值是可以任意的吗?请说明原因。

解析:考察的是XML命名空间与布局文件的关系,如果使用的自定义组件,是可以添加新的命名空间的,但是原来的命名空间是必须保留的。答案:xmlns:android是XML中的命名空间,为了防止属性冲突。类似于java中的package。xmlns:android的值是不允许任意设置的。xmlns:android的是必须是以“http://schemas.android.com/apk/res”开始,后面的部分表示定义属性R.java文件所在的包名。在R.java文件中包含了属性名的定义。例如,如果使用系统属性,需要指定系统R.java文件的位置。该文件位于res/android目录中,因此,xmlns:android值的最后是android。

二.Android布局使用的技巧

FrameLayout

(一)FrameLayout布局的主要用途?

答案:FrameLayout主要用于进行层次结构的布局。例如,想要把两个图像叠加在一起形成一张图像的效果就可以使用FrameLayout。这种叠加的方式很像photoshop的图层。 FrameLayout一般也是用来动态显示碎片页面。

(二)现在有三个按钮,如何让这三个按钮分别左对齐,居中对齐,右对齐?

解析:这个问题答案有很多种,使用六大布局中任意一种都是可以解决,但是有些很方便就实现,有些要复杂一点。答案一:使用FrameLayout结合gravity_layout可以很方便就实现这个功能。示例代码: <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="左边" android:layout_gravity="left" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="中间" android:layout_gravity="center_horizontal" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="右边" android:layout_gravity="right" /> </FrameLayout>答案二:使用RelativeLayout结合layout_alignParent可以很方便就实现这个功能。示例代码: <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="左边" android:layout_alignParentLeft="true" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="中间" android:layout_centerHorizontal="true" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="右边" android:layout_alignParentRight="true" /> </RelativeLayout>答案三:使用Linearlayout结合gravity_layout实现功能。这个实现现对来说会有点麻烦,因为水平方向线性布局对水平方向的对齐的不会有任何效果的,需要一个垂直方向的布局!示例代码: <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <LinearLayout android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="左边" android:layout_gravity="left" /> </LinearLayout> <LinearLayout android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="中间" android:layout_gravity="center_horizontal" /> </LinearLayout> <LinearLayout android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="右边" android:layout_gravity="right" /> </LinearLayout> </LinearLayout>

         上面相当于一个相性布局内有三个垂直方向的线性布局,每一个线性布局内,都有一个按钮控件。          这里使用表格布局或网格布局也是可以实现效果的,跟线性布局类似的繁琐,但是最麻烦的一个还是绝对布局,因为要用java代码测量布局大小后才能实现效果;

(三)FrameLayout中的View都是层叠摆放的。后一个View会覆盖掉前一个View的说法对吗?说明原因。

答案:不正确。FrameLayout中的View只有所有的View同样大小,并且在同一个位置时才会被覆盖,否则,View是以层叠的方式显示出来的,类似Photoshop中的图层,未被上一层View覆盖的部分会显示出来。

Linearlayout布局

(四)如何获得Linearlayout的宽度和高度?

解析: 考察View的属性方法的使用,这里不能直接使用View.getWidth或View.getHeight。 第一种:获取自定义的View布局的宽高,可以在onMeasure方法中获取 第二种:如果直接获取在布局中定义的组件的宽度和高度,当宽度和高度被设计为match_parent或wrap_content时,这两个变量会返回MATCH_PARENT、WRAP_CONTENT的常量。答案:由于LinearLayout是View的子类,因此可以直接使用View.getMeasuredWidth方法。View view=getLayoutInflater().inflate(R.layout.mian,null);LinearLayout linearlayout=View.findViewById(R.id.ll);//measure方法的参数值都设为0即可linearLayout.measure(0,0);//获取组件的宽度和高度int width=linearLayou.getMeasuredWidth();int height=linearLayout.getMeasureHeight();

(五)如何在LinrarLayout中添加分隔线?

答案:有两种方法添加,一种是添加一个View的横线,另一种是使用LinearLayout组件的属性。第一种方法的代码示例:<View android:layout_width=”match_parent”Android:;layout_height=”1dp” Android:background=”#000”/>第二种方法:设置LinrarLayout布局文件中的两个属性:1.Android:showDividers=“end”这个属性可以设置的只有四个:(1)none:不显示分隔线(2)beginning:分隔线显示在顶上(3)end:分隔线显示在末尾(4)middle:分隔线显示在两个子控件之间2.android:devider=“#000”这里需要的是一个DrawableID(图像资源或颜色资源)。RelativeLayout布局

(六)下图的布局如何实现(5个按钮成梅花状排列,并且整体水平居中显示)?

图: m1

代码实现:<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/btn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按鈕2" android:layout_centerInParent="true" /> <Button android:id="@+id/btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按鈕1" android:layout_toLeftOf="@id/btn2" android:layout_above="@id/btn2" /> <Button android:id="@+id/btn3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按鈕3" android:layout_toLeftOf="@id/btn2" android:layout_below="@id/btn2" /> <Button android:id="@+id/btn4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按鈕4" android:layout_toRightOf="@id/btn2" android:layout_above="@id/btn2" /> <Button android:id="@+id/btn5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按鈕5" android:layout_toRightOf="@id/btn2" android:layout_below="@id/btn2" /> </RelativeLayout>

         注意上面要灵活使用相对布局,如果只是水平居中显示,而不要整体居中,可以在外面嵌套一个FrameLayout,整个RelativeLayout的layout_gravity设置为center_horizontal,并且要设置为包裹内容的;

(七)在RelativeLayout中有一个Button(id:button),请确定该按钮相对于手机屏幕的位置坐标 。

答案:使用View.getLocationOnScreen方法可以获取当前View相对于屏幕的坐标,代码如下:View view=findViewById(R.id.button);//创建一个数组接收数据int[] locations=new int[2]; View.getLocationOnScreen(locations);//获取当前按钮的横坐标int x=locations[0];//获取当前按钮的纵坐标int y=locations[1];

(八)如何动态改变RelativeLayout中按钮的布局?

答案:首先获得按钮对象,然后使用LayoutParams.addRule方法设置相应的属性。例如:下面代码将按钮从左上角的位置动态设置到屏幕中心的位置。Button button=(Button)findViewById(R.id.button);//如果Button的外层是一个相对布局RelaviveLayout.LayoutParams layoutParams=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);//设置android:layout_centerInParent属性layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT,RekatuveLayout.RRUE);//修改按钮的android:layout_centerInParent属性值button.setLayoutParams(layoutParams);

TableLayout布局

(九)请描述一下TableLayout布局的用法?

答案:表格布局使用<TableLayout>来表示,在里面嵌套<TableRow>表示表格的一行,一行里面可以添加多个View表示行中的列,每行可以定义View的数量是可以不相等的,因此每行的列的数量是可以不相等的。示例代码: <TableLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TableRow> <Button android:text="第一行第一个列11" /> <Button android:text="第一行第二个列"/> </TableRow> <TableRow> <Button android:text="第二行第一个列" /> <Button android:text="第二行第二个列"/> </TableRow> <TableRow> <Button android:text="第三行第一个列" /> </TableRow> </TableLayout>

         显示的效果,第一列的长度是一样的,这个应用在登录界面设计,用户名和密码长度对齐效果比较好看一点。

(十)标签的StretchColumns属性的作用是什么? 如何使用StretchColumns属性?

答案:stretColumns属于用于要拉伸的列的索引(从0开始),如果指定多个列索引,中间用逗号(,)分隔。TableLayout会在设置完未通过stretchColumns指定的列宽后,使用stretchColumns指定的列填充剩余的宽度。如果stretchColumns指定了多列,这些列会平分剩余的宽度。stretchColumns属性的演示代码如下: <TableLayout android:stretchColumns="1" android:layout_width="match_parent" android:layout_height="match_parent"> <TableRow> <Button android:text="一行一列" /> <Button android:text="一行二列"/> </TableRow> <TableRow> <Button android:text="二行一列" /> <Button android:text="二行二列"/> </TableRow> <TableRow> <Button android:text="三行一列" /> </TableRow> </TableLayout>

布局存成图片

(十一)如何将当前界面的可视组件以同样的相对位置和大小保存成png图像文件中?写出实际代码。

解析:需要回答两部分内容:截取当前的组件和保存成png图像文件。首先要调用View.setDrawingCacheEnabled方法打开图像缓存,然后使用View.getDrawingCache方法获取View的Bitmap对象。保存成png图像使用Bitmap.comPRess方法即可。答案:将当前界面的可视组件以同样的相对位置和大小保存在png图像文件的代码如下:View view=getLayoutInflater().inflate(R.layout.main,null);//打开图像缓存view.setDrawingCacheEnabled(true);//必须要调用measure和layout方法才能成功保存可视组件的截图成png图像文件//测量View的大小View.measure(MeasureSpec.makeMeasureSpec(0,MeasureSpec.UMSPECIFIEN),MeasureSpec.makeMeasureSpec(0,MeasureSpec.UMSPECIFIEN));//发送位置和尺寸到View及其所有的子ViewView.layout(0,0,view.getMeasuredWidth(),view.getMeasuredHeight());try{//获取可视组件的截图Bitmap bitmap=view.getDrawingCache();//将截图保存在SD卡根目录的test.png图像文件中FileOutputStream fos=new FiledOutPutStream(“/sdcard/test.png”);//将Bitmap对象中的图像数据压缩成png格式的图像数据,并将这些数据保存在test.png文件中Bitmap.compress(CompressFormat.PNG,100,fos);//关闭文件输出流Fos.close();}catch(Exception e){}

设置渐变背景色(我也没见过,没用过,知道有就好)

(十二)如何将Android应用程序窗口的背景色设成渐变颜色?

解析:GradientDrawable类的用法。虽然可以使用渐变的图像来渲染窗口背景,但是更适合的是使用GradientDrawable类,因为灵活,可以随时变换背景的渐变颜色。答案:使用GradientDrawable类可以设置窗口的背景颜色(也可以同样的方法设置Button、TextView等组件的渐变背景颜色),代码如下://设置从上到下的渐变颜色,上边是红色,下边是黄色GradientDrawable gradientDrawable=new GradientDrawable(Orientation.TOP_BOTTOM,new int[]{Color.RED,Color.YELLOW});//设置当前窗口的渐变背景颜色getWindow().setBackgroundDrawable(gradientDrawable);

三.布局的属性

(一)android:;layout_weight属性的作用是什么?请举例说明。

答案:layout_weight属性表示组件的权重。用于设置占总体比重的多少。比如水平方向线性布局,有两个按钮,设置width=0,第一个按钮的weight=1,第二个按钮的weight=2,那么水平方向的这两个按钮,第一个按钮的宽度占的三分之一,第二个按钮占三分之二。

(二)请根据下图由Button和EditText组成的界面写出布局代码。

m2

解析:图中的布局由上中下三部分组成,外层既可以使用相对布局,也可以使用线性布局结合weight完成,而上面部分的实现必须要使用线性布局结合weight。答案:布局设计的代码如下(这里全部使用线性布局完成):<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="1/4" /> <Button android:layout_weight="2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="2/4" /> <Button android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="1/4" /> </LinearLayout> <EditText android:layout_weight="1" android:layout_width="match_parent" android:layout_height="0dp" android:text="EditText(充滿上方和下方按鈕之间的整个屏幕)" android:gravity="center" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="按钮" /> </LinearLayout>

(三)如何在EditText中显示提示文本,在显示文本后面可以输入文本?效果如下图:

s1

解析:在EditText内部显示提示文本(这部分被锁,不可删除和修改,文本在后面输入),一般可以通过android:drawableLeft属性来实现,但是这个方法不灵活,如果左边的文字改变,就需要替换图片。还用另一种方法就是自定义控件来实现,实现EditText。答案:可以直接在EditText中绘制提示文本。首先编写一个类继承自EditText,并覆盖onDraw方法,并在该方法中绘制提示文本,代码如下:@voerrideProtected void onDraw(Canvas canvas){Paint paint=new Paint();paint.setTextSize(18);paint.setColor(Color.GRAY);//绘制提示文本canvas.drawText(“输入提示文本”,2,getHeight()/2+5,paint);super.onDraw(canvas);} 绘制完提示文本后,需要在提示文本后面输入文本,这需要使用android:paddingLeft属性根据提示文本的宽度 设置开始输入文本的位置,例如android:paddingLeft=”100dp”,表示从左侧100个dp开始输入文本。

(四)如何重用布局文件?

答案:可以使用<include>标签引用其他的布局文件,并用android:id属性覆盖被应用布局文件中顶层的android:id属性值。代码如下:<!-- 引用mylayout.xml文件 --><include android:id=”@+id/layout” layout=”@layout/mylayout”>

(五)你觉得直接在布局文件的顶层节点使用好不好,有没有使用其他节点取代FrameLayout?

解析:本题考察布局文件的优化。

答案:无论布局文件的根节点是什么,系统都会在上一层生成一个<FrameLayout>标签,因此,在布局文件的根节点使用FrameLayout是多余的。但是xml文件又不能没有根节点,因此可以使用<merge>代替<FrameLayout>,系统在编译xml布局文件时不会为了merge生成任何节点,相当于一个xml文件的节点占位符。Merge的意思实际上也是合并两个FrameLayout,所以使用merge代替根节点FrameLayout,可以大大减少FrameLayout标签的生成。

(六)为了研究修改布局的实现,如何查看apk文件中的布局文件源码

解析:这题不是考察技术,而是考查是否会去研究别人写的代码,优秀的布局文件的实现,看你会不会反编译!答案:由于apk文件中的xml布局文件是经过编译处理的,所以无法直接阅读。因此要经过反编译工具处理后再阅读这些文件。

上面可能对于Android命名空间的使用还是不太清楚,这里有一个程序的示例演示。 Android命名空间总结:http://blog.csdn.net/wenzhi20102321/article/details/54849679


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表