HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

诚聘H5前端开发人员

HTML5+ mui HTML5 招聘

工作地点: 北京

工作内容:开发维护公司的网站及移动APP

工作要求:

Web开发经验、移动端开发经验

熟练运用HTML、CSS进行网页制作。

熟悉HTML5及CSS3特性,了解响应式设计

精通Javascript语言的各特性,掌握Ajax

能熟练使用Hbuilder,H5 ,Mui框架者更佳

有Html5 APP经验者优先

请发送简历至 mike@kingnova.net

不怕经验不足,就怕没进取心,期待您的加入!

继续阅读 »

工作地点: 北京

工作内容:开发维护公司的网站及移动APP

工作要求:

Web开发经验、移动端开发经验

熟练运用HTML、CSS进行网页制作。

熟悉HTML5及CSS3特性,了解响应式设计

精通Javascript语言的各特性,掌握Ajax

能熟练使用Hbuilder,H5 ,Mui框架者更佳

有Html5 APP经验者优先

请发送简历至 mike@kingnova.net

不怕经验不足,就怕没进取心,期待您的加入!

收起阅读 »

IOS平台使用SDK集成,Native代码和HTML页面进行交互的方法

集成 iOS SDK

Native代码保存数据,HTML页面读取数据

用户可在Native代码或者HTML页面中使用NSUserDefaults类来保存数据,并在另一侧获取

页面保存数据native代码获取

JS Code

在HTML页面中调用如下代码实现数据的保存  
function SetUserDefault(key, value)  
        {  
            if (typeof value != 'undefined' && typeof key === "string")  
            {  
                var UserDefaultsClass = plus.ios.importClass("NSUserDefaults");  
                var standardUserDefaults = UserDefaultsClass.standardUserDefaults();  
                plus.ios.invoke(standardUserDefaults, "setObject:forKey:", value, key);  
                plus.ios.invoke(standardUserDefaults,"synchronize");  
            }  
        }

Objective-c Code
在native代码中调用如下方法,获取在HTML页面中保存的数据

 NSUserDefaults* pDefDefaults = [NSUserDefaults standardUserDefaults];  
    if (pDefDefaults) {  
        NSString* pString =  [pDefDefaults objectForKey:@"Input Your Key"];          
    }

Native保存数据,页面获取数据

JS Code
在HTML页面中调用如下方法,实现读取Native保存的数据

function getUserDefault(key)  
        {  
            if(typeof key != 'undefined' && typeof key === "string")  
            {  
                var UserDefaultsClass = plus.ios.importClass("NSUserDefaults");  
                var standardUserDefaults = UserDefaultsClass.standardUserDefaults();  
                return plus.ios.invoke(standardUserDefaults, "objectForKey:", key);  
            }  
            return null;  
        }

Objective-c Code
在Native代码中调用如下方法,实现保存数据

   NSUserDefaults* pDefDefaults = [NSUserDefaults standardUserDefaults];  
    if (pDefDefaults) {  
        [pDefDefaults setObject:@"Input Your Value" forKey:@"Input Your Key"];  
    }

Native代码调用当前运行应用的指定HTML页面内的JS方法

开发者可通过以下方法,在Native层找到需要交互的Webview对象,并触发该页面中的JS方法

根据webview的ID找到对应的HTML页面,并执行页面的JS方法

     PDRCoreAppFrame* pFrame = [[[[[PDRCore Instance] appManager] activeApp] appWindow] getFrameByName:@"plus/audio.html"];  
    if (pFrame)  
    {  
        // 找到指定的页面并调用stringByEvaluatingJavaScriptFromString方法调用该html页面的JS方法  
        [pFrame stringByEvaluatingJavaScriptFromString:@"InputJSFunctionNameInHtmlPage()"];  
    }

找到应用的主页面,并调用HTML中的JS方法

     PDRCoreAppFrame* pMainFrame =[[[[PDRCore Instance] appManager] activeApp] mainFrame] ;  
    if (pMainFrame) {  

        [pMainFrame stringByEvaluatingJavaScriptFromString:@"InputJSFunctionNameInHtmlPage()"];  
    }

HTML 页面调用原生方法

开发者可使用NativeJS调用已经写好的原生类的方法,也可以用NativeJS发送一个消息,由原生代码接收这个消息并处理
//IOS NJS 代码发送消息到原生层的示例
var notiClass = plus.ios.importClass("NSNotificationCenter");
notiClass.defaultCenter().postNotificationNameobject("CloseWebAPP",null);

继续阅读 »

Native代码保存数据,HTML页面读取数据

用户可在Native代码或者HTML页面中使用NSUserDefaults类来保存数据,并在另一侧获取

页面保存数据native代码获取

JS Code

在HTML页面中调用如下代码实现数据的保存  
function SetUserDefault(key, value)  
        {  
            if (typeof value != 'undefined' && typeof key === "string")  
            {  
                var UserDefaultsClass = plus.ios.importClass("NSUserDefaults");  
                var standardUserDefaults = UserDefaultsClass.standardUserDefaults();  
                plus.ios.invoke(standardUserDefaults, "setObject:forKey:", value, key);  
                plus.ios.invoke(standardUserDefaults,"synchronize");  
            }  
        }

Objective-c Code
在native代码中调用如下方法,获取在HTML页面中保存的数据

 NSUserDefaults* pDefDefaults = [NSUserDefaults standardUserDefaults];  
    if (pDefDefaults) {  
        NSString* pString =  [pDefDefaults objectForKey:@"Input Your Key"];          
    }

Native保存数据,页面获取数据

JS Code
在HTML页面中调用如下方法,实现读取Native保存的数据

function getUserDefault(key)  
        {  
            if(typeof key != 'undefined' && typeof key === "string")  
            {  
                var UserDefaultsClass = plus.ios.importClass("NSUserDefaults");  
                var standardUserDefaults = UserDefaultsClass.standardUserDefaults();  
                return plus.ios.invoke(standardUserDefaults, "objectForKey:", key);  
            }  
            return null;  
        }

Objective-c Code
在Native代码中调用如下方法,实现保存数据

   NSUserDefaults* pDefDefaults = [NSUserDefaults standardUserDefaults];  
    if (pDefDefaults) {  
        [pDefDefaults setObject:@"Input Your Value" forKey:@"Input Your Key"];  
    }

Native代码调用当前运行应用的指定HTML页面内的JS方法

开发者可通过以下方法,在Native层找到需要交互的Webview对象,并触发该页面中的JS方法

根据webview的ID找到对应的HTML页面,并执行页面的JS方法

     PDRCoreAppFrame* pFrame = [[[[[PDRCore Instance] appManager] activeApp] appWindow] getFrameByName:@"plus/audio.html"];  
    if (pFrame)  
    {  
        // 找到指定的页面并调用stringByEvaluatingJavaScriptFromString方法调用该html页面的JS方法  
        [pFrame stringByEvaluatingJavaScriptFromString:@"InputJSFunctionNameInHtmlPage()"];  
    }

