Android 屏幕适配全攻略(中)-从九宫格到矢量图,揭秘Android多屏幕适配的正确打开方式

本文主要是介绍Android 屏幕适配全攻略(中)-从九宫格到矢量图,揭秘Android多屏幕适配的正确打开方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


在移动互联网时代,无论是小小的手机屏幕,还是大大的平板显示器,Android 应用都必须做到完美适配,给用户以极佳的体验。本文将剖析 Android 多屏幕适配背后的种种技术细节,为您揭开最佳实践的正确打开方式,让您的应用在任何设备上都能呈现出最专业、最优雅的一面。


一、Android 布局适配


布局适配主要包括以下几个方面:

  1. 使用合理的布局方式
    • 选择合适的布局容器,如 LinearLayoutRelativeLayoutConstraintLayout 等。
    • 合理地使用 wrap_contentmatch_parent 等属性来根据内容自适应布局大小。
    • 适当使用 weight 属性来实现动态布局。
  2. 使用多尺寸资源
    • res/layout-* 目录下提供不同屏幕尺寸的布局文件。
    • res/values-* 目录下提供不同屏幕尺寸的尺寸资源。
    • res/drawable-* 目录下提供不同屏幕尺寸的图片资源。
  3. 动态适配布局
    • 在代码中动态获取屏幕尺寸和密度信息。
    • 根据获取的信息动态调整 UI 元素的大小和位置。
  4. 适配不同屏幕方向
    • res/layout-land 目录下提供横屏布局文件。
    • 在代码中监听屏幕方向变化,动态切换布局。

下面示例,演示如何在 Java 代码中动态适配布局:

public class MainActivity extends AppCompatActivity {private TextView textView;private FrameLayout.LayoutParams layoutParams;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView = findViewById(R.id.text_view);layoutParams = (FrameLayout.LayoutParams) textView.getLayoutParams();// 获取屏幕尺寸和密度信息DisplayMetrics displayMetrics = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);int screenWidth = displayMetrics.widthPixels;int screenHeight = displayMetrics.heightPixels;float density = displayMetrics.density;// 根据屏幕尺寸和密度动态调整 TextView 的大小和位置int textViewWidth = (int) (200 * density);int textViewHeight = (int) (100 * density);layoutParams.width = textViewWidth;layoutParams.height = textViewHeight;layoutParams.gravity = Gravity.CENTER;textView.setLayoutParams(layoutParams);}
}

在这个示例中,我们首先获取了当前设备的屏幕尺寸和密度信息。然后,根据这些信息动态地调整了 TextView 的大小和位置,确保它在不同设备上显示的效果一致。


二、使用限定符资源,轻松匹配不同屏幕尺寸


1、什么是限定符资源?

  • 限定符资源是 Android 用于支持多种设备屏幕尺寸和密度的一种机制。

  • 开发者可以在应用的资源目录下创建多个不同的资源文件夹,每个文件夹都包含了针对特定设备特征的资源文件。

  • 当应用运行在某台设备上时,Android 系统会根据该设备的特征,自动选择最匹配的资源文件夹,并加载相应的资源。


2、常见的限定符

  • 屏幕尺寸: small, normal, large, xlarge

  • 屏幕密度: ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi

  • 屏幕方向: port (portrait), land (landscape)

  • 语言和地区: en, fr, zh-rCN, zh-rTW 等

  • Android 版本: v21, v23, v26 等


3、如何使用限定符资源


(1)、在应用的res目录下,创建不同的资源文件夹,并在文件夹名称中添加相应的限定符:

  • res/layout/:默认布局文件

  • res/layout-large/:针对大屏幕设备的布局文件

  • res/layout-land/:针对横屏设备的布局文件

  • res/drawable-hdpi/:针对高密度设备的图片资源

  • res/values-zh-rCN/:针对中国大陆地区的字符串资源


(2)、在代码中,直接引用这些资源文件即可

