Android 面试题总结之Android 基础(六)

在上一章节Android 面试题总结之Android 基础ListView(五) 主要是ListView的优化,原理以及一些基本问题。

在阅读过程中有任何问题,请及时联系。如需转载请注明 fuchenxuan de Blog 
本章系《Android 之美 从0到1 – 高手之路》Android基础将会总结了Android 布局常见面试问题。其实对于基础方面Android 开发来说,经常面试无非就是UI,网络,数据库,这三大方面,本章节总结了笔记经典的问题,希望对广大Android 开发者,有所帮助。

布局面试问题

  1. Android 中常用的布局都有哪些? 
    • FrameLayout
    • RelativeLayout
    • LinearLayout
    • AbsoluteLayout
    • TableLayout
    • GrideLayout(Android 4.0 推出)
  2. 谈谈 UI 中, Padding 和 Margin 有什么区别?

    android:padding 和 android:layout_margin 的区别,其实概念很简单,padding 是站在父 view 的角度描述问 题,它规定它里面的内容必须与这个父 view 边界的距离。margin 则是站在自己的角度描述问题,规定自己和其他(上下左右)的 view 之间的距离,如果同一级只有一个 view,那么它的效果基本上就和 padding 一样了。

  3. 使用权重如何让一个控件的宽度为父控件的 1/3? 
    可以在水平方向的 LinearLayout 中设置 weightSum 为 3,然后让其子控件的 weight 为 1,那么该子控件就是 父控件的 1/3。
  4. Android 中布局的优化措施都有哪些? 
    这个问题也属于Android 性能优化的一部分。 
    1、尽可能减少布局的嵌套层级 
    可以使用 sdk 提供的 hierarchyviewer 工具分析视图树,帮助我们发现没有用到的布局。 
    2、不用设置不必要的背景,避免过度绘制 比如父控件设置了背景色,子控件完全将父控件给覆盖的情况下,那么父控件就没有必要设置背景。 
    3、使用<include>标签复用相同的布局代码 
    4、使用<merge>标签减少视图层次结构 
    该标签主要有两种用法: 
    1) 因为所有的 Activity 视图的根节点都是 FrameLayout,因此如果我们的自定义的布局也是 FragmenLayout 的时候那么可以使用 merge 替换。 
    2) 当应用 Include 或者 ViewStub 标签从外部导入 xml 结构时,可以将被导入的 xml 用 merge 作为根节 点表示,这样当被嵌入父级结构中后可以很好的将它所包含的子集融合到父级结构中,而不会出现冗余的节点。 
    <merge>只能作为 xml 布局的根元素。 
    5、通过<ViewStub>实现 View 的延迟加载
  5. android:layout_gravity 和 android:gravity 的区别? 
    第一个是让该布局在其父控件中的布局方式,第二个是该布局布置其字对象的布局方式。

  6. 关于LinearLayout 的权重算法?

        <LinearLayout
        android:layout_width="210dp"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    
        <Button
            android:layout_width="30dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:text="button1" />
    
        <Button
            android:layout_width="30dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:text="button2" />
    
        <Button
            android:layout_width="30dp"
            android:layout_height="40dp"
            android:layout_weight="2"
            android:text="button3" />
         </LinearLayout>
       
       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    如上代码,如何计算出每一个Button的宽度?

    布局大小=剩余空间大小权重所占比例+设定的宽度

    这里写图片描述

  7. scrollView 嵌套 listview 方式除了测量还有什么方法?

    1. 手动设置 ListView 高度 
      经过测试发现,在 xml 中直接指定 ListView 的高度,是可以解决这个问题的,但是 ListView 中的数据是可变的,实际高度还需要实际测量。 
      于是手动代码设置 ListView 高度的方法就诞生了。
    2. 使用单个 ListView 取代 ScrollView 中所有内容 
      如果满足头布局和脚布局的 UI 设计,直接使用 listview 替代 scrollview
    3. 使用 LinearLayout 取代 ListView 
      既然 ListView 不能适应 ScrollView,那就换一个可以适应 ScrollView 的控件,干嘛非要吊死在 ListView 这一棵树上呢? 
      而 LinearLayout 是最好的选择。但如果我仍想继续使用已经定义好的 Adater 呢?我们只需要自定 义一个类继承自 LinearLayout,为其加上对 BaseAdapter 的适配。
    4. 自定义可适应 ScrollView 的 ListView 
      这个方法和上面的方法是异曲同工,方法 3 是自定义了 LinearLayout 以取代 ListView 的功能,但如果 我脾气就是倔,就是要用 ListView 怎么办? 
      那就只好自定义一个类继承自 ListView,通过重写其 onMeasure 方法,达到对 ScrollView 适配的效果。
  8. dp 和 px 之间的关系? 
    dp:是 dip 的简写,指密度无关的像素。 指一个抽象意义上的像素,程序用它来定义界面元素。一个与密度无关的,在逻辑尺寸上,与一个位于像素密度为 160dpi 的屏幕上的像素是一致的。 要把密度无关像素转换为屏幕像素,可以用这样一个简单的公式: pixels=dips*(density/160)。举个例子,在 DPI 为 240 的屏幕上,1 个 DIP 等 于 1.5 个物理像素。 
    布局时最好使用 dp 来定义我们程序的界面,因为这样可以保证我们的 UI 在各种分辨率的屏幕上都可以正常显示。

    /**
    * 根据手机的分辨率从 px(像素) 的单位 转成为 dp */
    public static int px2dip(Context context, float pxValue) {
    final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f);
    }
    /**
    * 根据手机的分辨率从 dip 的单位 转成为 px(像素) */
    public static int dip2px(Context context, float dpValue) {
    final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f);
    }
       
       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    于是乎,应该也能理解android项目中的图片资源文件,一般我们需要在以下几个文件夹中提供不同大小的图片。

    • xhdpi: 2.0
    • hdpi: 1.5
    • mdpi: 1.0 (baseline)
    • ldpi: 0.75 
      如果一张放在mdpi 的图片加载到内存中大小是 10m ,那么遇到hdpi的设备图片加载到内存中大小是15m。
  9. 什么是屏幕尺寸、屏幕分辨率、屏幕像素密度? 
    屏幕尺寸是指屏幕对角线的长度。单位是英寸,1英寸=2.54厘米 
    屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1像素点,一般是纵向像素横向像素,如1280×720 
    屏幕像素密度是指每英寸上的像素点数,单位是dpi,即“dot per inch”的缩写,像素密度和屏幕尺寸和屏幕分辨率有关。

  10. Android 样式和主题? 
    样式(Styles): 
    Android 允许在外部样式文件中定义 Android 应用程序的 Look 和 Feel ,你可以将定义好的样式应用在不同的视图(Views)上。你可以在 XML 文件中定义样式,并将这些样式运用到不同的组件上。使用XML这种方式定义样式,你只需要配置一些通用的属性,以后如果需要修改样式,可以集中修改。 
    属性(Attributes): 
    你也可以将单个属性应用到 Android 样式上,通常会在自定义View 的时候,自定义属性。 
    主题(Themes): 
    主题相比单个视图而言,是应用到整个 Activity 或者 application 的样式

  11. 如何将Acitivity中的Window的背景图设置为空? 
    getWindow().setBackgroundDrawable(null);android的默认背景是不是为空。

