"Android 屏幕适配"-Android面试必问"精华技能点"汇总

来源:互联网 发布:淘宝怎么改评价 编辑:程序博客网 时间:2024/06/05 19:55

目录:

  • 屏幕适配的方式都有哪些
    • 1 方式之-dp
      • 11 名词解释
      • 12 res文件夹下的目录分类
      • 13 Android中的像素密度分辨率dp和px的关系
      • 14布局里的160dp和180dp的
    • 方式之-dimens尺寸
    • 方式之-layout
    • 方式之-代码适配
    • 方式之-weight权重
      • 多个相对的标准权重
      • 单个相对父布局的权重
      • 自动权重
  • 二屏幕适配的处理技巧都有哪些
    • 横竖屏的切换
    • 权重的反比例

1. 屏幕适配的方式都有哪些?

1.1 方式之-dp

1.1.1 名词解释:

  • 分辨率

    480*800,1280*720,表示像素点的总和

  • px(pix)-像素

    是屏幕里的最小单元

  • dpi-像素密度

    • 每英寸屏幕具有的像素数量,像素密度越大,细节越丰富
    • 公式:像素密度 = √{(长度像素数^2+宽度像素数^2)}/ 屏幕尺寸
    • 尺寸单位为:英寸;屏幕尺寸为:对角线长度(如下图)
      这里写图片描述

1.1.2 res文件夹下的目录分类

(如图)
这里写图片描述
应用查找图片的顺序:

先从自己开始(没有)->逐个就往高的找(没有)->就往比自己低的

1.1.3 Android中的像素密度/分辨率/dp和px的关系

类型 dip 分辨率 dp和px比例 ldip 120 240*320 1dp = 0.75px mdip(标准) 160 320*480 1dp = 1px hdip 240 480*800 1dp = 1.75px xhdip 320 720*1280 1dp = 2px xxhdip 480 1080*1920 1dp = 3px

比例图如下:
这里写图片描述

  • 由上面的标准mdip,那么如果在320*480的手机上,只需要dp就等效于px,因为1:1
  • 我们在代码运算过程中经常要做dp和px的互换,根据上面的比例特点.我们只需通过获取资源.获取屏幕分辨率.获取比例即可
/*       density   分辨率       dp和px的转换ldip    120     240*320     1dp = 0.75pxmdip    160     320*480     1dp = 1pxhdip    240     480*800     1dp = 1.5pxxhdip   320     720*1280    1dp = 2pxxxhdip  480     1080*1920   1dp = 3pxpx和dip的转换,只需获取比例值即可;得出dp和px参考标准的mhdip,额算出其他:pixels=dips*(density/160)如果是240*320的求得density肯定是1;1.获取比例值-自动根据当前的手机获取比例值(不同分辨率得到的不同,比如我的模拟器720*1280返回2)(PS:传入dp得px:乘以比例即可;传入px得dp:除以比例即可),写成工具类2.四舍五入*/public class DensityUtil {      /**      * 根据手机的分辨率从 dip 的单位 转成为 px(像素)      */      public static int dip2px(Context context, float dpValue) {         final float scale = context.getResources().getDisplayMetrics().density;            return (int) (dpValue * scale + 0.5f);      }      /**      * 根据手机的分辨率从 px(像素) 的单位 转成为 dp      */      public static int px2dip(Context context, float pxValue) {          final float scale = context.getResources().getDisplayMetrics().density;        return (int) (pxValue / scale + 0.5f);      }  }  

1.1.4布局里的160dp和180dp的

160dp:

  • 设置一个按钮的宽度为160dp,在320*480分辨率的机器里,那么正好是一半(因为1:1)
  • 在240*320的机器里,正好也显示一半,因为(1:0.75),160dp = 120px
  • 在480*800的机器里,也是一半,因为(1:1.5).160dp = 240px
  • 所以在以上三种分辨率下设置多少dp是等效的,归为一档.
    <Button        android:background="#ff0000"        android:layout_width="60dp"        android:layout_height="wrap_content"/>    <Button        android:background="#00ff00"        android:layout_width="100dp"        android:layout_height="wrap_content"/>

三种分辨率同样的代码都显示这样的效果:
这里写图片描述


180dp:

  • 如果将上面的160dp,放到720*1280或者1920 *1080,那么得到的效果和以上机器是不同的
  • 设置180dp宽度的按钮,在这两者里面的效果是一样的
  • 因为:720*1280(比例是:1:2)所以180dp = 360px,就是一半
  • 1920*1080(比例是:1:3)所以180dp = 540px,也是一半
  • 所以这两种分辨率下设置的dp是等效的,也是一档
    <Button        android:background="#ff0000"        android:layout_width="80dp"        android:layout_height="wrap_content"/>    <Button        android:background="#00ff00"        android:layout_width="100dp"        android:layout_height="wrap_content"/>

两种分辨率下都显示同样效果
这里写图片描述