Android 系统会根据设备特征自动选择合适的资源文件。

  • 假设我们有以下几个资源文件:

    • res/layout/activity_main.xml
    • res/layout-large/activity_main.xml
    • res/layout-land/activity_main.xml
    • res/drawable-hdpi/my_image.png

  • 在 Java 代码中,我们可以这样使用这些资源:

    // 加载布局文件
    setContentView(R.layout.activity_main);// 获取图片资源
    ImageView imageView = findViewById(R.id.my_image);
    imageView.setImageResource(R.drawable.my_image);// 获取字符串资源
    String myString = getString(R.string.my_string);
    

  • 当应用运行在不同的设备上时,Android 系统会自动选择最合适的资源文件进行加载。例如:

    • 在小屏幕设备上,使用 res/layout/activity_main.xml
    • 在大屏幕设备上,使用 res/layout-large/activity_main.xml
    • 在横屏设备上,使用 res/layout-land/activity_main.xml
    • 在高密度设备上,使用 res/drawable-hdpi/my_image.png

二、九宫格图片适配


除了布局适配,图片资源的适配同样很关键。我们可以为不同分辨率提供对应分辨率的图片:

res/drawable-mdpi/image.png
res/drawable-hdpi/image.png 
...

不过这种做法会使 APK 体积变大。从 Android 4.0 开始,就可以使用九宫格图片 (.9.png) 来渲染可拉伸的资源。


1、什么是九宫格图片资源?

九宫格图片资源(Nine-Patch Images)是一种特殊的图片格式,它可以根据图片的内容自动拉伸或缩放,而不会造成图片失真或模糊。它通常用于实现可伸缩的 UI 元素,如按钮、对话框等。


九宫格图片由以下9个区域组成:

  • 四个角落区域(不可拉伸)

  • 上下中间区域(只能水平拉伸)

  • 左右中间区域(只能垂直拉伸)

  • 中间区域(可以水平和垂直拉伸)


在这里插入图片描述


2、如何使用九宫格图片资源?


(1)、创建九宫格图片

  • 在 Android Studio 的 drawable 文件夹中创建一个以 .9.png 结尾的文件,表示这是一个九宫格图片。
  • 使用图像编辑工具(如 GIMP、Photoshop 等)绘制图像,并在图像的左侧和上侧添加黑色像素边框。这些额外的边框将定义图像的可拉伸区域。

(2)、在布局中使用九宫格图片

  • 在 XML 布局文件中,将九宫格图片资源设置为 View 的背景:

    <Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/my_nine_patch" />
    

(3)、在代码中使用九宫格图片

  • 可以使用NinePatchDrawable类动态创建和应用九宫格图片:

    // 从资源文件中获取九宫格图片
    NinePatchDrawable drawable = (NinePatchDrawable) ContextCompat.getDrawable(context, R.drawable.my_nine_patch);// 设置九宫格图片为 View 的背景
    view.setBackground(drawable);
    

下面示例,演示如何使用九宫格图片资源:

import android.content.Context;
import android.graphics.drawable.NinePatchDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;public class NinePatchExampleActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_nine_patch_example);// 获取 LinearLayoutLinearLayout container = findViewById(R.id.container);// 创建 3 个 Buttonfor (int i = 0; i < 3; i++) {Button button = createButton(this);container.addView(button);}}private Button createButton(Context context) {// 创建 ButtonButton button = new Button(context);button.setText("Nine-Patch Button");// 获取九宫格图片资源NinePatchDrawable drawable = (NinePatchDrawable) ContextCompat.getDrawable(context, R.drawable.my_nine_patch);// 设置九宫格图片为 Button 的背景button.setBackground(drawable);// 设置 Button 的宽度和高度LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);button.setLayoutParams(params);return button;}
}

在这个示例中,我们创建了一个 NinePatchExampleActivity。在 onCreate() 方法中,我们获取 LinearLayout 容器,并动态创建了 3 个 Button


createButton() 方法中,我们首先创建一个 Button 对象,并设置它的文本为"Nine-Patch Button"。然后,我们使用 ContextCompat.getDrawable() 获取九宫格图片资源,并使用 NinePatchDrawable 类将其设置为 Button 的背景。最后,我们设置 Button 的宽度和高度,并返回 Button 对象。


