HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

Hbuilder护眼主题分享

主题

Sublime还有Webstorm有很多主题,但是Hbuilder就相对较少,或者直接说基本没什么主题,在网上搜索了很久也很少有Hbuilder的主题分享,于是就自己取色调了一个仿的护眼主题来分享一下,希望能帮助到和我一样想换主题的朋友~

哇新手不会在这插入图片啊,这是效果图啊!
https://imgsa.baidu.com/forum/w%3D580/sign=94d273a0ec1190ef01fb92d7fe1a9df7/ddf279dda3cc7cd99cf797943201213fb90e9106.jpg

使用方法:

  方法一:把下面一大堆代码复制一下,保存在后缀为 .tmTheme 的文件中,名字随便取,重要的是后缀。然后再Hbuilder中视觉主题设置中选择“高级”选项,导入 .tmTheme 的文件就可以了。

  方法二:如果你懒得复制粘贴,那就直接下载 .tmTheme 文件就好了,然后再导入。下载地址:http://pan.baidu.com/s/1hseoAcG

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>name</key>
<string>eyecare</string>
<key>uuid</key>
<string>a6e4607a-4f30-32a2-8df4-b2e341afa72e</string>
<key>settings</key>
<array>
<dict>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f2</string>
<key>background</key>
<string>#282c34</string>
<key>caret</key>
<string>#5ba4cf</string>
<key>lineHighlight</key>
<string>#49483eff</string>
<key>selection</key>
<string>#808080ff</string>
<key>invisibles</key>
<string>#404040</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>invisibles</string>
<key>scope</key>
<string>invisibles</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#49483eff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>-Common-</string>
<key>scope</key>
<string>dont.match</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>--Console--</string>
<key>scope</key>
<string>dont.match</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>console.error</string>
<key>scope</key>
<string>console.error</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ca0000ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>console.input</string>
<key>scope</key>
<string>console.input</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#d5cc6dff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>console.prompt</string>
<key>scope</key>
<string>console.prompt</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#c59163ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>console.warning</string>
<key>scope</key>
<string>console.warning</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#cccc33ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>console.debug</string>
<key>scope</key>
<string>console.debug</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#80b96eff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>hyperlink</string>
<key>scope</key>
<string>hyperlink</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#db6a73ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>--Misc.--</string>
<key>scope</key>
<string>dont.match</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>Unstaged files</string>
<key>scope</key>
<string>markup.deleted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f8ff</string>
<key>background</key>
<string>#420e09ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Staged files</string>
<key>scope</key>
<string>markup.inserted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f8ff</string>
<key>background</key>
<string>#253b22ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>markup.changed</string>
<key>scope</key>
<string>markup.changed</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f8ff</string>
<key>background</key>
<string>#4a410dff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>markup.underline</string>
<key>scope</key>
<string>markup.underline</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f2ff</string>
<key>fontStyle</key>
<string>underline</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>markup.bold</string>
<key>scope</key>
<string>markup.bold</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#5ba4cfff</string>
<key>fontStyle</key>
<string>bold</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>markup.italic</string>
<key>scope</key>
<string>markup.italic</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#5ba4cfff</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>meta.diff, meta.diff.header</string>
<key>scope</key>
<string>meta.diff, meta.diff.header</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f8ff</string>
<key>background</key>
<string>#006fa4ff</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>meta.separator.diff</string>
<key>scope</key>
<string>meta.separator.diff</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ffffffff</string>
<key>background</key>
<string>#3467d1ff</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>meta.separator</string>
<key>scope</key>
<string>meta.separator</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ffffffff</string>
<key>background</key>
<string>#3467d1ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>property</string>
<key>scope</key>
<string>property</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#879ab5ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>-Theme Specific-</string>
<key>scope</key>
<string>dont.match</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>Comment</string>
<key>scope</key>
<string>comment</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#75715eff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>String</string>
<key>scope</key>
<string>string</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#80b96eff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Number</string>
<key>scope</key>
<string>constant.numeric</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#c59163ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Built-in constant</string>
<key>scope</key>
<string>constant.language</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ae81ffff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>User-defined constant</string>
<key>scope</key>
<string>constant.character, constant.other</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ae81ffff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Variable</string>
<key>scope</key>
<string>variable</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#5ba4cfff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Keyword</string>
<key>scope</key>
<string>keyword</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#55b5bcff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Storage</string>
<key>scope</key>
<string>storage</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#db6a73ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Storage type</string>
<key>scope</key>
<string>storage.type</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#b76bbaff</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Class name</string>
<key>scope</key>
<string>entity.name.class</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#cb9856ff</string>
<key>fontStyle</key>
<string>underline</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Inherited class</string>
<key>scope</key>
<string>entity.other.inherited-class</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#cb9856ff</string>
<key>fontStyle</key>
<string>italic,underline</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Function name</string>
<key>scope</key>
<string>entity.name.function</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#cb9856ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Function argument</string>
<key>scope</key>
<string>variable.parameter</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#fd971fff</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Tag name</string>
<key>scope</key>
<string>entity.name.tag</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#db6a73ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Tag attribute</string>
<key>scope</key>
<string>entity.other.attribute-name</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#cb9856ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Library function</string>
<key>scope</key>
<string>support.function</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#b76bbaff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Library constant</string>
<key>scope</key>
<string>support.constant</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#80b96eff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Library class/type</string>
<key>scope</key>
<string>support.type, support.class</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#5ba4cfff</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Library variable</string>
<key>scope</key>
<string>support.other.variable</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#5ba4cfff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Invalid</string>
<key>scope</key>
<string>invalid</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f0ff</string>
<key>background</key>
<string>#f92672ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Invalid deprecated</string>
<key>scope</key>
<string>invalid.deprecated</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f0ff</string>
<key>background</key>
<string>#ae81ffff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>markup.deleted</string>
<key>scope</key>
<string>markup.deleted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ffe0e0ff</string>
<key>background</key>
<string>#9a0b0bff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>markup.inserted</string>
<key>scope</key>
<string>markup.inserted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#d4ffd4ff</string>
<key>background</key>
<string>#3ca83cff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>punctuation.section</string>
<key>scope</key>
<string>punctuation.section</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ffa727ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Annotation Override - searchResultIndication</string>
<key>scope</key>
<string>override.searchResultIndication</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>Annotation Override - xmlTagPairOccurrenceIndication</string>
<key>scope</key>
<string>override.xmlTagPairOccurrenceIndication</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>Annotation Override - htmlTagPairOccurrenceIndication</string>
<key>scope</key>
<string>override.htmlTagPairOccurrenceIndication</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>Annotation Override - rubyBlockPairOccurrenceIndication</string>
<key>scope</key>
<string>override.rubyBlockPairOccurrenceIndication</string>
<key>settings</key>
<dict>
</dict>
</dict>
</array>
</dict>
</plist>

继续阅读 »

Sublime还有Webstorm有很多主题,但是Hbuilder就相对较少,或者直接说基本没什么主题,在网上搜索了很久也很少有Hbuilder的主题分享,于是就自己取色调了一个仿的护眼主题来分享一下,希望能帮助到和我一样想换主题的朋友~

