在android应用程序中我们可能需要切换模式,如晚上切换到夜间模式便于阅读等。本文参考了网上的一些资料,并结合实例,实现了动态更改主题的效果。

Android中实现theme主题可以使用在activity中使用setTheme(int)的方法,SDK中对此方法的说明为:

//Set the base theme for this context. Note that this should be called before any views are instantiated in the Context (for example before calling android.app.Activity.setContentView or android.view.LayoutInflater.inflate).
//需要在setcontentview函数或者inflate函数之前使用。

效果图如下:

  

实现步骤:

首先需要定义一个属性,此属性用于赋值给控件的属性,相当于控件属性值的“变量”。

在attrs.xml中,定义三个属性,属性的format均为reference|color

<resources>

    <attr name="button_bg" format="reference|color" />
<attr name="activity_bg" format="reference|color" />
<attr name="text_cl" format="reference|color" /> </resources>

接下来,在styles.xml中,编写自定义的Theme

<style name="AppBaseTheme" parent="android:Theme.Light">
</style> <style name="AppTheme" parent="AppBaseTheme">
<item name="text_cl">#ffffff</item>
<item name="button_bg">#000000</item>
<item name="activity_bg">#ffffff</item>
</style> <style name="DarkTheme" parent="AppBaseTheme">
<item name="text_cl">#000000</item>
<item name="button_bg">#ffffff</item>
<item name="activity_bg">#000000</item>
</style>

选择一种模式作为程序的默认theme,注意:由于我是在layout布局文件中定义的view的样式,因此,为了保证theme切换时不会出现找不到资源的问题,因此需要在每一种用到的自定义theme中,都加上item。这里的item如text_cl和view的textColor属性的format是一致的。

Android manifest文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testandroidsettheme"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" /> <application
android:allowBackup="true"
android:name="com.example.testandroidsettheme.app.MyApp"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.testandroidsettheme.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>

我将android:theme="@style/AppTheme"作为默认的样式。

主界面layout布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?activity_bg"
android:gravity="center"
android:orientation="vertical" > <Button
android:id="@+id/button0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?button_bg"
android:textColor="?text_cl"
android:text="set theme" /> </LinearLayout>

在布局文件中,button的background属性采用的是当前theme下的button_bg的属性值,外部的linearlayout采用的是当前theme下的activity_bg的属性值,在填写此属性值时,需要在前面添加”?”,表示这是一个style中的变量。

在需要切换显示不同theme的activity中,一些博客中在button点击事件中使用

setTheme(int);

recreate();

的方式,我发现此种方式无法实现theme的切换,因为recreate()方法会重新创建此activity,之前的setTheme()无效。我的实现方式如下:

public class MainActivity extends Activity {

    public Button button0;

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApp app = (MyApp)MainActivity.this.getApplication();
if(app.theme == 0){
//使用默认主题
}else{
//使用自定义的主题
setTheme(app.theme);
}
setContentView(R.layout.activity_main); button0 = (Button) this.findViewById(R.id.button0);
button0.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MyApp app = (MyApp)MainActivity.this.getApplication();
app.theme = R.style.DarkTheme;
recreate();
}
});
}
} public class MyApp extends Application{
public int theme = 0;
}

在此activityoncreate()中的setContentView()方法调用之前,判断当前的theme,并调用setTheme(),实现改变theme的效果。

注意:这种方法实现切换theme不是很友好,因为在activity重新创建时,可能会有闪屏的现象。比较好的解决方案如知乎客户端采用的是截屏,并渐隐图片的过度方式,具体的实现还有待学习。

参考资料:http://www.kymjs.com/code/2015/05/26/01/