找到应用的主页面,并调用HTML中的JS方法

     PDRCoreAppFrame* pMainFrame =[[[[PDRCore Instance] appManager] activeApp] mainFrame] ;  
    if (pMainFrame) {  

        [pMainFrame stringByEvaluatingJavaScriptFromString:@"InputJSFunctionNameInHtmlPage()"];  
    }

HTML 页面调用原生方法

开发者可使用NativeJS调用已经写好的原生类的方法,也可以用NativeJS发送一个消息,由原生代码接收这个消息并处理
//IOS NJS 代码发送消息到原生层的示例
var notiClass = plus.ios.importClass("NSNotificationCenter");
notiClass.defaultCenter().postNotificationNameobject("CloseWebAPP",null);

收起阅读 »

ios 下拉刷新中进行重置上拉加载失效的问题

下拉刷新

情况如下:
ajax获取20条数据显示在滚动页面上,上拉加载获取8条数据,3次上拉后数据加载完毕底部出现没有更多数据了,进行下拉刷新后上拉出现底部没有更多数据了但不进行上拉加载数据
(查文档说用mui('#下拉容器id').pullRefresh().refresh(true);是进行上拉加载重新激活)
下拉刷新数据加载完后加了(加粗的部分)
mui('#pullrefresh').pullRefresh().refresh(true);
mui('#pullrefresh').pullRefresh().endPulldownToRefresh();

在android中测试上拉加载到出现没有更多数据了,在进行下拉刷新后在进行上拉加载可以加载数据,测试正常,
但是在iphone5s ios8中测试出现下拉刷新与上拉加载失效
后来换成
mui('#pullrefresh').pullRefresh().endPulldownToRefresh();
mui('#pullrefresh').pullRefresh().refresh(true);
ios测试正常 有点坑,遂记之。

继续阅读 »

情况如下:
ajax获取20条数据显示在滚动页面上,上拉加载获取8条数据,3次上拉后数据加载完毕底部出现没有更多数据了,进行下拉刷新后上拉出现底部没有更多数据了但不进行上拉加载数据
(查文档说用mui('#下拉容器id').pullRefresh().refresh(true);是进行上拉加载重新激活)
下拉刷新数据加载完后加了(加粗的部分)
mui('#pullrefresh').pullRefresh().refresh(true);
mui('#pullrefresh').pullRefresh().endPulldownToRefresh();

在android中测试上拉加载到出现没有更多数据了,在进行下拉刷新后在进行上拉加载可以加载数据,测试正常,
但是在iphone5s ios8中测试出现下拉刷新与上拉加载失效
后来换成
mui('#pullrefresh').pullRefresh().endPulldownToRefresh();
mui('#pullrefresh').pullRefresh().refresh(true);
ios测试正常 有点坑,遂记之。

收起阅读 »

官方的demo里的tab-webview-main.html里面如何能够让webview打开第三方网站?

比如点击后打开http://www.dcloud.io

<a id="defaultTab" class="mui-tab-item mui-active" href="http://www.dclound.io/">
<span class="mui-icon mui-icon-home"></span>
<span class="mui-tab-label">首页</span>
</a>

刚接触mui。

继续阅读 »

比如点击后打开http://www.dcloud.io

<a id="defaultTab" class="mui-tab-item mui-active" href="http://www.dclound.io/">
<span class="mui-icon mui-icon-home"></span>
<span class="mui-tab-label">首页</span>
</a>

刚接触mui。

收起阅读 »

Objective-C中的存取方法

iOS

iOS开发中,因为Objective-C的发展问题,Objective-C里存取方法有好几种,不同时期的代码采用的不同方式,往往让人感到迷惑,下面就来看看Objective-C中有哪些存取方法吧。

通过@property关键字

在.h接口文件中通过@property关键字去声明变量

@property id variableName;
然后再在.m实现文件中,通过@synthesize指令,告诉编译器,让其帮你生成相应的setter和getter方法

不用@systhesize指令

我们也经常会在一些教程的代码中看到,变量名开头有个下划线,这个其实就是采用了@property关键字,但是没有使用@systhesize指令去让编译器自动生成相应的方法,这时访问实例变量需要再原来的变量名前面加一个下划线。

自己去实现

比较原始的方法就是这个,自己去实现getter和setter方法,

  • (void) setProperty: (id) value;
  • (id) property;
继续阅读 »

iOS开发中,因为Objective-C的发展问题,Objective-C里存取方法有好几种,不同时期的代码采用的不同方式,往往让人感到迷惑,下面就来看看Objective-C中有哪些存取方法吧。

通过@property关键字

在.h接口文件中通过@property关键字去声明变量

@property id variableName;
然后再在.m实现文件中,通过@synthesize指令,告诉编译器,让其帮你生成相应的setter和getter方法

不用@systhesize指令

我们也经常会在一些教程的代码中看到,变量名开头有个下划线,这个其实就是采用了@property关键字,但是没有使用@systhesize指令去让编译器自动生成相应的方法,这时访问实例变量需要再原来的变量名前面加一个下划线。

自己去实现

比较原始的方法就是这个,自己去实现getter和setter方法,

  • (void) setProperty: (id) value;
  • (id) property;
收起阅读 »

简约风格在网页设计中的应用

随着网页技术的不断发展,网页设计的趋势在改变,扁平化、响应式、视觉差滚动、卡片式等给设计师带来了更多的发挥空间。在网页中,简约的设计,往往具清晰的页面结构、简单的交互操作等特征,在满足传递信息的同时,从视觉体验的角度,为用户带来轻松、愉悦的美感,那么在网页中,通过以下几种方式可以做到简约设计。

1、大背景
大图片背景,是目前应用最多的一种网页呈现方式。将整张大图片作为背景,不仅能产生强烈的视觉冲击力,还可以对网页内容起到一个很好的补充,有效的突出品牌形象。

2、大标题
将大标题作为网页的视觉中心,简洁图片作为大标题的背景,这样很容易将视觉聚焦,让人一眼就能看出这个网页是做什么的。另外,大标题在字体和色彩上,也尽量选择一些简单的、颜色单一的效果,这样视觉会更纯粹。

3、“纤薄”文本框和铵钮
在页面中,将文本框或者铵钮做得轻薄简洁,或为纯色或者没有纹理的一层薄线框。这种设计在确保功能性的同时,给人一种纤细的视觉美感。

4、留白
留白,是页面构图的重要组成部分,适当的加入留白,能让文字便于阅读,让页面各元素得到很好的区分,这样的设计通俗易懂,有得于提升一个页面的品质感。

5、单纯色彩
一个页面,给人带来第一印象的往往是它的色彩。不同的颜色带给人不同的心理感受。当我们看惯色彩绚丽、对比鲜明的网页之后,静下来,回归最自然的状态,运用单纯的色彩,会有不一样的体会和感悟。