布局适配

在明白上面基础问题的一些基本概念后,这里总结了一些布局适配的经验。 
在Android 中 有4种普遍尺寸:小(small),普通(normal),大(large),超大(xlarge) 
常见的普遍分辨率: 低精度(ldpi), 中精度(mdpi), 高精度(hdpi), 超高精度(xhdpi) 1080P(xxhdpi)

  • 基本设置 
    在中Menifest中添加子元素 
    android:anyDensity=”true”时,应用程序安装在不同密度的终端上时,程序会分别加载xxhdpi、xhdpi、hdpi、mdpi、ldpi文件夹中的资源。 
    相反,如果设为false,即使在文件夹下拥有相同资源,应用不会自动地去相应文件夹下寻找资源

  • 适配方案:

    1. 使用wrap_content、math_parent、weight wrap_content: 
      根据控件的内容设置控件的尺寸 math_parent:根据父控件的尺寸大小设置控件的尺寸 weight:权重,在线性布局中可以使用weight属性设置控件所占的比例
    2. 使用相对布局,禁用绝对布局

    3. 创建不同的layout:每一种layout需要保存在相应的资源目录中,目录以-为后缀命名。例如,对大尺寸屏幕(large screens),一个唯一的layout文件应该保存在res/layout-large/中。

    4. 使用9-patch PNG图片:当我们需要使图片在拉伸后还能保持一定的显示效果,比如,不能使图片中的重要像素拉伸,不能使内容区域受到拉伸的影响,我们就可以使用.9.png图来实现