哇新手不会在这插入图片啊,这是效果图啊!
https://imgsa.baidu.com/forum/w%3D580/sign=94d273a0ec1190ef01fb92d7fe1a9df7/ddf279dda3cc7cd99cf797943201213fb90e9106.jpg

使用方法:

  方法一:把下面一大堆代码复制一下,保存在后缀为 .tmTheme 的文件中,名字随便取,重要的是后缀。然后再Hbuilder中视觉主题设置中选择“高级”选项,导入 .tmTheme 的文件就可以了。

  方法二:如果你懒得复制粘贴,那就直接下载 .tmTheme 文件就好了,然后再导入。下载地址:http://pan.baidu.com/s/1hseoAcG

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>name</key>
<string>eyecare</string>
<key>uuid</key>
<string>a6e4607a-4f30-32a2-8df4-b2e341afa72e</string>
<key>settings</key>
<array>
<dict>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f2</string>
<key>background</key>
<string>#282c34</string>
<key>caret</key>
<string>#5ba4cf</string>
<key>lineHighlight</key>
<string>#49483eff</string>
<key>selection</key>
<string>#808080ff</string>
<key>invisibles</key>
<string>#404040</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>invisibles</string>
<key>scope</key>
<string>invisibles</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#49483eff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>-Common-</string>
<key>scope</key>
<string>dont.match</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>--Console--</string>
<key>scope</key>
<string>dont.match</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>console.error</string>
<key>scope</key>
<string>console.error</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ca0000ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>console.input</string>
<key>scope</key>
<string>console.input</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#d5cc6dff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>console.prompt</string>
<key>scope</key>
<string>console.prompt</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#c59163ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>console.warning</string>
<key>scope</key>
<string>console.warning</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#cccc33ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>console.debug</string>
<key>scope</key>
<string>console.debug</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#80b96eff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>hyperlink</string>
<key>scope</key>
<string>hyperlink</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#db6a73ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>--Misc.--</string>
<key>scope</key>
<string>dont.match</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>Unstaged files</string>
<key>scope</key>
<string>markup.deleted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f8ff</string>
<key>background</key>
<string>#420e09ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Staged files</string>
<key>scope</key>
<string>markup.inserted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f8ff</string>
<key>background</key>
<string>#253b22ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>markup.changed</string>
<key>scope</key>
<string>markup.changed</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f8ff</string>
<key>background</key>
<string>#4a410dff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>markup.underline</string>
<key>scope</key>
<string>markup.underline</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f2ff</string>
<key>fontStyle</key>
<string>underline</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>markup.bold</string>
<key>scope</key>
<string>markup.bold</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#5ba4cfff</string>
<key>fontStyle</key>
<string>bold</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>markup.italic</string>
<key>scope</key>
<string>markup.italic</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#5ba4cfff</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>meta.diff, meta.diff.header</string>
<key>scope</key>
<string>meta.diff, meta.diff.header</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f8ff</string>
<key>background</key>
<string>#006fa4ff</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>meta.separator.diff</string>
<key>scope</key>
<string>meta.separator.diff</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ffffffff</string>
<key>background</key>
<string>#3467d1ff</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>meta.separator</string>
<key>scope</key>
<string>meta.separator</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ffffffff</string>
<key>background</key>
<string>#3467d1ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>property</string>
<key>scope</key>
<string>property</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#879ab5ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>-Theme Specific-</string>
<key>scope</key>
<string>dont.match</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>Comment</string>
<key>scope</key>
<string>comment</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#75715eff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>String</string>
<key>scope</key>
<string>string</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#80b96eff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Number</string>
<key>scope</key>
<string>constant.numeric</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#c59163ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Built-in constant</string>
<key>scope</key>
<string>constant.language</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ae81ffff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>User-defined constant</string>
<key>scope</key>
<string>constant.character, constant.other</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ae81ffff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Variable</string>
<key>scope</key>
<string>variable</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#5ba4cfff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Keyword</string>
<key>scope</key>
<string>keyword</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#55b5bcff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Storage</string>
<key>scope</key>
<string>storage</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#db6a73ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Storage type</string>
<key>scope</key>
<string>storage.type</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#b76bbaff</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Class name</string>
<key>scope</key>
<string>entity.name.class</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#cb9856ff</string>
<key>fontStyle</key>
<string>underline</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Inherited class</string>
<key>scope</key>
<string>entity.other.inherited-class</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#cb9856ff</string>
<key>fontStyle</key>
<string>italic,underline</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Function name</string>
<key>scope</key>
<string>entity.name.function</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#cb9856ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Function argument</string>
<key>scope</key>
<string>variable.parameter</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#fd971fff</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Tag name</string>
<key>scope</key>
<string>entity.name.tag</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#db6a73ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Tag attribute</string>
<key>scope</key>
<string>entity.other.attribute-name</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#cb9856ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Library function</string>
<key>scope</key>
<string>support.function</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#b76bbaff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Library constant</string>
<key>scope</key>
<string>support.constant</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#80b96eff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Library class/type</string>
<key>scope</key>
<string>support.type, support.class</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#5ba4cfff</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Library variable</string>
<key>scope</key>
<string>support.other.variable</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#5ba4cfff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Invalid</string>
<key>scope</key>
<string>invalid</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f0ff</string>
<key>background</key>
<string>#f92672ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Invalid deprecated</string>
<key>scope</key>
<string>invalid.deprecated</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#f8f8f0ff</string>
<key>background</key>
<string>#ae81ffff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>markup.deleted</string>
<key>scope</key>
<string>markup.deleted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ffe0e0ff</string>
<key>background</key>
<string>#9a0b0bff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>markup.inserted</string>
<key>scope</key>
<string>markup.inserted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#d4ffd4ff</string>
<key>background</key>
<string>#3ca83cff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>punctuation.section</string>
<key>scope</key>
<string>punctuation.section</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#ffa727ff</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Annotation Override - searchResultIndication</string>
<key>scope</key>
<string>override.searchResultIndication</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>Annotation Override - xmlTagPairOccurrenceIndication</string>
<key>scope</key>
<string>override.xmlTagPairOccurrenceIndication</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>Annotation Override - htmlTagPairOccurrenceIndication</string>
<key>scope</key>
<string>override.htmlTagPairOccurrenceIndication</string>
<key>settings</key>
<dict>
</dict>
</dict>
<dict>
<key>name</key>
<string>Annotation Override - rubyBlockPairOccurrenceIndication</string>
<key>scope</key>
<string>override.rubyBlockPairOccurrenceIndication</string>
<key>settings</key>
<dict>
</dict>
</dict>
</array>
</dict>
</plist>

收起阅读 »

关于选择地图导航心得以及解决方案(仅供参考,也许哪位大神会有更好的解决方案)

