当前位置:  编程技术>移动开发
本页文章导读:
    ▪带更新内容揭示的自动更新的一种实现        带更新内容提示的自动更新的一种实现 思路如下: 1.实现一个只有程序安装后第一次打开时才会执行的方法,这样方便在配置文件PreferenceManager.getDefaultSharedPreferences(Context)中保存程序的一些.........
    ▪ 基于OPhone 2.0的2D动画片实践(二)        基于OPhone 2.0的2D动画实践(二) 基于OPhone 2.0的2D动画实践(二) OPhone平台开发, 2010-10-18 16:53:43 标签 : OPhone2.0 2D 动画     本系列文章主要介绍了OPhone 2.0 SDK提供的两种实现2D动画的方式.........
    ▪ WLAN中各种基准(或者说各种协议)的说明       WLAN中各种标准(或者说各种协议)的说明 1.0 802.11a标准:   5GHZ;支持的最大速度为54Mbps 2.0 802.11b标准:2.4GHZ;支持的最大速度为11Mbps 3.0 802.11g标准:2.4GHZ;支持的最大速度为54Mbps 4.0 802.11E标.........

[1]带更新内容揭示的自动更新的一种实现
    来源: 互联网  发布时间: 2014-02-18
带更新内容提示的自动更新的一种实现

思路如下:

1.实现一个只有程序安装后第一次打开时才会执行的方法,这样方便在配置文件PreferenceManager.getDefaultSharedPreferences(Context)中保存程序的一些信息,比如apk安装时间,这个值之后会和服务器上的apk修改时间做比较来判断是否要更新,如我这个例子里的showOnFirstLaunch(),程序入口活动JumpActivity onCreate时获取程序包信息中的versionCode版本代码号,如果与配置中保存的版本号不一致,表示安装新版后第一次打开程序,则执行之后的代代码片段,如保存当前版本号,设置新版已安装的值为true,多设了这个值的目的是,我们自动更新时虽然下载了新版本,但是没有对其安装,则打开旧版本时提示下载的更新没有被安装,给用户一个安装的选择。

 

JumpActivity.class

private void showOnFirstLaunch() {
	  setContentView(R.layout.splash);
    try {
      PackageInfo info = getPackageManager().getPackageInfo(PACKAGE_NAME, 0);
      int currentVersion = info.versionCode;
      prefs = PreferenceManager.getDefaultSharedPreferences(this);
      int lastVersion = prefs.getInt(PreferencesActivity.KEY_HELP_VERSION_SHOWN, 0);
      if (currentVersion != lastVersion) {//安装好后第一次启动
    	  //设置版本号
        prefs.edit().putInt(PreferencesActivity.KEY_HELP_VERSION_SHOWN, currentVersion).commit(); 
        prefs.edit().putBoolean(PreferencesActivity.KEY_LATEST_VERSION_INSTALL, true).commit();
        File apk = new File(apkFile);
		if(apk.exists())apk.delete();
		//显示关于对话框
		Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                intent.setClassName(this, HelpActivity.class.getName());
                startActivity(intent);
                finish();
         }else {//不是第一次启动
  		  //是否完成上次下载的更新的安装
  		 if(!prefs.getBoolean(PreferencesActivity.KEY_LATEST_VERSION_INSTALL, true)){
  		    new AlertDialog.Builder(JumpActivity.this)
  		    .setTitle(R.string.app_update_title)
	  	    .setCancelable(false)
	  	    .setMessage(R.string.app_update_not_install)
	  	    .setPositiveButton(R.string.button_update_ok,new DialogInterface.OnClickListener() {   
				public void onClick(DialogInterface dialog, int which) {
					File apk = new File(apkFile);
			    		if(apk.exists())install();//下载的文件存在则安装
			    		else {//不存在则提示重新下载
			    			Intent update = new Intent(JumpActivity.this,UpdateService.class);
			    			startService(update);
			    		}
				}
		      })
		     .setNegativeButton(R.string.button_update_no,new DialogInterface.OnClickListener() {   
				public void onClick(DialogInterface dialog, int which) {
					//如果放弃本次更新,将不再进行提示
	prefs.edit().putBoolean(PreferencesActivity.KEY_LATEST_VERSION_INSTALL, true).commit();
					Log.v(TAG, "129");
					launchActivity();
					}
			     })
	  			.show();
  		   return;
  	     }
  		launchActivity();
  		
      }
    } catch (PackageManager.NameNotFoundException e) {
      Log.w(TAG, e);
    }
  }
 

 

 

