无论是定制系统还是自行开发APP的UI,其无论是使用标准UI还是自定义UI,最终都是需要自己熟悉主题风格的各种属性设置,不过属性非常的多,如果需要知道某个UI可以临时查看一下SDK的



D:\liuzhibao\Android\sdk\platforms\android-N\data\res路径下的,但是这个是纯粹的资源文件,没有java文件,所以还是推荐repo下来framework/base代码.

下面先看看自定义View如何添加属性之类的:

新建一个PumpKinCustomeView的android studio工程:

主类程序:

package org.durian.pumpkincustomeview;import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;public class PumpKinMainActivity extends AppCompatActivity {private Button mButton;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_pump_kin_main);mButton=(Button)findViewById(R.id.button);mButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent=new Intent(PumpKinMainActivity.this,ThemeActivity.class);PumpKinMainActivity.this.startActivity(intent);finish();}});}}

既然要自定义View,那么就需要新建一个atts.xml文件到res/values下,下面随便举几个:

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="UIView"><attr name="pumpkin_background" format="color"/><attr name="pumpkin_textcolor" format="color" /><attr name="pumpkin_textsize" format="integer"/><attr name="pumpkin_view_width" format="dimension"/><attr name="pumpkin_view_height" format="dimension"/><attr name="pumpkin_text" format="string"/><attr name="pumpkin_draw" format="reference"/><attr name="pumpkin_enable" format="boolean"/><attr name="pumpkin_style" format="reference" /><attr name="pumpkin_enum" format="enum" /><attr name="pumpkin_float" format="float" /><attr name="pumpkin_fraction" format="fraction" />
</declare-styleable></resources>

上面基本上一看还是非常清楚的,上面只缺少flag位运算format,fraction为百分比,reference为引用,enum可以如下:

<declare-styleable name="pumpkin_enum_style">
<attr name="pumpkin_enum"><enum name="enum1">1</enum><enum name="enum2">2</enum><enum name="enum3">3</enum>
</attr>
</declare-styleable>

定义好上面的属性后,新建一个UIView的继承View的类:

package org.durian.pumpkincustomeview.view;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;import org.durian.pumpkincustomeview.R;/*** Project name : PumpKinCustomeView* Created by zhibao.liu on 2016/4/28.* Time : 10:32* Email warden_sprite@foxmail.com* Action : durian*/
public class UIView extends View {private Paint mPaint;private Paint mTextPaint;private int rectWidth;private int rectHeight;public UIView(Context context) {super(context);}public UIView(Context context, AttributeSet attrs) {super(context, attrs);initView(context);TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.UIView);int textSize=typedArray.getInteger(R.styleable.UIView_pumpkin_textsize,128);int textColor=typedArray.getColor(R.styleable.UIView_pumpkin_textcolor, Color.GRAY);mTextPaint.setColor(textColor);mTextPaint.setStrokeWidth(2);mTextPaint.setTextSize(textSize);int backgroundColor=typedArray.getColor(R.styleable.UIView_pumpkin_background,Color.GRAY);rectWidth=(int)typedArray.getDimension(R.styleable.UIView_pumpkin_view_width,512);rectHeight=(int)typedArray.getDimension(R.styleable.UIView_pumpkin_view_height,513);rectWidth=Utils.px2dip(context,rectWidth);rectHeight=Utils.px2dip(context,rectHeight);//rectHeight=Utils.dip2px(context,rectHeight);mPaint.setColor(backgroundColor);android.util.Log.i("UIVIEW","rectWidth : "+rectWidth+" rectHeight : "+rectHeight);}public void initView(Context context){mPaint=new Paint();mTextPaint=new Paint();}@Overridepublic void draw(Canvas canvas) {super.draw(canvas);canvas.drawRect(new Rect(10,10,rectWidth,rectHeight),mPaint);canvas.drawText("hello view",50,800,mTextPaint);}}

然后在工程主Activity的布局中添加这个自定义View.在添加之前,先为这个View写一个自定义style:

<!-- add by pumpkin custom style --><style name="Pumpkin_style"><item name="pumpkin_background">#ffff0000</item><item name="pumpkin_textcolor">#ff00ff00</item><item name="pumpkin_view_width">500dp</item><item name="pumpkin_view_height">500dp</item></style>

然后添加到主Activity的布局中:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:pumpkin="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"android:orientation="vertical"tools:context="org.durian.pumpkincustomeview.PumpKinMainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!" /><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="theme"/><org.durian.pumpkincustomeview.view.UIViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"pumpkin:pumpkin_textsize="128"style="@style/Pumpkin_style"/></LinearLayout>

注意:

<org.durian.pumpkincustomeview.view.UIViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"pumpkin:pumpkin_textsize="128"style="@style/Pumpkin_style"/>

这里故意分开一部分直接写在布局中,有一部分属性赋值封装到PumKin_style,但是直接写到布局中需要注意比如(pumpkin:pumpkin_textsize):

在布局头部需要标记路径:现在android studio可以直接res-auto,以前需要换成res/报名

xmlns:pumpkin=<a target=_blank href="http://schemas.android.com/apk/res-auto">http://schemas.android.com/apk/res-auto</a>

在自定义UIView中注意:

rectWidth=Utils.px2dip(context,rectWidth);rectHeight=Utils.px2dip(context,rectHeight);

注意: 我们在风格中明明写着是500,但是如果没有上面两句程序,RectWidth的值将是1500,也就是这个地方设置的500dp(预想这样),但是打印log出来将是1500px,结果整个屏幕的方形将非常的大,也不是我们所需要的,所以获取尺寸以后需要转一下从px转到pd单位,所以这个地方需要特别注意.字体也存在这个转换,但是上面程序没有在给出了,转换一般如下:

package org.durian.pumpkincustomeview.view;import android.content.Context;/*** Project name : PumpKinCustomeView* Created by zhibao.liu on 2016/4/28.* Time : 14:42* Email warden_sprite@foxmail.com* Action : durian*/
public class Utils {public static int dip2px(Context context, float dipValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dipValue * scale + 0.5f);}public static int px2dip(Context context, float pxValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (pxValue / scale + 0.5f);}}

