Android 建立自己的手写笔画图案 Gesture Builder

2024-03-10 19:58

本文主要是介绍Android 建立自己的手写笔画图案 Gesture Builder,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

/****************************************************

大家都知道写博客会很累的,大热天的。

希望=转载请注明出处:http://blog.csdn.net/ta893115871

请不要可怜你的鼠标,(*^__^*) 嘻嘻……

***************************************************/

 

自SDK 1.6开始,Android手机已支持内置Gesture Builder程序,若是被Google签署(Signed)过出厂的手机应会内置此程序.

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

下面看一下配置UI界面的activity_gesture_builder_demo.xml文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="fill_parent"android:layout_height="fill_parent"android:background="@drawable/white" ><LinearLayoutandroid:id="@+id/linear_top_id"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_alignParentTop="true"android:weightSum="2"android:orientation="horizontal" ><TextViewandroid:id="@+id/text_id"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="@dimen/padding_medium"android:text="@string/hello_world"android:textSize="18sp"tools:context=".GestureBuilderDemo" /><EditTextandroid:id="@+id/edit_id"android:layout_width="fill_parent"android:layout_height="wrap_content"android:inputType="text" /></LinearLayout><android.gesture.GestureOverlayViewandroid:id="@+id/myGestures1"android:layout_width="fill_parent"android:layout_height="300dip"android:layout_below="@+id/linear_top_id"android:layout_marginRight="30sp"android:gestureColor="#8909"android:gestureStrokeType="multiple" /><!-- 	android:gestureStrokeType="multiple" 表示多笔支持,single则支持单一笔画--><SlidingDrawerandroid:id="@+id/slidingDreaer"android:layout_width="wrap_content"android:layout_height="wrap_content"android:content="@+id/content"android:handle="@+id/handler"android:orientation="horizontal" ><ImageViewandroid:id="@+id/handler"android:layout_width="wrap_content"android:layout_height="wrap_content"android:contentDescription="@string/app_name"android:src="@drawable/open" /><ListViewandroid:id="@+id/content"android:layout_width="fill_parent"android:layout_height="wrap_content"android:choiceMode="singleChoice"android:background="@drawable/back"android:divider="@drawable/divider" ></ListView></SlidingDrawer><LinearLayoutandroid:id="@+id/linear_botton_id"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:weightSum="2"style="@android:style/ButtonBar" android:orientation="horizontal" ><Buttonandroid:id="@+id/button1_id"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1.0"android:text="@string/str_button1" /><Buttonandroid:id="@+id/button2_id"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1.0"android:text="@string/str_button2" /></LinearLayout></RelativeLayout>

其中有一个TAG为<android.gesture. GestureOverlayView>的Widget,可称为“手写绘图区”,当中有两项较重要的属性,分别为android:layout_width设置为“fill_parent”以及android:gestureStrokeType设置为“multiple”,这表示为支持多笔画,若设置为“single”则仅支持单一笔画。

 

AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.gesturebuilderdemo"android:versionCode="1"android:versionName="1.0" android:installLocation="preferExternal"><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><applicationandroid:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name=".GestureBuilderDemo"android:label="@string/title_activity_gesture_builder_demo" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>


由于Gesture手写Libary文件"/sdcard/gestures"默认保存在SD存储卡中,所以需要写入External Storage的权限。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

再看java文件中看几个函数:

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

GestureBuilderDemo.java

