NSTimer初始化器接受调用方法逻辑之间的间隔作为它的其中一个参数,预设一秒执行30次。CADisplayLink默认每秒运行60次,通过它的frameInterval属性改变每秒运行帧数,如设置为2,意味CADisplayLink每隔一帧运行一次,有效的逻辑每秒运行30次。
此外,NSTimer接受另一个参数是否重复,而把CADisplayLink设置为重复(默认重复?)直到它失效。
还有一个区别在于,NSTimer一旦初始化它就开始运行,而CADisplayLink需要将显示链接添加到一个运行循环中,即用于处理系统事件的一个Cocoa Touch结构。
NSTimer 我们通常会用在背景计算,更新一些数值资料,而如果牵涉到画面的更新,动画过程的演变,我们通常会用CADisplayLink。
但是要使用CADisplayLink,需要加入QuartzCore.framework及#import
NSTimer
@interface ViewController : UIViewController { NSTimer *theTimer; //声明 } //使用 float theInterval = 1.0 / 30.0f; //每秒调用30次 theTimer = [NSTimer scheduledTimerWithTimeInterval:theInterval target:self selector:@selector(MyTask) userInfo:nil repeats:YES]; //停用 [theTimer invalidate]; theTimer = nil;
CADisplayLink,需要加入QuartzCore.framework及#import
if(theTimer == nil) { theTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(MyTask)]; theTimer.frameInterval = 2; [theTimer addToRunLoop: [NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; } //停用 [theTimer invalidate]; theTimer = nil;
原文:http://blog.sina.com.cn/s/blog_76550fd70101dfnj.html
说到android的左右滑动效果我们可以说是在每个应用上面都可以看到这样的效果,不管是微博,还是QQ等。实现左右滑动的方式很多,有ViewPaer(不过这个和需要android-support-v4.jar的支持),自定义实现Viewgroup,gallery等都可以达到这种效果。这里做下ViewFliper实现左右滑动的效果。
以下会会用到的技术有:
1、ViewFlipper
2、GestureDetector
3、Animation
第一次在iteye写博文,本人又是菜鸟,不喜勿喷,虚心听取建议。
原理:向左向右滑动主要是依赖手势来控制,手势向右滑动就调用 viewFlipper.showNext();方法,同理,向左滑动就会去调用viewFlipper.showPrevious();方法。
话不多少,直接上代码。
main_activity.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <ViewFlipper android:id="@+id/viewFlipper" android:layout_width="fill_parent" android:layout_height="fill_parent"></ViewFlipper> </RelativeLayout>
下面是MainActivity内容:
package com.zls.viewflipper; import android.os.Bundle; import android.app.Activity; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.Menu; import android.view.MotionEvent; import android.view.Window; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.ImageView; import android.widget.ViewFlipper; /** * 这个程序的功能:手势滑动 * @author zls * */ public class MainActivity extends Activity implements OnGestureListener{ private Animation left_in,left_out,right_in,right_out; private ViewFlipper viewFilpper; private GestureDetector detector; //手势监听 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); //动画效果 left_in = AnimationUtils.loadAnimation(this, R.anim.left_in); left_out = AnimationUtils.loadAnimation(this, R.anim.left_out); right_in = AnimationUtils.loadAnimation(this, R.anim.right_in); right_out = AnimationUtils.loadAnimation(this, R.anim.right_out); //获得viewFlipper viewFilpper = (ViewFlipper) findViewById(R.id.viewFlipper); detector = new GestureDetector(this); //给viewFlipper添加ImageView viewFilpper.addView(getImageView(R.drawable.lufei)); viewFilpper.addView(getImageView(R.drawable.namei)); viewFilpper.addView(getImageView(R.drawable.solong)); } //touch事件交给手势处理 @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub return this.detector.onTouchEvent(event); } public ImageView getImageView(int id) { ImageView imageView = new ImageView(this); imageView.setImageResource(id); return imageView; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if(e2.getX()-e1.getX()<-120) { viewFilpper.setInAnimation(left_in); viewFilpper.setOutAnimation(left_out); viewFilpper.showNext(); return true; } else if(e2.getX()-e1.getX()>120){ viewFilpper.setInAnimation(right_in); viewFilpper.setOutAnimation(right_out); viewFilpper.showPrevious(); return true; } return false; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; } }
在res文件夹下新建anim文件夹,在里面建4个animation动画的xml文件,具体代码如下:
Left_in.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="100%p" android:toXDelta="0%p" android:duration="500"/> <alpha android:fromAlpha="0.1" android:toAlpha="1.0" android:duration="500"/> </set> Left_out.xnl: <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0%p" android:toXDelta="-100%p" android:duration="500"/> <alpha android:fromAlpha="1.0" android:toAlpha="0.1" android:duration="500"/> </set>
right_in.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="-100%p" android:toXDelta="0%p" android:duration="500"/> <alpha android:fromAlpha="0.1" android:toAlpha="1.0" android:duration="500"/> </set>
right_out.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0%p" android:toXDelta="100%p" android:duration="500"/> <alpha android:fromAlpha="1.0" android:toAlpha="0.1" android:duration="500"/> </set>
未重构之前的代码
public class Employee
{
private int _type;
static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2
Employee(int type)
{
_type = type;
}
int payAmout()
{
switch (_type){
case ENGINEER:
return 1;
case SALESMAN:
return 2;
case MANAGER:
return 3;
default:
throw new RuntimeException("error");
}
}
}
第一步,我们进行自封装字段,代码变为:
public class Employee
{
private int _type;
static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2;
Employee(int type)
{
setType(type);
}
int payAmout()
{
switch (getType()){
case ENGINEER:
return 1;
case SALESMAN:
return 2;
case MANAGER:
return 3;
default:
throw new RuntimeException("error");
}
}
void setType(int type)
{
_type = type;
}
int getType()
{
return _type;
}
}
第二步,我们增加间接层
public abstract class EmployeeType {
abstract int getTypeCode();
}
第三部,创建间接层子类
public class Engineer extends EmployeeType {
int getTypeCode(){
return Employee.ENGINEER;
}
}
public class Manager extends EmployeeType {
int getTypeCode() {
return Employee.MANAGER;
}
}
public class SalesMan extends EmployeeType
{
int getTypeCode()
{
return Employee.SALESMAN;
}
}
第四步,用声明的间接层去替换Employee中的类型码成员变量
public class Employee
{
EmployeeType _type;
static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2;
Employee(int arg)
{
setType(arg);
}
int payAmout(int arg)
{
switch (arg){
case ENGINEER:
return 1;
case SALESMAN:
return 2;
case MANAGER:
return 3;
default:
throw new RuntimeException("error");
}
}
void setType(int arg)
{
switch(arg){
case ENGINEER:
_type = new Engineer();
break;
case MANAGER:
_type = new Manager();
break;
case SALESMAN:
_type = new SalesMan();
break;
default:
throw new RuntimeException("code error");
}
}
int getType()
{
return _type.getTypeCode();
}
}
第五步,建立一个工厂函数,来生产EmployeeType实例
public abstract class EmployeeType {
abstract int getTypeCode();
static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2;
static EmployeeType newType(int code)
{
switch(code){
case ENGINEER:
return new Engineer();
case SALESMAN:
return new SalesMan();
case MANAGER:
return new Manager();
default:
throw new RuntimeException("wrongcode");
}
}
}
第六步,去掉Employee当中的类型码
public class Employee
{
EmployeeType _type;
Employee(int arg)
{
setType(arg);
}
int payAmout()
{
switch (getType()){
case EmployeeType.ENGINEER:
return 1;
case EmployeeType.MANAGER:
return 2;
case EmployeeType.SALESMAN:
return 3;
default:
throw new RuntimeException("error");
}
}
void setType(int arg)
{
_type = EmployeeType.newType(arg);
}
int getType()
{
return _type.getTypeCode();
}
}
第七步,将payAmout函数提到它应该在的地方
public abstract class EmployeeType {
abstract int getTypeCode();
static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2;
static EmployeeType newType(int code)
{
switch(code){
case ENGINEER:
return new Engineer();
case SALESMAN:
return new SalesMan();
case MANAGER:
return new Manager();
default:
throw new RuntimeException("wrongcode");
}
}
int payAmout()
{
switch (getTypeCode()){
case ENGINEER:
return 1;
case MANAGER:
return 2;
case SALESMAN:
return 3;
default:
throw new RuntimeException("error");
}
}
}
第八步,将payAccout声明为abstract,然后各子类分别实现这个方法
public class Engineer extends EmployeeType {
int getTypeCode(){
return ENGINEER;
}
int payAccount(){
return 2;
}
}
public class Manager extends EmployeeType {
int getTypeCode() {
return MANAGER;
}
int payAccount()
{
return 3;
}
}
public class SalesMan extends EmployeeType {
int getTypeCode() {
return SALESMAN;
}
int payAccount()
{
return 1;
}
}
第九步,修改Employee的payAccount函数
public class Employee
{
EmployeeType _type;
Employee(int arg)
{
setType(arg);
}
int payAmout()
{
return _type.payAccount();
}
void setType(int arg)
{
_type = EmployeeType.newType(arg);
}
int getType()
{
return _type.getTypeCode();
}
}