当你运行这个程序时,你会看到 3 个使用九宫格图片资源作为背景的 Button。无论 Button 的大小如何变化,它们的外观都不会失真。

通过这个示例,相信你已经掌握了如何在 Android 开发中使用九宫格图片资源进行适配的基本方法。这种技术可以帮助你创建出更加美观、适配性强的 UI 元素。


随后 Android 5.0 又推出了矢量图形式,可自动缩放且不失真,这成为图片适配的最佳选择。


四、矢量图形式适配


1、为什么要使用矢量图?


在 Android 开发中,我们通常会使用位图图像(如 PNG、JPEG 等)来作为应用程序的图标和UI元素。但是,这种方式存在一些问题:


  • 图像质量下降

    当位图图像在不同分辨率的设备上显示时,可能会出现图像质量下降的问题。这是因为位图图像是由固定大小的像素组成的,在进行缩放时会导致失真。


  • 文件体积增大

    为了适配不同分辨率的设备,开发者通常需要准备多套不同尺寸的图像资源,这会大大增加应用程序的安装包体积。


为了解决这些问题,Android 提供了矢量图形式(Vector Drawable)作为一种新的图像资源格式。矢量图使用可缩放的数学公式来描述图形,能够在任何分辨率下保持优质的图像质量,同时文件体积也相对较小。


2、如何使用矢量图进行屏幕适配?


(1)、创建矢量图资源

  • 您可以使用 Android Studio 自带的 Vector Asset Studio 工具来创建矢量图资源。

  • 也可以使用其他矢量图编辑工具(如 Adobe Illustrator、Sketch 等)来创建 SVG 格式的矢量图,然后导入到 Android Studio 项目中。


(2)、在布局中使用矢量图

  • 在 XML 布局文件中,使用 <vector> 标签来引用矢量图资源:

    <ImageViewandroid:layout_width="48dp"android:layout_height="48dp"android:src="@drawable/my_vector_icon" />
    

(3)、在代码中使用矢量图

  • 在 Java 代码中,可以使用 VectorDrawableCompat 类来加载和使用矢量图资源:

    Drawable vectorDrawable = VectorDrawableCompat.create(getResources(), R.drawable.my_vector_icon, null);
    imageView.setImageDrawable(vectorDrawable);
    

(4)、适配不同屏幕密度

  • 矢量图本身是可缩放的,因此不需要为不同屏幕密度准备多套图像资源。

  • 但是,仍然需要为不同的屏幕密度提供合适的图标尺寸,以确保在各种设备上都能够正常显示。

  • 可以使用 VectorDrawableCompat.create 方法,并传入 DisplayMetrics 对象来动态调整图标大小

    DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
    float density = displayMetrics.density;
    Drawable vectorDrawable = VectorDrawableCompat.create(getResources(), R.drawable.my_vector_icon, null);
    vectorDrawable.setBounds(0, 0, (int)(48 * density), (int)(48 * density));
    imageView.setImageDrawable(vectorDrawable);
    

(5)、使用矢量图进行屏幕适配完整案例

下面是一个完整的 Java 代码示例,演示如何在 Android 中使用矢量图进行屏幕适配:

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.widget.ImageView;import androidx.appcompat.app.AppCompatActivity;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;public class VectorDrawableActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_vector_drawable);ImageView imageView = findViewById(R.id.image_view);loadVectorDrawable(this, imageView, R.drawable.my_vector_icon, 48);}private void loadVectorDrawable(Context context, ImageView imageView, int vectorDrawableId, int desiredSizeDp) {DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();float density = displayMetrics.density;int desiredSizePx = (int) (desiredSizeDp * density);Drawable vectorDrawable = VectorDrawableCompat.create(context.getResources(), vectorDrawableId, null);vectorDrawable.setBounds(0, 0, desiredSizePx, desiredSizePx);imageView.setImageDrawable(vectorDrawable);}
}