导航 地图
//调用第三方导航  
    document.getElementById('ios_navigation').addEventListener('tap', ios_navigation);  

    function ios_navigation() {  

        plus.geolocation.getCurrentPosition(function(p) {  
            var origin_gps_x = p.coords.longitude;  
            var origin_gps_y = p.coords.latitude;  
            //百度转火星  
            var x_pi = 3.14159265358979324 * 3000.0 / 180.0;  
            var x = analysis_cps_x - 0.0065;  
            var y = analysis_cps_y - 0.006;  
            var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);  
            var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);  
            var gg_lng = z * Math.cos(theta).toFixed(8);  
            var gg_lat = z * Math.sin(theta).toFixed(8);  
            // 设置目标位置坐标点和起始位置坐标点  
            var dst = new plus.maps.Point(gg_lng, gg_lat); // 导航目的地坐标  
            var src = new plus.maps.Point(origin_gps_x, origin_gps_y); // 导航起始地  
            plus.maps.openSysMap(dst, mpMc, src);  
        }, function(e) {  
            var origin_gps_x = null;  
            var origin_gps_y = null;  
            if (origin_gps_x == null && origin_gps_y == null) {  
                mui.toast("由于没有授权gps定位,当前位置无法获取");  
            }  
        });  
        // 调用系统地图显示   

    }  

    function androidMarket(pname) {  
        plus.runtime.openURL("market://details?id=" + pname);  
    }  

    function iosAppstore(url) {  
        plus.runtime.openURL("itms-apps://" + url);  
    }  
    document.getElementById('baidu_navigation').addEventListener('tap', function() {  

        //plus.runtime.openURL('baidumap://map/direction?destination='+analysis_cps_y+','+analysis_cps_x+'&mode=driving&coord_type=bd09&src=webapp.marker.yourCompanyName.yourAppName');  
        var url = null,  
            id = null,  
            f = null;  
        switch (plus.os.name) {  
            case "Android":  
                // 规范参考官方网站:http://developer.baidu.com/map/index.php?title=uri/api/android  
                url = 'baidumap://map/marker?location=' + analysis_cps_y + ',' + analysis_cps_x + '&title=' + mpMc + '&content=' + mp_dz + '&src=wenvip';  
                f = androidMarket;  
                id = "com.baidu.BaiduMap";  
                break;  
            case "iOS":  
                // 规范参考官方网站:http://developer.baidu.com/map/index.php?title=uri/api/ios  
                url = 'baidumap://map/navi?location=' + analysis_cps_y + ',' + analysis_cps_x + '&src=push&type=BLK&src=webapp.line.yourCompanyName.yourAppName';  
                f = iosAppstore;  
                id = "itunes.apple.com/cn/app/bai-du-de-tu-yu-yin-dao-hang/id452186370?mt=8";  
                break;  
            default:  
                return;  
                break;  
        }  
        plus.runtime.openURL(url, function(e) {  
            plus.nativeUI.confirm("检查到您未安装\"百度地图\",是否到商城搜索下载?", function(i) {  
                if (i.index == 0) {  
                    f(id);  
                }  
            });  
        });  

    });  
    document.getElementById('gaode_navigation').addEventListener('tap', function() {  
        //百度转火星  
        var x_pi = 3.14159265358979324 * 3000.0 / 180.0;  
        var x = analysis_cps_x - 0.0065;  
        var y = analysis_cps_y - 0.006;  
        var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);  
        var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);  
        var gg_lng = z * Math.cos(theta).toFixed(8);  
        var gg_lat = z * Math.sin(theta).toFixed(8);  
        var url = null,  
            id = null,  
            f = null;  
        switch (plus.os.name) {  
            case "Android":  
                // 规范参考官方网站:http://lbs.amap.com/api/uri-api/android-uri-explain/  
                url = 'androidamap://navi?sourceApplication=wenvip&poiname=' + mpMc + '&lat=' + gg_lat + '&lon=' + gg_lng + '&dev=0&style=2';  
                f = androidMarket;  
                id = "com.autonavi.minimap";  
                break;  
            case "iOS":  
                // 规范参考官方网站:http://lbs.amap.com/api/uri-api/ios-uri-explain/  
                url = 'iosamap://navi?sourceApplication=wenvip&backScheme=wenvip&lat=' + gg_lat + '&lon=' + gg_lng + '&dev=0&style=2';  
                f = iosAppstore;  
                id = "itunes.apple.com/cn/app/gao-tu-zhuan-ye-dao-hang-ban/id461703208?mt=8";  
                break;  
            default:  
                return;  
                break;  
        }  
        //IOS里,dev=0是关键,0代表gcj02坐标系,就是火星坐标, 没这个参数 高德是打不开的  
        plus.runtime.openURL(url, function(e) {  
            plus.nativeUI.confirm("检查到您未安装\"高德地图\",是否到商城搜索下载?", function(i) {  
                if (i.index == 0) {  
                    f(id);  
                }  
            });  
        }, id);  
    });

翻了翻以前的代码,找到了关于导航选择地图的部分!仅供分享交流!

继续阅读 »
//调用第三方导航  
    document.getElementById('ios_navigation').addEventListener('tap', ios_navigation);  

    function ios_navigation() {  

        plus.geolocation.getCurrentPosition(function(p) {  
            var origin_gps_x = p.coords.longitude;  
            var origin_gps_y = p.coords.latitude;  
            //百度转火星  
            var x_pi = 3.14159265358979324 * 3000.0 / 180.0;  
            var x = analysis_cps_x - 0.0065;  
            var y = analysis_cps_y - 0.006;  
            var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);  
            var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);  
            var gg_lng = z * Math.cos(theta).toFixed(8);  
            var gg_lat = z * Math.sin(theta).toFixed(8);  
            // 设置目标位置坐标点和起始位置坐标点  
            var dst = new plus.maps.Point(gg_lng, gg_lat); // 导航目的地坐标  
            var src = new plus.maps.Point(origin_gps_x, origin_gps_y); // 导航起始地  
            plus.maps.openSysMap(dst, mpMc, src);  
        }, function(e) {  
            var origin_gps_x = null;  
            var origin_gps_y = null;  
            if (origin_gps_x == null && origin_gps_y == null) {  
                mui.toast("由于没有授权gps定位,当前位置无法获取");  
            }  
        });  
        // 调用系统地图显示   

    }  

    function androidMarket(pname) {  
        plus.runtime.openURL("market://details?id=" + pname);  
    }  

    function iosAppstore(url) {  
        plus.runtime.openURL("itms-apps://" + url);  
    }  
    document.getElementById('baidu_navigation').addEventListener('tap', function() {  

        //plus.runtime.openURL('baidumap://map/direction?destination='+analysis_cps_y+','+analysis_cps_x+'&mode=driving&coord_type=bd09&src=webapp.marker.yourCompanyName.yourAppName');  
        var url = null,  
            id = null,  
            f = null;  
        switch (plus.os.name) {  
            case "Android":  
                // 规范参考官方网站:http://developer.baidu.com/map/index.php?title=uri/api/android  
                url = 'baidumap://map/marker?location=' + analysis_cps_y + ',' + analysis_cps_x + '&title=' + mpMc + '&content=' + mp_dz + '&src=wenvip';  
                f = androidMarket;  
                id = "com.baidu.BaiduMap";  
                break;  
            case "iOS":  
                // 规范参考官方网站:http://developer.baidu.com/map/index.php?title=uri/api/ios  
                url = 'baidumap://map/navi?location=' + analysis_cps_y + ',' + analysis_cps_x + '&src=push&type=BLK&src=webapp.line.yourCompanyName.yourAppName';  
                f = iosAppstore;  
                id = "itunes.apple.com/cn/app/bai-du-de-tu-yu-yin-dao-hang/id452186370?mt=8";  
                break;  
            default:  
                return;  
                break;  
        }  
        plus.runtime.openURL(url, function(e) {  
            plus.nativeUI.confirm("检查到您未安装\"百度地图\",是否到商城搜索下载?", function(i) {  
                if (i.index == 0) {  
                    f(id);  
                }  
            });  
        });  

    });  
    document.getElementById('gaode_navigation').addEventListener('tap', function() {  
        //百度转火星  
        var x_pi = 3.14159265358979324 * 3000.0 / 180.0;  
        var x = analysis_cps_x - 0.0065;  
        var y = analysis_cps_y - 0.006;  
        var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);  
        var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);  
        var gg_lng = z * Math.cos(theta).toFixed(8);  
        var gg_lat = z * Math.sin(theta).toFixed(8);  
        var url = null,  
            id = null,  
            f = null;  
        switch (plus.os.name) {  
            case "Android":  
                // 规范参考官方网站:http://lbs.amap.com/api/uri-api/android-uri-explain/  
                url = 'androidamap://navi?sourceApplication=wenvip&poiname=' + mpMc + '&lat=' + gg_lat + '&lon=' + gg_lng + '&dev=0&style=2';  
                f = androidMarket;  
                id = "com.autonavi.minimap";  
                break;  
            case "iOS":  
                // 规范参考官方网站:http://lbs.amap.com/api/uri-api/ios-uri-explain/  
                url = 'iosamap://navi?sourceApplication=wenvip&backScheme=wenvip&lat=' + gg_lat + '&lon=' + gg_lng + '&dev=0&style=2';  
                f = iosAppstore;  
                id = "itunes.apple.com/cn/app/gao-tu-zhuan-ye-dao-hang-ban/id461703208?mt=8";  
                break;  
            default:  
                return;  
                break;  
        }  
        //IOS里,dev=0是关键,0代表gcj02坐标系,就是火星坐标, 没这个参数 高德是打不开的  
        plus.runtime.openURL(url, function(e) {  
            plus.nativeUI.confirm("检查到您未安装\"高德地图\",是否到商城搜索下载?", function(i) {  
                if (i.index == 0) {  
                    f(id);  
                }  
            });  
        }, id);  
    });