网页中的简约通常是多种表现形式结合使用,简约并不等于简单,它需要我们去用心发现、感受、提炼,通过视觉去发掘、去实现。简约的网页设计不仅能带给用户轻松、实用、愉快的体验,而且还能让信息更为有效合理的传达给用户。

继续阅读 »

随着网页技术的不断发展,网页设计的趋势在改变,扁平化、响应式、视觉差滚动、卡片式等给设计师带来了更多的发挥空间。在网页中,简约的设计,往往具清晰的页面结构、简单的交互操作等特征,在满足传递信息的同时,从视觉体验的角度,为用户带来轻松、愉悦的美感,那么在网页中,通过以下几种方式可以做到简约设计。

1、大背景
大图片背景,是目前应用最多的一种网页呈现方式。将整张大图片作为背景,不仅能产生强烈的视觉冲击力,还可以对网页内容起到一个很好的补充,有效的突出品牌形象。

2、大标题
将大标题作为网页的视觉中心,简洁图片作为大标题的背景,这样很容易将视觉聚焦,让人一眼就能看出这个网页是做什么的。另外,大标题在字体和色彩上,也尽量选择一些简单的、颜色单一的效果,这样视觉会更纯粹。

3、“纤薄”文本框和铵钮
在页面中,将文本框或者铵钮做得轻薄简洁,或为纯色或者没有纹理的一层薄线框。这种设计在确保功能性的同时,给人一种纤细的视觉美感。

4、留白
留白,是页面构图的重要组成部分,适当的加入留白,能让文字便于阅读,让页面各元素得到很好的区分,这样的设计通俗易懂,有得于提升一个页面的品质感。

5、单纯色彩
一个页面,给人带来第一印象的往往是它的色彩。不同的颜色带给人不同的心理感受。当我们看惯色彩绚丽、对比鲜明的网页之后,静下来,回归最自然的状态,运用单纯的色彩,会有不一样的体会和感悟。

网页中的简约通常是多种表现形式结合使用,简约并不等于简单,它需要我们去用心发现、感受、提炼,通过视觉去发掘、去实现。简约的网页设计不仅能带给用户轻松、实用、愉快的体验,而且还能让信息更为有效合理的传达给用户。

收起阅读 »

不知道是怎么回事,打不出大于号,有人遇到过么?

HBuilder

不知道是怎么回事,打不出大于号,有人遇到过么?也就是“>”这个符号

不知道是怎么回事,打不出大于号,有人遇到过么?也就是“>”这个符号

2015,Objective-C的这些新改变

iOS

当众人的目光聚焦在WWDC 2015新推出的Swift 2和iOS 9上时,还有多少人会想起自己初入iOS开发时所看的那一本本Objective-C 资料,如今Objective-C 的种种局限已不复存在,2015年的Objective-C 以全新的面貌重新出现在我们眼前,下面就来看看这位熟悉的旧友有了哪些改变吧。

会弱化Swift代码和可读性

很遗憾,Swift支持泛型(generics)就意味着Objective-C 只会以optional的AnyObject集合的形式出现。如此一来,开发者要使用该属性就必须在Swift和Objective-C之间进行转换。

Nullability Annotations

单单一个属性就引发了这么多担忧,还挺让人不安的。如果代码本身引发很多质疑,出现error的可能性就大大增加,更别提在广为熟知的Objective-C和语言新秀Swift之间相互调用(interoperability)了。现在有了nullability annotations,问题就简单多了,编程也会省下很多麻烦。

@property (strong, nonatomic, nonnull) NSArray *someViews;

intent.大大提升了Objective-C,而且这个属性也不会在Swift里满满都是optional了,开发者看看代码就知道有没有nil pointer了。计算机的静态检验和Swift的可用性都得到了提升,最重要的是实现了API的intent通讯。

泛型的出现,泛型的缺席一直以来是Objective-C开发者心头之痛,而诞生32年之后,Objective-C终于也支持泛型了,支持泛型将带来诸多改变,而且都是积极的改变。

现在可以定义属性,下指令给编译器来显示所有UIView:

@property (strong, nonatomic, nonnull) NSArray<UIView > someViews;

向属性强加UIView之外的东西时,编译器会报错,而且如今不用做大量头痛的转换(cast)了。

Objective-C支持泛型对Swift而言也是好消息。上次更新时,让Swift知道对象不应该是optional的,现在Swift还知道它们是UIViews,如此一来含混不清的AnyObject声明就不需要了。如今的Objective-C可以像C#、C++、Swift等语言一样通过<>括号来表示类型了。虽然通常是对协议表示一致性(conformance),但编译器知道何时、何地以及如何运用它们,且运用是经过推理的。

再进一步,可以用参数来表示扩展(extensions)、类别(categories)和类(classes),好处不仅仅体现在集合(collections)上。泛型的强大体现在整个Objective-C之中,集合仅仅是结果而已。

type erasure不但能实现二进制兼容,而且不改变Objective-C的执行时间。所以开发者们,C#的泛型的确胜过其他语言,这点依旧不会改变,所以发发牢骚就好了。

KindOf Types,再次调用之前定义的属性,就会显示UIView。判断里面包含着views和buttons是再正常不过的事。这种情况下,添加如下代码会发生什么呢?

[self.someViews[0]addTarget:selfaction:selector(aMethod:)
forControlEvents:UIControlEventTouchUpInside];

编译器警告,因为即便可以在这个属性里插入一个button,就算可以假设是个UIView,button也不一定没有经过转换,现在新的KindOf特性能够轻松解决这种始料未及的情况:

@property (strong, nonatomic, nonnull) NSArray<__kindof UIView > someViews;

实际上编译器已经知道了:属性及其集合会出现一些UIView。这样在类型协议里显示更多我们之前看不到的信息,其本质是向下转型(downcasting)。这意味着上述代码编译没什么问题,因为编译器知道集合里肯定会出现一个button,现在那些担忧就都解释得清了。

虽然不喜欢Swift的人可能会刻意夸大Objective-C的优点,但如今两种语言实现了互相调用,这是Objective-C所有提升的最大价值所在,毋庸置疑,Objective-C的确比以往更加强大。

虽然如今Swift正以迅雷不及掩耳之势蚕食着Objective-C,但Objective-C 对每一个iOS开发者来说,就如初恋一般的美好,因此如今Objective-C的提升对开发者而言,是件非常值得高兴的事,它能够帮助开发者写出更好的代码,而且这些优势已经在Foundation中随处可见了。

继续阅读 »

当众人的目光聚焦在WWDC 2015新推出的Swift 2和iOS 9上时,还有多少人会想起自己初入iOS开发时所看的那一本本Objective-C 资料,如今Objective-C 的种种局限已不复存在,2015年的Objective-C 以全新的面貌重新出现在我们眼前,下面就来看看这位熟悉的旧友有了哪些改变吧。

会弱化Swift代码和可读性

