总结一篇初级Android 开发 适配

总结一篇Android 开发 适配

 

   博主从入职的第一个项目起就遇到了Android 适配,适配各种手机和主流平板,那可真的蛋疼,而我们的UI设计师又比较严格,所以为此我也是研究了不少,学到了不少!仅作为入门级适配!

本文主要讲语言适配,分辨率(尺寸)适配,图片适配,布局适配,以及其他的一些规范适配!

语言适配:

   一般的APP 都只适配国内的,我自己专门下载了几个,比如国内的直播平台,读书平台,骑行平台都未做国际化适配,因为他们主打国内市场,像微信,支付宝,DJI,这样有外国市场才有国际化。像我们公司这么“牛逼”的产品当然也要有了,我们适配了 中,英,德,法,中文繁体字就默认为英文了。

  一般的 适配规则:values-语言代号-地区代号,比如我们项目中用到的values-zh-rCN,values-de-rDE,values-fr-rFR。中间“r”是必须的,这样在每一个语言下就也可写和默认values 下同样的xml文件了。


分辨率(尺寸)适配:

  这个就比较有意思,有用了,毕竟这个才是Android手机的痛点,因为各式各样的手机和各种奇葩分辨率让我们~,这里我们说下命名规范,并拿博主自己项目中主流的分辨率聊下。

  在android3.2以前,所有的资源文件都有相应的xhdpi,hdpi,mdpi,ldpi四种文件来对应,android3.2以后,为了提供更精准的对布局文件的控制,可以通过为资源文件(res目录下文件)增加后缀来指定该文件夹里的xml布局文件

  常用的几种后缀分别是【sw<N>dp】,【w<N>dp】,【h<N>dp】。例如values-sw600dp-480x720  ,x是小写的 字符“x”,因为代码中一般我们都可以采用上拉下滑而对内容进行扩展,而对于宽度却很少做左右滑动的,RecyclerView通过布局管理器可以实现左右滑动,而<N>对应的就是600,一般600以上都是平板类型。

 第一种后缀:sw<N>dp,如layout-sw600dp, values-sw600dp
这里的sw代表smallwidth的意思,当你所有屏幕的最小宽度都大于600dp时,屏幕就会自动到带sw600dp后缀的资源文件里去寻找相关资源文件,这里的最小宽度是指屏幕宽高的较小值,每个屏幕都是固定的,不会随着屏幕横向纵向改变而改变。
 第二种后缀w<N>dp 如layout-w600dp, values-w600dp
带这样后缀的资源文件的资源文件制定了屏幕宽度的大于Ndp的情况下使用该资源文件,但它和sw<N>dp不同的是,当屏幕横向纵向切换时,屏幕的宽度是变化的,以变化后的宽度来与N相比,看是否使用此资源文件下的资源。
 第三种后缀h<N>dp 如layout-h600dp, values-h600dp
这个后缀的使用方式和w<N>dp一样,随着屏幕横纵向的变化,屏幕高度也会变化,根据变化后的高度值来判断是否使用h<N>dp ,但这种方式很少使用,因为屏幕在纵向上通常能够滚动导致长度变化,不像宽度那样基本固定,因为这个方法灵活性不是很好,google官方文档建议尽量少使用这种方式。


   这里博主用了默认手机的分辨率 +3类平板的,第一个sw600dp 针对720的,而后的后缀也写的很清楚,分辨针对主流的一些平板分辨率.寻找顺序是从上倒下,最近原则!比如1080x1920,他就会寻找到values-sw600dp-1824x1200.

图片适配:

  针对图片,大家会发现,创建Android studio 默认生成了mipmap,和之前的Eclipse 不一样Google 称之为Mipmap纹理技术,经过一番搜索获得以下信息:

  在三维世界中,显示一张图的大小与摄象机的位置有关,近的地方,图片实际象素就大一些,远的地方图片实际象素就会小一些,就要进行一些压缩,例如一张64*64的图,在近处,显示出来可能是50*50,在远处可能显示出来是20*20. 如果只限于简单的支掉某些像素,将会使缩小后的图片损失很多细节,图片变得很粗糙,因此,图形学有很多复杂的方法来处理缩小图片的问题,使得缩小后的图片依然清晰,然而,这些计算都会耗费一定的时间.

  Mipmap纹理技术是目前解决纹理分辨率与视点距离关系的最有效途径,它会先将图片压缩成很多逐渐缩小的图片,例如一张64*64的图片,会产生64*64,32*32,16*16,8*8,4*4,2*2,1*1的7张图片,当屏幕上需要绘制像素点为20*20 时,程序只是利用 32*32 和 16*16 这两张图片来计算出即将显示为 20*20 大小的一个图片,这比单独利用 32*32 的那张原始片计算出来的图片效果要好得多,速度也更快.

  总而言之,言而总之,google官方和广大人民群众总结mipmap文件夹下,仅仅建议放启动图标/app launcher icons,也就是应用安装后,会显示在桌面的那个图标。其他图片资源仍然放在 drawable 下面。

  博主的第一个项目的资源全部都是放在mipmap中的,后来第二个项目听了组长的说的,之后图片都放在drawable。也只是听话,并没有去研究和查阅资料!