运行结果:

下面来看看如果是系统UI的属性如何修改:下面android5.0来简说,

加入我的Activity有CheckBox和EditText,我希望这个Activity中所有的CheckBox都是一致的,所有的EditText风格也是一致的,如何处理呢?

系统资源设计有几个基本原则和规律:

<1> : 具有继承性:如

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"><!-- Customize your theme here. --><item name="colorPrimary">@color/colorPrimary</item><item name="colorPrimaryDark">@color/colorPrimaryDark</item><item name="colorAccent">@color/colorAccent</item></style>

使用parent关键字,继承parent的所有属性值.

<2> : 子类属性覆盖父类属性值:即在虽然在父类对某个属性赋值了,但是子类希望在这个属性值上面不同于父类,那么就在子类重新对改属性值赋值,如下:

<style name="CustomeAppTheme" parent="@style/AppTheme"><item name="colorPrimary">#ffff0000</item><!--<item name="colorAccent">#fff4e80b</item>--><item name="editTextStyle">@style/pumpkin_editTextStyle</item><item name="checkboxStyle">@style/pumpkin_checkboxStyle</item></style>

属性colorPrimary在父类AppTheme中已经赋了值,但还是我希望自己的Activity的titlebar的颜色是红色,那么在这里就重新赋值,达到覆盖父类那个属性值的目的.

<3> : 回答最上面那个问题,如果需要调整一个页面内所以某个UI的风格,那么就需要重新将UI的风格重新写,但是一般推荐继承父类,只调整需要调整的部分,其他的仍然采用父类的属性,这样就不要从零开始写了:

<style name="pumpkin_editTextStyle" parent="@android:style/Widget.Material.EditText"><item name="android:textColorPrimary">#ffff0000</item><item name="android:textColor">#ff11e7f3</item><item name="android:textSize">48sp</item></style><style name="pumpkin_checkboxStyle" parent="@android:style/Widget.Material.CompoundButton.CheckBox"><item name="android:textColor">#fff107f3</item><item name="android:textSize">32sp</item></style>

将页面的EditText和CheckBox的几个属性重新调整.

在新建一个Activity测试一下:

package org.durian.pumpkincustomeview;import android.content.Intent;
import android.content.res.Resources;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;public class ThemeActivity extends AppCompatActivity {private Button button;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_theme);button=(Button)findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent=new Intent(ThemeActivity.this,CompareThemeActivity.class);ThemeActivity.this.startActivity(intent);}});}}

manifest.xml添加自定义主题给它:

<activityandroid:name=".ThemeActivity"android:theme="@style/CustomeAppTheme"></activity>

对应的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"android:orientation="vertical"tools:context="org.durian.pumpkincustomeview.ThemeActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="hello textview"/><CheckBoxandroid:text="hello checkbox"android:layout_width="wrap_content"android:layout_height="wrap_content" /><EditTextandroid:layout_width="fill_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/button"android:text="button"android:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout>

