Overheard Word 的单词和手势文档格式.docx
- 文档编号:17260349
- 上传时间:2022-11-29
- 格式:DOCX
- 页数:14
- 大小:136.78KB
Overheard Word 的单词和手势文档格式.docx
《Overheard Word 的单词和手势文档格式.docx》由会员分享,可在线阅读,更多相关《Overheard Word 的单词和手势文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
如果您的Android项目已正确设置,那么IDE会自动将libs目录中的任何文件识别为一个依赖关系。
当时,我的单词引擎中的代码是通过JSON文档实例进行初始化的。
JSON文档可以是驻留在设备上的文件系统中的一个文件、对HTTP请求的响应,甚至是对数据库查询的响应—就目前来说,这并不重要。
重要的是,您有一个实用的库,让您可以使用Word对象。
每个Word对象包含一个Definition对象的集合,以及一个相应的词性。
虽然单词及其定义之间的关系远不是如此简单,但它现在是可行的。
之后,我们可以添加例句、同义词和反义词。
Android中的第三方库
将第三方库集成到Android项目很容易;
事实上,每一个Android启动项目都包括一个特殊的目录libs,您可以将第三方JAR放在该目录中。
在Android的构建过程中,普通的JVM文件和第三方JAR都被转换为可以兼容Dalvik(这是专用的AndroidVM)。
环境约束
虽然您可以想像得到如何将喜欢的任何第三方库添加到应用程序中,但永远不要忘记移动环境的局限性。
运行您的应用程序的设备毕竟不是什么可靠的Web服务器!
用户会感谢您提高数据处理的能力,并尽可能减少第三方附件的下载大小。
除了将单词引擎库插入到我的应用程序中,我还准备添加另一个名称为Gesticulate的第三方应用程序。
就像使用单词引擎库一样,您可以通过从GitHub上克隆或下载它的源代码来获得Gesticulate。
然后运行ant,您会得到一个JAR文件,您可以将这个文件放进应用程序的libs目录。
更新UI
现在,我们进入本文的核心,即更新UI,以集成您刚刚免费抢购到的所有第三方代码。
幸运的是,我利用我的OverheardWord应用程序提前为这一刻做好了计划。
回到我编写该应用程序的第一次迭代时,我定义了一个简单的布局,其中包括一个单词、其词性,以及一个定义,如图1所示:
图1.OverheardWord的默认视图
该布局使用占位符文本定义,我准备使用从我的可插拔单词引擎获取的实际单词替换占位符文本。
所以,我会初始化一系列单词,抓取其中一个,并使用其值相应地更新UI。
为了更新UI,我必须能够获得每个视图元素的一个句柄,并为这些元素提供值。
例如,一个显示的单词(如Pedestrian)被定义为一个TextView,其ID是word_study_word,如清单1所示:
清单1.在一个布局中定义的TextView
1.<
TextView
2.
android:
id="
@+id/word_study_word"
3.
layout_width="
wrap_content"
4.
layout_height="
5.
layout_gravity="
center"
6.
layout_marginBottom="
10dp"
7.
layout_marginTop="
60dp"
8.
textColor="
@color/black"
9.
textSize="
30sp"
10.
text="
Word"
/>
如果您仔细看的话,就会发现我已经在XML中将文本设置为“Word”;
但是,我能够以编程方式,通过获取TextView实例的引用,并调用setText来设置该值。
在可以进行下一步之前,我需要建立一个单词列表。
您或许还记得我的单词引擎可以通过JSON文档创建Word实例,因此,我需要做的只是设置我的Android应用程序,让它包括并读取这些自定义文件。
使用文件:
res和raw目录
默认情况下,一个Android应用程序具有读取设备的基础文件系统的权限,但您只可以访问应用程序本身下面的本地文件系统。
因此,您可以在您的应用程序中包括文件,并相应地引用它们。
(这意味着,您可以读取和写入相对于您的应用程序是本地的文件;
写入到SD卡等在您的应用程序之外的文件系统则需要专门的权限。
)因为我的单词引擎可以采用一个JSON文档来初始化单词列表,所以就没有什么可以阻止我包括一个应用程序会在运行时读取的JSON文档。
就像在我以前的文章中所演示的图标资产一样,您可以将文件存储在res目录中。
如果我发现自己需要自定义文件,我喜欢将它们添加到被称为raw的一个目录中。
我放在该目录中的任何文件都可以通过生成的R文件来引用,我在OverheardWord中已经使用过几次该文件。
基本上,Android平台利用来自res目录的资产,并建立一个名称为R的类,然后,该类为这些资产提供一个句柄。
如果资产是一个文件,那么R文件将提供一个引用,以打开文件并获取其内容。
我在res目录结构中创建一个raw目录,并将一个JSON文档放在该目录中,如图2所示:
图2.包含新单词的raw目录
接下来,Eclipse重新构建项目,而我的R文件可以方便地引用新文件,如图3所示:
图3.更新后的R文件
当我有一个文件的句柄时,我就可以打开它,读取它,并最终构建一个JSON文档来作为生成一个单词列表的基础。
构建一个单词列表
当应用程序启动时,我就开始执行一系列步骤,加载原始JSON文档,并构建一个单词列表。
我将创建一个名称为buildWordList的方法来处理这些步骤,如清单2所示:
清单2.在Android中读取文件的内容
1.private
List<
Word>
buildWordList()
{
InputStream
resource
=
getApplicationContext().getResources().openRawResource(R.raw.words);
words
new
ArrayList<
();
try
StringBuilder
sb
StringBuilder();
BufferedReader
br
BufferedReader(new
InputStreamReader(resource));
String
read
br.readLine();
while
(read
!
null)
sb.append(read);
11.
12.
}
13.
JSONObject
document
JSONObject(sb.toString());
14.
JSONArray
allWords
document.getJSONArray("
words"
);
15.
for
(int
i
0;
<
allWords.length();
i++)
16.
words.add(Word.manufacture(allWords.getJSONObject(i)));
17.
18.
catch
(Exception
e)
19.
Log.e(APP,
"
Exception
in
buildWordList:
+
e.getLocalizedMessage());
20.
21.
return
words;
22.}
您应该注意到在buildWordList方法中执行的一些操作。
首先,请注意如何使用Android平台的调用创建InputStream,Android平台的调用最终引用在raw目录中发现的words.json文件。
我没有使用String来代表路径,这使得代码可跨多种设备进行移植。
接下来,我使用包含在Android平台中的一个简单的JSON库,将内容(通过String表示)转换成一系列的JSON文档。
在Word上的静态方法manufacture读取一个JSON文档,该文档代表一个单词。
单词的JSON格式如清单3所示:
清单3.JSON代表一个单词
1.{
spelling"
:
sagacious"
definitions"
[
part_of_speech"
adjective"
definition"
having
or
showing
acute
mental
discernment
and
keen
practical
sense;
shrewd"
]
10.}
我的WordStudyEngine类是Thingamajig的主要外观。
它从Word实例列表产生随机单词和函数。
所以,我的下一步是利用新建的WordList初始化引擎,如清单4所示:
清单4.初始化WordStudyEngine
1.List<
buildWordList();
2.WordStudyEngine
engine
WordStudyEngine.getInstance(words);
当有一个已初始化的引擎实例,我就可以向其请求一个单词(自动随机排列),然后相应地更新UI的三个元素。
例如,我可以更新定义的单词部分,如清单5所示:
清单5.以编程方式更新UI元素
1.Word
aWord
engine.getWord();
2.TextView
wordView
(TextView)
findViewById(R.id.word_study_word);
3.wordView.setText(aWord.getSpelling());
清单5中的findViewById是一个Android平台调用,它读取一个整数ID,您可以从您的应用程序的R类中获得该ID。
您能够以编程方式将文本设置为TextView。
您也可以设置字体类型,字体颜色,或文字显示的大小,类似于这样:
wordView.setTextColor(Color.RED)。
在清单6中,我基本上按照相同的流程来更新应用程序的UI的定义和词性元素:
清单6.更多编程式更新
1.Definition
firstDef
aWord.getDefinitions().get(0);
wordPartOfSpeechView
findViewById(R.id.word_study_part_of_speech);
3.wordPartOfSpeechView.setText(firstDef.getPartOfSpeech());
5.TextView
defView
findViewById(R.id.word_study_definition);
6.defView.setText(formatDefinition(aWord));
请注意在清单5和清单6中,如何使用R文件按名称引用布局元素。
驻留在我的Activity类中的formatDefinition方法读取一个定义字符串,并将其首字母变成大写。
该方法还格式化字符串,若句末没有句号,它就会在句末使用一个句号。
(请注意,Thingamajig与格式化没有任何关系—它只是一个单词引擎!
)
我已完成这些UI元素的更新,所以就可以启动我的应用程序,并检查结果。
瞧!
我现在要学习一个合法的单词!
图4.OverheardWord有单词了!
添加手势:
将滑动连接到单词
现在,我可以有效地显示一个单词,我希望让用户能够快速滑动我的单词引擎中的所有单词。
为了更简单,我准备使用Gesticulate,这是我自己的第三方库,可以计算滑动速度和方向。
我也把滑动逻辑放进一个名称为initializeGestures的方法中。
初始化了滑动手势后,第一步是将显示一个单词的逻辑移动到一个新方法中,当有人滑动时,我可以调用该方法来显示一个新单词。
更新后的onCreate方法(最初是在Android创建应用程序实例时调用它)如清单7所示:
清单7.当初始化手势时,onCreate即可显示一个单词
1.protected
void
onCreate(Bundle
savedInstanceState)
super.onCreate(savedInstanceState);
Log.d(APP,
onCreated
Invoked"
setContentView(R.layout.activity_overheard_word);
initializeGestures();
if
(engine
==
Word
firstWord
displayWord(firstWord);
15.}
请注意engine变量,我将它定义为OverheardWordActivity本身的一个privatestatic成员变量。
我将简单地解释为什么要这样做。
接下来,我进入initGestureDetector方法,如果您按照所克隆的代码,就会发现在initializeGestures方法中引用了它。
如果你还记得,initGestureDetector方法有一个逻辑,当用户在设备屏幕上向上、向下、向左或向右滑动时,它就会执行一个操作。
在OverheardWord中,当用户从右到左滑动时(这是左滑),我想显示一个新单词。
我首先删除Toast消息,这是该代码的占位符,将其替换为一个对displayWord的调用,如清单8所示:
清单8.当向左滑动时,initGestureDetector即可显示一个单词
GestureDetector
initGestureDetector()
GestureDetector(new
SimpleOnGestureListener()
public
boolean
onFling(MotionEvent
e1,
MotionEvent
e2,
float
velocityX,
velocityY)
final
SwipeDetector
detector
SwipeDetector(e1,
velocityY);
(detector.isDownSwipe())
false;
else
(detector.isUpSwipe())
(detector.isLeftSwipe())
displayWord(engine.getWord());
(detector.isRightSwipe())
Toast.makeText(getApplicationContext(),
Right
Swipe"
Toast.LENGTH_SHORT).show();
{}
});
21.}
我的单词引擎由engine变量表示,它需要在整个Activity中都可以被访问。
这就是为什么我将其定义为一个成员变量,以确保每次有左滑时都会显示一个新单词。
来回滑动
现在,当打开应用程序,并开始滑动,每当向左滑动时,我都会看到显示一个新单词和定义。
但是,当向其他方向滑动时,我只会得到一条微小的消息,显示我已经滑动了。
如果我能够通过向右滑动回到前一个单词,岂不是更好吗?
回退似乎不应该是困难的。
也许我可以使用一个堆栈,只是弹出由前一次左滑放在那里的最高元素?
但是,当用户在回退后再次左滑时,这种想法是站不住脚的。
如果最高的位置被弹出,则将显示一个新单词,而不是用户以前看到的单词。
仔细思考后,我倾向于尝试一个链表的方法,当用户来回滑动时,可以摆脱之前浏览的单词。
我将首先创建所有已显示单词的一个LinkedList,如清单9所示。
然后,我会保持让一个指针指向该列表中的元素的索引,我可以用它来检索已经看到的单词。
当然,我会将这些定义为static成员变量。
我也将我的指针初始化为-1,并且每当将一个新单词添加到LinkedList实例时,我就将其递增。
就像任何语言中大部分类似于数组支持的集合一样,LinkedList是从0开始建立索引。
清单9.新的成员变量
static
LinkedList<
wordsViewed;
2.private
int
viewPosition
-1;
在清单10中,我将我的应用程序的onCreate中的LinkedList初始化:
清单10.初始化LinkedList
1.if
(wordsViewed
wordsViewed
3.}
现在,当显示第一个单词时,我需要将其添加到LinkedList实例(wordsViewed)并递增指针变量viewPosition,如清单11所示:
清单11.不要忘记递增视图位置
2.wordsViewed.add(firstWord);
3.viewPosition++;
4.displayWord(firstWord);
滑动的逻辑
现在,我进入逻辑的主要部分,这需要一些思考。
当用户向左滑动时,我想显示下一个单词,当他或她向右滑动时,我要显示前一个单词。
如果用户再次向右滑动,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Overheard Word 的单词和手势 单词 手势