在中英字典翻译的首界面简单:
一个简单的输入框一个查询按钮,实现功能如下用户输入一个字词,首先在 本地缓存(Map )中查询是否存在相关的的字词的信息。如果不存在,通过Httpclient请求一个远程连接,解析相关的结果。
在代码中重点注意的是进度条和使用:
//创建一个进度条的信息
pdialog = ProgressDialog.show(DetailActivity.this, "请稍等...", "正在请求数据...", true);
//创建一个每一个单词的线程
new Thread(){
public void run() {
//获取单词的相关的信息
final DetailItem detailItem = getDetailItems(word);
//使用手机开发中UI线程 用于更新界面的信息
runOnUiThread(new Runnable() {
@Override
public void run() {
wordTextView.setText(detailItem.getWord());
if (detailItem.getYinbiao() != null){
yinbiaoTextView.setText(Html.fromHtml("<span>[" + detailItem.getYinbiao() + "]</span><br>"));
}
if (detailItem.getDescription() != null){
descTextView.setText(detailItem.getDescription() + "\n");
}
if (!detailItem.getSampleItems().isEmpty()){
StringBuilder sb = new StringBuilder();
int i=1;
for(SampleItem item : detailItem.getSampleItems()){
sb.append(i + ". " + item.getOrig() + "\n");
sb.append(" " + item.getTrans() + "\n\n");
i++;
}
sampleTextView.setText(sb.toString());
}
if (detailItem.getAudioUrl() == null || detailItem.getAudioUrl().trim().length() == 0){
speImageButton.setEnabled(false);
}
currentItem = detailItem;
}
});
//进度条消失的进度条
pdialog.dismiss();
};
}.start();
Andriod中xml的解析:
/**
* 获取解析Document文档
* 使用Dom解析xml信息
* @param result
* @return
* @throws SAXException
* @throws IOException
* @throws ParserConfigurationException
*/
public Document getDocument(String result) throws SAXException, IOException, ParserConfigurationException{
DocumentBuilderFactory docbuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = docbuilderFactory.newDocumentBuilder();
Document doc = documentBuilder.parse(new InputSource(new StringReader(result)));
return doc;
}
远程访问:
/**
* 获取查询单词相关的单词信息
* @param word
* @return
*/
private DetailItem getDetailItems(String word){
//从缓存中查询如果查不到,发送请求服务
DetailItem cacheData = cache.get(word);
if (cacheData != null){
return cacheData;
}
DetailItem rt = new DetailItem();
rt.setWord(word);
try {
//构建请求路径的信息
String urlString = "http://api.dict.cn/ws.php?utf8=true&q=" + URLEncoder.encode(word, "UTF-8");
Map<String,String> paramsMap=getParamsMap();
String result=HTTPClient.executeHttpClientByApache(urlString, paramsMap);
if (result!=null&&result.length()>0){
//解析xml的信息
parseDocument(rt, result);
}
} catch (Exception e) {
e.printStackTrace();
}
if (cache.size()>100){
cache.remove(cache.keySet().iterator().next());
}
cache.put(word, rt);
return rt;
}
源代码如下:
package com.easyway.android.xdict;
import java.io.IOException;
import java.io.StringReader;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.text.Html;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
/**
* Android远程请求页面解析
* @author longgangbai
* @date 2010-5-28
* @version 1.0
* @since JDK6.0
*/
public class DetailActivity extends Activity{
//声明一个进度条在查询显示
private ProgressDialog pdialog;
private static final String YINBIAO_PATTERN = "<pron>{%}</pron>";
private static final String DESC_PATTERN = "<def>{%}</def>";
/**
* 定义本地单词的缓存信息 key:String 表示单词 value:DetailItem单词相关()的信息
*/
private static Map<String, DetailItem> cache = new HashMap<String, DetailItem>();
private static DetailItem currentItem = null;
//缓存相关单词录音的路径
private static Map<String, MediaPlayer> audioCache = new HashMap<String, MediaPlayer>();
private TextView wordTextView =null;
private TextView yinbiaoTextView=null;
private TextView descTextView =null;
private TextView sampleTextView =null;
private Button backButton =null;
private ImageButton speImageButton =null;
/**
* 界面创建调用
* @param savedInstanceState 上下文的信息
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置视图内容
setContentView(R.layout.detail);
Intent intent = getIntent();
final String word = intent.getExtras().getString("word");
//创建各种组件的方法
createComponent(word);
//绑定事件
bindListener(word);
}
/**
* 添加各种事件
* @param word
*/
public void bindListener(final String word){
/**
* 点击播放按钮的事件(如果存在对应的录音的信息直接播放,否则创建)
*/
speImageButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//缓存获取录音的信息
MediaPlayer cache = audioCache.get(currentItem.getWord());
if ( cache != null){
cache.start();
return ;
}
MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource(currentItem.getAudioUrl());
mp.prepare();
mp.start();
if (audioCache.size() > 100){
audioCache.remove(audioCache.keySet().iterator().next());
}
audioCache.put(currentItem.getWord(), mp);
} catch (Exception e) {
e.printStackTrace();
}
}
});
/**
* 点击返回按钮的事件
*/
backButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
//创建一个进度条的信息
pdialog = ProgressDialog.show(DetailActivity.this, "请稍等...", "正在请求数据...", true);
//创建一个每一个单词的线程
new Thread(){
public void run() {
//获取单词的相关的信息
final DetailItem detailItem = getDetailItems(word);
//使用手机开发中UI线程 用于更新界面的信息
runOnUiThread(new Runnable() {
@Override
public void run() {
wordTextView.setText(detailItem.getWord());
if (detailItem.getYinbiao() != null){
yinbiaoTextView.setText(Html.fromHtml("<span>[" + detailItem.getYinbiao() + "]</span><br>"));
}
if (detailItem.getDescription() != null){
descTextView.setText(detailItem.getDescription() + "\n");
}
if (!detailItem.getSampleItems().isEmpty()){
StringBuilder sb = new StringBuilder();
int i=1;
for(SampleItem item : detailItem.getSampleItems()){
sb.append(i + ". " + item.getOrig() + "\n");
sb.append(" " + item.getTrans() + "\n\n");
i++;
}
sampleTextView.setText(sb.toString());
}
if (detailItem.getAudioUrl() == null || detailItem.getAudioUrl().trim().length() == 0){
speImageButton.setEnabled(false);
}
currentItem = detailItem;
}
});
//进度条消失的进度条
pdialog.dismiss();
};
}.start();
}
/**
* 创建组件
* @param word
*/
public void createComponent(String word){
wordTextView = (TextView) findViewById(R.id.word_textview);
wordTextView.setText(word);
yinbiaoTextView = (TextView) findViewById(R.id.yinbiao_textview);
descTextView = (TextView) findViewById(R.id.desc_textview);
sampleTextView = (TextView) findViewById(R.id.sample_textview);
backButton = (Button) findViewById(R.id.back_button);
speImageButton = (ImageButton) findViewById(R.id.speak_img_button);
}
/**
* 获取查询单词相关的单词信息
* @param word
* @return
*/
private DetailItem getDetailItems(String word){
//从缓存中查询如果查不到,发送请求服务
DetailItem cacheData = cache.get(word);
if (cacheData != null){
return cacheData;
}
DetailItem rt = new DetailItem();
rt.setWord(word);
try {
//构建请求路径的信息
String urlString = "http://api.dict.cn/ws.php?utf8=true&q=" + URLEncoder.encode(word, "UTF-8");
Map<String,String> paramsMap=getParamsMap();
String result=HTTPClient.executeHttpClientByApache(urlString, paramsMap);
if (result!=null&&result.length()>0){
//解析xml的信息
parseDocument(rt, result);
}
} catch (Exception e) {
e.printStackTrace();
}
if (cache.size()>100){
cache.remove(cache.keySet().iterator().next());
}
cache.put(word, rt);
return rt;
}
/**
* 设置查询需要的各种参数
* @return
*/
public Map<String,String> getParamsMap()
{
Map<String,String> paramsMap=new HashMap<String,String>();
paramsMap.put("User-Agent", "Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6");
paramsMap.put("Referer", "http://dict.cn/");
return paramsMap;
}
/**
* 获取解析Document文档
* 使用Dom解析xml信息
* @param result
* @return
* @throws SAXException
* @throws IOException
* @throws ParserConfigurationException
*/
public Document getDocument(String result) throws SAXException, IOException, ParserConfigurationException{
DocumentBuilderFactory docbuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = docbuilderFactory.newDocumentBuilder();
Document doc = documentBuilder.parse(new InputSource(new StringReader(result)));
return doc;
}
/**
* 相关的xml信息
* @param rt
* @param result
* @throws FactoryConfigurationError
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
*/
private void parseDocument(DetailItem rt, String result)
throws FactoryConfigurationError, ParserConfigurationException,
SAXException, IOException {
//获取解析Document文档
Document doc=getDocument(result);
if(doc==null)
{
return ;
}
//获取单词录音的路径
NodeList audioNodes = doc.getElementsByTagName("audio");
if (audioNodes != null && audioNodes.getLength() > 0){
rt.setAudioUrl(audioNodes.item(0).getChildNodes().item(0).getNodeValue());
}
//获取音标的信息
List<List<String>> list = Squirrel.extract(YINBIAO_PATTERN, result);
if (!list.isEmpty()){
rt.setYinbiao(list.get(0).get(0));
}
//获取匹配的描述
List<List<String>> list2 = Squirrel.extract(DESC_PATTERN, result);
if (!list2.isEmpty()){
rt.setDescription(list2.get(0).get(0));
}
if (list2.get(0).get(0).indexOf("\n")> -1){
System.out.print(true);
}
NodeList sentNodes = doc.getElementsByTagName("sent");
if (sentNodes != null && sentNodes.getLength() > 0){
for(int i=0;i<sentNodes.getLength();i++){
Node item = sentNodes.item(i);
NodeList nodeList = ((Element)item).getElementsByTagName("orig");
String orig = nodeList.item(0).getChildNodes().item(0).getNodeValue();
NodeList nodeList1 = ((Element)item).getElementsByTagName("trans");
String trans = nodeList1.item(0).getChildNodes().item(0).getNodeValue();
SampleItem si = new SampleItem(orig, trans);
rt.getSampleItems().add(si);
}
}
}
}
public static boolean areProvidersEnabled(Context context) {
ContentResolver cr = context.getContentResolver();
String providersAllowed = Settings.Secure.getString(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
return providersAllowed != null && providersAllowed.length() > 0;
}
如果没有设置 那你可以提醒用户设置打开
Intent intent = new Intent(Settings.ACTION_SECURITY_SETTINGS);
startActivity(intent);
在查询之后的详细信息中,我会注意到在UI开发中关于回车键的实现功能以及在listView中展示所有信息的实现,一个查看单个单词信息怎么实现呢?
实现回车键代码功能在Android中的实现
/**
* 编辑框添加事件
*/
wordEdit.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER){
// user input enter
queryButton.performClick();
return true;
}
return false;
}
});
在Android中细心童鞋可以发现,Android中可以支持JSON格式的:
/**
* 获取查询项的信息
* @param word
* @param result
* @return
* @throws JSONException
*/
private List<SearchItem> getAudioVoiceByJSON(String word, String result)
throws JSONException {
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonArray = jsonObject.getJSONArray("s");
if (jsonArray!= null && jsonArray.length() >0){
List<SearchItem> rt = new ArrayList<SearchItem>();
for(int i=0;i<jsonArray.length(); i++){
JSONObject row = jsonArray.getJSONObject(i);
String rword = row.getString("g");
String e = row.getString("e");
rt.add(new SearchItem(rword, e));
}
if (cache.size() > 100){
cache.remove(cache.keySet().iterator().next());
}
cache.put(word, rt);
return rt;
}
return Collections.emptyList();
}
实现关闭页面的代码如下:
/**
* 点击返回按钮的事件
*/
backButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
实现界面切换的代码如下:
/**
*点击一个页面的记录跳转的方法
*/
searchListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
SearchItem item = searchItemAdapter.getItems().get(arg2);
if (item != null){
//设置跳转的信息 DictActivity 当前的页面 , DetailActivity 单词的详细情况
Intent intent = new Intent(DictActivity.this, DetailActivity.class);
//设置辅助的信息
intent.putExtra("word", item.getWord());
//设置激活的界面
startActivity(intent);
}
}
});
至于ListView在下一篇Blog中讲解。
(*^__^*) 嘻嘻……
源代码如下:
package com.easyway.android.xdict;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
/**
* 字典首界面
* @author longgangbai
* @date 2010-5-28
* @version 1.0
* @since JDK6.0
*/
public class DictActivity extends Activity {
/** Called when the activity is first created. */
/* (non-Javadoc)
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
private ProgressDialog pdialog;
private SearchItemAdapter searchItemAdapter;
private static final int DIALOG_WORD_REQUIRED = 0;
private EditText wordEdit;
private Button queryButton;
private ListView searchListView;
private static Map<String, List<SearchItem>> cache = new HashMap<String, List<SearchItem>>();
/**
* 界面启动时使用弹出框
*/
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_WORD_REQUIRED:
AlertDialog.Builder builder = new AlertDialog.Builder(
DictActivity.this);
builder.setMessage("请输入你想查询的单词!").setCancelable(false)
.setPositiveButton("确定", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
//设置焦点
wordEdit.setFocusable(true);
}
});
try {
return builder.create();
} catch (Exception e) {
Log.e(DictActivity.class.getName(), e.getMessage(), e);
}
break;
default:
return super.onCreateDialog(id);
}
return super.onCreateDialog(id);
}
/**
* 调用时启动线程
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置视图
setContentView(R.layout.main);
//设置标题
setTitle("XDict");
//创建组件
createComponent();
//绑定事件
bindListener();
}
/**
* 创建组件
*/
public void createComponent(){
List<SearchItem> items = new ArrayList<SearchItem>();
//创建自定义的ArrayAapter的适配器对象
searchItemAdapter = new SearchItemAdapter(this, R.layout.row, items);
//获取ListView对象
searchListView = (ListView) findViewById(R.id.search_listview);
//设置适配器对象
searchListView.setAdapter(searchItemAdapter);
queryButton = (Button) findViewById(R.id.query_button);
wordEdit = (EditText) findViewById(R.id.word_edittext);
}
/**
* 绑定事件
*/
public void bindListener(){
/**
* 编辑框添加事件
*/
wordEdit.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER){
// user input enter
queryButton.performClick();
return true;
}
return false;
}
});
/**
* 查询按钮添加事件
*/
queryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
searchItemAdapter.getItems().clear();
searchItemAdapter.notifyDataSetChanged();
String word = wordEdit.getText().toString();
if (word == null || word.trim().length() == 0){
showDialog(DIALOG_WORD_REQUIRED);
return ;
}
//添加进度条
pdialog = ProgressDialog.show(DictActivity.this, "请稍等...", "正在请求数据...", true);
//添加线程的
new Thread(){
@Override
public void run() {
final List<SearchItem> searchItems = getSearchItems(wordEdit.getText().toString());
searchItemAdapter.getItems().addAll(searchItems);
//采用UI线程更改界面信息
runOnUiThread(new Runnable() {
@Override
public void run() {
searchItemAdapter.notifyDataSetChanged();
View noresultTextview = findViewById(R.id.nosearchresult_textview);
if (searchItems.isEmpty()){
noresultTextview.setVisibility(View.VISIBLE);
queryButton.setFocusable(true);
}else{
noresultTextview.setVisibility(View.INVISIBLE);
}
//进度条消失
pdialog.dismiss();
}
});
}
}.start();
}
});
/**
*点击一个页面的记录跳转的方法
*/
searchListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
SearchItem item = searchItemAdapter.getItems().get(arg2);
if (item != null){
//设置跳转的信息 DictActivity 当前的页面 , DetailActivity 单词的详细情况
Intent intent = new Intent(DictActivity.this, DetailActivity.class);
//设置辅助的信息
intent.putExtra("word", item.getWord());
//设置激活的界面
startActivity(intent);
}
}
});
}
/**
* 设置查询参数
* @return
*/
public Map<String,String> getDicAppParamsMap(){
Map<String,String> paramsMap=new HashMap<String,String>();
paramsMap.put("User-Agent", "Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6");
paramsMap.put("Referer", "http://dict.cn/");
paramsMap.put("ISAJAX", "yes");
paramsMap.put("Cookie", "dictid=u; __utma=7761447.596616007.1262230974.1262230974.1262321903.2; __utmz=7761447.1262230974.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=(none); h=%2Ffuck%2Fmy%2F%B0%B2%C8%AB%BC%EC%B2%E9%2F%CE%D2%B5%C4%2F%CD%AC%D2%E5%B4%CA%2Fshitwork%2Ffuckhead%2F; __utmc=7761447; __utmb=7761447");
paramsMap.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
return paramsMap;
}
/**
* 查询相关建议的页面
* @param word
* @return
*/
private List<SearchItem> getSearchItems(String word){
List<SearchItem> cacheData = cache.get(word);
if (cacheData != null){
return cacheData;
}
try{
String urlString = "http://dict.cn/ajax/suggestion.php?"+"q=" + URLEncoder.encode(word,"utf-8") + "&s=all";
Map<String,String> paramsMap=getDicAppParamsMap();
String result=HTTPClient.executeByHttpURLConnection(urlString, paramsMap);
if (result!=null&&result.length()>0){
return getAudioVoiceByJSON(word, result);
}
} catch (Exception e) {
Log.d(DictActivity.class.getName(), "Failed to get the search items", e);
}
return Collections.emptyList();
}
/**
* 获取查询项的信息
* @param word
* @param result
* @return
* @throws JSONException
*/
private List<SearchItem> getAudioVoiceByJSON(String word, String result)
throws JSONException {
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonArray = jsonObject.getJSONArray("s");
if (jsonArray!= null && jsonArray.length() >0){
List<SearchItem> rt = new ArrayList<SearchItem>();
for(int i=0;i<jsonArray.length(); i++){
JSONObject row = jsonArray.getJSONObject(i);
String rword = row.getString("g");
String e = row.getString("e");
rt.add(new SearchItem(rword, e));
}
if (cache.size() > 100){
cache.remove(cache.keySet().iterator().next());
}
cache.put(word, rt);
return rt;
}
return Collections.emptyList();
}
}