Android应用中动态更改主题的实现的更多相关文章

  1. android ArrayAdapter 如何动态更改数据

    在android开发中ListView是比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示,使用adpater与listview捆绑后,有时希望在程序使用过程中能动态的更改l ...

  2. Android代码中动态设置图片的大小(自动缩放),位置

    项目中需要用到在代码中动态调整图片的位置和设置图片大小,能自动缩放图片,用ImageView控件,具体做法如下: 1.布局文件 <RelativeLayout xmlns:android=&qu ...

  3. 在带(继承)TextView的控件中,在代码中动态更改TextView的文字颜色

    今天由于公司项目需求,须要实现一种类似tab的选项卡,当时直接想到的就是使用RadioGroup和RadioButton来实现. 这种方法全然没问题.可是在后来的开发过程中,却遇到了一些困扰非常久的小 ...

  4. VS2013中如何更改主题颜色(深色)和恢复默认的窗口布局

    1.通常情况下,我们会根据个人爱好更改VS2013的主题颜色,一开始我喜欢白色,后来我偏爱深色. 依次选择:工具->选项->常规->主题->深色->确定,ok 2.我们在 ...

  5. Android中动态更新ListView(转)

    在使用ListView时,会遇到当ListView列表滑动到最底端时,添加新的列表项的问题,本文通过代码演示如何动态的添加新的列表项到ListView中.实现步骤:调用ListView的setOnSc ...

  6. 关于Android NDK中调用第三方的动态库

    因为最近在整合Android 上RTSP播放器的网络库,因需要调用自己编译的网络库,调用一直出现问题,开始时是直接在Android.mk 中加入LOCAL_SHARED_LIBRARIES := li ...

  7. Android开发中无处不在的设计模式——动态代理模式

    继续更新设计模式系列.写这个模式的主要原因是近期看到了动态代理的代码. 先来回想一下前5个模式: - Android开发中无处不在的设计模式--单例模式 - Android开发中无处不在的设计模式-- ...

  8. Android中样式及主题

    Android应用程序中不可避免的需要使用的样式和主题,样式指定一般指定View的高度.字体.字体颜色.背景,Android里的样荐定义在Style.xml文件里.主题也是一种样式,只不过它是应用在整 ...

  9. Android项目中JNI技术生成并调用.so动态库实现详解

    生成 jni方式有两种:一种是通过SWIG从C++代码生成过度的java代码:另一种是通过javah的方式从java代码自动生成过度的C++代码.两种方式下的步骤流程正好相反. 第一种方式:由于需要配 ...

随机推荐

  1. PHP类与继承

    <?php class Person { private $name; private $age; function __construct($name,$age){ $this->nam ...

  2. Magcodes.WeiChat——自定义CustomCreationConverter之实现微信自定义菜单的序列化

    微信自定义菜单接口是一个比较麻烦的接口,往往开发的小伙伴们看到下面的这段返回JSON,整个人就会不好了:   {"menu":{"button":[{" ...

  3. PyCharm 4.5.4 环境配置

    1.去掉“自动保存功能” pycharm默认是自动保存的,习惯自己按 ctrl + s 的可以进行如下设置: 菜单File -> Settings... -> Appearance &am ...

  4. ASP.NET MVC 4源码分析之如何定位控制器

    利用少有的空余时间,详细的浏览了下ASP.NET MVC 4的源代码.照着之前的步伐继续前进(虽然博客园已经存在很多大牛对MVC源码分析的博客,但是从个人出发,还是希望自己能够摸索出这些).首先有一个 ...

  5. onFocus="this.blur()"的解释

    onFocus="this.blur()" onFocus即获取焦点的意思,而blur却是失去焦点的意思,因此onFocus="this.blur()"的通俗理 ...

  6. python time

    Python-time 计算程序运行时间 import time start = time.clock() time.sleep(5) end = time.clock() runtime = end ...

  7. Nginx学习笔记(一) Nginx架构

    Nginx架构 Nginx全程是什么? Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器. ...

  8. Working With Taxonomy Field in CSOM

    How to create taxonomy field with CSOM If you need to programmatic create a taxonomy field, you need ...

  9. 如何在ASP.NET中用C#将XML转换成JSON

    本文旨在介绍如果通过C#将获取到的XML文档转换成对应的JSON格式字符串,然后将其输出到页面前端,以供JavaScript代码解析使用.或许你可以直接利用JavaScript代码通过Ajax的方式来 ...

  10. Win10年度更新开发必备:VS2015 Update 3正式版下载汇总

    微软在06月27日发布了Visual Studio 2015 Update 3 .在MSDN中微软也提供下载,而且MSDN的Visual Studio 2015 Update 3与官方免费下载的文件是 ...