项目本来是在windows下,转到MAC开发后,ant编译出现这个错误。
Buildfile: /Users/mac/Documents/luzaimou/bussiness/meinvjiqi/build.xml init: [echo] start initing ... [echo] finish initing. main: [echo] generating R.java for project to dir gen (using aapt) ... [echo] generating R.java for library to dir gen (using aapt) ... [echo] compiling java files to class files (include R.java, library and the third-party jars) ... [javac] Compiling 22 source files to /Users/mac/Documents/luzaimou/bussiness/meinvjiqi/bin/classes [javac] /Users/mac/Documents/luzaimou/bussiness/meinvjiqi/src/com/speakit/tts/engine/CallBackSynthesize.java:1: illegal character: \65279 [javac] ?package com.speakit.tts.engine; [javac] ^ [javac] /Users/mac/Documents/luzaimou/bussiness/meinvjiqi/src/com/speakit/tts/engine/CallBackText.java:1: illegal character: \65279 [javac] ?package com.speakit.tts.engine; [javac] ^ [javac] /Users/mac/Documents/luzaimou/bussiness/meinvjiqi/src/com/speakit/tts/engine/ITTSInputTextProc.java:1: illegal character: \65279 [javac] ?package com.speakit.tts.engine; [javac] ^
解决办法:用16位文本编辑器0xED来去掉各个java前的三个字节,他们的值是65279,我们不需要。
现在似乎只要是个列表,都要有下拉刷新这一项,否则就跟不上潮流了,呵呵。下拉刷新应该很多人都采用了EGORefreshTableHeaderView,具体的UI效果当然会根据自己产品的设计,再进行修改。应用中如果要展示大量数据列表,肯定不会一次都加载进来的,常规的方法都是从服务器翻页请求,每次请求n条,用户选择加载更多的时候再请求n条。根据这个需求,我们可以仿照EGORefreshTableHeaderView再实现一个footerView加在列表下面,支持上拉列表松开加载下一页数据。
效果如下
一、EGORefreshTableHeaderView的使用
1. 创建headerView
获取最新的刷新时间的委托方法被我改了个名字而已,因为后续要创建footerView,也要用到。这个方法可选,如果不实现则不会显示时间,或者干脆自己把显示时间的label之类的都去掉好了。
2. 触发刷新操作
实现委托方法 egoRefreshTableHeaderDidTriggerRefresh,在里面开始实现你自己的数据刷新。
3. 例子里面的这几个函数很重要。
之前看demo的时候看到注释“just for demo”之类的就以为这个_reloading的值可以不设置,结果铸成大错,才知道其重要性。无论是之后自定义footer还是这个header,判断到底是否触发刷新动作的时候,除了判断拖动到了什么位置之类的,都判断了_reloading值,如果正在_reloading,即使再怎样上拉下拉,都不能刷新,否则势必影响当前正在进行的数据加载或刷新操作,我也是在实际项目中出现了相关的bug才知道其重要性,果断加上。
4. 其它细节参考一下demo例子就行了,也没啥其它的了。
二、自定义EGORefreshTableFooterView
1. 直接改写HeaderView类就可以。
初始化里面各种label、imageView的位置要改变,文字内容修改
_arrowImage的箭头旋转方向要调换过来,让它刚好相反。
修改判断是否触发刷新和是否恢复到原位的代码,例如将判断是否触发刷新的条件改为:
scrollView.contentOffset.y+(scrollView.frame.size.height) > scrollView.contentSize.height+REFRESH_REGION_HEIGHT
REFRESH_REGION_HEIGHT是自己根据需要定义的拖动的高度。我定义为
#define REFRESH_REGION_HEIGHT 65.0f
因为原来的delegate只用于headerView,现在增加了footer,自然名字要稍微改改。另外,一个tableview里面既有headerView又有footerView,总要标识一下是在下拉刷新,还是上拉加载更多,因此把egoRefreshTableDidTriggerRefresh回调方法的参数改了一下,作为标识。定义的公共头文件如下:
用法方面跟headerView是一样的,记得触发刷新动作的时候要根据参数aRefreshPos来决定具体的操作。
开发一个验证码类:
编写验证码类(PHP图像处理)
validationcode.class.php
<?php
class ValidationCode {
private $width;
private $height;
private $codeNum;
private $image; //图像资源
private $disturbColorNum;
private $checkCode;
function __construct($width=80, $height=20, $codeNum=4){
$this->width=$width;
$this->height=$height;
$this->codeNum=$codeNum;
$this->checkCode=$this->createCheckCode();
$number=floor($width*$height/15);
if($number > 240-$codeNum){
$this->disturbColorNum= 240-$codeNum;
}else{
$this->disturbColorNum=$number;
}
}
//通过访问该方法向浏览器中输出图像
function showImage($fontFace=""){
//第一步:创建图像背景
$this->createImage();
//第二步:设置干扰元素
$this->setDisturbColor();
//第三步:向图像中随机画出文本
$this->outputText($fontFace);
//第四步:输出图像
$this->outputImage();
}
//通过调用该方法获取随机创建的验证码字符串
function getCheckCode(){
return $this->checkCode;
}
private function createImage(){
//创建图像资源
$this->image=imagecreatetruecolor($this->width, $this->height);
//随机背景色
$backColor=imagecolorallocate($this->image, rand(225, 255), rand(225,255), rand(225, 255));
//为背景添充颜色
imagefill($this->image, 0, 0, $backColor);
//设置边框颜色
$border=imagecolorallocate($this->image, 0, 0, 0);
//画出矩形边框
imagerectangle($this->image, 0, 0, $this->width-1, $this->height-1, $border);
}
private function setDisturbColor(){
for($i=0; $i<$this->disturbColorNum; $i++){
$color=imagecolorallocate($this->image, rand(0, 255), rand(0, 255), rand(0, 255));
imagesetpixel($this->image, rand(1, $this->width-2), rand(1, $this->height-2), $color);
}
for($i=0; $i<10; $i++){
$color=imagecolorallocate($this->image, rand(200, 255), rand(200, 255), rand(200, 255));
imagearc($this->image, rand(-10, $this->width), rand(-10, $this->height), rand(30, 300), rand(20, 200), 55, 44, $color);
}
}
private function createCheckCode(){
$code="23456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKMNPQRSTUVWXYZ";
$string='';
for($i=0; $i < $this->codeNum; $i++){
$char=$code{rand(0, strlen($code)-1)};
$string.=$char;
}
return $string;
}
private function outputText($fontFace=""){
for($i=0; $i<$this->codeNum; $i++){
$fontcolor=imagecolorallocate($this->image, rand(0, 128), rand(0, 128), rand(0, 128));
if($fontFace==""){
$fontsize=rand(3, 5);
$x=floor($this->width/$this->codeNum)*$i+3;
$y=rand(0, $this->height-15);
imagechar($this->image,$fontsize, $x, $y, $this->checkCode{$i},$fontcolor);
}else{
$fontsize=rand(12, 16);
$x=floor(($this->width-8)/$this->codeNum)*$i+8;
$y=rand($fontSize+5, $this->height);
imagettftext($this->image,$fontsize,rand(-30, 30),$x,$y ,$fontcolor, $fontFace, $this->checkCode{$i});
}
}
}
private function outputImage() {
if(imagetypes() & IMG_GIF){
header("Content-Type:image/gif");
imagepng($this->image);
}else if(imagetypes() & IMG_JPG){
header("Content-Type:image/jpeg");
imagepng($this->image);
}else if(imagetypes() & IMG_PNG){
header("Content-Type:image/png");
imagepng($this->image);
}else if(imagetypes() & IMG_WBMP){
header("Content-Type:image/vnd.wap.wbmp");
imagepng($this->image);
}else{
die("PHP不支持图像创建");
}
}
function __destruct(){
imagedestroy($this->image);
}
}
使用验证码使用验证码使用验证码
code.php
<?php
session_start();
include "validationcode.class.php";
$code=new ValidationCode(80, 20, 4);
$code->showImage(); //输出到页面中供 注册或登录使用
$_SESSION["code"]=$code->getCheckCode(); //将验证码保存到服务器中