翻了翻以前的代码,找到了关于导航选择地图的部分!仅供分享交流!

收起阅读 »

h5+ 跨平台 app开发学习路线及对应视频教程

h5+ mui

《JavaScript 快速提高视频教程》 js基础快速提高课程 【免费】
http://www.hcoder.net/course/info_229.html

《MUI 视频教程》【免费】
http://www.hcoder.net/course/info_211.html

《h.js 视频教程》【免费】
http://www.hcoder.net/tutorials/info_147.html

《HTML 5 开发教程》【免费】
http://www.hcoder.net/course/info_212.html

《APP开发实例教程 - 窗口切换 》【免费】
http://www.hcoder.net/course/info_218.html

《HBuilder 8.0.1 APP开发 - 新功能全接触》【免费】
http://www.hcoder.net/course/info_227.html

--------- 实战收费教程 ------------------------

MUI、H5 APP 实战教程 - 仿《有道词典》
https://ke.qq.com/course/194834

H5 跨平台APP开发电商项目实战教程 -《仿京东优选商城》
https://ke.qq.com/course/225830

更多课程中心
http://www.hcoder.net/course

继续阅读 »

《JavaScript 快速提高视频教程》 js基础快速提高课程 【免费】
http://www.hcoder.net/course/info_229.html

《MUI 视频教程》【免费】
http://www.hcoder.net/course/info_211.html

《h.js 视频教程》【免费】
http://www.hcoder.net/tutorials/info_147.html

《HTML 5 开发教程》【免费】
http://www.hcoder.net/course/info_212.html

《APP开发实例教程 - 窗口切换 》【免费】
http://www.hcoder.net/course/info_218.html

《HBuilder 8.0.1 APP开发 - 新功能全接触》【免费】
http://www.hcoder.net/course/info_227.html

--------- 实战收费教程 ------------------------

MUI、H5 APP 实战教程 - 仿《有道词典》
https://ke.qq.com/course/194834

H5 跨平台APP开发电商项目实战教程 -《仿京东优选商城》
https://ke.qq.com/course/225830

更多课程中心
http://www.hcoder.net/course

收起阅读 »

仿做APP 就几个页面,APP外包

仿做APP 就几个页面,APP外包
能做后端一起的优先

有时间能做的 联系QQ 1120094610

仿做APP 就几个页面,APP外包
能做后端一起的优先

有时间能做的 联系QQ 1120094610

原生底部选项卡示例已经更新啦

nativeObj模式底部选项卡 底部选项卡

鉴于之前有小伙伴提到的此示例存在的问题和实现方案上的欠缺,此示例已经做出更新。
获取最新demo示例:

  1. 更细HBuilder版本至最新版,新建App -> 选择模板 底部选项卡模板
  2. github仓库
  3. ask文章附件代码,在此文章中也对新版示例做出了相应说明。

注:如果有小伙伴存在底部图标飞到顶部的问题,请更新HBuilder和示例代码查看最终效果

继续阅读 »

鉴于之前有小伙伴提到的此示例存在的问题和实现方案上的欠缺,此示例已经做出更新。
获取最新demo示例:

  1. 更细HBuilder版本至最新版,新建App -> 选择模板 底部选项卡模板
  2. github仓库
  3. ask文章附件代码,在此文章中也对新版示例做出了相应说明。

注:如果有小伙伴存在底部图标飞到顶部的问题,请更新HBuilder和示例代码查看最终效果

收起阅读 »

oppo手机通讯录权限禁用闪退的解决方案

在oppo手机中 如果权限被禁用addressbook.find()这行会被执行,发生闪退,plus.contacts.getAddressBook方法无论权限同意与否都会执行成功的回调函数,所以解决闪退问题就需要判断权限是否被禁用,在H5+ 中plus.navigator.checkPermission()方法暂时不支持Android,废话不多说,一下方法可以询问到通讯录权限,进而解决oppo手机的闪退问题

var main = plus.android.runtimeMainActivity();
var a = plus.android.importClass('android.content.ContentProviderOperation');
var b = plus.android.importClass('android.content.ContentResolver');
var c = plus.android.importClass('android.database.Cursor');
var cc = plus.android.importClass('android.net.Uri');
var d = plus.android.importClass('android.test.AndroidTestCase');
var e = plus.android.importClass('android.util.Log');

var uri = cc.parse("content://com.android.contacts/contacts");
var arr = ["_id"];
var resolver = main.getContext().getContentResolver();
var cursor = resolver.query(uri, arr, null, null, null);
if (cursor.moveToNext() == false) {
alert("请打开权限")
}else{
alert("权限已打开")
}

继续阅读 »

在oppo手机中 如果权限被禁用addressbook.find()这行会被执行,发生闪退,plus.contacts.getAddressBook方法无论权限同意与否都会执行成功的回调函数,所以解决闪退问题就需要判断权限是否被禁用,在H5+ 中plus.navigator.checkPermission()方法暂时不支持Android,废话不多说,一下方法可以询问到通讯录权限,进而解决oppo手机的闪退问题

