|
|
51CTO旗下网站
|
|
移动端

5.25 建立自己的手写笔画图案(1)

《Google Android SDK开发范例大全(第2版)》第5章讲述的是交互式通信服务与手机控制。本节为大家介绍建立自己的手写笔画图案。

作者:佘志龙等来源:人民邮电出版社|2010-07-16 16:56

5.25 建立自己的手写笔画图案(1)
Gesture Builder

范例说明

自SDK 1.6开始,Android手机已支持内置Gesture Builder程序,若是被Google签署(Signed)过出厂的手机应会内置此程序,如果是程序开发人员,可在SDK文件夹里的"\android\platforms\ android\samples\GestureBuilder"找到这支程序的源代码,编译后即可生成各SDK版本可使用的Gesture Builder程序(apk)自行安装使用。

Gesture Builder提供了一手写识别的功能,让用户以类似于涂鸦的方式绘制一个手写符号,使之对应一个字符串名称,然而GestureBuilder功能虽完整,但在手写字符串的创建上却有些限制,如:制式化的建立方式、无法自行配置涂鸦区、查看手写(Gesture)以ListView来呈现等,在实际开发上稍显"复杂"了些。

本范例程序练习,是编写一个迷你版的Gesture Builder,可以通过全屏(GestureOverlayView)接收User的手写,并让我们"共享"系统预设使用的Gesture Library,在日后的项目开发中,便可依据此范例作为开发模板,创建、保存手写笔画图案。

运行结果(见图5-28)

 
图5-28  创建一个名为RICK的手写符号
范例程序
  1. res/layout/main.xml 

我们可以看到在res/layout/main.xml版面配置中,其中有一个TAG为<android.gesture. GestureOverlayView>的Widget,可称为"手写绘图区",当中有两项较重要的属性,分别为android:layout_width设置为"fill_parent"以及android:gestureStrokeType设置为"multiple",这表示为支持多笔画,若设置为"single"则仅支持单一笔画。

  1. <android.gesture.GestureOverlayView 
  2.   android:id="@+id/myGestures1" 
  3.   android:layout_width="fill_parent" 
  4.   android:layout_height="0dip" 
  5.   android:layout_weight="1.0" 
  6.   android:gestureStrokeType="multiple" 
  7. /> 

src/irdc.ex05_25/EX05_25.java

