建立自己的手写笔画图案
来源:互联网 发布:windows所有快捷键 编辑:程序博客网 时间:2024/06/09 15:35
范例说明
自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,在日后的项目开发中,便可依据此范例作为开发模板,创建、保存手写笔画图案。
<!--[endif]-->▲ 图5-28 创建一个名为RICK的手写符号
范例程序
res/layout/main.xml
我们可以看到在res/layout/main.xml版面配置中,其中有一个TAG为<android.gesture. GestureOverlayView>的Widget,可称为“手写绘图区”,当中有两项较重要的属性,分别为android:layout_width设置为“fill_parent”以及android:gestureStrokeType设置为“multiple”,这表示为支持多笔画,若设置为“single”则仅支持单一笔画。
<android.gesture.GestureOverlayView
android:id="@+id/myGestures1"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1.0"
android:gestureStrokeType="multiple"
/>
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()删除手写数据等方法。
/* import程序略 */
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.view.MotionEvent;
public class EX05_25 extends Activity
{
private Gesture ges;
private GestureLibrary lib;
private GestureOverlayView overlay;
private Button button01,button02;
private EditText et;
private String gesPath;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* 加载main.xml Layout */
setContentView(R.layout.main);
/* 查看SDCard是否存在 */
if(!Environment.MEDIA_MOUNTED.equals
(Environment.getExternalStorageState()))
{
/* SD卡不存在,显示Toast信息 */
Toast.makeText(EX05_25.this,"SD卡不存在!程序无法执行",
Toast.LENGTH_LONG).show();
finish();
}
/* 以findViewById()取得对象 */
et = (EditText)this.findViewById(R.id.myEditText1);
button01 = (Button)this.findViewById(R.id.myButton1);
button02 = (Button)this.findViewById(R.id.myButton2);
overlay = (GestureOverlayView) findViewById(R.id.myGestures1);
/* 取得系统默认的GestureLibrary文件路径 */
gesPath = new File
(
Environment.getExternalStorageDirectory(),"gestures"
).getAbsolutePath();
/* 设置EditText的OnKeyListener */
et.setOnKeyListener(new EditText.OnKeyListener()
{
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
/* 名称与手写都均设置好时将新建的Button enable */
if(ges!=null&&et.getText().length()!=0)
{
button01.setEnabled(true);
}
else
{
button01.setEnabled(false);
}
return false;
}
});
/* 设置Overlay的OnGestureListener */
overlay.addOnGestureListener
(new GestureOverlayView.OnGestureListener()
{
@Override
public void onGesture
(GestureOverlayView overlay,MotionEvent event)
{
}
/* 开始画手写时将添加的Button disable,并清除Gesture */
@Override
public void onGestureStarted
(GestureOverlayView overlay,MotionEvent event)
{
button01.setEnabled(false);
ges = null;
}
/* 手写画完时判断名称与手写是否完整建立 */
@Override
public void onGestureEnded
(GestureOverlayView overlay, MotionEvent event)
{
ges = overlay.getGesture();
if (ges!=null&&et.getText().length()!=0)
{
button01.setEnabled(true);
}
}
@Override
public void onGestureCancelled
(GestureOverlayView overlay, MotionEvent event)
{
}
});
/* 设定button01的OnClickListener */
button01.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(View v)
{
String gesName=et.getText().toString();
try
{
File file = new File(gesPath);
lib = GestureLibraries.fromFile(gesPath);
if(!file.exists())
{
/* 文件不存在就直接写入 */
lib.addGesture(gesName,ges);
if(lib.save())
{
/* 将设置画面数据清除 */
et.setText("");
button01.setEnabled(false);
overlay.clear(true);
/* 保存成功,显示Toast信息 */
Toast.makeText
(
EX05_25.this,getString(R.string.save_success)+":"+
gesPath,Toast.LENGTH_LONG
).show();
}
else
{
/* 保存失败,显示Toast信息 */
Toast.makeText
(
EX05_25.this, getString(R.string.save_failed)+":"+
gesPath,Toast.LENGTH_LONG
).show();
}
}
else
{
/* 文件存在时先读取已保存的Gesture */
if (!lib.load())
{
/* Library读取失败,显示Toast信息 */
Toast.makeText
(
EX05_25.this, getString(R.string.load_failed)+":"+
gesPath,Toast.LENGTH_LONG
).show();
}
else
{
/* 如果Library中存在相同名称,则先将其移除再写入 */
Set<String> en=lib.getGestureEntries();
if(en.contains(gesName))
{
ArrayList<Gesture> al=lib.getGestures(gesName);
for(int i=0;i<al.size();i++)
{
lib.removeGesture(gesName,al.get(i));
}
}
lib.addGesture(gesName,ges);
if(lib.save())
{
/* 将设置画面数据清除 */
et.setText("");
button01.setEnabled(false);
overlay.clear(true);
/* 保存成功,显示Toast信息 */
Toast.makeText
(
EX05_25.this,getString(R.string.save_success)+":"+
gesPath,Toast.LENGTH_LONG
).show();
}
else
{
/* 保存失败,显示Toast信息 */
Toast.makeText
(
EX05_25.this, getString(R.string.save_failed)+":"+
gesPath,Toast.LENGTH_LONG
).show();
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
});
/* 设置button02的OnClickListener,清除建立的Overlay */
button02.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(View v)
{
et.setText("");
button01.setEnabled(false);
overlay.clear(true);
}
});
}
}
AndroidManifest.xml
由于Gesture手写Library文件“/sdcard/gestures”默认保存在SD存储卡中,故需要写入External Storage的相关权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
扩展学习
如果要加载Gesture手写的Library文件,主程序中所使用的方法是GestureLibraries.fromFile(),除此方法外,还有其他方法,分别为从gesture路径(String)、File对象、从私有的gesture文件路径加载和从资源文件里加载gesture等,如表5-12所示。
表5-12 gesture相关列表
static GestureLibrary
fromFile(String path)
static GestureLibrary
fromFile(File path)
static GestureLibrary
fromPrivateFile(Context context, String name)
static GestureLibrary
fromRawResource(Context context, int resourceId)
另一个扩展练习,通过读取/sdcard/gestures里方才建立的手写,并显示在ListView中,此扩展学习范例的关键程序,提示如下(详细解答可参考范例光盘):
/* 读取gesture信息的method */
private void loadGestures()
{
gesNames=new ArrayList<String>();
gesPics=new ArrayList<Bitmap>();
try
{
lib = GestureLibraries.fromFile(gesFile);
if(gesFile.exists())
{
/* 文件存在时先读取已存储的Gesture */
if (!lib.load())
{
/* Library读取失败 */
mEmpty.setText(getString(R.string.load_failed));
mEmpty.setVisibility(EditText.VISIBLE);
}
else
{
/* 读取gesture信息 */
Object[] en=lib.getGestureEntries().toArray();
for(int i=0;i<en.length;i++)
{
ArrayList<Gesture> al=lib.getGestures(en[i].toString());
for(int j=0;j<al.size();j++)
{
/* 手写名称 */
gesNames.add(en[i].toString());
Gesture gs=(Gesture)al.get(j);
/* 将手写转成Bitmap图片 */
gesPics.add(gs.toBitmap(64,64,12,Color.GREEN));
}
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
▲ 图5-29 读取/sdcard/gestures中已经建立的手写笔画并显示在ListView中
- 建立自己的手写笔画图案
- 建立自己的手写笔画图案
- Android 建立自己的手写笔画图案 Gesture Builder
- Android 建立自己的手写笔画图案 Gesture Builder
- 手写自己的BufferedReader
- 自己手写简单的ArrayList
- 设计中的手写识别(输入法)笔画--中篇
- 设计中的手写识别(输入法)笔画--中篇
- android如何做自己的手写输入法
- caffe训练自己的手写数字
- LeNet识别自己的手写数字
- 建立自己的资源管理器
- 建立自己的网络电台
- 建立自己的RSS
- 建立自己的RSS
- 建立自己的影响
- 建立自己的RSS
- 建立自己的RSS
- http错误码整理
- Spring的LocalSessionFactoryBean类(转)
- centos/linux安装中文输入法
- mocks 代理工具
- Yii修炼宝典
- 建立自己的手写笔画图案
- Java各种布局实例
- 积累问题三
- MFC DestroyWindow
- MyEclipse连ORA-00604和ORA-12705报错
- CentOS下CPPCMS的编译指南
- 跟我一起写 Makefile(Linux)
- 在使用逗号连接的时候,切割最后一个逗号
- 记录下