var main = plus.android.runtimeMainActivity();
var a = plus.android.importClass('android.content.ContentProviderOperation');
var b = plus.android.importClass('android.content.ContentResolver');
var c = plus.android.importClass('android.database.Cursor');
var cc = plus.android.importClass('android.net.Uri');
var d = plus.android.importClass('android.test.AndroidTestCase');
var e = plus.android.importClass('android.util.Log');

var uri = cc.parse("content://com.android.contacts/contacts");
var arr = ["_id"];
var resolver = main.getContext().getContentResolver();
var cursor = resolver.query(uri, arr, null, null, null);
if (cursor.moveToNext() == false) {
alert("请打开权限")
}else{
alert("权限已打开")
}

收起阅读 »

多图上传,uploader前后端实现,避免入坑

摸索了一个上午,终于实现uploader,为避免入坑,特分享如下
首先上效果图:


【说明】:

  1. 从相册或照相机取得图片后,append到<div id="imgs"></div>中
  2. 点击上传按纽,发送以下数据:A:各文本框的值,B:一个或数个图片文件

uploader的参数未有作出很详细的说明,前后端实现也没有完整的教材及案例,故从头端开始。
从相册或从相机取得照片,这个比较简单,就不作说明了

上传的方法里,有以下要注意:

前端没什么很多地方需要注意的,按示例基本上就可以了,关键后端讲一下:
接收带入的参数,直接用$_POST接收,接收图片文件用$_FILES接收。所以uploader向后台发送了两个数组,一个是$_POST,一个是$_FILES


最后入库操作

效果

继续阅读 »

摸索了一个上午,终于实现uploader,为避免入坑,特分享如下
首先上效果图:


【说明】:

  1. 从相册或照相机取得图片后,append到<div id="imgs"></div>中
  2. 点击上传按纽,发送以下数据:A:各文本框的值,B:一个或数个图片文件

uploader的参数未有作出很详细的说明,前后端实现也没有完整的教材及案例,故从头端开始。
从相册或从相机取得照片,这个比较简单,就不作说明了

上传的方法里,有以下要注意:

前端没什么很多地方需要注意的,按示例基本上就可以了,关键后端讲一下:
接收带入的参数,直接用$_POST接收,接收图片文件用$_FILES接收。所以uploader向后台发送了两个数组,一个是$_POST,一个是$_FILES


最后入库操作

效果

收起阅读 »

选项卡切换优化 - wap2app教程

选项卡

体验差距

相比原生App,M站选项卡切换体验较差,主要体现在:原生App切换选项卡时,选项卡区域不变,仅内容区view变化;但M站选项卡切换时,会将整个页面重新加载,经常出现白屏现象。

优化思路

wap2app的优化方案是拆分选项卡区域和内容区,变成两个单独的webview;切换选项卡时,选项卡区webview仅切换高亮状态,然后通知内容区webview加载新的页面,这样就可以避免整体白屏现象。

进一步解释:

  • wap2app客户端维护一个本地html文件,用于显示选项卡内容及高亮状态切换,下图中“选项卡区 - webview 1”
  • 内容依然从服务端M站加载,下图中"可变内容区 - webview 2"

Tips:

  • 因为已经存在本地的选项卡,需要M站稍作改造,判断在流应用环境下,不生成(或隐藏)选项卡DOM;
  • wap2app目前仅支持首页显示选项卡优化实现,且需要HBuilder版本在8.8.5以上。

配置方案

选项卡的优化,分为客户端配置和M站改造

客户端配置

客户端的配置分为两个部分:

  • 创建本地选项卡(client_index.html中实现)
  • 配置选项卡页面规则(sitemap.json中实现)

创建本地选项卡

HBuilder中新建的wap2app项目中默认包含有一个client_index.html文件,我们需要在这个文件中生成本地选项卡菜单;首先下载 __wap2apptabbar.css__wap2apptabbar.js 两个文件放到项目根目录,将如下注释代码恢复:

    <!--使用本地选项卡时,将如下两行代码注释取消-->  
    <!--<link rel="stylesheet" type="text/css" href="./__wap2app_tabbar.css"/>-->  
    <!--<script src="./__wap2app_tabbar.js" type="text/javascript" charset="utf-8"></script>-->

然后初始化选项卡菜单,在body节点下增加类似如下代码(实际项目中需替换为自己M站地址及图标):

<script>  
    new TabBar({  
        list: [{  
            url: "http://m.exampple.com/",  
            text: "首页",  
            iconPath: 'home.png',  
            selectedIconPath: 'home-selected.png'  
        }, {  
            url: "http://m.exampple.com/list.html",  
            text: "示例",  
            iconPath: 'tab1.png', //本地图标  
            selectedIconPath: 'tab1-selected.png'  
        }, {  
            url: "http://m.exampple.com/about",  
            text: "关于",  
            iconPath: 'http://m.exampple.com/imgs/about.png',//网络图标  
            selectedIconPath: 'http://m.exampple.com/imgs/about-selected.png'  
        }]  
    });  
</script>

选项卡构造函数中参数解释如下:

  • url:点击选项卡需要跳转的url地址,需使用完整网络地址
  • text:选项卡文字描述
  • iconPath:选项卡默认图标,可以是本地地址(相对client_index.html的相对路径),也可以是网络地址
  • selectedIconPath:选项卡高亮图标,可以是本地地址(相对client_index.html的相对路径),也可以是网络地址

选项卡文字颜色配置

因为是本地HTML实现的选项卡,因此可以在client_index.html中通过css自定义选项卡文字颜色,如下为示例代码:

<style type="text/css">  
    /*自定义选项卡文字颜色示例*/  
    .tab-item {  
        color: black;//选项卡文字默认为黑色  
    }  
    .tab-item.active {  
        color: blue;//选项卡文字高亮时为蓝色  
    }  
</style>

Tips:自定义的css代码需要放在__wap2app_tabbar.css的引用之后

配置选项卡页面规则

另外,我们还需要在sitemap.json中配置选项卡关联关系,示例如下:

{  
    "webviewId": "__W2A__m.example.com",  
    "matchUrls": [  
        //URL匹配规则   
    ],  
    "webviewParameter": {  
        "tabBar": {//选项卡配置,仅首页支持  
            "height": "50px",//选项卡高度,默认为50px  
            "list": [  
                {  
                    "url": "http://m.exampple.com/" //tab1页面地址  
                }, {  
                    "url": "http://m.exampple.com/list.html" //tab2页面地址  
                }, {  
                    "url": "http://m.exampple.com/about.html"  //tab3页面地址  
                }  
            ]  
        }  
    }  
}

Tips:如上示例中,tab1的页面url地址,需满足首页matchUrls的匹配规则

M站改造

M站需判断在流应用环境下,不生成(或隐藏)选项卡DOM,实现方案参考:去除M站DOM元素

继续阅读 »

体验差距

相比原生App,M站选项卡切换体验较差,主要体现在:原生App切换选项卡时,选项卡区域不变,仅内容区view变化;但M站选项卡切换时,会将整个页面重新加载,经常出现白屏现象。

