目录
内容
用户界面
就
就
需要在当前主题的 functions.php
中添加自定义代码,才能实现在文章中自定义 CSS
样式表,插件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
/* 为特定文章添加特定css最简单的方式. */ /*添加自定义CSS的meta box*/ add_action('admin_menu', 'cwp_add_my_custom_css_meta_box'); /*保存自定义CSS的内容*/ add_action('save_post', 'cwp_save_my_custom_css'); /*将自定义CSS添加到特定文章(适用于Wordpress中文章、页面、自定义文章类型等)的头部*/ add_action('wp_head','cwp_insert_my_custom_css'); function cwp_add_my_custom_css_meta_box() { add_meta_box('my_custom_css', '自定义CSS', 'cwp_output_my_custom_css_input_fields', 'post', 'normal', 'high'); add_meta_box('my_custom_css', '自定义CSS', 'cwp_output_my_custom_css_input_fields', 'page', 'normal', 'high'); } function cwp_output_my_custom_css_input_fields() { global $post; echo '<input type="hidden" name="my_custom_css_noncename" id="my_custom_css_noncename" value="'.wp_create_nonce('custom-css').'" />'; echo '<textarea name="my_custom_css" id="my_custom_css" rows="5" cols="30" style="width:100%;">'.get_post_meta($post->ID,'_my_custom_css',true).'</textarea>'; } function cwp_save_my_custom_css($post_id) { if (!wp_verify_nonce($_POST['my_custom_css_noncename'], 'custom-css')) return $post_id; if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id; $my_custom_css = $_POST['my_custom_css']; update_post_meta($post_id, '_my_custom_css', $my_custom_css); } function cwp_insert_my_custom_css() { if (is_page() || is_single()) { if (have_posts()) : while (have_posts()) : the_post(); echo '<style type="text/css">'.get_post_meta(get_the_ID(), '_my_custom_css', true).'</style>'; endwhile; endif; rewind_posts(); } } |
添加完成之后,会在文章编辑页面的最下面,出现 CSS
编辑窗口,之后在这个窗口中添加 CSS
会被自动保存。
链入外部样式表是把样式表保存为一个样式表文件,然后在页面中link
标记链接到这个样式表文件,这个标记必须放到页面的区内,如下:
1 2 3 |
<head> <link rel="stylesheet" type="text/css" href="mystyle.css"> </head> |
上面这个例子表示浏览器从mystyle.css
文件中以文档格式读出定义的样式表。rel="stylesheet"
是指在页面中使用这个外部的样式表。 type="text/css"
是指文件的类型是样式表文本。href="mystyle.css"
是文件所在的位置。
一个外部样式表文件可以应用于多个页面。当你改变这个样式表文件时,所有页面的样式都随之而改变。在制作大量相同样式页面的网站时,非常有用,不仅减少了重复的工作量,而且有利于以后的修改、编辑,浏览时也减少了重复下载代码。
样式表文件可以用任何文本编辑器(例如:记事本)打开并编辑,一般样式表文件扩展名为.css
。内容是定义的样式表,不包含HTML标记,mystyle.css
这个文件的内容如下:
1 2 3 |
hr {color: sienna} p {margin-left: 20px} body {background-image: url("images/back40.gif")} |
(定义水平线的颜色为土黄;段落左边的空白边距为20象素;页面的背景图片为images目录下的back40.gif文件)
内部样式表是把样式表放到页面head
区里,这些定义的样式就应用到页面中了,样式表是用style
标记插入的,从下例中可以看出style
标记的用法:
1 2 3 4 5 6 7 |
<head> <style type="text/css"> hr {color: sienna} p {margin-left: 20px} body {background-image: url("images/back40.gif")} </style> </head> |
注意:有些低版本的浏览器不能识别style
标记,这意味着低版本的浏览器会忽略style
标记里的内容,并把style
标记里的内容以文本直接显示到页面上。为了避免这样的情况发生,我们用加HTML注释的方式(<!--注释-->)隐藏内容而不让它显示:
1 2 3 4 5 |
<head> <style type="text/css"> <!-- hr {color: sienna} p {margin-left: 20px} body {background-image: url("images/back40.gif")} --> </style> </head> |
导入外部样式表是指在内部样式表的style
里导入一个外部样式表,导入时用@import
,看下面这个实例:
1 2 3 4 5 |
<head> <style type=”text/css”> <!-- @import “mystyle.css” 其他样式表的声明 --> </style> </head> |
例中@import "mystyle.css"
表示导入mystyle.css
样式表,注意使用时外部样式表的路径。方法和链入样式表的方法很相似,但导入外部样式表输入方式更有优势。实质上它相当于存在内部样式表中的。 注意:导入外部样式表必须在样式表的开始部分,在其他内部样式表上面。
内嵌样式是混合在HTML标记里使用的,用这种方法,可以很简单的对某个元素单独定义样式。内嵌样式的使用是直接将在HTML标记里加入style
参数。而style
参数的内容就是CSS的属性和值,如下例:
1 |
<div style="color: sienna; margin-left: 20px">这是一个段落</div> |
(这个段落颜色为土黄色,左边距为20象素) 在style
参数后面的引号里的内容相当于在样式表大括号里的内容。 注意:style
参数可以应用于任意BODY
内的元素(包括BODY
本身),除了BASEFONT
、PARAM
和SCRIPT
。
上一章里我们已经提到样式表的层叠顺序,这里我们讨论插入样式表的这几种方法的叠加,如果在同一个选择器上使用几个不同的样式表时,这个属性值将会叠加几个样式表,遇到冲突的地方会以最后定义的为准。例如,我们首先链入一个外部样式表,其中定义了h3
选择符的color
、text-alig
和font-size
属性:
1 |
h3 { color: red; text-align: left; font-size: 8pt } |
(标题3的文字颜色为红色;向左对齐;文字尺寸为8号字) 然后在内部样式表里也定义了h3选择符的text-align和font-size属性:
1 |
h3 { text-align: right; font-size: 20pt } |
(标题3文字向右对齐;尺寸为20号字) 那么这个页面叠加后的样式就是:
1 |
color: red; text-align: right; font-size: 20pt |
(文字颜色为红色;向右对齐;尺寸为20号字) 字体颜色从外部样式表里保留下来,而对齐方式和字体尺寸都有定义时,按照后定义的优先而依照内部样式表。 注意:依照后定义的优先,所以优先级最高的是内嵌样式,内部样式表高于导入外部样式表,链入的外部样式表和内部样式表之间是最后定义的优先级高。
之前写css,一直是把position:absolute当做android的FrameLayout用的,其他类似。
后来看了下面的文章,满面羞愧。
这些基础的东西,还是要了解透彻的,一直不求甚解的搞下去,自己都不知道做的什么,为什么会出现这种错误,希望能从下面的内容中,总结出一个类似于Androidlayout的规则。
关于position看下面的文章就够了
http://blog.csdn.net/chen_zw/article/details/8741365
css属性大全
http://css.doyoe.com/
这里主要记一下看完自己的理解:
文档流
首先需要了解什么是文档流,可以理解为方块布局,从上到下,从左到右的布局方式就是文档流。
1.margin和padding是占用文档流的,也就是说,layout函数一定是这么写的
element.margin + elment.width/height +element.padding = dom真正占用的空间。
position:static很容易理解,完全遵循文档流。
position:relative 有点特殊,本身遵循文档流,但可以在文档流中使用top left bottom right设置偏移,偏移不遵循文档流。需要注意的是,后面的dom会按照relative元素不偏移来排列。layout函数中完全可以把relative按照static先处理,最后在当前位置进行偏移。
注:relative static无父辈时以body为参考;
position:absolute 脱离文档流,使用top left bottom right设置偏移,偏移参照为父辈最近的非static元素(之前一直认为absolute参照window,深刻检讨)。
注:absolute无父辈时以html为参考。
1、body默认有9个px的margin
2、absolute的元素没有设置top、left时,默认是文档流的位置,会造成设置了absolute,看起来没有效果的现象。
position:fixed fixed以window为参考(即不管你怎么scroll,位置都不会变),设置偏移。
float:absolute会屏蔽掉float,其他的可以共存。
float不遵循文档流。
clear:clear是配合float使用的。意思是把dom的哪边给清除掉。
如clear:both,意思是两边都不许浮动。
如果我来写 html的layout,
1.dom tree static,relative的按照文档流布局,relative单独处理下偏移,完全不影响文档流。
fixed很简单粗暴。
2.处理absolute float
absolute屏蔽float
absolute需要寻找父辈非static元素直到html,比较蛋疼。这个webkit在渲染的时候会把absolute的元素单独出来一层。
float是浮动排版,按文档流布局就差不多。
当然,css3还有更多的排版方式,上面几种已经基本够用,如果还要学习的话就是box了。
1.先参照Android Studio中创建keystore生成指定的证书文件。
2.在app/build.gradle文件中增加signingConfigs
字段:如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
apply plugin: 'com.android.application' android { compileSdkVersion 21 buildToolsVersion "21.1.0" defaultConfig { applicationId "com.test.example" minSdkVersion 14 targetSdkVersion 21 versionCode 1 versionName "1.0" } signingConfigs { debug { File strFile = new File("../../Keystore/Debug/debug.jks") storeFile file(strFile) storePassword "storeDebug1234567890" keyAlias "debugkey" keyPassword "aliasDebug1234567890" //println strFile.absolutePath; } release { File strFile = new File("../../Keystore/Release/release.jks") storeFile file(strFile) storePassword "storeRelease1234567890" keyPassword "keyRelease1234567890" keyAlias "releasekey" // println strFile.absolutePath; } } buildTypes { release { signingConfig signingConfigs.release runProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } |
注意
1.storeFile
,storePassword
,keyAlias
,keyPassword
缺一不可,都必须填写,并且填写正确。
如果没有填写keyAlias
,则签名时候会报告Android-APK signing error : Failed to read key from keystore
密码不正确的时候,会报告java.security.UnrecoverableKeyException: Cannot recover key
This exception may result from the fact that you had provided a key password that was different from the keystore password
2.对于Release
配置,在buildTypes
中必须指定
1 |
signingConfig signingConfigs.release |
否则,会出现
1 |
Error: The apk for your currently selected variant(app-release-unsigned.apk) is not signed. please specify a signing configuration for this variant(release) |
3.signingConfigs
必须在buildTypes
前面声明,否则会出现找不到配置选项的错误。
1 |
$ keytool -list -v -keystore keystoreName -storepass keystorePassword |
解压出apk中META-INF目录下的CERT.RSA文件,然后用keytool即可查看签名信息:
1 |
$ keytool -printcert -file CERT.RSA |
验证APK的签名是不是我们给定的签名文件的签名。
1.解压出apk中META-INF目录下的CERT.RSA文件.
2.执行如下命令:
Windows:
1 2 3 |
$ keytool -printcert -file CERT.RSA | findstr MD5 $ keytool -list -v -keystore keystoreName -storepass keystorePassword | findstr MD5 |
Linux:
1 2 3 |
$ keytool -printcert -file CERT.RSA | grep MD5 $ keytool -list -v -keystore keystoreName -storepass keystorePassword | grep MD5 |
比较两者输出的MD5字符串,是否一致即可。
Android Studio 1.5创建的工程,会生成两个默认的测试目录:test
,androidTest
,其中,test
目录为在本机执行单元测试代码的目录,androidTest
为在Android设备上执行单元测试代码的目录。
目录如下图所示:
对于新建的工程,默认会生成相应的测试代码例子。如下图所示:
请注意上图的两个文件图标的差别,一个文件的图标的右上角是两个三角标记,另一个文件的右下角是个时钟的标记。
右击androidTest
目录下的ApplicationTest.java
,就会出现执行测试用例的菜单。如下图:
但是当右击test
目录下的ExampleUnitTest.java
则没有任何的运行菜单。如下图:
那么,如何执行test
目录下的ExampleUnitTest.java
呢?
操作方法为"View"
->"Tool Windows"
->"Build Variants"
,然后,切换Test Artifact
从Android Instrumentation Tests
到Unit Tests
。
如下图:
切换Test Artifact
可以看到,切换完成后,两个文件的图标互换了一下:
此时右击test
目录下的ExampleUnitTest.java
则会出现Run 'ExampleUnitTest'
,Debug 'ExampleUnitTest'
的菜单了。
如下图:
至于
1 2 |
Test running startedTest running failed: Instrumentation run failed due to 'java.lang.RuntimeException' Empty test suite |
这个问题,是由于Android Studio 的BUG,导致的,一般是没有执行上述的切换命令,然后右击test
目录下的ExampleUnitTest.java
依旧会出现Run 'ExampleUnitTest'
,Debug 'ExampleUnitTest'
的菜单,然后点击后,会让我们选择运行的设备,这个时候,明显是把我们当作可以在设备上运行的测试用例了,因此,找不到是必然的。
应对这个BUG的解决方法,就是清理代码,然后重新加载工程,一般可以解决这个问题了。
Android Studio编译报错 java.lang.OutOfMemoryError: GC overhead limit exceeded
详细的崩溃信息如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
UNEXPECTED TOP-LEVEL ERROR: java.lang.OutOfMemoryError: GC overhead limit exceeded at com.android.dx.cf.code.RopperMachine.getSources(RopperMachine.java:665) at com.android.dx.cf.code.RopperMachine.run(RopperMachine.java:288) at com.android.dx.cf.code.Simulator$SimVisitor.visitLocal(Simulator.java:612) at com.android.dx.cf.code.BytecodeArray.parseInstruction(BytecodeArray.java:412) at com.android.dx.cf.code.Simulator.simulate(Simulator.java:94) at com.android.dx.cf.code.Ropper.processBlock(Ropper.java:782) at com.android.dx.cf.code.Ropper.doit(Ropper.java:737) at com.android.dx.cf.code.Ropper.convert(Ropper.java:346) at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:282) at com.android.dx.dex.cf.CfTranslator.translate0(CfTranslator.java:139) at com.android.dx.dex.cf.CfTranslator.translate(CfTranslator.java:94) at com.android.dx.command.dexer.Main.processClass(Main.java:682) at com.android.dx.command.dexer.Main.processFileBytes(Main.java:634) at com.android.dx.command.dexer.Main.access$600(Main.java:78) at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:572) at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284) at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166) at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144) at com.android.dx.command.dexer.Main.processOne(Main.java:596) at com.android.dx.command.dexer.Main.processAllFiles(Main.java:498) at com.android.dx.command.dexer.Main.runMonoDex(Main.java:264) at com.android.dx.command.dexer.Main.run(Main.java:230) at com.android.dx.command.dexer.Main.main(Main.java:199) at com.android.dx.command.Main.main(Main.java:103) |
1 2 3 4 5 6 7 8 |
android { .............. dexOptions { incremental true javaMaxHeapSize "4g" } ............... } |
1 2 3 4 5 6 7 8 9 10 |
android { .............. testOptions { android.dexOptions { incremental true javaMaxHeapSize "4g" } } ............... } |
Android Studio 编译工程的时候,如果出现错误,会打印如下信息:
1 2 3 4 5 6 7 8 9 10 11 |
:myapp:processDebugResources FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:processDebugResources'. ... ... * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log outp |
最后会提示,增加--stacktrace
,--info
或 --debug
来获取更加详细的信息。
那么如何设置这些参数呢?如下操作即可:
"Android Studio"
->"preferences-Build, Execution, Deployment"
->"Compiler"
如下图所示:
注意,本文描述的方案,仅在Android Studio 1.5,Gradle插件版本1.3.1中测试成立!
同时在工程中引入了多个第三方jar包,导致调用的方法数超过了android设定的65536个(DEX 64K problem),进而导致dex无法生成,也就无法生成APK文件。
编译时候产生如下的异常信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Error:Execution failed for task ':xxx:dexRelease'. > com.android.ide.common.internal.LoggedErrorException: Failed to run command: C:\Android\sdk\android-sdk\build-tools\23.0.1\dx.bat --dex --output D:\Source\android\build\intermediates\dex\release --input-list=D:\Source\android\build\intermediates\tmp\dex\release\inputList.txt Error Code: Output: UNEXPECTED TOP-LEVEL EXCEPTION: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 at com.android.dx.merge.DexMerger$6.updateIndex(DexMerger.java:502) at com.android.dx.merge.DexMerger$IdMerger.mergeSorted(DexMerger.java:277) at com.android.dx.merge.DexMerger.mergeMethodIds(DexMerger.java:491) at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:168) at com.android.dx.merge.DexMerger.merge(DexMerger.java:189) at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:454) at com.android.dx.command.dexer.Main.runMonoDex(Main.java:302) at com.android.dx.command.dexer.Main.run(Main.java:245) at com.android.dx.command.dexer.Main.main(Main.java:214) at com.android.dx.command.Main.main(Main.java:106) |
Google给出的解决方案就是使用MultiDexApplication
1.在项目的build.gradle文件的dependencies 节中添加分包设置:
1 2 3 4 5 |
dependencies { ... compile 'com.android.support:multidex:1.0.1' ... } |
2.通过在defaultConfig节中设置multiDexEnabled标签为true,开启multi-dexing支持.
1 2 3 4 5 |
defaultConfig { ... multiDexEnabled true ... } |
3.如果没有创建自己的Application.class
,直接在AndroidManifest.xml
文件的Application声明中添加:
1 |
android:name="android.support.multidex.MultiDexApplication" |
如果实现了自己的Application.class
,则修改继承的父类为
android.support.multidex.MultiDex.MultiDexApplication
1.在项目的build.gradle文件的dependencies 节中添加分包设置:
1 2 3 4 5 |
dependencies { ... androidTestCompile 'com.android.support:multidex-instrumentation:1.0.1' ... } |
2.通过在defaultConfig节中设置multiDexEnabled标签为true,开启multi-dexing支持.
1 2 3 4 5 6 |
defaultConfig { ... multiDexEnabled true testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner" ... } |