高能!下面就是一个小技巧了,好多人都不知道!博主也是言传身教学来的。

  我们在做语言国际化的时候很容易能适配中英文,但是在做图片的时候,很少人知道也可以这么搞,最原始的做法!这是项目之前的写法!手动适配中英文,或者多国语言文字图片。

       

 ImageView imageView = (ImageView) iPageView.findViewById(R.id.guide_pic_into_main);
            Locale local = Locale.getDefault();
            String language = local.getLanguage();
            if(language.equals("zh")){
                imageView.setImageResource(resId);
            } else {
                imageView.setImageResource(engResId);
            }

  这样太low,不仅仅是代码量的增加,如果你遇到了selector事件,只有一国语言的话还好办!如果是多国语言你就只能做二个selector_x_x.xml文件了,

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/pattern_refers" android:state_pressed="false"/>

    <item android:drawable="@drawable/pattern_refers_click" android:state_pressed="true"/>

</selector>

说了这么多废话,其实简单的一一一批。


  在图片默认对应的分辨率文件下创建一个 需要国际化图片的文件夹,参照图示!依此类推!

drawable-xhdpi 都默认为英文图片,强调,不能只有

drawable-<X>-xhdpi的资源,默认文件夹中的文件必须有!!

布局适配:

通常没什么必要的,我们都会选择layout,其实layout还有很多

  比如layout-sw600dp,类似图片和dimens 这样的规则,还有layout-land如果要支持橫屏,就会取同名的layout放在layout-land文件夹下。layout-port 竖屏,layout-finger, layout-land-finger, finger使用在对手指触摸支持很好的屏幕(finger-friendly touchscree)。平时开发基本不会用到。

  这样我们在应对不同分辨率的布局的时候就可以用上了,博主没怎么用过,因为一般进行dimens 适配 加之布局使用的是权重亦或者是

RelativeLayout 就可以满足基本的布局适配,不需要特别的做一个同名步同尺寸的的布局。

其他适配:

  对于简单的xml动画和selector 颜色状态变化,我们可以创建anim 和color 来管理,而点9图之所以称之为点9图,就可以在drawable随意放置。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个适配Android 11的WiFi开发代码示例: 1. 在AndroidManifest.xml文件中添加以下权限: ```xml <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> ``` 2. 在你的Java代码中,使用以下代码来检查是否已获得位置权限: ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, PERMISSION_REQUEST_CODE); } ``` 3. 在Android 11中,需要先请求位置权限才能扫描WiFi网络。以下是一个例子: ```java if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_CODE); } else { startWifiScan(); } ``` 4. 在Android 11及以上版本中,需要使用以下代码来打开WiFi: ```java WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder().setSsid(ssid).build(); NetworkRequest request = new NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).setNetworkSpecifier(specifier).build(); ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { super.onAvailable(network); // WiFi已连接 } @Override public void onUnavailable() { super.onUnavailable(); // WiFi连接不可用 } }; connectivityManager.requestNetwork(request, callback); } else { wifiManager.setWifiEnabled(true); WifiConfiguration configuration = new WifiConfiguration(); configuration.SSID = "\"" + ssid + "\""; int networkId = wifiManager.addNetwork(configuration); wifiManager.disconnect(); wifiManager.enableNetwork(networkId, true); wifiManager.reconnect(); } ``` 5. 扫描您周围的WiFi网络,您可以使用以下代码: ```java WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE); if (!wifiManager.isWifiEnabled()) { wifiManager.setWifiEnabled(true); } registerReceiver(wifiScanReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); wifiManager.startScan(); ``` 6. 可以使用以下代码来获取WiFi扫描结果: ```java public BroadcastReceiver wifiScanReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { List<ScanResult> results = wifiManager.getScanResults(); for (ScanResult result : results) { String ssid = result.SSID; // 处理WiFi扫描结果 } unregisterReceiver(this); } }; ``` 这是一个适配Android 11的WiFi开发代码示例,仅供参考。在实际使用时,您应该根据您的应用程序需要进行修改和调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值