private void install() {    
	   	Intent i = new Intent();
	   	i.setAction(Intent.ACTION_VIEW);    
	   	i.setDataAndType(Uri.fromFile(new File(apkFile)),    
               "application/vnd.android.package-archive");    
	   	startActivity(i);  
   }

 这个例子做了一个简单的跳转功能,通过Integer.parseInt(Build.VERSION.SDK) >= 5来分别启动适合不同系统版本的活动,使程序可以兼容跟多的手机。

 

private void launchActivity(){
	  if (Integer.parseInt(Build.VERSION.SDK) >= CameraManager.VERSION_CODES_LEVEL) {
			intent = new Intent(this,BJFILE.class);
		}else {
			intent = new Intent(this,EarlyBJFILE.class);
		}
	  startActivity(intent);
	  finish();
  }
 

2.在BJFILE或EarlyBJFILE活动中重我们使用一个Service来检查首否需要更新应用,当服务器上的apk文件的最后修改时间与程序配置文件中的最后修改时间不同,则表示发现新更新。

 

UpdateService.class

 

@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		Log.v(TAG, "onStart");
		new Thread(){
			public void run(){
				if(checkUpdate()){//如果有更新,则显示更新界面UpdateActivity,类似一个对话框
				       Intent update = new Intent(UpdateService.this,UpdateActivity.class);
				       update.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				       update.putExtra(VERSITON, newVersion);
				      startActivity(update);
	  		  }else stopSelf();
			}
		}.start();
		
	}


         //可能是不存在该请求对象,返回的向应头中没有设置last-modified域,则取到的值为0
	private long getLastModified() {
		try {
			URL url = new URL(/blog_article/UpdateActivity.updateURL);
			URLConnection con = (URLConnection) url.openConnection();
			Log.v(TAG, "con.getLastModified()"+con.getLastModified());
			return  con.getLastModified();
		} catch (MalformedURLException e) {
			e.printStackTrace();
			Log.v(TAG, "MalformedURLException");
			return  1;
		} catch (IOException e) {
			e.printStackTrace();
			Log.v(TAG, "IOException");
			return  2;
		}
	}
	
	//判断是否需要更新
	private boolean checkUpdate(){
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
		long latest = prefs.getLong(PreferencesActivity.KEY_LATEST_VERSION, 0);
		newVersion = getLastModified();
		Log.v(TAG, "latest=" + latest);
		Log.v(TAG, "newVersion=" + newVersion);
		if(newVersion>latest)return true;
		else return false;
	}

 3.UpdateActivity的样式为

 

<style name="BackgroundOnly">
		<item name="android:windowBackground">@null</item>
		<item name="android:windowContentOverlay">@null</item>
		<item name="android:windowAnimationStyle">@null</item>
		<item name="android:windowNoTitle">true</item>
		<item name="android:windowNoDisplay">true</item>
		<item name="android:windowIsFloating">true</item>
</style>

 源代码

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;

public class UpdateActivity extends Activity{
	private static String TAG = "UpdateActivity";
	public static String updateURL = "http://www.bjnote.com/down4/bjnote.apk";//更新程序位置
	private static String updateContentURL="http://www.bjnote.com/down4/bjnote.txt";//更新内容
	private StringBuffer sb =null;
	private ProgressDialog download;
	private Handler mHandler;
	protected static final int GUI_STOP_NOTIFIER = 0x108;
	protected static final int GUI_THREADING_NOTIFIER = 0x109;
	protected static final int GUI_ERROR_NOTIFIER = 0x110;
	protected static final int GUI_IO_NOTIFIER = 0x111;
	protected static final int GUI_INTERRUPTED_NOTIFIER = 0x112;
	protected static final int GUI_PROGRESS_NOTIFIER = 0x113;//开始进度条的进度值显示
	protected static final int GUI_UPDATE_CONTENT_NOTIFIER = 0x114;//有更新文本
	private int count = 0;
	private long total;
	private DownThread downThread;
	private UpdateContent updateContent;
	private SharedPreferences prefs;
	private long newVersion;
	private String apkFile = Environment.getExternalStorageDirectory()+"/bjfile.apk";
	
	    class DownThread extends Thread{
	    	
	    	private boolean cancel=false;
	    	private  File file;
	    	