很遗憾,Swift支持泛型(generics)就意味着Objective-C 只会以optional的AnyObject集合的形式出现。如此一来,开发者要使用该属性就必须在Swift和Objective-C之间进行转换。

Nullability Annotations

单单一个属性就引发了这么多担忧,还挺让人不安的。如果代码本身引发很多质疑,出现error的可能性就大大增加,更别提在广为熟知的Objective-C和语言新秀Swift之间相互调用(interoperability)了。现在有了nullability annotations,问题就简单多了,编程也会省下很多麻烦。

@property (strong, nonatomic, nonnull) NSArray *someViews;

intent.大大提升了Objective-C,而且这个属性也不会在Swift里满满都是optional了,开发者看看代码就知道有没有nil pointer了。计算机的静态检验和Swift的可用性都得到了提升,最重要的是实现了API的intent通讯。

泛型的出现,泛型的缺席一直以来是Objective-C开发者心头之痛,而诞生32年之后,Objective-C终于也支持泛型了,支持泛型将带来诸多改变,而且都是积极的改变。

现在可以定义属性,下指令给编译器来显示所有UIView:

@property (strong, nonatomic, nonnull) NSArray<UIView > someViews;

向属性强加UIView之外的东西时,编译器会报错,而且如今不用做大量头痛的转换(cast)了。

Objective-C支持泛型对Swift而言也是好消息。上次更新时,让Swift知道对象不应该是optional的,现在Swift还知道它们是UIViews,如此一来含混不清的AnyObject声明就不需要了。如今的Objective-C可以像C#、C++、Swift等语言一样通过<>括号来表示类型了。虽然通常是对协议表示一致性(conformance),但编译器知道何时、何地以及如何运用它们,且运用是经过推理的。

再进一步,可以用参数来表示扩展(extensions)、类别(categories)和类(classes),好处不仅仅体现在集合(collections)上。泛型的强大体现在整个Objective-C之中,集合仅仅是结果而已。

type erasure不但能实现二进制兼容,而且不改变Objective-C的执行时间。所以开发者们,C#的泛型的确胜过其他语言,这点依旧不会改变,所以发发牢骚就好了。

KindOf Types,再次调用之前定义的属性,就会显示UIView。判断里面包含着views和buttons是再正常不过的事。这种情况下,添加如下代码会发生什么呢?

[self.someViews[0]addTarget:selfaction:selector(aMethod:)
forControlEvents:UIControlEventTouchUpInside];

编译器警告,因为即便可以在这个属性里插入一个button,就算可以假设是个UIView,button也不一定没有经过转换,现在新的KindOf特性能够轻松解决这种始料未及的情况:

@property (strong, nonatomic, nonnull) NSArray<__kindof UIView > someViews;

实际上编译器已经知道了:属性及其集合会出现一些UIView。这样在类型协议里显示更多我们之前看不到的信息,其本质是向下转型(downcasting)。这意味着上述代码编译没什么问题,因为编译器知道集合里肯定会出现一个button,现在那些担忧就都解释得清了。

虽然不喜欢Swift的人可能会刻意夸大Objective-C的优点,但如今两种语言实现了互相调用,这是Objective-C所有提升的最大价值所在,毋庸置疑,Objective-C的确比以往更加强大。

虽然如今Swift正以迅雷不及掩耳之势蚕食着Objective-C,但Objective-C 对每一个iOS开发者来说,就如初恋一般的美好,因此如今Objective-C的提升对开发者而言,是件非常值得高兴的事,它能够帮助开发者写出更好的代码,而且这些优势已经在Foundation中随处可见了。

收起阅读 »

Hbuilder移动app java开发微信支付-前后端要点

微信支付

本人第一次在dcloud上写文章,写的不好,请大家多多包涵,觉得有帮助,感谢送分!!!其他的不多说,本文为解决hbuilder上开发app微信支付的诸多细节,因缺少文档带来的不便。
一.开发前准备:
1.首先必须在微信开放平台注册账号,认证开发者资质。附链接:https://open.weixin.qq.com/

  1. 新建移动应用,如果要跟微信公众号的账号同步,可以关联上公众账号.如图附件图1.

  1. 新建应用的要填写的应用签名和包名(这个后面说配置)
  2. 要为所建应用申请微信支付,申请成功之后,获取商户号以及微信支付签名串paysignkey(32位)以备用。