Android Drawable

Drawable属于轻量级的、使用也很简单,Android把可绘制的对象抽象为Drawable,不同的图形图像资源就代表着不同的drawable类型, 在实际的开发过程中使用@drawable来使用drawable资源。关于Drawable更多的请看下图

这里写图片描述

Android 5.0 新特性–使用SVG图片资源 
SVG的全称是Scalable Vector Graphics,叫可缩放矢量图形。它和位图(Bitmap)相对,SVG不会像位图一样因为缩放而让图片质量下降。 
优点: 
* 图片的完美适配。SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失。这样我们大大减少了适配所需要的多种分辨率图片,而且能够让图片完美适配多种分辨率,减少了APK包大小并提升了用户体验。 
* 尺寸的减小。SVG 是使用XML文件描述的,这种文本格式的图片尺寸很小,而且便于修改。 
* 设计上的轻便。在设计方面我们可以任意修改SVG图片的颜色,这对于某些情况下需要同一张图像但不同的颜色图片是非常方便的,只需要修改fill颜色就可以了。比如,单击下图片的不同状态、按钮的背景图片等等。 
这里写图片描述

View 初步了解

  1. View是什么? 
    简单来说,View是Android系统在屏幕上的视觉呈现,也就是说你在手机屏幕上看到的东西都是View。

  2. View是如何绘制出来的? 
    View的绘制流程是从ViewRoot的performTraversals()方法开始,依次经过measure(),layout()和draw()三个过程才最终将一个View绘制出来。 
    后面的章节会详细讲View 绘制过程,这里只是基础略带一下。

  3. View是怎么呈现在界面上的? 
    Android中的视图都是通过Window来呈现的,不管Activity、Dialog还是Toast它们都有一个Window,然后通过WindowManager来管理View。Window和顶级View——DecorView的通信是依赖ViewRoot完成的。

  4. 关于Android View控件的理解 
    Android中控件大致被分为两类ViewGroup,View。ViewGroup作为容器管理View。Android视图,是类似于Dom树的架构。父视图负责测量定位绘制等操作。我们经常在用的findViewById 方法代价昂贵的原因,就是因为他负责至上而下遍历整棵控件树,来寻找View实例,在重复操作中尽量少用。现在在用的很多控件都是直接或者间接继承自View的,为了方便理解可看下图

    这里写图片描述

  5. View和ViewGroup什么区别? 
    Android的UI界面都是由View和ViewGroup及其派生类组合而成的。其中,View是所有UI组件的基类,而ViewGroup是容纳这些组件的容器,其本身也是从View派生出来的。AndroidUI界面的一般结构可参见

    这里写图片描述

    需要注意的是嵌套次数最好不要超过10层,否则会降低效率,上图是3层

  6. Android View刷新机制? 
    在Android的布局体系中,父View负责刷新、布局显示子View;而当子View需要刷新时,则是通知父View来完成

  7. RelativeLayout和LinearLayout性能比较? 
    1.RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,也会调用子View2次onMeasure 
    2.RelativeLayout的子View如果高度和RelativeLayout不同,则会引发效率问题,当子View很复杂时,这个问题会更加严重。如果可以,尽量使用padding代替margin。 
    3.在不影响层级深度的情况下,使用LinearLayout和FrameLayout而不是RelativeLayout。

  8. Android UI界面架构理解 
    每个Activity,Dialog,Toast都包含一个PhoneWindow对象,PhoneWindow设置DecorView为应用窗口的根视图。在里面就是熟悉的TitleView和ContentView,没错,平时使用的setContentView()就是设置的ContentView。 
    这里写图片描述

    关于View的内容还是比较多的,而本文只是作为Android基础的知识点作为初步了解,后面会有专门的章节来讲解关于View的更多知识点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值