            public void run() {  
                HttpClient client = new DefaultHttpClient();  
                HttpGet get = new HttpGet(updateURL);  
                HttpResponse response = null; 
                FileOutputStream fileOutputStream = null;  
                InputStream is=null;
                try {  
                	response = client.execute(get);
                	if(response.getStatusLine().getStatusCode()!=200)
					throw new IOException("StatusCode!=200");
                    HttpEntity entity = response.getEntity();  
                    total = entity.getContentLength();
                    mHandler.sendEmptyMessage(GUI_PROGRESS_NOTIFIER);
                    is = entity.getContent(); 
                    if (is != null) {  
  
                        file = new File(apkFile);  
                        fileOutputStream = new FileOutputStream(file);  
                          
                        byte[] buf = new byte[1024];  
                        int ch = -1;
                        while ((ch = is.read(buf)) != -1) {
                        	if(cancel)throw new InterruptedException();
                        	count+=ch;
                            fileOutputStream.write(buf, 0, ch);
                            mHandler.sendEmptyMessage(GUI_THREADING_NOTIFIER);
                        } 
                        if(count==total)mHandler.sendEmptyMessage(GUI_STOP_NOTIFIER);
                        fileOutputStream.flush();
                        if(fileOutputStream!=null)fileOutputStream.close();
                    } 
                } catch (ClientProtocolException e) {   
                    e.printStackTrace();
                    mHandler.sendEmptyMessage(GUI_ERROR_NOTIFIER);
                    if(file.exists())file.delete(); 
        
                } catch (IOException e) {
                	if(file.exists())file.delete();   
                    e.printStackTrace();  
                    mHandler.sendEmptyMessage(GUI_IO_NOTIFIER);
                } catch (InterruptedException e) {
					e.printStackTrace();
					if(file.exists())file.delete(); 
					mHandler.sendEmptyMessage(GUI_INTERRUPTED_NOTIFIER);
				} finally{
					try {
						is.close();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
            }  
            
            private void setCancel(boolean isCancel){
            	cancel = isCancel;
            }
  
        }
	    
	    
    //读取更新内容
	    class UpdateContent extends Thread{
	    
            public void run() {  
                HttpClient client = new DefaultHttpClient();  
                HttpGet get = new HttpGet(updateContentURL);  
                HttpResponse response = null; 
                BufferedReader bis = null; 
                try {  
                	response = client.execute(get);
                	//添加更新提示
                	sb.append(UpdateActivity.this.getString(R.string.app_update_tip));
                	if(response.getStatusLine().getStatusCode()!=200){
                		throw new IOException("StatusCode!=200");
                	}
                    HttpEntity entity = response.getEntity();
                    //XXX 可能需要改成其他的编码,Apple默认是gb2312
                    bis = new BufferedReader(new InputStreamReader(entity.getContent(),"gb2312"));
                    String s=null;
                    if (bis != null) {  
                    	s=bis.readLine();
                        while (s!=null) {
                        	sb.append("\n"+s);
                        	s=bis.readLine();
                        } 
                        mHandler.sendEmptyMessage(GUI_UPDATE_CONTENT_NOTIFIER);
                        bis.close();
                    } 
                } catch (ClientProtocolException e) {   
                    e.printStackTrace();
                    stopService();
        
                } catch (IOException e) {
                    e.printStackTrace();  
                    stopService();
                }
            }  
            
        }
	    
	@Override
	public void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		Log.v(TAG, "onCreate");
		mHandler = new Handler() {
			public void handleMessage(Message msg) {
				switch(msg.what) {
				case GUI_THREADING_NOTIFIER:
					download.setProgress(count);
					break;
				case GUI_STOP_NOTIFIER:
					 download.dismiss();
	 prefs.edit().putLong(PreferencesActivity.KEY_LATEST_VERSION, newVersion).commit();
					 //表示已下载但还未安装
	 prefs.edit().putBoolean(PreferencesActivity.KEY_LATEST_VERSION_INSTALL, false).commit();
					
					new AlertDialog.Builder(UpdateActivity.this)
		  			.setCancelable(false)
		  			.setTitle(R.string.app_update_title)
		  			.setMessage(R.string.button_update_finish)
		  		.setPositiveButton(R.string.button_ok,new DialogInterface.OnClickListener() {   
	  					public void onClick(DialogInterface dialog, int which) {
	  						install();
	  					}
	  			     })
		  		.setNegativeButton(R.string.button_exit, new DialogInterface.OnClickListener() {
		  					public void onClick(DialogInterface dialog, int which) {
		  						stopService();
		  					}
		  			 })
		  			.show();
					break;
				case GUI_IO_NOTIFIER:
				case GUI_ERROR_NOTIFIER:
					if(download!=null)download.dismiss();
					new AlertDialog.Builder(UpdateActivity.this)
		  			.setCancelable(false)
		  			.setMessage(R.string.app_update_error)
		  		.setPositiveButton(R.string.button_exit,new DialogInterface.OnClickListener() {   
	  					public void onClick(DialogInterface dialog, int which) {
	  						stopService();
	  					}
	  			     })
		  			.show();
					break;
				case GUI_INTERRUPTED_NOTIFIER:
					download.dismiss();
					new AlertDialog.Builder(UpdateActivity.this)
		  			.setCancelable(false)
		  			.setMessage(R.string.app_update_cancel)
		  		.setPositiveButton(R.string.button_exit,new DialogInterface.OnClickListener() {   
	  					public void onClick(DialogInterface dialog, int which) {
	  						stopService();
	  						//如果放弃本次更新,将不再进行提示
	  	prefs.edit().putLong(PreferencesActivity.KEY_LATEST_VERSION, newVersion).commit();
	        prefs.edit().putBoolean(PreferencesActivity.KEY_LATEST_VERSION_INSTALL, true).commit();
	  					}
	  			     })
		  			.show();
					break;
				case GUI_PROGRESS_NOTIFIER:
					 download.setMax((int) total);
					 download.setProgress(0);
					break;
				case GUI_UPDATE_CONTENT_NOTIFIER:
					download();
					break;
				}
			}
		};
		newVersion = getIntent().getLongExtra(UpdateService.VERSITON, 0);
		prefs = PreferenceManager.getDefaultSharedPreferences(this);
		sb = new StringBuffer();
		updateContent = new UpdateContent();
		updateContent.start();
	} 
   