二,java服务端代码:
/**

  • app微信支付 调用接口
  • @return
  • @throws Exception
    */
    public String getWxPayShopParameters()throws Exception{
    BigDecimal totalAmt = new BigDecimal (getParameter("total"));
    String notify_url = getUrl()+"/appshop/app_shop_api!notifywxPayment.action"; //支付成功通知路径
    Setting setting = SettingUtil.getSetting();
    String appId = setting.getShopAppId();//移动应用的appid
    String paySignKey = setting.getShopAppPaySignKey();//微信支付签名串
    String mch_id = setting.getShopPartnerId(); //商户号(微信支付申请的商户号)
    String totalfee = totalAmt.multiply(new BigDecimal(100)).intValue() + ""; // 支付金额,单位为分
    String nonce_str = WxUtil.CreateNoncestr(); //随机数
    String body = getParameter("body"); //商品描述
    String attach = appId; //附加数据
    String out_trade_no = getParameter("out_trade_no"); //商户订单号
    String spbill_create_ip = getRequest().getRemoteAddr(); //订单生成的机器 IP
    String trade_type = "APP";//交易类型
    SortedMap<String, String> packageParams = new TreeMap<String, String>();
    packageParams.put("appid", appId);
    packageParams.put("mch_id", mch_id);
    packageParams.put("nonce_str", nonce_str);
    if(body != null && body.length() > 15) {
    body = body.substring(0, 10) + "...";
    }
    packageParams.put("body", body);
    packageParams.put("attach", attach);
    packageParams.put("out_trade_no", out_trade_no);
    packageParams.put("total_fee", totalfee);
    packageParams.put("fee_type", "CNY");//币种
    packageParams.put("spbill_create_ip", spbill_create_ip);
    packageParams.put("notify_url", notify_url);
    packageParams.put("trade_type", trade_type);
    //packageParams.put("openid", "oc3KnjpEVsQDDYWq-KHMSPDhOTwU");

    String sign = WxUtil.createSign(packageParams, paySignKey);  
    packageParams.put("sign", sign);//打包签名  
    String xml = WxUtil.ArrayToXml(packageParams);  
    log.info("packageParams:" + packageParams);  
    Map<String, Object> dataMap = new HashMap();  
    try {  
        dataMap = WxUtil.getPrepayId(xml);  
        log.info("dataMap:" + dataMap);  
    } catch (Exception e) {  
        e.printStackTrace();  
    }  
    if(!"SUCCESS".equals(dataMap.get("return_code")) || !"SUCCESS".equals(dataMap.get("result_code"))) {  
        throw new RuntimeException("获取prepay_id失败!");  
    }  
    String prepay_id = (String) dataMap.get("prepay_id");  
    //wxOrderInfo.setPrepayId(prepay_id);  
    SortedMap<String, String> finalpackage = new TreeMap<String, String>();  
    String timestamp = String.valueOf(System.currentTimeMillis() / 1000);  
    String nonceStr2 = nonce_str;  
            //需要的参数如下:  
    finalpackage.put("appid",appId);    
    finalpackage.put("partnerid",mch_id);    
    finalpackage.put("prepayid", prepay_id);    
    finalpackage.put("package", "Sign=WXPay");  
    finalpackage.put("noncestr",nonceStr2);    
    finalpackage.put("timestamp",timestamp);    
    String paySign = WxUtil.createSign(finalpackage, paySignKey);  
    finalpackage.put("sign", paySign);  
    return ajax(finalpackage);  

    }
    三,hbuilder页面逻辑代码:
    <script type="text/javascript">
    mui.init();
    var channel = null;
    var channels = null;
    var pays={};
    function plusReady(){
    // 获取支付通道
    plus.payment.getChannels(function(cs) {
    channels = cs;
    }, function(e) {
    alert("获取支付通道失败:" + e.message);
    });
    }
    document.addEventListener('plusready',plusReady,false);
    var w=null;
    var WXPAYSERVER='..../gateway/mui_pay!getWxPayShopParameters.action?payid=';
    var ALIPAYSERVER='.../payservice?payid='
    //调用支付
    function pay(id,amount,sheetNo){
    if(w){return;}//检查是否请求订单中
    // 从服务器请求支付订单
    var PAYSERVER = '';
    if (id == 'alipay') {
    PAYSERVER = ALIPAYSERVER;
    } else if (id == 'wxpay') {
    PAYSERVER = WXPAYSERVER;
    } else {
    plus.nativeUI.alert("不支持此支付通道!");
    return;
    }
    //获取支付通道
    for (var i in channels) {
    if (channels[i].id == id) {
    channel = channels[i];
    }
    }
    w=plus.nativeUI.showWaiting();
    //获取支付通道
    mui.get(PAYSERVER, {
    total: 0.01,//支付费用
    body: "测试支付",
    out_trade_no:sheetNo
    }, function(data) {
    var varpay = {//参数顺序必须正确
    retcode: 0,//5+必备参数
    retmsg: "ok",//5+必备参数
    appid: data.appid,
    noncestr: data.noncestr,
    package: "Sign=WXPay",
    partnerid: data.partnerid,
    prepayid: data.prepayid,
    timestamp: data.timestamp,
    sign: data.sign
    }
    plus.payment.request(channel, varpay, function(result) {
    w.close();w=null;
    plus.nativeUI.alert("支付成功!", function() {
    saveSuccess()
    });
    }, function(e) {
    w.close();w=null;
    plus.nativeUI.alert("支付失败:" + e.message);
    });
    }, "json");
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
    switch (xhr.readyState) {
    case 4:
    w.close();w=null;
    if (xhr.status == 200) {
    alert(xhr.result);
    plus.payment.request(channel, xhr.result, function(result) {
    plus.nativeUI.alert("支付成功!", function() {
    saveSuccess()
    });
    }, function(error) {
    plus.nativeUI.alert("支付失败:" + error.code);
    });
    } else {
    alert("获取订单信息失败!");
    }
    break;
    default:
    break;
    }
    }
    }
    </script>

四,注意的细节:
1.测试包名可随意填写,格式参照(应用在一台设备上的唯一标识,在manifest文件里面声明,该包名应和正式发布应用的包名一致。例如,微信的包名为com.tencent.mm)

  1. 签名:如果是dcloud证书打包,包名默认为:d382d671c6672cba4b87980992cd9d77(必须小写)
  2. 支付测试时必须打包成.apk,才能测试。
    如还不能支付,请检查参数是否正确,参数顺序是否正确,包名是否匹配,以及appid和商户号,以及支付签名是否正确有效。
继续阅读 »

本人第一次在dcloud上写文章,写的不好,请大家多多包涵,觉得有帮助,感谢送分!!!其他的不多说,本文为解决hbuilder上开发app微信支付的诸多细节,因缺少文档带来的不便。
一.开发前准备:
1.首先必须在微信开放平台注册账号,认证开发者资质。附链接:https://open.weixin.qq.com/

  1. 新建移动应用,如果要跟微信公众号的账号同步,可以关联上公众账号.如图附件图1.

  1. 新建应用的要填写的应用签名和包名(这个后面说配置)
  2. 要为所建应用申请微信支付,申请成功之后,获取商户号以及微信支付签名串paysignkey(32位)以备用。