Gesture对象是自GestureOverlayView.getGesture() 所取得的手写对象;GestureLibraries为保存手写背后所包含的意义(String),本范例利用GestureLibraries.fromFile()方法来加载预设的Gesture文件,倘若默认手机的SD存储卡中尚未创建Gesture手写数据文件,此程序也会处理创建新文件的工作。此外,程序中举例应用了GestureLibraries.addGesture()新建手写数据、GestureLibraries.save()保存写入手写数据GestureLibraries.load()加载手写数据、GestureLibraries. removeGesture()删除手写数据等方法。

  1. /* import程序略 */  
  2. import android.gesture.Gesture;  
  3. import android.gesture.GestureLibraries;  
  4. import android.gesture.GestureLibrary;  
  5. import android.gesture.GestureOverlayView;  
  6. import android.view.MotionEvent;  
  7.  
  8. public class EX05_25 extends Activity  
  9. {  
  10.   private Gesture ges;  
  11.   private GestureLibrary lib;  
  12.   private GestureOverlayView overlay;  
  13.   private Button button01,button02;  
  14.   private EditText et;  
  15.   private String gesPath;  
  16.     
  17.   /** Called when the activity is first created. */  
  18.   @Override   
  19.   public void onCreate(Bundle savedInstanceState)  
  20.   {  
  21.     super.onCreate(savedInstanceState);  
  22.     /* 加载main.xml Layout */  
  23.     setContentView(R.layout.main);  
  24.        
  25.     /* 查看SDCard是否存在 */  
  26.     if(!Environment.MEDIA_MOUNTED.equals  
  27.         (Environment.getExternalStorageState()))  
  28.     {   
  29.       /* SD卡不存在,显示Toast信息 */  
  30.       Toast.makeText(EX05_25.this,"SD卡不存在!程序无法执行",  
  31.                      Toast.LENGTH_LONG).show();  
  32.       finish();  
  33.     }  
  34.     /* 以findViewById()取得对象 */  
  35.     et = (EditText)this.findViewById(R.id.myEditText1);  
  36.     button01 = (Button)this.findViewById(R.id.myButton1);  
  37.     button02 = (Button)this.findViewById(R.id.myButton2);  
  38.     overlay = (GestureOverlayView) findViewById(R.id.myGestures1);  
  39.  
  40.     /* 取得系统默认的GestureLibrary文件路径 */  
  41.     gesPath = new File  
  42.     (  
  43.       Environment.getExternalStorageDirectory(),"gestures"   
  44.     ).getAbsolutePath();  
  45.  
  46.     /* 设置EditText的OnKeyListener */  
  47.     et.setOnKeyListener(new EditText.OnKeyListener()  
  48.     {  
  49.       @Override  
  50.       public boolean onKey(View v, int keyCode, KeyEvent event)  
  51.       {  
  52.         /* 名称与手写都均设置好时将新建的Button enable */  
  53.         if(ges!=null&&et.getText().length()!=0)  
  54.         {  
  55.           button01.setEnabled(true);  
  56.         }  
  57.         else  
  58.         {  
  59.           button01.setEnabled(false);  
  60.         }  
  61.         return false;  
  62.       }  
  63.     });  
  64.       
  65.     /* 设置Overlay的OnGestureListener */  
  66.     overlay.addOnGestureListener  
  67.     (new GestureOverlayView.OnGestureListener()  
  68.     {  
  69.       @Override  
  70.       public void onGesture  
  71.       (GestureOverlayView overlay,MotionEvent event)   
  72.       {  
  73.       }  
  74.       /* 开始画手写时将添加的Button disable,并清除Gesture */  
  75.       @Override  
  76.       public void onGestureStarted  
  77.       (GestureOverlayView overlay,MotionEvent event)  
  78.       {  
  79.         button01.setEnabled(false);  
  80.         ges = null;  
  81.       }  
  82.       /* 手写画完时判断名称与手写是否完整建立 */  
  83.       @Override  
  84.       public void onGestureEnded  
  85.       (GestureOverlayView overlay, MotionEvent event)  
  86.       {  
  87.         ges = overlay.getGesture();  
  88.         if (ges!=null&&et.getText().length()!=0)  
  89.         {  
  90.           button01.setEnabled(true);  
  91.         }  
  92.       }  
  93.       @Override  
  94.       public void onGestureCancelled  
  95.       (GestureOverlayView overlay, MotionEvent event)  
  96.       {  
  97.       }  
  98.     });  
  99.       
  100.     /* 设定button01的OnClickListener */  
  101.     button01.setOnClickListener(new Button.OnClickListener()  
  102.     {   
  103.       @Override   
  104.       public void onClick(View v)   
  105.       {   
  106.         String gesName=et.getText().toString();  
  107.         try  
  108.         {  
  109.           File file = new File(gesPath);  
  110.           lib = GestureLibraries.fromFile(gesPath);  
  111.             
  112.           if(!file.exists())  
  113.           {  
  114.             /* 文件不存在就直接写入 */  
  115.             lib.addGesture(gesName,ges);  
  116.             if(lib.save())  
  117.             {  
  118.               /* 将设置画面数据清除 */  
  119.               et.setText("");  
  120.               button01.setEnabled(false);  
  121.               overlay.clear(true);  
  122.               /* 保存成功,显示Toast信息 */  
  123.               Toast.makeText  
  124.               (  
  125.                 EX05_25.this,getString(R.string.save_success)+":"+  
  126.                 gesPath,Toast.LENGTH_LONG  
  127.               ).show();  
  128.             }  
  129.             else  
  130.             {  
  131.               /* 保存失败,显示Toast信息 */  
  132.               Toast.makeText  
  133.               (  
  134.                 EX05_25.this, getString(R.string.save_failed)+":"+  
  135.                 gesPath,Toast.LENGTH_LONG  
  136.               ).show();   
  137.             }   
  138.           }  
  139.           else  
  140.           {  
  141.             /* 文件存在时先读取已保存的Gesture */  
  142.             if (!lib.load())   
  143.             {  
  144.               /* Library读取失败,显示Toast信息 */  
  145.               Toast.makeText  
  146.               (  
  147.                 EX05_25.this, getString(R.string.load_failed)+":"+  
  148.                 gesPath,Toast.LENGTH_LONG  
  149.               ).show();  
  150.             }  
  151.             else  
  152.             {  
  153.               /* 如果Library中存在相同名称,则先将其移除再写入 */  
  154.               Set<String> en=lib.getGestureEntries();  
  155.               if(en.contains(gesName))  
  156.               {  
  157.                 ArrayList<Gesture> al=lib.getGestures(gesName);  
  158.                 for(int i=0;i<al.size();i++)  
  159.                 {  
  160.                   lib.removeGesture(gesName,al.get(i));  
  161.                 }  
  162.               }  
  163.               lib.addGesture(gesName,ges);  
  164.               if(lib.save())  
  165.               {   
  166.                 /* 将设置画面数据清除 */  
  167.                 et.setText("");   
  168.                 button01.setEnabled(false);  
  169.                 overlay.clear(true);  
  170.                 /* 保存成功,显示Toast信息 */  
  171.                 Toast.makeText  
  172.                 (  
  173.                   EX05_25.this,getString(R.string.save_success)+":"+  
  174.                   gesPath,Toast.LENGTH_LONG  
  175.                 ).show();  
  176.               }  
  177.               else   
  178.               {    
  179.                 /* 保存失败,显示Toast信息 */  
  180.                 Toast.makeText  
  181.                 (  
  182.                   EX05_25.this, getString(R.string.save_failed)+":"+  
  183.                   gesPath,Toast.LENGTH_LONG  
  184.                 ).show();  
  185.               }   
  186.             }  
  187.           }  
  188.         }  
  189.         catch(Exception e)   
  190.         {   
  191.           e.printStackTrace();   
  192.         }   
  193.       }   
  194.     });  
  195.       
  196.     /* 设置button02的OnClickListener,清除建立的Overlay */  
  197.     button02.setOnClickListener(new Button.OnClickListener()  
  198.     {   
  199.       @Override   
  200.       public void onClick(View v)  
  201.       {  
  202.         et.setText("");  
  203.         button01.setEnabled(false);  
  204.         overlay.clear(true);  
  205.       }  
  206.     });  
  207.   }  
【责任编辑:云霞 TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

Jenkins Pipeline可持续化集成

Jenkins Pipeline可持续化集成

优化运维流水线
共3章 | youerning

25人订阅学习

笑熬浆糊之职场那些事

笑熬浆糊之职场那些事

IT人的职场心法
共22章 | Bear_Boss

64人订阅学习

Redis运维秘籍

Redis运维秘籍

运维标配技术
共15章 | one叶孤舟

140人订阅学习

读 书 +更多

Java程序设计专家门诊

精选目前国内外最流行的程序设计语言——Java作为本书的选题,并以丰富的内容来解决读者学习该语言时可能遇到的各种问题。以专业的论坛为基...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO播客