运行结果:

发现颜色有54%透明度的黑色变为指定的颜色了.

有读者可能又会问题,如何知道EditText等的属性风格,比如

<item name="editTextStyle">

这个地方记住顺序:

打开android源代码,查看EditText.java源代码:

public EditText(Context context, AttributeSet attrs) {this(context, attrs, com.android.internal.R.attr.editTextStyle);}

看到了吧,这就是为什么前面要自己先写一个自定义的UIView,回顾一下这些主题风格是如何被UI使用的,看到上面的editTextStyle,然后搜索:

        <item name="editTextStyle">@style/Widget.Material.EditText</item>

我的是android5.0的代码,所以带有material.

同时搜索的时候一定要注意,这个搜索的关键字一定要出现在Public.xml中,因为android系统后面的资源需要声明,如果声明在Public.xml中才能够被APP developer使用,即公共的,如果是在symbol.xml,那就算是系统内部自己使用,即私有的.很显然我们这里是需要在APP中使用,所以一定是需要公有的才行.在自己APP程序重新再写这些属性值即可覆盖framework中预设的.

假如自己的UI的一些属性在系统中声明为私有的,怎么办,最粗暴的做法就是直接将系统中的风格和资源文件全部挑选出来放到自己的APP资源下,单个UI的话并不是很难.

假设,这里只是个假设SeekBar 这个ui风格是私有的,那么步骤如下:

<1> : 查看SeekBar.java这个类:

public SeekBar(Context context, AttributeSet attrs) {this(context, attrs, com.android.internal.R.attr.seekBarStyle);}

继续看seekBarStyle风格:

<item name="seekBarStyle">@style/Widget.Material.SeekBar</item>

找到"定义处":

<style name="Widget.Material.SeekBar"><item name="indeterminateOnly">false</item><item name="progressDrawable">@drawable/seekbar_track_material</item><item name="indeterminateDrawable">@drawable/seekbar_track_material</item><item name="thumb">@drawable/seekbar_thumb_material_anim</item><item name="splitTrack">true</item><item name="useDisabledAlpha">false</item><item name="focusable">true</item><item name="paddingStart">16dip</item><item name="paddingEnd">16dip</item><item name="mirrorForRtl">true</item><item name="background">@drawable/control_background_32dp_material</item></style>

其实一般改的并不多,一般是修改SeekBar的进度线的风格(粗细,颜色等)以及游标图案或者颜色,将上面的copy到自己的工程

假如修改背景颜色,那么就还需要提取这个资源:

@drawable/control_background_32dp_material

这个想都不用想,绝对是个xml文件:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2015 The Android Open Source ProjectLicensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.
--><ripple xmlns:android="http://schemas.android.com/apk/res/android"android:color="@color/control_highlight_material"android:radius="16dp" />

一看,control_highlight_material还是一个xml:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source ProjectLicensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.
--><selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_checked="true"android:state_enabled="true"android:alpha="@dimen/highlight_alpha_material_colored"android:color="?attr/colorControlActivated" /><item android:color="?attr/colorControlHighlight" />
</selector>

也需要提取出来.继续查找颜色:

        <item name="colorControlActivated">?attr/colorAccent</item>

一看colorAccent这个颜色值,这个颜色值很疯狂的,是一个全局的,比如你在自己的APP主题中设置:

<item name="colorAccent">#fff4e80b</item>

你会发现你的所有UI都变色了,而不是一个.

继续查看另外一个颜色colorCotrolHighlight:

<item name="colorControlHighlight">@color/ripple_material_dark</item>

这个颜色值也是一个xml:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2015 The Android Open Source ProjectLicensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.
--><selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:alpha="@dimen/highlight_alpha_material_dark"android:color="@color/foreground_material_dark" />
</selector>

再来看看foreground_material_dark,最终是

<color name="foreground_material_dark">@color/white</color>

即白色前景.

了解上面的流程,如果参考系统的UI就可以拷贝出来自行调整各自的值.

当然上面都是调整APP部分的属性,如果是定制系统,那么就可以在vendor/overlay/framework中自行开发,这样整个系统都有了,但是一般这样的都要拷贝系统原生的,如果希望自己定制的系统中运行的第三方app也跟着调整,也可以直接改原生的主题风格,将原生的代码改掉,当然一般不推荐.

后面一篇可以看看系统基本UI都是谁演化而来:

Button extends TextView 
TextView extends View 