二,java服务端代码:
/**

  • app微信支付 调用接口
  • @return
  • @throws Exception
    */
    public String getWxPayShopParameters()throws Exception{
    BigDecimal totalAmt = new BigDecimal (getParameter("total"));
    String notify_url = getUrl()+"/appshop/app_shop_api!notifywxPayment.action"; //支付成功通知路径
    Setting setting = SettingUtil.getSetting();
    String appId = setting.getShopAppId();//移动应用的appid
    String paySignKey = setting.getShopAppPaySignKey();//微信支付签名串
    String mch_id = setting.getShopPartnerId(); //商户号(微信支付申请的商户号)
    String totalfee = totalAmt.multiply(new BigDecimal(100)).intValue() + ""; // 支付金额,单位为分
    String nonce_str = WxUtil.CreateNoncestr(); //随机数
    String body = getParameter("body"); //商品描述
    String attach = appId; //附加数据
    String out_trade_no = getParameter("out_trade_no"); //商户订单号
    String spbill_create_ip = getRequest().getRemoteAddr(); //订单生成的机器 IP
    String trade_type = "APP";//交易类型
    SortedMap<String, String> packageParams = new TreeMap<String, String>();
    packageParams.put("appid", appId);
    packageParams.put("mch_id", mch_id);
    packageParams.put("nonce_str", nonce_str);
    if(body != null && body.length() > 15) {
    body = body.substring(0, 10) + "...";
    }
    packageParams.put("body", body);
    packageParams.put("attach", attach);
    packageParams.put("out_trade_no", out_trade_no);
    packageParams.put("total_fee", totalfee);
    packageParams.put("fee_type", "CNY");//币种
    packageParams.put("spbill_create_ip", spbill_create_ip);
    packageParams.put("notify_url", notify_url);
    packageParams.put("trade_type", trade_type);
    //packageParams.put("openid", "oc3KnjpEVsQDDYWq-KHMSPDhOTwU");

    String sign = WxUtil.createSign(packageParams, paySignKey);  
    packageParams.put("sign", sign);//打包签名  
    String xml = WxUtil.ArrayToXml(packageParams);  
    log.info("packageParams:" + packageParams);  
    Map<String, Object> dataMap = new HashMap();  
    try {  
        dataMap = WxUtil.getPrepayId(xml);  
        log.info("dataMap:" + dataMap);  
    } catch (Exception e) {  
        e.printStackTrace();  
    }  
    if(!"SUCCESS".equals(dataMap.get("return_code")) || !"SUCCESS".equals(dataMap.get("result_code"))) {  
        throw new RuntimeException("获取prepay_id失败!");  
    }  
    String prepay_id = (String) dataMap.get("prepay_id");  
    //wxOrderInfo.setPrepayId(prepay_id);  
    SortedMap<String, String> finalpackage = new TreeMap<String, String>();  
    String timestamp = String.valueOf(System.currentTimeMillis() / 1000);  
    String nonceStr2 = nonce_str;  
            //需要的参数如下:  
    finalpackage.put("appid",appId);    
    finalpackage.put("partnerid",mch_id);    
    finalpackage.put("prepayid", prepay_id);    
    finalpackage.put("package", "Sign=WXPay");  
    finalpackage.put("noncestr",nonceStr2);    
    finalpackage.put("timestamp",timestamp);    
    String paySign = WxUtil.createSign(finalpackage, paySignKey);  
    finalpackage.put("sign", paySign);  
    return ajax(finalpackage);  

    }
    三,hbuilder页面逻辑代码:
    <script type="text/javascript">
    mui.init();
    var channel = null;
    var channels = null;
    var pays={};
    function plusReady(){
    // 获取支付通道
    plus.payment.getChannels(function(cs) {
    channels = cs;
    }, function(e) {
    alert("获取支付通道失败:" + e.message);
    });
    }
    document.addEventListener('plusready',plusReady,false);
    var w=null;
    var WXPAYSERVER='..../gateway/mui_pay!getWxPayShopParameters.action?payid=';
    var ALIPAYSERVER='.../payservice?payid='
    //调用支付
    function pay(id,amount,sheetNo){
    if(w){return;}//检查是否请求订单中
    // 从服务器请求支付订单
    var PAYSERVER = '';
    if (id == 'alipay') {
    PAYSERVER = ALIPAYSERVER;
    } else if (id == 'wxpay') {
    PAYSERVER = WXPAYSERVER;
    } else {
    plus.nativeUI.alert("不支持此支付通道!");
    return;
    }
    //获取支付通道
    for (var i in channels) {
    if (channels[i].id == id) {
    channel = channels[i];
    }
    }
    w=plus.nativeUI.showWaiting();
    //获取支付通道
    mui.get(PAYSERVER, {
    total: 0.01,//支付费用
    body: "测试支付",
    out_trade_no:sheetNo
    }, function(data) {
    var varpay = {//参数顺序必须正确
    retcode: 0,//5+必备参数
    retmsg: "ok",//5+必备参数
    appid: data.appid,
    noncestr: data.noncestr,
    package: "Sign=WXPay",
    partnerid: data.partnerid,
    prepayid: data.prepayid,
    timestamp: data.timestamp,
    sign: data.sign
    }
    plus.payment.request(channel, varpay, function(result) {
    w.close();w=null;
    plus.nativeUI.alert("支付成功!", function() {
    saveSuccess()
    });
    }, function(e) {
    w.close();w=null;
    plus.nativeUI.alert("支付失败:" + e.message);
    });
    }, "json");
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
    switch (xhr.readyState) {
    case 4:
    w.close();w=null;
    if (xhr.status == 200) {
    alert(xhr.result);
    plus.payment.request(channel, xhr.result, function(result) {
    plus.nativeUI.alert("支付成功!", function() {
    saveSuccess()
    });
    }, function(error) {
    plus.nativeUI.alert("支付失败:" + error.code);
    });
    } else {
    alert("获取订单信息失败!");
    }
    break;
    default:
    break;
    }
    }
    }
    </script>

四,注意的细节:
1.测试包名可随意填写,格式参照(应用在一台设备上的唯一标识,在manifest文件里面声明,该包名应和正式发布应用的包名一致。例如,微信的包名为com.tencent.mm)

  1. 签名:如果是dcloud证书打包,包名默认为:d382d671c6672cba4b87980992cd9d77(必须小写)
  2. 支付测试时必须打包成.apk,才能测试。
    如还不能支付,请检查参数是否正确,参数顺序是否正确,包名是否匹配,以及appid和商户号,以及支付签名是否正确有效。
收起阅读 »

PHP开发中的缓存技术汇总

PHP

PHP开发中,出于对网站服务器负载的考虑,往往需要对页面、数据等内容进行缓存处理,下面就来看看,在PHP开发中有哪些缓存方式吧。

1、页面部分缓存
该种方式,是将一个页面中不经常变的部分进行静态缓存,而经常变化的块不缓存,最后组装在一起显示;可以使用类似于ob_get_contents的方式实现,也可以利用类似ESI之类的页面片段缓存策略,使其用来做动态页面中相对静态的片段部分的缓存(ESI技术,请baidu,此处不详讲)。该种方式可以用于如商城中的商品页;

2、数据缓存
顾名思义,就是缓存数据的一种方式;比如,商城中的某个商品信息,当用商品id去请求时,就会得出包括店铺信息、商品信息等数据,此时就可以将这些数据缓存到一个php文件中,文件名包含商品id来建一个唯一标示;下一次有人想查看这个商品时,首先就直接调这个文件里面的信息,而不用再去数据库查询;其实缓存文件中缓存的就是一个php数组之类;Ecmall商城系统里面就用了这种方式;

3、全页面静态化缓存
也就是将页面全部生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程。此种方式,在CMS系统中比较常见,比如dedecms;一种比较常用的实现方式是用输出缓存:
Ob_start()
**要运行的代码*
$content = Ob_get_contents();
**
将缓存内容写入html文件*

Ob_end_clean();

4、查询缓存
其实这跟数据缓存是一个思路,就是根据查询语句来缓存;将查询得到的数据缓存在一个文件中,下次遇到相同的查询时,就直接先从这个文件里面调数据,不会再去查数据库;但此处的缓存文件名可能就需要以查询语句为基点来建立唯一标示;按时间变更进行缓存。
其实,这一条不是真正的缓存方式;上面的2、3、4的缓存技术一般都用到了时间变更判断;就是对于缓存文件您需要设一个有效时间,在这个有效时间内,相同的访问才会先取缓存文件的内容,但是超过设定的缓存时间,就需要重新从数据库中获取数据,并生产最新的缓存文件;

5、按内容变更进行缓存
这个也并非独立的缓存技术,需结合着用;就是当数据库内容被修改时,即刻更新缓存文件;
比如,一个人流量很大的商城,商品很多,商品表必然比较大,这表的压力也比较重;就可以对商品显示页进行页面缓存;当商家在后台修改这个商品的信息时,点击保存,我们同时就更新缓存文件;那么,买家访问这个商品信息时,实际上访问的是一个静态页面,而不需要再去访问数据库;试想,如果对商品页不缓存,那么每次访问一个商品就要去数据库查一次,如果有10万人在线浏览商品,那服务器压力就大了;