  private void install() {    
	   	Intent i = new Intent(); 
       i.setAction(Intent.ACTION_VIEW);    
       i.setDataAndType(Uri.fromFile(new File(apkFile)),    
               "application/vnd.android.package-archive");    
       startActivity(i);
   }
  
  private void download() {
	  downThread = new DownThread();
	  
		new AlertDialog.Builder(this)
		.setTitle(R.string.app_update_title)
		.setCancelable(false)
		.setMessage(sb.toString())
		.setPositiveButton(R.string.button_update_ok,new DialogInterface.OnClickListener() {
			 public void onClick(DialogInterface dialog, int which) {
				 download = new ProgressDialog(UpdateActivity.this);
				 download.setMessage(getString(R.string.app_update_warn));
				 download.setCancelable(false);
				 download.setIndeterminate(false);
				 download.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
	download.setButton(getString(R.string.button_cancel), new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						downThread.setCancel(true);
					}
				});
				download.show();
				downThread.start();
					
				}
	     })
		 .setNegativeButton(R.string.button_update_no, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					stopService();
	prefs.edit().putLong(PreferencesActivity.KEY_LATEST_VERSION, newVersion).commit();
	prefs.edit().putBoolean(PreferencesActivity.KEY_LATEST_VERSION_INSTALL, true).commit();
				}
		 })
		.show();
}

	/**
	 * stopSelf,服务关闭自身
	 */
	private void stopService() {
		Intent stop = new Intent(this,UpdateService.class);
		stopService(stop);
		Log.v(TAG, "stopService");
		finish();
		Log.v(TAG, "finish activity");
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		prefs=null;
		Log.v(TAG, "onDestroy");
	}
}
 
1 楼 yanghuaixi 2011-01-06  
很好很详细,多谢 
2 楼 yanghuaixi 2011-01-06  
我也刚刚做了一个相关的东西,有机会可以交流下
3 楼 ck19860613 2011-01-09  
自己逻辑很清楚,就是表述出来不太清楚
4 楼 live17909 2011-04-17  
老大,能发下源码吗?谢谢.paladin383@gmail.com

    
[2] 基于OPhone 2.0的2D动画片实践(二)
    来源: 互联网  发布时间: 2014-02-18