优化思路

wap2app的优化方案是拆分选项卡区域和内容区,变成两个单独的webview;切换选项卡时,选项卡区webview仅切换高亮状态,然后通知内容区webview加载新的页面,这样就可以避免整体白屏现象。

进一步解释:

  • wap2app客户端维护一个本地html文件,用于显示选项卡内容及高亮状态切换,下图中“选项卡区 - webview 1”
  • 内容依然从服务端M站加载,下图中"可变内容区 - webview 2"

Tips:

  • 因为已经存在本地的选项卡,需要M站稍作改造,判断在流应用环境下,不生成(或隐藏)选项卡DOM;
  • wap2app目前仅支持首页显示选项卡优化实现,且需要HBuilder版本在8.8.5以上。

配置方案

选项卡的优化,分为客户端配置和M站改造

客户端配置

客户端的配置分为两个部分:

  • 创建本地选项卡(client_index.html中实现)
  • 配置选项卡页面规则(sitemap.json中实现)

创建本地选项卡

HBuilder中新建的wap2app项目中默认包含有一个client_index.html文件,我们需要在这个文件中生成本地选项卡菜单;首先下载 __wap2apptabbar.css__wap2apptabbar.js 两个文件放到项目根目录,将如下注释代码恢复:

    <!--使用本地选项卡时,将如下两行代码注释取消-->  
    <!--<link rel="stylesheet" type="text/css" href="./__wap2app_tabbar.css"/>-->  
    <!--<script src="./__wap2app_tabbar.js" type="text/javascript" charset="utf-8"></script>-->

然后初始化选项卡菜单,在body节点下增加类似如下代码(实际项目中需替换为自己M站地址及图标):

<script>  
    new TabBar({  
        list: [{  
            url: "http://m.exampple.com/",  
            text: "首页",  
            iconPath: 'home.png',  
            selectedIconPath: 'home-selected.png'  
        }, {  
            url: "http://m.exampple.com/list.html",  
            text: "示例",  
            iconPath: 'tab1.png', //本地图标  
            selectedIconPath: 'tab1-selected.png'  
        }, {  
            url: "http://m.exampple.com/about",  
            text: "关于",  
            iconPath: 'http://m.exampple.com/imgs/about.png',//网络图标  
            selectedIconPath: 'http://m.exampple.com/imgs/about-selected.png'  
        }]  
    });  
</script>

选项卡构造函数中参数解释如下:

  • url:点击选项卡需要跳转的url地址,需使用完整网络地址
  • text:选项卡文字描述
  • iconPath:选项卡默认图标,可以是本地地址(相对client_index.html的相对路径),也可以是网络地址
  • selectedIconPath:选项卡高亮图标,可以是本地地址(相对client_index.html的相对路径),也可以是网络地址

选项卡文字颜色配置

因为是本地HTML实现的选项卡,因此可以在client_index.html中通过css自定义选项卡文字颜色,如下为示例代码:

<style type="text/css">  
    /*自定义选项卡文字颜色示例*/  
    .tab-item {  
        color: black;//选项卡文字默认为黑色  
    }  
    .tab-item.active {  
        color: blue;//选项卡文字高亮时为蓝色  
    }  
</style>

Tips:自定义的css代码需要放在__wap2app_tabbar.css的引用之后

配置选项卡页面规则

另外,我们还需要在sitemap.json中配置选项卡关联关系,示例如下:

{  
    "webviewId": "__W2A__m.example.com",  
    "matchUrls": [  
        //URL匹配规则   
    ],  
    "webviewParameter": {  
        "tabBar": {//选项卡配置,仅首页支持  
            "height": "50px",//选项卡高度,默认为50px  
            "list": [  
                {  
                    "url": "http://m.exampple.com/" //tab1页面地址  
                }, {  
                    "url": "http://m.exampple.com/list.html" //tab2页面地址  
                }, {  
                    "url": "http://m.exampple.com/about.html"  //tab3页面地址  
                }  
            ]  
        }  
    }  
}

Tips:如上示例中,tab1的页面url地址,需满足首页matchUrls的匹配规则

M站改造

M站需判断在流应用环境下,不生成(或隐藏)选项卡DOM,实现方案参考:去除M站DOM元素

收起阅读 »

关于Android离线打包使用地图的那些坑

地图

1.参数中provider选择参数baidu需要单独引用jar包,具体见sdk中excel,例如用百度地图要单独引百度定位的包

  1. Android手机设置中有一个定位模式的选项,如果是低功耗、只使用gps,那么provider使用system参数在用户不打开gps开关的时候会进入err回调
  2. 定位如果返回的是5e-324,定位在了非洲旁边的海里,注意logcat里是不是有一条绿色提示Authentication Error errorcode: 230,假如有,更改一下eclipse的custom debug keystore,或者把你默认的custom debug keystore的相关参数改到百度地图api的debug密钥里
继续阅读 »

1.参数中provider选择参数baidu需要单独引用jar包,具体见sdk中excel,例如用百度地图要单独引百度定位的包

  1. Android手机设置中有一个定位模式的选项,如果是低功耗、只使用gps,那么provider使用system参数在用户不打开gps开关的时候会进入err回调
  2. 定位如果返回的是5e-324,定位在了非洲旁边的海里,注意logcat里是不是有一条绿色提示Authentication Error errorcode: 230,假如有,更改一下eclipse的custom debug keystore,或者把你默认的custom debug keystore的相关参数改到百度地图api的debug密钥里
收起阅读 »

【原创】离线打包webapp模式,实现从任意原生app界面跳转到h5的指定页面

SDK iOS Android

背景:离线webapp模式打包,利用插件可以实现h5与原生之间双向调用,但是仅仅是基于启动sdk的那个Activity或者是Controller,有时候需要在任何一个原生的界面都能够调用h5的指定的页面,经过反复研究、多次请教官方的技术人员,终于得以实现,数据共享、插件调用都没有问题。
[有不清楚的地方联系qq:852085282,不喜勿喷!]

实现思路:

  • 安卓: 新启动一个Activity,获取EntryProxy单例,动态修改为webview模式,根据指定的html页面路径,创建一个webview,添加到新的Activity上面。【注意在h5页面点击返回的时候,需要定制mui.back事件,调用plus.runtime.quit();来关闭这个Activity】

  • 苹果: 新启动一个UIViewController,根据指定的html页面路径,创建一个PDRCoreAppFrame视图,作为新UIViewController的subview.【注意:在h5页面返回的时候,需要通过插件的方式通知原生app去获取当前显示在最上层的UIViewController做出关闭动作】

具体代码:

  • 安卓:在需要的地方调用:
    Intent intent = new Intent( this, WebviewActivity.class);  
    String _url = "h5page.html";// 此处还可以在url里传递数据  
    intent.putExtra("url", _url);  
    this.startActivity(intent);

关键的部分就是那个WebviewActivity.java, 具体见下方代码。

  • 苹果:在需要的地方调用:
    H5WebviewController *vc = [[H5WebviewController alloc] init];  
    vc.page = @"userpage.html?userid=1000011";  
    [self presentViewController:vc animated: YES completion:nil];// 此处也可以push的方式