6、apache缓存模块
apache安装完以后,是不允许被cache的。如果外接了cache或squid服务器要求进行web加速的话,就需要在htttpd.conf里进行设置,当然前提是在安装apache的时候要激活mod_cache的模块。
安装apache时:./configure --enable-cache --enable-disk-cache --enable-mem-cache

7、php APC缓存扩展
Php有一个APC缓存扩展,windows下面为php_apc.dll,需要先加载这个模块,然后是在php.ini里面进行配置:
[apc]
extension=php_apc.dll
apc.rfc1867 = on
upload_max_filesize = 100M
post_max_size = 100M
apc.max_file_size = 200M
upload_max_filesize = 1000M
post_max_size = 1000M
max_execution_time = 600 ; 每个PHP页面运行的最大时间值(秒),默认30秒
max_input_time = 600 ; 每个PHP页面接收数据所需的最大时间,默认60
memory_limit = 128M ; 每个PHP页面所吃掉的最大内存,默认8M
比较知名的是XCache、Turck MM Cache、PHP Accelerator等

8、内存式缓存
提到这个,可能大家想到的首先就是Memcached;memcached是高性能的分布式内存缓存服务器。 一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、 提高可扩展性。它就是将需要缓存的信息,缓存到系统内存中,需要获取信息时,直接到内存中取;比较常用的方式就是 key-->value方式;
<?php
$memcachehost = '192.168.6.191';
$memcacheport = 11211;
$memcachelife = 60;
$memcache = new Memcache;
$memcache->connect($memcachehost,$memcacheport) or die ("Could not connect");
$memcache->set('key','缓存的内容');
$get = $memcache->get($key); //获取信息
?>

继续阅读 »

PHP开发中,出于对网站服务器负载的考虑,往往需要对页面、数据等内容进行缓存处理,下面就来看看,在PHP开发中有哪些缓存方式吧。

1、页面部分缓存
该种方式,是将一个页面中不经常变的部分进行静态缓存,而经常变化的块不缓存,最后组装在一起显示;可以使用类似于ob_get_contents的方式实现,也可以利用类似ESI之类的页面片段缓存策略,使其用来做动态页面中相对静态的片段部分的缓存(ESI技术,请baidu,此处不详讲)。该种方式可以用于如商城中的商品页;

2、数据缓存
顾名思义,就是缓存数据的一种方式;比如,商城中的某个商品信息,当用商品id去请求时,就会得出包括店铺信息、商品信息等数据,此时就可以将这些数据缓存到一个php文件中,文件名包含商品id来建一个唯一标示;下一次有人想查看这个商品时,首先就直接调这个文件里面的信息,而不用再去数据库查询;其实缓存文件中缓存的就是一个php数组之类;Ecmall商城系统里面就用了这种方式;

3、全页面静态化缓存
也就是将页面全部生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程。此种方式,在CMS系统中比较常见,比如dedecms;一种比较常用的实现方式是用输出缓存:
Ob_start()
**要运行的代码*
$content = Ob_get_contents();
**
将缓存内容写入html文件*

Ob_end_clean();

4、查询缓存
其实这跟数据缓存是一个思路,就是根据查询语句来缓存;将查询得到的数据缓存在一个文件中,下次遇到相同的查询时,就直接先从这个文件里面调数据,不会再去查数据库;但此处的缓存文件名可能就需要以查询语句为基点来建立唯一标示;按时间变更进行缓存。
其实,这一条不是真正的缓存方式;上面的2、3、4的缓存技术一般都用到了时间变更判断;就是对于缓存文件您需要设一个有效时间,在这个有效时间内,相同的访问才会先取缓存文件的内容,但是超过设定的缓存时间,就需要重新从数据库中获取数据,并生产最新的缓存文件;

5、按内容变更进行缓存
这个也并非独立的缓存技术,需结合着用;就是当数据库内容被修改时,即刻更新缓存文件;
比如,一个人流量很大的商城,商品很多,商品表必然比较大,这表的压力也比较重;就可以对商品显示页进行页面缓存;当商家在后台修改这个商品的信息时,点击保存,我们同时就更新缓存文件;那么,买家访问这个商品信息时,实际上访问的是一个静态页面,而不需要再去访问数据库;试想,如果对商品页不缓存,那么每次访问一个商品就要去数据库查一次,如果有10万人在线浏览商品,那服务器压力就大了;

6、apache缓存模块
apache安装完以后,是不允许被cache的。如果外接了cache或squid服务器要求进行web加速的话,就需要在htttpd.conf里进行设置,当然前提是在安装apache的时候要激活mod_cache的模块。
安装apache时:./configure --enable-cache --enable-disk-cache --enable-mem-cache

7、php APC缓存扩展
Php有一个APC缓存扩展,windows下面为php_apc.dll,需要先加载这个模块,然后是在php.ini里面进行配置:
[apc]
extension=php_apc.dll
apc.rfc1867 = on
upload_max_filesize = 100M
post_max_size = 100M
apc.max_file_size = 200M
upload_max_filesize = 1000M
post_max_size = 1000M
max_execution_time = 600 ; 每个PHP页面运行的最大时间值(秒),默认30秒
max_input_time = 600 ; 每个PHP页面接收数据所需的最大时间,默认60
memory_limit = 128M ; 每个PHP页面所吃掉的最大内存,默认8M
比较知名的是XCache、Turck MM Cache、PHP Accelerator等

8、内存式缓存
提到这个,可能大家想到的首先就是Memcached;memcached是高性能的分布式内存缓存服务器。 一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、 提高可扩展性。它就是将需要缓存的信息,缓存到系统内存中,需要获取信息时,直接到内存中取;比较常用的方式就是 key-->value方式;
<?php
$memcachehost = '192.168.6.191';
$memcacheport = 11211;
$memcachelife = 60;
$memcache = new Memcache;
$memcache->connect($memcachehost,$memcacheport) or die ("Could not connect");
$memcache->set('key','缓存的内容');
$get = $memcache->get($key); //获取信息
?>

收起阅读 »

HBuilder能否对平板上本地的SQLite数据库进行读写?如果不能,可否加上这项功能?

HBuilder能否对平板上本地的SQLite数据库进行读写?如果不能,可否加上这项功能?
我的邮箱:moyan_zh@163.com QQ:88579773 微信:jingtiankeji_zhou

HBuilder能否对平板上本地的SQLite数据库进行读写?如果不能,可否加上这项功能?
我的邮箱:moyan_zh@163.com QQ:88579773 微信:jingtiankeji_zhou

扁平化设计的几个要点

Android

如今扁平化设计在Android开发中应用日渐广泛,扁平化设计依赖于清晰的层次结构和元素布局,不仅能给用户非常强烈的感觉,而且优秀的扁平化设计还能帮助用户理解产品以及交互,那么该如何做好扁平化设计?

