利用反射去存儲對對象到SharedPreferences
http://www.eoeandroid.com/thread-202940-1-1.html
基于Android平臺的車輛信息查詢系統的開發
http://www.eoeandroid.com/thread-202933-1-1.html
【每日話題】程序猿早餐都吃啥?是吃還是不吃呢?
http://www.eoeandroid.com/thread-202803-1-1.html
?
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=http:
//blog.csdn.net/ta893115871/article/details/"@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個<A class=relatedlink target=_blank>按鈕</A><A class=relatedlink target=_blank>布局</A>
private LinearLayout layout_top;
//頂部的2個按鈕布局
private MyListAdapter adapter;
//適配器
@Override
public 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 stub
mImageView.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 stub
mImageView.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;}
};
@Override
public 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&
gt; gesNames ;
private List<Bitmap&
gt; gesPics ;public MyListAdapter(Context mContext,List<String> gesNames,List<Bitmap&
gt; 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的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。