基于OPhone 2.0的2D动画实践(二)
基于OPhone 2.0的2D动画实践(二) OPhone平台开发, 2010-10-18 16:53:43 标签 : OPhone2.0 2D 动画

 

  本系列文章主要介绍了OPhone 2.0 SDK提供的两种实现2D动画的方式:帧动画和补间动画。文章的每个知识点都提供了精彩的实例以向读者展示2D动画的具体实现方法。通过对本系列文章的学习,读者可利用2D动画实现非常绚丽的界面效果。
 

  补间动画简介
  如果动画中的图像变换比较有规律时,可以采用自动生成中间图像的方式来生成动画。例如,图像的移动、旋转、缩放等。当然,还有更复杂的情况,例如,由正方形变成圆形、圆形变成椭圆形,这些变化过程中的图像都可以根据一定的数学算法自动生成。而我们只需要指定动画的第1帧和最后一帧的图像即可。这种自动生成中间图像的动画被称为补间(Tween)动画。
  补间动画的优点是节省硬盘空间。这是因为这种动画只需要提供两帧图像(第1帧和最后一帧),其他的图像都由系统自动生成。当然,这种动画也有一定的缺点,就是动画很复杂时无法自动生成中间图像,例如,由电影画面组件的动画,由于每幅画面过于复杂,系统无法预料下一幅画面是什么样子。因此,这种复杂的动画只能使用帧动画来完成。在本节将介绍OPhone SDK提供的4种补间动画效果:移动、缩放、旋转和透明度。OPhone SDK并未提供更复杂的补间动画。如果要实现更复杂的补间动画,需要开发人员自已编码来完成。
 

  移动补间动画
  移动是最常见的动画效果。我们可以通过配置动画文件(xml文件)或Java代码来实现补间动画的移动效果。补间动画文件需要放在res\anim目录中。在动画文件中通过<translate>标签设置移动效果。假设在res\anim目录下有一个动画文件:test.xml,该文件的内容如下:

view plaincopy to clipboardprint?
  • <translate xmlns:android="http://schemas.android.com/apk/res/android"  
  •   android:interpolator="@android:anim/accelerate_interpolator"  
  •   android:fromXDelta="0" android:toXDelta="320" android:fromYDelta="0"  
  •   android:toYDelta="0" android:duration="2000" />  
  • <translate xmlns:android="http://schemas.android.com/apk/res/android"   android:interpolator="@android:anim/accelerate_interpolator"   android:fromXDelta="0" android:toXDelta="320" android:fromYDelta="0"   android:toYDelta="0" android:duration="2000" />


      从上面的配置代码可以看出,<translate>标签中设置了6个属性,这6个属性的含义如下:
       android:interpolator:表示动画渲染器。通过android:interpolator属性可以设置3个动画渲染器:accelerate_interpolator(动画加速器)、decelerate_interpolator(动画减速器)和accelerate_decelerate_interpolator(动画加速减速器)。动画加速器使动画在开始时速度最慢,然后逐渐加速。动画减速器使动画在开始时速度最快,然后逐渐减速。动画加速减速器使动画在开始和结束时速度最慢,但在前半部分时开始加速,在后半部分时开始减速。
       android:fromXDelta:动画起始位置的横坐标。
       android:toXDelta:动画结束位置的横坐标。
       android:fromXDelta:动画起始位置的纵坐标。
       android:toYDelta:动画结束位置的纵坐标。
       android:duration:动画的持续时间。单位是毫秒。也就是说,动画要在android:duration属性指定的时间内从起始点移动到结束点。


      装载补间动画文件需要使用android.view.animation.AnimationUtils. loadAnimation方法,该方法的定义如下:
     

    view plaincopy to clipboardprint?
  • public static Animation loadAnimation(Context context, int id);  
  • public static Animation loadAnimation(Context context, int id);

      其中id表示动画文件的资源ID。装载test.xml文件的代码如下:
     

    view plaincopy to clipboardprint?
  • Animation animation = AnimationUtils.loadAnimation(this, R.anim.test);  
  • Animation animation = AnimationUtils.loadAnimation(this, R.anim.test);

      假设有一个EditText组件(editText),将test.xml文件中设置的补间动画应用到EditText组件上的方式有如下两种:
      1.  使用EditText类的startAnimation方法,代码如下:

    view plaincopy to clipboardprint?
  • editText.startAnimation(animation);  
  • editText.startAnimation(animation);


      2.  使用Animation类的start方法,代码如下:
     

    view plaincopy to clipboardprint?
  • //  绑定补间动画   
  •   editText.setAnimation(animation);   
  •   //  开始动画   
  •   animation.start();  
  • // 绑定补间动画   editText.setAnimation(animation);   // 开始动画   animation.start();


      使用上面两种方式开始补间动画都只显示一次。如果想循环显示动画,需要使用如下的代码将动画设置成循环状态。

    view plaincopy to clipboardprint?
  • animation.setRepeatCount(Animation.INFINITE);  
  • animation.setRepeatCount(Animation.INFINITE);


      上面两行代码在开始动画之前和之后执行都没有问题。

      移动补间动画的实例
      本例的动画效果是在屏幕上方的EditText组件从左到右循环匀速水平移动。EditText下方的小球上下移动。从上到下移动时加速。从下到上移动时减速。
      本例涉及到3个动画渲染器:accelerate_interpolator、decelerate_interpolator和linear_interpolator。其中前两个动画渲染器可以直接作为android:interpolator属性的值,而linear_interpolator虽然在系统中已定义,但由于不是public的,因此,需要自己定义linear_interpolator.xml文件。当然,也可以将系统的linear_interpolator.xml文件复制到Eclipse工程中的res\anim目录下。
      在本例中定义了3个动画文件,其中translate_right.xml被应用于EditText组件。translate_bottom.xml(从上到下移动,加速)和translate_top.xml(从下到上移动,减速)被应用于小球(ImageView组件)。这3个动画文件的内容如下:

    view plaincopy to clipboardprint?
  • translate_right.xml   
  •   <translate xmlns:android="http://schemas.android.com/apk/res/android"  
  •   android:interpolator="@anim/linear_interpolator"  
  •   android:fromXDelta="-320" android:toXDelta="320" android:fromYDelta="0"  
  •   android:toYDelta="0" android:duration="5000" />   
  •   
  • translate_bottom.xml   
  •   <translate xmlns:android="http://schemas.android.com/apk/res/android"  
  •    android:interpolator="@android:anim/accelerate_interpolator"  
  •    android:fromXDelta="0" android:toXDelta="0" android:fromYDelta="0"  
  •    android:toYDelta="260" android:duration="2000" />   
  • translate_top.xml   
  •   <translate xmlns:android="http://schemas.android.com/apk/res/android"  
  •   android:interpolator="@android:anim/decelerate_interpolator"  
  •   android:fromXDelta="0" android:toXDelta="0" android:fromYDelta="260"  
  •   android:toYDelta="0" android:duration="2000" />  
  • translate_right.xml   <translate xmlns:android="http://schemas.android.com/apk/res/android"   android:interpolator="@anim/linear_interpolator"   android:fromXDelta="-320" android:toXDelta="320" android:fromYDelta="0"   android:toYDelta="0" android:duration="5000" /> translate_bottom.xml   <translate xmlns:android="http://schemas.android.com/apk/res/android"    android:interpolator="@android:anim/accelerate_interpolator"    android:fromXDelta="0" android:toXDelta="0" android:fromYDelta="0"    android:toYDelta="260" android:duration="2000" /> translate_top.xml   <translate xmlns:android="http://schemas.android.com/apk/res/android"   android:interpolator="@android:anim/decelerate_interpolator"   android:fromXDelta="0" android:toXDelta="0" android:fromYDelta="260"   android:toYDelta="0" android:duration="2000" />


      EditText组件的循环水平移动可以直接使用setRepeatMode和setRepeatCount方法进行设置。而小球的移动需要应用两个动画文件。本例采用的方法是在一个动画播放完后,再将另一个动画文件应用到显示小球的ImageView组件中。这个操作需要在AnimationListener接口的onAnimationEnd方法中完成。
      运行本例后,单击【开始动画】按钮后,EditText组件从屏幕的左侧出来,循环水平向右移动,当EditText组件完全移进屏幕右侧时,会再次从屏幕左侧出来。同时小球会上下移动。效果如图1所示。

      图1  移动补间动画

      本例的完整代码如下:

    view plaincopy to clipboardprint?
  • package net.blogjava.mobile;   
  •   
  •   import android.app.Activity;   
  •   import android.os.Bundle;   
  •   import android.view.View;   
  •   import android.view.View.OnClickListener;   
  •   import android.view.animation.Animation;   
  •   import android.view.animation.AnimationUtils;   
  •   import android.view.animation.Animation.AnimationListener;   
  •   import android.widget.Button;   
  •   import android.widget.EditText;   
  •   import android.widget.ImageView;   
  •   
  •   public class Main extends Activity implements OnClickListener, AnimationListener   
  •   {   
  •   private EditText editText;   
  •   private ImageView imageView;   
  •   private Animation animationRight;   
  •   private Animation animationBottom;   
  •   private Animation animationTop;   
  •   
  •   //  animation参数表示当前应用到组件上的Animation对象   
  •   @Override  
  •   public void onAnimationEnd(Animation animation)   
  •   {   
  •   //  根据当前显示的动画决定下次显示哪一个动画   
  •   if (animation.hashCode() == animationBottom.hashCode())   
  •   imageView.startAnimation(animationTop);   
  •   else if (animation.hashCode() == animationTop.hashCode())   
  •   imageView.startAnimation(animationBottom);   
  •   }   
  •   @Override  
  •   public void onAnimationRepeat(Animation animation)   
  •   {   
  •   }   
  •   @Override  
  •   public void onAnimationStart(Animation animation)   
  •   {   
  •   }   
  •   @Override  
  •   public void onClick(View view)   
  •   {   
  •   //  开始EditText的动画   
  •   editText.setAnimation(animationRight);   
  •   animationRight.start();   
  •   animationRight.setRepeatCount(Animation.INFINITE);   
  •   editText.setVisibility(EditText.VISIBLE);   
  •   //  开始小球的动画   
  •   imageView.startAnimation(animationBottom);   
  •   }   
  •   @Override  
  •   public void onCreate(Bundle savedInstanceState)   
  •   {   
  •   super.onCreate(savedInstanceState);   
  •   setContentView(R.layout.main);   
  •   editText = (EditText) findViewById(R.id.edittext);   
  •   editText.setVisibility(EditText.INVISIBLE);   
  •   Button button = (Button) findViewById(R.id.button);   
  •   button.setOnClickListener(this);   
  •   imageView = (ImageView) findViewById(R.id.imageview);   
  •   animationRight = AnimationUtils.loadAnimation(this,R.anim.translate_right);   
  •   animationBottom = AnimationUtils.loadAnimation(this,R.anim.translate_bottom);   
  •   animationTop = AnimationUtils.loadAnimation(this, R.anim.translate_top);   
  •   animationBottom.setAnimationListener(this);   
  •   animationTop.setAnimationListener(this);   
  •   }   
  •   }  
  • package net.blogjava.mobile;   import android.app.Activity;   import android.os.Bundle;   import android.view.View;   import android.view.View.OnClickListener;   import android.view.animation.Animation;   import android.view.animation.AnimationUtils;   import android.view.animation.Animation.AnimationListener;   import android.widget.Button;   import android.widget.EditText;   import android.widget.ImageView;   public class Main extends Activity implements OnClickListener, AnimationListener   {   private EditText editText;   private ImageView imageView;   private Animation animationRight;   private Animation animationBottom;   private Animation animationTop;   // animation参数表示当前应用到组件上的Animation对象   @Override   public void onAnimationEnd(Animation animation)   {   // 根据当前显示的动画决定下次显示哪一个动画   if (animation.hashCode() == animationBottom.hashCode())   imageView.startAnimation(animationTop);   else if (animation.hashCode() == animationTop.hashCode())   imageView.startAnimation(animationBottom);   }   @Override   public void onAnimationRepeat(Animation animation)   {   }   @Override   public void onAnimationStart(Animation animation)   {   }   @Override   public void onClick(View view)   {   // 开始EditText的动画   editText.setAnimation(animationRight);   animationRight.start();   animationRight.setRepeatCount(Animation.INFINITE);   editText.setVisibility(EditText.VISIBLE);   // 开始小球的动画   imageView.startAnimation(animationBottom);   }   @Override   public void onCreate(Bundle savedInstanceState)   {   super.onCreate(savedInstanceState);   setContentView(R.layout.main);   editText = (EditText) findViewById(R.id.edittext);   editText.setVisibility(EditText.INVISIBLE);   Button button = (Button) findViewById(R.id.button);   button.setOnClickListener(this);   imageView = (ImageView) findViewById(R.id.imageview);   animationRight = AnimationUtils.loadAnimation(this,R.anim.translate_right);   animationBottom = AnimationUtils.loadAnimation(this,R.anim.translate_bottom);   animationTop = AnimationUtils.loadAnimation(this, R.anim.translate_top);   animationBottom.setAnimationListener(this);   animationTop.setAnimationListener(this);   }   }


      缩放补间动画
      通过<scale>标签可以定义缩放补间动画。下面的代码定义了一个标准的缩放补间动画。

    view plaincopy to clipboardprint?
  • <scale xmlns:android="http://schemas.android.com/apk/res/android"  
  •   android:interpolator="@android:anim/decelerate_interpolator"  
  •   android:fromXScale="0.2" android:toXScale="1.0" android:fromYScale="0.2"  
  •   android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%"  
  •   android:duration="2000" />  
  • <scale xmlns:android="http://schemas.android.com/apk/res/android"   android:interpolator="@android:anim/decelerate_interpolator"   android:fromXScale="0.2" android:toXScale="1.0" android:fromYScale="0.2"   android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%"   android:duration="2000" />


      <scale>标签和<translate>标签中有些属性是相同的,而有些属性是<scale>标签特有的,这些属性的含义如下:
       android:fromXScale:表示沿X轴缩放的起始比例。
       android:toXScale:表示沿X轴缩放的结束比例。
       android:fromYScale:表示沿Y轴缩放的起始比例。
       android:toYScale:表示沿Y轴缩放的结束比例。
       android:pivotX:表示沿X轴方向缩放的支点位置。如果该属性值为"50%",则支点在沿X轴中心的位置。
       android:pivotY:表示沿Y轴方向缩放的支点位置。如果该属性值为"50%",则支点在沿Y轴中心的位置。
      其中前4个属性的取值规则如下:
       0.0:表示收缩到没有。
       1.0:表示正常不收缩。
       大于1.0:表示将组件放大到相应的比例。例如,值为1.5,表示放大到原组件的1.5倍。
       小于1.0:表示将组件缩小到相应的比例。例如,值为0.5,表示缩小到原组件的50%。
      如果想通过Java代码实现缩放补间动画,可以创建android.view.animation.ScaleAnimation对象。ScaleAnimation类构造方法的定义如下:
      public ScaleAnimation(float fromX, float toX, float fromY, float toY,float pivotX, float pivotY)
      通过ScaleAnimation类的构造方法可以设置上述6个属性值。设置其他属性的方法与移动补间动画相同。


      总结
      本文主要两种补间动画:移动补间动画和缩放补间动画,并给出了相应的实例。在下一篇文章中将会介绍另外两种补间动画。


      作者介绍
      李宁,东北大学计算机专业硕士,拥有超过10年的软件开发经验。曾任国内某知名企业项目经理;目前担任eoeandroid和ophonesdn版主;中国移动开发者社区OPhone专家;51CTO客作专家;CSDN博客专家。曾领导并参与开发了多个大中型项目。目前主要从事Android及其相关产品的研发。从2005年进入写作领域以来,为《程序员》、《电脑编程技巧与维护》、《电脑报》、IT168、天极网等平面媒体和网络媒体撰写了一百多篇原创技术和评论文章。并在个人blog(http://nokiaguy.blogjava.net)上发表了大量的原创技术文章。2007年获《电脑编程技巧与维护》优秀作者。2009年获得OPhone征文大赛二等奖。个人著作:《Android/OPhone开发完全讲义》、《人人都玩开心网:Ext JS+Android+SSH整合开发Web与移动SNS》、《Java Web开发速学宝典》。


        
    [3] WLAN中各种基准(或者说各种协议)的说明
        来源: 互联网  发布时间: 2014-02-18
    WLAN中各种标准(或者说各种协议)的说明

    1.0 802.11a标准:   5GHZ;支持的最大速度为54Mbps

    2.0 802.11b标准:2.4GHZ;支持的最大速度为11Mbps

    3.0 802.11g标准:2.4GHZ;支持的最大速度为54Mbps

    4.0 802.11E标准

    5.0 802.11i 标准

    6.0 wap(无线应用协议)


        
    最新技术文章:
    ▪Android开发之登录验证实例教程
    ▪Android开发之注册登录方法示例
    ▪Android获取手机SIM卡运营商信息的方法
    ▪Android实现将已发送的短信写入短信数据库的...
    ▪Android发送短信功能代码
    ▪Android根据电话号码获得联系人头像实例代码
    ▪Android中GPS定位的用法实例
    ▪Android实现退出时关闭所有Activity的方法
    ▪Android实现文件的分割和组装
    ▪Android录音应用实例教程
    ▪Android双击返回键退出程序的实现方法
    ▪Android实现侦听电池状态显示、电量及充电动...
    ▪Android获取当前已连接的wifi信号强度的方法
    ▪Android实现动态显示或隐藏密码输入框的内容
    ▪根据USER-AGENT判断手机类型并跳转到相应的app...
    ▪Android Touch事件分发过程详解
    ▪Android中实现为TextView添加多个可点击的文本
    ▪Android程序设计之AIDL实例详解
    ▪Android显式启动与隐式启动Activity的区别介绍
    ▪Android按钮单击事件的四种常用写法总结
    ▪Android消息处理机制Looper和Handler详解
    ▪Android实现Back功能代码片段总结
    ▪Android实用的代码片段 常用代码总结
    ▪Android实现弹出键盘的方法
    ▪Android中通过view方式获取当前Activity的屏幕截...
    ▪Android提高之自定义Menu(TabMenu)实现方法
    ▪Android提高之多方向抽屉实现方法
    ▪Android提高之MediaPlayer播放网络音频的实现方法...
    ▪Android提高之MediaPlayer播放网络视频的实现方法...
    ▪Android提高之手游转电视游戏的模拟操控
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3