2.方式之-dimens(尺寸)

  • (PS:根据上一节的160dp和180dp的讲解,我们现在通过自动dimens解决自动适配问题)
  • 1.在res目录下有默认的values文件夹和dimens.xml文件
  • 2.为了自动适配1280 *720和1920 *1080分辨率,我们分边创建各自的文件夹
    • values-1280x720(eclipase写法),Android Studio写成values-w320dp
      这里写图片描述
  • 3.把刚才的dimens.xml复制一份到目标文件夹

    • 默认的dimens.xml写成160dp,移到新文件的定义成180dp;
      这里写图片描述
  • 4.最后在布局文件中写单位大小时,用@dimens/width即可,自动根据屏幕灵活调用
    这里写图片描述
    (PS:因为有默认的和指定各种分辨率(另外写1920*1080的,虽然和720等效,但是还是要写,否则他就用默认的了)的文件夹,所以找不到指定的就用默认的)

3.方式之-layout

  • 原理和上述情况一样,些不同的layout,会根据分辨率自动找到合适的layout
    这里写图片描述

4.方式之-代码适配

  • 需求:通过代码设置,让一个TextView的宽和高都为屏幕的一半;
  • 初始:布局是默认的包裹,如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"                xmlns:tools="http://schemas.android.com/tools"                android:layout_width="match_parent"                android:layout_height="match_parent"                tools:context=".MainActivity">    <!-- 现在是默认的包裹 -->    <TextView        android:id="@+id/tv"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="#e18080"        android:text="hello_world"/></RelativeLayout>

这里写图片描述
* 步骤:
* 1.获取tv控件
* 2.获取当前机器的分辨率.
* 3.新建一个和跟布局一样(根是线性就线性,是关系就设置关系)的参数,构造传入长和宽(分辨率的一半)
* 4.再让tv控件设置参数即可.
*代码如下:

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //1.        TextView tv = (TextView) findViewById(R.id.tv);        //2.        int height = getWindowManager().getDefaultDisplay().getHeight();        int width = getWindowManager().getDefaultDisplay().getWidth();        //3.        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int) ((float)width/2+0.5), (int) ((float)height/2+0.5));        //4.        tv.setLayoutParams(params);    }}

效果:
这里写图片描述

5.方式之-weight权重

(PS:必须是线性布局)

1.多个相对的标准权重

  • 如果是横向:把高度设置为0dp

  • 如果是竖向:把宽度设置为0dp

  • 然后色字不同控件所占的权重

    <Button        android:layout_weight="1"        android:text="bt1"        android:layout_width="0dp"        android:layout_height="wrap_content"/>    <Button        android:text="bt2"        android:layout_weight="2"        android:layout_width="0dp"        android:layout_height="wrap_content"/> </LinearLayout>

效果:
这里写图片描述

2.单个相对父布局的权重

  • 1.设置父布局的总权重:SumWeight
  • 2.设置自己的所占的权重即可
<LinearLayout    android:weightSum="3"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="horizontal">    <Button        android:layout_weight="2"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:text="bt1"/></LinearLayout>

效果:
这里写图片描述

3.自动权重

  • 想让前面的完全填充,并且设置权重
  • 然后后面的用包裹即可
<LinearLayout    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="horizontal">    <EditText        android:text="请输入内容"        android:layout_weight="1"        android:layout_width="match_parent"        android:layout_height="wrap_content"/>    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="输出"/></LinearLayout>

效果如下:
这里写图片描述


二.屏幕适配的处理技巧都有哪些?

横竖屏的切换

(正常情况下,每次横竖屏切换都会导致Activity的重新创建)

  • 1.在活动销毁前保存活动状态(重写onSaveInstanceState方法),可以参考前面我们讲的思维(点击访问).
@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    //切换屏幕后获取信息    if (savedInstanceState != null) {        System.out.println(savedInstanceState.get("height")+"-------");        System.out.println(savedInstanceState.get("width")+"-------");    }}    //保存信息    @Override    protected void onSaveInstanceState(Bundle outState) {        outState.putInt("height", 100);        outState.putInt("width", 50);        super.onSaveInstanceState(outState);    }
  • 2.在清单文件把方向写死:

    • android:screenOrientation=”portrait”(landscape是横向,portrait是纵向)
  • 3.如果不想重新让Activity调用,就设置配置更改

    • 在清单文件设置三个参数:

      • 方向|按键隐藏|屏幕尺寸

        android:configChanges="orientation|keyboardHidden|screenSize"
    • 另外重写Activity里的更改方法

      • 如果切换横竖屏,之后重新调用这个方法
@Overridepublic void onConfigurationChanged(Configuration newConfig) {    super.onConfigurationChanged(newConfig);    if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {        //横向就干嘛 TODO    }     else if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){        //竖向就干嘛 TODO    }}

权重的反比例

经过改善一般我们都是设置0dp,然后使用权重,占多少就占用多少部分

如果反比例,比如按钮A权重是1,按钮B是2,那么就反过来了,代码和效果图如下.
就是不用0dp,而改用填充

        <Button            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="bt1"/>        <Button            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_weight="2"            android:text="bt2"/>    </LinearLayout>

这里写图片描述

0 0
原创粉丝点击