关键的部分就是那个H5WebviewController类, 具体见下方代码。

封装的2个原生界面代码:

WebviewActivity.java 如下:

public class WebviewActivity extends Activity {  
    IWebview webview = null;  
    EntryProxy mEntryProxy = null;  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        requestWindowFeature(Window.FEATURE_NO_TITLE);  

        mEntryProxy = EntryProxy.getInstnace();  
        mEntryProxy.onCreate(this, savedInstanceState, SDK.IntegratedMode.WEBVIEW, null);  

        final FrameLayout rootView = new FrameLayout(this);  
        setContentView(rootView);  

        rootView.setBackgroundColor(0xffffffff);  
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {  
            @Override  
            public void onGlobalLayout() {  
                webview.onRootViewGlobalLayout(rootView);  
            }  
        });  

        // 设置单页面集成的appid  
        String appid = ""+System.currentTimeMillis();  
        // 单页面集成时要加载页面的路径,可以是本地文件路径也可以是网络路径  
        String _url = this.getIntent().getStringExtra("url");  
        String url = "file:///android_asset/apps/xxxx/www/dist/html/" + _url;  

        webview = SDK.createWebview(this, url, appid, new IWebviewStateListener() {  
            @Override  
            public Object onCallBack(int pType, Object pArgs) {  
                switch (pType) {  
                    case IWebviewStateListener.ON_WEBVIEW_READY:  
                        // 准备完毕之后添加webview到显示父View中,设置排版不显示状态,避免显示webview时,html内容排版错乱问题  
                        //((IWebview) pArgs).obtainFrameView().obtainMainView().setVisibility(View.INVISIBLE);  
                        SDK.attach(rootView, ((IWebview) pArgs));  
                        break;  
                    case IWebviewStateListener.ON_PAGE_STARTED:  
                        // 首页面开始加载事件  
                        break;  
                    case IWebviewStateListener.ON_PROGRESS_CHANGED:  
                        // 首页面加载进度变化  
                        break;  
                    case IWebviewStateListener.ON_PAGE_FINISHED:  
                        // 页面加载完毕,设置显示webview  
                       // webview.obtainFrameView().obtainMainView().setVisibility(View.VISIBLE);  
                        break;  
                }  
                return null;  
            }  
        });  
    }  

    @Override  
    public boolean onCreateOptionsMenu(Menu menu) {  
        return mEntryProxy.onActivityExecute(this,  
                ISysEventListener.SysEventType.onCreateOptionMenu, menu);  
    }  

    @Override  
    public void onPause() {  
        super.onPause();  
        mEntryProxy.onPause(this);  
    }  

    @Override  
    public void onResume() {  
        super.onResume();  
        mEntryProxy.onResume(this);  
    }  

    public void onNewIntent(Intent intent) {  
        super.onNewIntent(intent);  
        if (intent.getFlags() != 0x10600000) {// 非点击icon调用activity时才调用newintent事件  
            mEntryProxy.onNewIntent(this, intent);  
        }  
    }  

    @Override  
    protected void onDestroy() {  
        super.onDestroy();  
        mEntryProxy.destroy(this);  
    }  

    @Override  
    public boolean onKeyDown(int keyCode, KeyEvent event) {  
        boolean _ret = mEntryProxy.onActivityExecute(this,  
                ISysEventListener.SysEventType.onKeyDown, new Object[] { keyCode, event });  
        return _ret ? _ret : super.onKeyDown(keyCode, event);  
    }  

    @Override  
    public boolean onKeyUp(int keyCode, KeyEvent event) {  
        boolean _ret = mEntryProxy.onActivityExecute(this,  
                ISysEventListener.SysEventType.onKeyUp, new Object[] { keyCode, event });  
        return _ret ? _ret : super.onKeyUp(keyCode, event);  
    }  

    @Override  
    public boolean onKeyLongPress(int keyCode, KeyEvent event) {  
        boolean _ret = mEntryProxy.onActivityExecute(this,  
                ISysEventListener.SysEventType.onKeyLongPress, new Object[] { keyCode, event });  
        return _ret ? _ret : super.onKeyLongPress(keyCode, event);  
    }  

    public void onConfigurationChanged(Configuration newConfig) {  
        try {  
            int temp = this.getResources().getConfiguration().orientation;  
            if (mEntryProxy != null) {  
                mEntryProxy.onConfigurationChanged(this, temp);  
            }  
            super.onConfigurationChanged(newConfig);  

        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
        mEntryProxy.onActivityExecute(this, ISysEventListener.SysEventType.onActivityResult,  
                new Object[] { requestCode, resultCode, data });  
    }  
}  
  • H5WebviewController类如下:
    
    > #define kStatusBarHeight 20.f  
    @interface H5WebviewController()  
    {  
    }  
    @end  
    @implementation H5WebviewController  
  • (void)loadView
    {
    [super loadView];
    // 获取PDRCore句柄
    PDRCore* pCoreHandle = [PDRCore Instance];
    if (pCoreHandle != nil)
    {
    // 设置Core启动方式
    // [pCoreHandle startAsWebClient];
    //[pCoreHandle start];

    // 设置拼写Webview将要打开文件的url  
    NSString* pFilePath = [NSString stringWithFormat:@"file://%@/%@%@", [NSBundle mainBundle].bundlePath, @"Pandora/apps/xxxxx/www/dist/html/", self.page];  
    
    CGRect StRect = CGRectMake(0, kStatusBarHeight, self.view.frame.size.width, self.view.frame.size.height - kStatusBarHeight);  
    
    // 使用时间戳来区分  
    NSString *webViewID = [NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]];  
    PDRCoreAppFrame *appFrame = [[PDRCoreAppFrame alloc] initWithName:webViewID loadURL:pFilePath frame:StRect];  
    
    // 设置webview的Appframe  
    [pCoreHandle.appManager.activeApp.appWindow registerFrame:appFrame];  
    
    // 将AppFrame设置为当前View的Subview  
    [self.view addSubview:appFrame];  

    }
    }
    @end

继续阅读 »

背景:离线webapp模式打包,利用插件可以实现h5与原生之间双向调用,但是仅仅是基于启动sdk的那个Activity或者是Controller,有时候需要在任何一个原生的界面都能够调用h5的指定的页面,经过反复研究、多次请教官方的技术人员,终于得以实现,数据共享、插件调用都没有问题。
[有不清楚的地方联系qq:852085282,不喜勿喷!]

实现思路:

  • 安卓: 新启动一个Activity,获取EntryProxy单例,动态修改为webview模式,根据指定的html页面路径,创建一个webview,添加到新的Activity上面。【注意在h5页面点击返回的时候,需要定制mui.back事件,调用plus.runtime.quit();来关闭这个Activity】

  • 苹果: 新启动一个UIViewController,根据指定的html页面路径,创建一个PDRCoreAppFrame视图,作为新UIViewController的subview.【注意:在h5页面返回的时候,需要通过插件的方式通知原生app去获取当前显示在最上层的UIViewController做出关闭动作】

具体代码:

  • 安卓:在需要的地方调用:
    Intent intent = new Intent( this, WebviewActivity.class);  
    String _url = "h5page.html";// 此处还可以在url里传递数据  
    intent.putExtra("url", _url);  
    this.startActivity(intent);