package com.example.gesturebuilderdemo;import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.GestureOverlayView.OnGestureListener;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SlidingDrawer;
import android.widget.SlidingDrawer.OnDrawerCloseListener;
import android.widget.SlidingDrawer.OnDrawerOpenListener;
import android.widget.Toast;public class GestureBuilderDemo extends Activity {private static final  String TAG="GestureBuilderDemo";private Button mButton1, mButton2;private GestureOverlayView mGestureOverlayView;//手写绘制区private EditText mEditText;private Gesture ges;private GestureLibrary lib;private String gesPath;// ----------------------------private ImageView mImageView;//拉动式抽屉private SlidingDrawer mDrawer;//拉动式抽屉的手柄private ListView mListView;//拉动式抽屉的内容private List<String> gesNames = new ArrayList<String>();//保存手写的名称集合private List<Bitmap> gesPics = new ArrayList<Bitmap>();//保存转换为手写的图片的集合//------------------- -------private LinearLayout layout_bottom;//底部的2个按钮布局private LinearLayout layout_top;//顶部的2个按钮布局private MyListAdapter adapter;//适配器@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);/* 查看SDCard是否存在 */setContentView(R.layout.activity_gesture_builder_demo);if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {Toast.makeText(this, "SDCard不存在!", Toast.LENGTH_SHORT).show();this.finish();}/* 取得系统默认的GestureLibrary的文件路径 */gesPath = new File(Environment.getExternalStorageDirectory(),"gestures").getAbsolutePath();mButton1 = (Button) this.findViewById(R.id.button1_id);mButton2 = (Button) this.findViewById(R.id.button2_id);mGestureOverlayView = (GestureOverlayView) this.findViewById(R.id.myGestures1);mEditText = (EditText) this.findViewById(R.id.edit_id);mButton1.setEnabled(false);mImageView = (ImageView) this.findViewById(R.id.handler);mDrawer = (SlidingDrawer) this.findViewById(R.id.slidingDreaer);mListView = (ListView) this.findViewById(R.id.content);mEditText.setOnKeyListener(keyListener);mGestureOverlayView.addOnGestureListener(onGestureListener);mButton1.setOnClickListener(listener1);mButton2.setOnClickListener(listener2);layout_bottom=(LinearLayout)this.findViewById(R.id.linear_botton_id);layout_top=(LinearLayout)this.findViewById(R.id.linear_top_id);adapter=new MyListAdapter(this,gesNames,gesPics);getExitGesture();//读取SD卡中的/sdcard/gestures里建立的手写,并显示在ListView中mListView.setAdapter(adapter);mListView.setOnItemClickListener(list_listener);mDrawer.setOnDrawerOpenListener(onDrawerOpenListener_open);mDrawer.setOnDrawerCloseListener(onDrawerCloseListener_close);}OnItemClickListener  list_listener=new OnItemClickListener(){public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {// TODO Auto-generated method stubToast.makeText(GestureBuilderDemo.this, "GestureName:"+gesNames.get(arg2),Toast.LENGTH_SHORT).show();}};//抽屉打开OnDrawerOpenListener  onDrawerOpenListener_open=new OnDrawerOpenListener(){public void onDrawerOpened() {// TODO Auto-generated method stubmImageView.setImageResource(R.drawable.close);layout_bottom.setVisibility(View.GONE);layout_top.setVisibility(View.GONE);mGestureOverlayView.setVisibility(View.GONE);getExitGesture();}};//抽屉关闭OnDrawerCloseListener  onDrawerCloseListener_close=new OnDrawerCloseListener(){public void onDrawerClosed() {// TODO Auto-generated method stubmImageView.setImageResource(R.drawable.open);layout_bottom.setVisibility(View.VISIBLE);layout_top.setVisibility(View.VISIBLE);mGestureOverlayView.setVisibility(View.VISIBLE);}};//读取SD卡中的/sdcard/gestures里建立的手写,并显示在ListView中public void getExitGesture() {Log.i(TAG, "getExitGesture()");gesNames.clear();gesPics.clear();File f = new File(gesPath);lib = GestureLibraries.fromFile(f);if (f.exists()) {if (!lib.load()) {Toast.makeText(GestureBuilderDemo.this, "加载失败!!",Toast.LENGTH_SHORT).show();} else {Object[] obj = lib.getGestureEntries().toArray();for (int i = 0; i < obj.length; i++) {ArrayList<Gesture> al = lib.getGestures(obj[i].toString());//	Log.i(TAG, "i="+i);for (int j = 0; j < al.size(); j++) {//		Log.i(TAG, "j="+j);//		Log.i(TAG, "obj[i].toString()==="+obj[i].toString());// 手写名称gesNames.add(obj[i].toString());Gesture gs = (Gesture) al.get(j);//将手写转成Bitmap图片gesPics.add(gs.toBitmap(50, 50, 12, Color.MAGENTA));}}}} else {Toast.makeText(GestureBuilderDemo.this, "文件不存在!",Toast.LENGTH_SHORT).show();}adapter.notifyDataSetChanged();}OnGestureListener onGestureListener = new OnGestureListener() {public void onGesture(GestureOverlayView overlay, MotionEvent event) {// TODO Auto-generated method stub}public void onGestureCancelled(GestureOverlayView overlay,MotionEvent event) {// TODO Auto-generated method stub}public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {// TODO Auto-generated method stubges = overlay.getGesture();if (ges != null&& mEditText.getText().toString().trim().length() != 0) {mButton1.setEnabled(true);}}public void onGestureStarted(GestureOverlayView overlay,MotionEvent event) {// TODO Auto-generated method stubges = null;mButton1.setEnabled(false);}};OnKeyListener keyListener = new OnKeyListener() {public boolean onKey(View arg0, int arg1, KeyEvent arg2) {// TODO Auto-generated method stubif (ges != null&& mEditText.getText().toString().trim().length() != 0) {mButton1.setEnabled(true);} else {mButton1.setEnabled(false);}return false;}};@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.activity_gesture_builder_demo, menu);return true;}OnClickListener listener1 = new OnClickListener() {public void onClick(View arg0) {// TODO Auto-generated method stubString gestureName = mEditText.getText().toString().trim();lib = GestureLibraries.fromFile(gesPath);File f = new File(gesPath);if (!f.exists()) {/* 文件不存在就直接写入 */lib.addGesture(gestureName, ges);if (lib.save()) {mEditText.setText("");mGestureOverlayView.clear(true);mButton1.setEnabled(false);Toast.makeText(GestureBuilderDemo.this,"保存成功,路径为:" + gesPath, Toast.LENGTH_SHORT).show();} else {Toast.makeText(GestureBuilderDemo.this, "保存失败!",Toast.LENGTH_SHORT).show();}} else {// 文件存在时,先读取已经存在的Gestureif (lib.load()) {/* 如果Library中存在相同名称,则先将其移除再写入 */Set<String> set = lib.getGestureEntries();if (set.contains(gestureName)) {ArrayList<Gesture> list = lib.getGestures(gestureName);for (int i = 0; i < list.size(); i++) {//删除手写数据lib.removeGesture(gestureName, list.get(i));}}//新增手写数据lib.addGesture(gestureName, ges);// 保存写入手写数据if (lib.save()) {mEditText.setText("");mGestureOverlayView.clear(true);mButton1.setEnabled(false);Toast.makeText(GestureBuilderDemo.this,"保存成功,路径为:" + gesPath, Toast.LENGTH_SHORT).show();} else {Toast.makeText(GestureBuilderDemo.this, "保存失败!",Toast.LENGTH_SHORT).show();}} else {Toast.makeText(GestureBuilderDemo.this, "加载失败!",Toast.LENGTH_SHORT).show();}}mDrawer.toggle();}};OnClickListener listener2 = new OnClickListener() {public void onClick(View arg0) {// TODO Auto-generated method stubmEditText.setText("");mGestureOverlayView.clear(true);mButton1.setEnabled(false);}};}


ListView的适配器文件:

package com.example.gesturebuilderdemo;import java.util.List;import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;public class MyListAdapter extends BaseAdapter {private Context mContext;private List<String> gesNames ;private List<Bitmap> gesPics ;public MyListAdapter(Context mContext,List<String> gesNames,List<Bitmap> gesPics ){this.mContext=mContext;this.gesNames=gesNames;this.gesPics=gesPics;}public int getCount() {// TODO Auto-generated method stubreturn gesNames.size();}public Object getItem(int arg0) {// TODO Auto-generated method stubreturn gesNames.get(arg0);}public long getItemId(int position) {// TODO Auto-generated method stubreturn position;}public View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubconvertView=	LayoutInflater.from(mContext).inflate(R.layout.list, null);ImageView img=(ImageView)convertView.findViewById(R.id.img_id);img.setImageBitmap(gesPics.get(position));TextView text=(TextView)convertView.findViewById(R.id.text_id);text.setText(gesNames.get(position));return convertView;}}


 

ListView的布局配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent" ><ImageViewandroid:id="@+id/img_id"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:contentDescription="@string/app_name" /><TextViewandroid:id="@+id/text_id"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toRightOf="@+id/img_id"android:lines="1"android:textColor="#f699"android:textSize="20sp"android:textStyle="bold" /></RelativeLayout>


文件中有详细说明,不多说了。

当建立完手写和输入名称后自动把添加按钮Enable,所用的监听器为: mEditText.setOnKeyListener(keyListener);

点击添加按钮后悔自动打开抽屉获取以ListView显示在抽屉中。

界面如下所示:

 

 

 

 

这篇关于Android 建立自己的手写笔画图案 Gesture Builder的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/795344

相关文章

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整

Android 12解决push framework.jar无法开机的方法小结

《Android12解决pushframework.jar无法开机的方法小结》:本文主要介绍在Android12中解决pushframework.jar无法开机的方法,包括编译指令、框架层和s... 目录1. android 编译指令1.1 framework层的编译指令1.2 替换framework.ja

Android开发环境配置避坑指南

《Android开发环境配置避坑指南》本文主要介绍了Android开发环境配置过程中遇到的问题及解决方案,包括VPN注意事项、工具版本统一、Gerrit邮箱配置、Git拉取和提交代码、MergevsR... 目录网络环境:VPN 注意事项工具版本统一:android Studio & JDKGerrit的邮

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

Android使用ImageView.ScaleType实现图片的缩放与裁剪功能

《Android使用ImageView.ScaleType实现图片的缩放与裁剪功能》ImageView是最常用的控件之一,它用于展示各种类型的图片,为了能够根据需求调整图片的显示效果,Android提... 目录什么是 ImageView.ScaleType?FIT_XYFIT_STARTFIT_CENTE

Android实现在线预览office文档的示例详解

《Android实现在线预览office文档的示例详解》在移动端展示在线Office文档(如Word、Excel、PPT)是一项常见需求,这篇文章为大家重点介绍了两种方案的实现方法,希望对大家有一定的... 目录一、项目概述二、相关技术知识三、实现思路3.1 方案一:WebView + Office Onl

Android实现两台手机屏幕共享和远程控制功能

《Android实现两台手机屏幕共享和远程控制功能》在远程协助、在线教学、技术支持等多种场景下,实时获得另一部移动设备的屏幕画面,并对其进行操作,具有极高的应用价值,本项目旨在实现两台Android手... 目录一、项目概述二、相关知识2.1 MediaProjection API2.2 Socket 网络