在这个示例中,我们首先在 onCreate() 方法中加载了一个矢量图资源并将其设置到 ImageView 上。

然后,我们定义了一个 loadVectorDrawable() 方法,它接受四个参数:

  • context: 上下文对象

  • imageView: 要设置矢量图的 `ImageView``

  • ``vectorDrawableId`: 矢量图资源的 ID

  • desiredSizeDp: 期望的图标尺寸(以 dp 为单位)


在方法内部,我们首先获取设备的屏幕密度,并根据期望的尺寸计算出实际的像素尺寸。然后,我们使用 VectorDrawableCompat.create() 方法加载矢量图资源,并设置其大小,最后将其设置到 ImageView 上。


通过这种方式,我们可以在不同的屏幕密度下都能正确、清晰地显示矢量图,同时也大大减少了应用程序的安装包体积。

结语:

总之,随着各种全面屏、异形屏和可折叠屏的出现,Android 屏幕适配也变得越发重要和复杂。相信通过本文的详尽指导,您已经掌握了多屏幕适配的方方面面。不过在实际应用中屏幕适配永无止境, 还可能会遇到哪些其他问题和挑战呢?就让我们拭目以待,继续在这方面的实战中去探索和总结吧!


这篇关于Android 屏幕适配全攻略(中)-从九宫格到矢量图,揭秘Android多屏幕适配的正确打开方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/977977

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

揭秘世界上那些同时横跨两大洲的国家

我们在《世界人口过亿的一级行政区分布》盘点全球是那些人口过亿的一级行政区。 现在我们介绍五个横跨两州的国家,并整理七大洲和这些国家的KML矢量数据分析分享给大家,如果你需要这些数据,请在文末查看领取方式。 世界上横跨两大洲的国家 地球被分为七个大洲分别是亚洲、欧洲、北美洲、南美洲、非洲、大洋洲和南极洲。 七大洲示意图 其中,南极洲是无人居住的大陆,而其他六个大洲则孕育了众多国家和

三国地理揭秘:为何北伐之路如此艰难,为何诸葛亮无法攻克陇右小城?

俗话说:天时不如地利,不是随便说说,诸葛亮六出祁山,连关中陇右的几座小城都攻不下来,行军山高路险,无法携带和建造攻城器械,是最难的,所以在汉中,无论从哪一方进攻,防守方都是一夫当关,万夫莫开;再加上千里运粮,根本不需要打,司马懿只需要坚守城池拼消耗就能不战而屈人之兵。 另一边,洛阳的虎牢关,一旦突破,洛阳就无险可守,这样的进军路线,才是顺势而为的用兵之道。 读历史的时候我们常常看到某一方势

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

无线领夹麦克风什么牌子好用?揭秘领夹麦克风哪个牌子音质好!

随着短视频行业的星期,围绕着直播和视频拍摄的电子数码类产品也迎来了热销不减的高增长,其中除了数码相机外,最为重要的麦克风也得到了日益增长的高需求,尤其是无线领夹麦克风,近几年可谓是异常火爆。别看小小的一对无线麦克风,它对于视频拍摄的音质起到了极为关键的作用。 不过目前市面上的麦克风品牌种类多到让人眼花缭乱,盲目挑选的话容易踩雷,那么无线领夹麦克风什么牌子好用?今天就给大家推荐几款音质好的

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

负债不再是障碍?银行信贷“白名单“揭秘

谈及银行信贷产品,常闻有言称存在无需考量负债与查询记录之奇品,此等说法十有八九为中介诱人上钩之辞。轻信之下,恐将步入连环陷阱。除非个人资质出类拔萃,如就职于国央企或事业单位,工龄逾年,五险一金完备,还款能力卓越,或能偶遇线下产品对查询记录稍显宽容,然亦非全然无视。宣称全然不顾者,纯属无稽之谈。 银行非慈善机构,不轻易于困境中援手,更偏爱锦上添花之举。若无坚实资质,即便求助于银行亦难获青睐。反

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存