一.概述 正在开发的应用做了一版新UI,原打算将新版UI按项目名做成资源包,再在build.gradle里productFlavors{ }多渠道打包实现 但被告知新旧两个项目共用一个分支,那就做成两个主题(Theme1/Theme2)来适
正在开发的应用做了一版新UI,原打算将新版UI按项目名做成资源包,再在build.gradle里productFlavors{ }多渠道打包实现
但被告知新旧两个项目共用一个分支,那就做成两个主题(Theme1/Theme2)来适配了
如果只是变更UI,做成多主题来适配不同项目也是比较合适的方式
- 从服务器下载或提前放置不同主题资源包到设备指定目录,在代码里引用主题资源
- 定义不同的
各属性的具体值可以在Theme定义时配置,但是最好定义在各自的xml配置文件中(color.xml、string.xml、dimens.xml.....),然后在Theme定义时"@类型/..."格式引用
Theme中如果string类型不是引用而是字符串,在布局文件中使用正常,但代码里获取会有问题
使用过程也很简单,原本布局文件中引用UI属性的方式如下:
android:color="@color/colorAttrName"android:duration="@integer/integerValue"android:adjustViewBounds="@bool/booleanAttrName" android:layout_height="@dimen/dimensionValue"android:text="@string/stringAttrName"android:background="@drawable/referenceAttrName"
现在改为这样进行引用:
android:color="?attr/colorAttrName"android:duration="?attr/integerValue"android:adjustViewBounds="?attr/booleanAttrName" android:layout_height="?attr/dimensionValue"android:text="?attr/stringAttrName"android:background="?attr/referenceAttrName"
float比较特殊,一般它会在代码中被引用(后面会讲到),配置文件中多在dimens.xml中定义变量
要配置的都配置好了,需要注意的是:
- 最好写一个BaseActivity,其他的Activitiy都继承至它
- 主题设置需要在setContentView()之前
接下来就在代码中进行主题切换:
package com.android.example.ui;import android.os.Bundle;import com.android.example.R;import androidx.annotation.Nullable;import androidx.appcompat.app.AppCompatActivity;public class BaseActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (setThemeBlack) { setTheme(R.style.ThemeBlack); } else { setTheme(R.style.ThemeLight); } }}
主题设置写在BaseActivity的onCreate()函数中,它会在其他所有继承至它的Activity的onCreate()之前运行。
如果要在代码中引用 integerValue、floatAttrName、booleanAttrName,使用Context.obtainStyledAttributes()就可以了
package com.android.example.ui;import android.os.Bundle;import com.android.example.R;import android.content.res.TypedArray;import androidx.annotation.Nullable;import androidx.appcompat.app.AppCompatActivity;public class BaseActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (setThemeBlack) { setTheme(R.style.ThemeBlack); } else { setTheme(R.style.ThemeLight); } TypedArray tyar = obtainStyledAttributes(new int[]{ R.attr.colorValue, R.attr.integerValue, R.attr.booleanValue, R.attr.dimensionValue, R.attr.floatValue, R.attr.stringValue, R.attr.referenceValue }); int colorArrtValue = tyar.getColor(0, Color.BLACK); int integerArrtValue = tyar.getInt(1, Integer.MAX_VALUE); boolean booleanArrtValue = tyar.getBoolean(2, false); float dimensionArrtValue = tyar.getDimensionPixelSize(3, 66); float floatArrtValue = tyar.getFloat(4, 99.99f); String stringArrtValue = tyar.getString(5); Drawable drawableArrtValue = tyar.getDrawable(6); }}
到此,通过setTheme()切换主题方式就讲述完毕了
这种切换主题方式的优点是:不需要修改太多代码,大部分修改只要针对布局文件就行。
弊端就是:主题只能内置配置好,一旦程序发布后,应用支持的主题类型就固定了,要想增加更多主题,只能发布新的版本。
如果想要动态配置主题,可以使用前文中提到过第1、第3种主题切换方式。
就是接下来要讲的内容了
Apk主题切换和第1种将主题包整体下载或提前放置的方案很像。
共同点是:都需要在代码中动态设置图片、文字、颜色等UI信息。
区别是:第1种方法需要自行编写资源解析的方法。而Apk主题切换,可以使用Android自带api
APK主题方案的基本思路是:
在Android中,所有的资源都是基于包的。资源以id进行标识,在同一个应用中,每个资源都有唯一标识。但在不同的应用中,可以有相同的id。
因此,只要获取到了其他应用的Context对象,就可以通过它的 getRsources() 获取到其绑定的资源对象。
然后,就可以使用 Resources 的 getXXX 方法获取字符串、颜色、dimension、图片等。
要想获取其他应用的Context对象,Android已经为我们提供好了接口:
android.content.ContextWrapper.createPackageContext(String packageName, int flags)
package com.android.example.ui;import android.os.Bundle;import androidx.annotation.Nullable;public class MainActivity extends BaseActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView text = (TextView) findViewById(R.id.remoteText); TextView color = (TextView) findViewById(R.id.remoteColor); ImageView image = (ImageView) findViewById(R.id.remote_image); try { //主题资源Apk包名 String remotePackage = "com.xxx.themepackage"; //主题资源Apk Context Context remoteContext = createPackageContext(remotePackage,CONTEXT_IGNORE_SECURITY); //主题资源Apk Resources Resources remoteResources = remoteContext.getResources(); text.setText(remoteResources.getText(remoteResources.getIdentifier("application_name", "string", remotePackage))); color.setTextColor(remoteResources.getColor(remoteResources.getIdentifier("delete_target_hover_tint", "color", remotePackage))); image.setImageDrawable(remoteResources.getDrawable(remoteResources.getIdentifier("ic_launcher_home", "drawable", remotePackage))); } catch (NameNotFoundException e) { e.printStackTrace(); } }}
内置主题实现简单、配置方便,但可扩展性不强。
Apk切换主题扩展性高,但要在代码里设置所有可变资源,一旦界面布局改变,需要较长时间进行代码改写。
实际运用中,可以将以上两种结合起来使用:
涉及到界面风格,如整体色调、不同的文字颜色,使用内置主题。图片资源则在APK主题包中提供。
来源地址:https://blog.csdn.net/geyichongchujianghu/article/details/131024109
--结束END--
本文标题: Android:主题切换
本文链接: https://www.lsjlt.com/news/392281.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-01-21
2023-10-28
2023-10-28
2023-10-27
2023-10-27
2023-10-27
2023-10-27
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
一口价域名售卖能注册吗?域名是网站的标识,简短且易于记忆,为在线用户提供了访问我们网站的简单路径。一口价是在域名交易中一种常见的模式,而这种通常是针对已经被注册的域名转售给其他人的一种方式。
一口价域名买卖的过程通常包括以下几个步骤:
1.寻找:买家需要在域名售卖平台上找到心仪的一口价域名。平台通常会为每个可售的域名提供详细的描述,包括价格、年龄、流
443px" 443px) https://www.west.cn/docs/wp-content/uploads/2024/04/SEO图片294.jpg https://www.west.cn/docs/wp-content/uploads/2024/04/SEO图片294-768x413.jpg 域名售卖 域名一口价售卖 游戏音频 赋值/切片 框架优势 评估指南 项目规模
0