Android 主题资源风格定制 1相关推荐

  1. 华为5c android n风格,华为荣耀畅玩5C的屏幕怎么样

    华为荣耀畅玩5C的屏幕怎么样 屏幕方面,华为荣耀畅玩5C采用了5.2英寸1080P级别GFF贴合屏幕,塑料边框采用了弧面状的设计,握感比较舒适.华为荣耀畅玩5C采用了双主天线的设计,分别在上下的塑料区 ...

  2. 国内定制android系统吗,同样都是基于Android系统 国产定制系统差异有多大?

    目前国产手机的操作系统都是基于谷歌的Android系统深度定制的,每个厂商在进行定制时便产生了差异,也有了自家的特色功能.现在笔者手上就有荣耀V10和vivo Z3两款手机,所以今天就给大家带来这两款 ...

  3. 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统(瘋耔修改篇二)...

    第四章.Android编译系统与定制Android平台系统 4.1Android编译系统 Android的源码由几十万个文件构成,这些文件之间有的相互依赖,有的又相互独立,它们按功能或类型又被放到不同 ...

  4. Android Material风格的应用(三)--DrawerLayout

    添加抽屉导航 Android Material风格的应用(一)--AppBar TabLayout Android Material风格的应用(二)--RecyclerView Android Mat ...

  5. android 赛车 源码,android 3D风格赛车游戏源码

    android 3D风格赛车游戏源码,基于Libgdx 框架开发,三维视觉,包含20量敌方车辆和10量我方车辆,支持Admob广告插件,带游戏排行榜和成就系统 ,兼容手机.平板电脑等多种屏幕尺寸 ,游 ...

  6. 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统

    第四章.Android编译系统与定制Android平台系统 4.1Android编译系统 Android的源码由几十万个文件构成,这些文件之间有的相互依赖,有的又相互独立,它们按功能或类型又被放到不同 ...

  7. phpbb3 风格定制

    phpBB3把美工设计称之风格(Style),phpBB风格定制清晰地分为三个部分: 1. 模板修改:为了变换页面结构而修改模板文件. 2. 主题(Them)定制:通俗地说,就是更改页面的色调.色彩搭 ...

  8. Android系统固件定制方式

    Android系统固件定制方式 一般情况下,一款基于Android的设备,会根据需求定制系统APP,定制的规格往往需要依据设备的具体应用场景.比如,面向通信的设备,那么需要预装phone.tablet ...

  9. Android系统的定制

    深入浅出 - Android系统移植与平台开发(1)- Android系统的定制 http://blog.csdn.net/mr_raptor/article/details/30113417?utm ...

最新文章

  1. IOS 常见面试汇总
  2. C语言实现数据结构之栈的详解
  3. 函数递归方法反转字符串
  4. MongoDB学习笔记(二)使用Java操作MongoDB
  5. kafka部分重要参数配置-broker端参数
  6. 【SpringBoot 2】(四)详析SpringBoot的常用注解
  7. vue ---- 组件综合案例(购物车案例)
  8. 演练nerddinner 问题
  9. 安装和运行,意思差异应该很明显
  10. Oracle中删除重复记录
  11. 登陆服务器显示guest,登录界面如何隐藏guest账号
  12. 基于中文形近字相似度与加权编辑距离融合实现的汉字纠错算法
  13. linux虚拟机 dnw,linux下安装及使用DNW
  14. google gcr.io、k8s.gcr.io 国内镜像
  15. 基础js实现下雨效果(超简单)
  16. cdn perl_用perl对CDN节点日志进行统计
  17. [JavaWeb开发中]HTTP 协议的基本格式和Fiddler抓包工具
  18. 如何使用百度天气预报API接口
  19. (转)一篇令所有游戏圈的兄弟汗颜的文章
  20. 服务器如何数据备份?

热门文章

  1. 二手车价格预测数据探索
  2. PAT 甲级 1018. Public Bike Management
  3. [200902] 条件概率与独立事件
  4. Oracle 10g For Windows 10.1.0和 Oracle 10g For Linux 10.1.0.3下载地址
  5. 一个五层加密过的表白恢复密码解密的过程
  6. 电子电路学习笔记(6)——电阻的作用
  7. 如何让孩子保持兴趣,怎么培养孩子读书的兴趣
  8. 【机器学习】多项式回归案例五:正则惩罚解决过拟合(Ridge回归和Lasso回归)
  9. 从零开始Android游戏编程(第二版) 前言
  10. 【我在异世界学Linux】认识冯诺依曼体系结构