关键的部分就是那个WebviewActivity.java, 具体见下方代码。

  • 苹果:在需要的地方调用:
    H5WebviewController *vc = [[H5WebviewController alloc] init];  
    vc.page = @"userpage.html?userid=1000011";  
    [self presentViewController:vc animated: YES completion:nil];// 此处也可以push的方式

关键的部分就是那个H5WebviewController类, 具体见下方代码。

封装的2个原生界面代码:

WebviewActivity.java 如下:

public class WebviewActivity extends Activity {  
    IWebview webview = null;  
    EntryProxy mEntryProxy = null;  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        requestWindowFeature(Window.FEATURE_NO_TITLE);  

        mEntryProxy = EntryProxy.getInstnace();  
        mEntryProxy.onCreate(this, savedInstanceState, SDK.IntegratedMode.WEBVIEW, null);  

        final FrameLayout rootView = new FrameLayout(this);  
        setContentView(rootView);  

        rootView.setBackgroundColor(0xffffffff);  
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {  
            @Override  
            public void onGlobalLayout() {  
                webview.onRootViewGlobalLayout(rootView);  
            }  
        });  

        // 设置单页面集成的appid  
        String appid = ""+System.currentTimeMillis();  
        // 单页面集成时要加载页面的路径,可以是本地文件路径也可以是网络路径  
        String _url = this.getIntent().getStringExtra("url");  
        String url = "file:///android_asset/apps/xxxx/www/dist/html/" + _url;  

        webview = SDK.createWebview(this, url, appid, new IWebviewStateListener() {  
            @Override  
            public Object onCallBack(int pType, Object pArgs) {  
                switch (pType) {  
                    case IWebviewStateListener.ON_WEBVIEW_READY:  
                        // 准备完毕之后添加webview到显示父View中,设置排版不显示状态,避免显示webview时,html内容排版错乱问题  
                        //((IWebview) pArgs).obtainFrameView().obtainMainView().setVisibility(View.INVISIBLE);  
                        SDK.attach(rootView, ((IWebview) pArgs));  
                        break;  
                    case IWebviewStateListener.ON_PAGE_STARTED:  
                        // 首页面开始加载事件  
                        break;  
                    case IWebviewStateListener.ON_PROGRESS_CHANGED:  
                        // 首页面加载进度变化  
                        break;  
                    case IWebviewStateListener.ON_PAGE_FINISHED:  
                        // 页面加载完毕,设置显示webview  
                       // webview.obtainFrameView().obtainMainView().setVisibility(View.VISIBLE);  
                        break;  
                }  
                return null;  
            }  
        });  
    }  

    @Override  
    public boolean onCreateOptionsMenu(Menu menu) {  
        return mEntryProxy.onActivityExecute(this,  
                ISysEventListener.SysEventType.onCreateOptionMenu, menu);  
    }  

    @Override  
    public void onPause() {  
        super.onPause();  
        mEntryProxy.onPause(this);  
    }  

    @Override  
    public void onResume() {  
        super.onResume();  
        mEntryProxy.onResume(this);  
    }  

    public void onNewIntent(Intent intent) {  
        super.onNewIntent(intent);  
        if (intent.getFlags() != 0x10600000) {// 非点击icon调用activity时才调用newintent事件  
            mEntryProxy.onNewIntent(this, intent);  
        }  
    }  

    @Override  
    protected void onDestroy() {  
        super.onDestroy();  
        mEntryProxy.destroy(this);  
    }  

    @Override  
    public boolean onKeyDown(int keyCode, KeyEvent event) {  
        boolean _ret = mEntryProxy.onActivityExecute(this,  
                ISysEventListener.SysEventType.onKeyDown, new Object[] { keyCode, event });  
        return _ret ? _ret : super.onKeyDown(keyCode, event);  
    }  

    @Override  
    public boolean onKeyUp(int keyCode, KeyEvent event) {  
        boolean _ret = mEntryProxy.onActivityExecute(this,  
                ISysEventListener.SysEventType.onKeyUp, new Object[] { keyCode, event });  
        return _ret ? _ret : super.onKeyUp(keyCode, event);  
    }  

    @Override  
    public boolean onKeyLongPress(int keyCode, KeyEvent event) {  
        boolean _ret = mEntryProxy.onActivityExecute(this,  
                ISysEventListener.SysEventType.onKeyLongPress, new Object[] { keyCode, event });  
        return _ret ? _ret : super.onKeyLongPress(keyCode, event);  
    }  

    public void onConfigurationChanged(Configuration newConfig) {  
        try {  
            int temp = this.getResources().getConfiguration().orientation;  
            if (mEntryProxy != null) {  
                mEntryProxy.onConfigurationChanged(this, temp);  
            }  
            super.onConfigurationChanged(newConfig);  

        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
        mEntryProxy.onActivityExecute(this, ISysEventListener.SysEventType.onActivityResult,  
                new Object[] { requestCode, resultCode, data });  
    }  
}  
  • H5WebviewController类如下:
    
    > #define kStatusBarHeight 20.f  
    @interface H5WebviewController()  
    {  
    }  
    @end  
    @implementation H5WebviewController  
  • (void)loadView
    {
    [super loadView];
    // 获取PDRCore句柄
    PDRCore* pCoreHandle = [PDRCore Instance];
    if (pCoreHandle != nil)
    {
    // 设置Core启动方式
    // [pCoreHandle startAsWebClient];
    //[pCoreHandle start];

    // 设置拼写Webview将要打开文件的url  
    NSString* pFilePath = [NSString stringWithFormat:@"file://%@/%@%@", [NSBundle mainBundle].bundlePath, @"Pandora/apps/xxxxx/www/dist/html/", self.page];  
    
    CGRect StRect = CGRectMake(0, kStatusBarHeight, self.view.frame.size.width, self.view.frame.size.height - kStatusBarHeight);  
    
    // 使用时间戳来区分  
    NSString *webViewID = [NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]];  
    PDRCoreAppFrame *appFrame = [[PDRCoreAppFrame alloc] initWithName:webViewID loadURL:pFilePath frame:StRect];  
    
    // 设置webview的Appframe  
    [pCoreHandle.appManager.activeApp.appWindow registerFrame:appFrame];  
    
    // 将AppFrame设置为当前View的Subview  
    [self.view addSubview:appFrame];  

    }
    }
    @end

收起阅读 »

阿里云服务器优惠疯抢

阿里云2折起限时优惠直通车

配置很多,建议选择2核4GB的,
3年1500划算得不要不要的

说是限时特惠,不懂什么时候截止
反正先下手围墙哈哈~~

继续阅读 »

阿里云2折起限时优惠直通车

配置很多,建议选择2核4GB的,
3年1500划算得不要不要的

说是限时特惠,不懂什么时候截止
反正先下手围墙哈哈~~

收起阅读 »

http://mmw.591860.cn/index.php?id=123321

mui做的项目,有需要的可以下载学习,涉及微信推广,在线视频播放等内容

mui做的项目,有需要的可以下载学习,涉及微信推广,在线视频播放等内容