拒绝特效
顾名思义,扁平化设计仅仅采用二维元素。所有元素都不加修饰——阴影、斜面、突起、渐变这样会带来深度变化的设计都是不应该的。从图片框到按钮,再到导航栏都干脆有力,需要极力避免羽化、阴影这样的特效。现实主义、3D、拟物化更是扁平化设计的大敌。

扁平化设计中的层次和其它的一一对应,但各个位面间没有交叉,不会明确区分背景图片、前景图片、按钮、文本、导航,等等。

使用简单元素

扁平设计中使用到很多简单的UI元素,比如按钮和图标。设计师更常用矩形、圆形、方形等简单的形状。元素独立。正角、直角、圆弧都非常常见。

UI元素应该在保持高可用性的前提下尽可能的简单,保证应用或网站直观、易用,无需引导。为了同时达到简单但直观的效果,你可以尝试为按钮填充深色,以鼓励用户点击。

记住,简单的元素并不意味着设计起来很简单,恰恰相反,扁平化设计理念的复杂度可以与任何其他设计风格相提并论。

关注色彩

色彩的使用对于扁平化设计来说非常重要。你可能已经发现了,扁平化设计的网站、应用色彩明显要更加鲜艳、明亮。此外扁平化设计的项目也拥有更多的色调。一般的网站很少会使用3种以上的色调,但是在扁平化设计中,平均会使用6-8种颜色。
扁平化设计的色调偏通常更有活力,色彩更纯。其主要、次要颜色通常都是非常大众化的颜色,然后再配以几种其它颜色。扁平化设计的另一个趋势在于复古颜色的使用,浅澄色、紫色、绿色、蓝色都极为流行。

注重排版

因为扁平化设计要求元素更简单,排版的重要性就更为突出了。字体的大小应该匹配整体设计,高度美化的字体会与极简设计原则相冲突。字形上可以应该使用粗体,文案要求精简、干练,最终保证产品在视觉上和措辞上的一致性。字体选择上可以使用简单的无衬线字体,通过字体大小和比重来区分元素。同时你也可以使用新奇的字体作为点缀,但一定要记得不能过火。排版的目的在于帮助用户理解设计。标签按钮等其它元素更注重增强易用性和交互性。

准扁平化设计

最近,越来越多的设计师开始赞同准扁平化的设计。在准扁平化设计中,基调仍然是扁平风格的,但会在设计方案中添加一种,且仅添加一种特效,无论是阴影也好、梯度也好,这种设计风格比严肃的扁平化更加灵活。

设计师们喜欢它,因为可以添加深度和纹理;用户喜欢它,因为它能有助于直观的交互。但反过来,也有设计师不喜欢它,因为“准”扁平风格是另两种风格的混合体,缺乏明确的定义,所以更难用好。

极简主义

扁平化设计生而简单,整体上趋近极简主义设计理念。设计中应该驱除任何无关元素,尽可能地仅使用简单的颜色与文本。如果一定需要视觉元素,你可以添加简单的图形。

现在,越来越多的网站开始应用扁平化设计,在Android开发中这一趋势更为明显。在小屏幕中,按钮和选项更少,也让扁平化设计如鱼得水,逐渐成为了如今的主流设计趋势,但是一个好的设计并不该拘泥于某种设计风格,而更多是注重实用性,但如果这个APP并不适合采用扁平化,那么就不应强行套用。

继续阅读 »

如今扁平化设计在Android开发中应用日渐广泛,扁平化设计依赖于清晰的层次结构和元素布局,不仅能给用户非常强烈的感觉,而且优秀的扁平化设计还能帮助用户理解产品以及交互,那么该如何做好扁平化设计?

拒绝特效
顾名思义,扁平化设计仅仅采用二维元素。所有元素都不加修饰——阴影、斜面、突起、渐变这样会带来深度变化的设计都是不应该的。从图片框到按钮,再到导航栏都干脆有力,需要极力避免羽化、阴影这样的特效。现实主义、3D、拟物化更是扁平化设计的大敌。

扁平化设计中的层次和其它的一一对应,但各个位面间没有交叉,不会明确区分背景图片、前景图片、按钮、文本、导航,等等。

使用简单元素

扁平设计中使用到很多简单的UI元素,比如按钮和图标。设计师更常用矩形、圆形、方形等简单的形状。元素独立。正角、直角、圆弧都非常常见。

UI元素应该在保持高可用性的前提下尽可能的简单,保证应用或网站直观、易用,无需引导。为了同时达到简单但直观的效果,你可以尝试为按钮填充深色,以鼓励用户点击。

记住,简单的元素并不意味着设计起来很简单,恰恰相反,扁平化设计理念的复杂度可以与任何其他设计风格相提并论。

关注色彩

色彩的使用对于扁平化设计来说非常重要。你可能已经发现了,扁平化设计的网站、应用色彩明显要更加鲜艳、明亮。此外扁平化设计的项目也拥有更多的色调。一般的网站很少会使用3种以上的色调,但是在扁平化设计中,平均会使用6-8种颜色。
扁平化设计的色调偏通常更有活力,色彩更纯。其主要、次要颜色通常都是非常大众化的颜色,然后再配以几种其它颜色。扁平化设计的另一个趋势在于复古颜色的使用,浅澄色、紫色、绿色、蓝色都极为流行。

注重排版

因为扁平化设计要求元素更简单,排版的重要性就更为突出了。字体的大小应该匹配整体设计,高度美化的字体会与极简设计原则相冲突。字形上可以应该使用粗体,文案要求精简、干练,最终保证产品在视觉上和措辞上的一致性。字体选择上可以使用简单的无衬线字体,通过字体大小和比重来区分元素。同时你也可以使用新奇的字体作为点缀,但一定要记得不能过火。排版的目的在于帮助用户理解设计。标签按钮等其它元素更注重增强易用性和交互性。

准扁平化设计

最近,越来越多的设计师开始赞同准扁平化的设计。在准扁平化设计中,基调仍然是扁平风格的,但会在设计方案中添加一种,且仅添加一种特效,无论是阴影也好、梯度也好,这种设计风格比严肃的扁平化更加灵活。

设计师们喜欢它,因为可以添加深度和纹理;用户喜欢它,因为它能有助于直观的交互。但反过来,也有设计师不喜欢它,因为“准”扁平风格是另两种风格的混合体,缺乏明确的定义,所以更难用好。

极简主义

扁平化设计生而简单,整体上趋近极简主义设计理念。设计中应该驱除任何无关元素,尽可能地仅使用简单的颜色与文本。如果一定需要视觉元素,你可以添加简单的图形。

现在,越来越多的网站开始应用扁平化设计,在Android开发中这一趋势更为明显。在小屏幕中,按钮和选项更少,也让扁平化设计如鱼得水,逐渐成为了如今的主流设计趋势,但是一个好的设计并不该拘泥于某种设计风格,而更多是注重实用性,但如果这个APP并不适合采用扁平化,那么就不应强行套用。

收起阅读 »