在中英字典翻译的首界面简单:
一个简单的输入框一个查询按钮,实现功能如下用户输入一个字词,首先在 本地缓存(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(); } }