最近在搞android 新浪微博客户端,有一些心得分享
弄android客户端表情功能可以用以下思路
1.首页把新浪的表情下载到本地一文件夹种,表情图片的命名要用新浪微博表情原来的命名
比如 新浪的害羞表情是shame.gif 那么你在本地也得命名为shame.gif,命名相同主要是为了能够匹配表情对应的code.
2.把本地的表情都放进android的资源文件里----drawable下面
3.访问新浪的表情接口(新浪返回的数据类型有json和xml两种,本人用xml),把返回的信息,利用xml解析器解析出来的信息储存在一个Emotion.java的bean里,这样就可以根据Emotion.java的code找到一一对应的资源表情图片了
4.实现一个可以让用户选择的表情界面,本人用GridView实现
5.实现点击GridView的每一个item,处理根据item的index查找对应的表情code,然后再把code利用正则把code转换为相对应的表情图片,最后表情插入EditText进行发送。
下面是具体的实现过程
1.把新浪表情图片下载到本地的实现如下:(这个可以建一个java工程进行下载)
- public void getFriendList() throws Exception {
- BlogReleaseServiceImpl service = new BlogReleaseServiceImpl();
- List<Emotions> list = service.getEmotion();
- for (Emotions emotions : list) {
- String path = emotions.getUrl();
- String filename = path.substring(path.lastIndexOf("/") + 1,path.length());
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- conn.setRequestMethod("GET");
- conn.setReadTimeout(5 * 1000);
- if(conn.getResponseCode() == 200){
- InputStream is = conn.getInputStream();
- byte[] data = readStream(is);
- File file = new File("f: \\sina_images\\" + filename);
- FileOutputStream fs = new FileOutputStream(file);
- fs.write(data);
- fs.close();
- }else{
- System.out.println("请求失败");
- }
- }
- }
- public byte[] readStream(InputStream is) throws Exception {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- byte[] buffer = new byte[2048];
- int len = 0;
- while((len = is.read(buffer)) != -1){
- os.write(buffer,0,len);
- }
- is.close();
- return os.toByteArray();
- }
- public void getFriendList() throws Exception {
- BlogReleaseServiceImpl service = new BlogReleaseServiceImpl();
- List<Emotions> list = service.getEmotion();
- for (Emotions emotions : list) {
- String path = emotions.getUrl();
- String filename = path.substring(path.lastIndexOf("/") + 1,path.length());
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- conn.setRequestMethod("GET");
- conn.setReadTimeout(5 * 1000);
- if(conn.getResponseCode() == 200){
- InputStream is = conn.getInputStream();
- byte[] data = readStream(is);
- File file = new File("f: \\sina_images\\" + filename);
- FileOutputStream fs = new FileOutputStream(file);
- fs.write(data);
- fs.close();
- }else{
- System.out.println("请求失败");
- }
- }
- }
- public byte[] readStream(InputStream is) throws Exception {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- byte[] buffer = new byte[2048];
- int len = 0;
- while((len = is.read(buffer)) != -1){
- os.write(buffer,0,len);
- }
- is.close();
- return os.toByteArray();
- }
2:把本地的表情都放进android的资源文件里----drawable下面(这个就不用多说了,直接选取所有文件复制就行了)
3:
3.1访问新浪的表情接口,把返回的信息如下:
- <emotion>
- <phrase>[嘻嘻]</phrase>
- <type>face</type>
- <url>http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/c2/tooth.gif
- </url>
- <is_hot>false</is_hot>
- <is_common>true</is_common>
- <order_number>0</order_number>
- <category></category>
- lt;/emotion>
- <emotion>
- <phrase>[嘻嘻]</phrase>
- <type>face</type>
- <url>http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/c2/tooth.gif
- </url>
- <is_hot>false</is_hot>
- <is_common>true</is_common>
- <order_number>0</order_number>
- <category></category>
- lt;/emotion>
3.2 储存在一个Emotion.java里。Emotion.java代码如下:
- package com.uim.microblog.model;
- import java.io.Serializable;
- public class Emotions implements Serializable {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- private String phrase;//表情使用的替代文字
- private String type;
- private String url;//表情图片存放的位置
- private String isHot;//是否为热门表情
- private String isCommon;//是否属于通用
- private String orderNumber;//该表情在系统中的排序号码
- private String category;//表情分类
- private String imageName;//表情名称
- public String getImageName() {
- return imageName;
- }
- public void setImageName(String imageName) {
- this.imageName = imageName;
- }
- public String getPhrase() {
- return phrase;
- }
- public void setPhrase(String phrase) {
- this.phrase = phrase;
- }
- public String getType() {
- return type;
- }
- public void setType(String type) {
- this.type = type;
- }
- public String getUrl() {
- return url;
- }
- public void setUrl(String url) {
- this.url = url;
- }
- public String getIsHot() {
- return isHot;
- }
- public void setIsHot(String isHot) {
- this.isHot = isHot;
- }
- public String getIsCommon() {
- return isCommon;
- }
- public void setIsCommon(String isCommon) {
- this.isCommon = isCommon;
- }
- public String getOrderNumber() {
- return orderNumber;
- }
- public void setOrderNumber(String orderNumber) {
- this.orderNumber = orderNumber;
- }
- public String getCategory() {
- return category;
- }
- public void setCategory(String category) {
- this.category = category;
- }
- }
- package com.uim.microblog.model;
- import java.io.Serializable;
- public class Emotions implements Serializable {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- private String phrase;//表情使用的替代文字
- private String type;
- private String url;//表情图片存放的位置
- private String isHot;//是否为热门表情
- private String isCommon;//是否属于通用
- private String orderNumber;//该表情在系统中的排序号码
- private String category;//表情分类
- private String imageName;//表情名称
- public String getImageName() {
- return imageName;
- }
- public void setImageName(String imageName) {
- this.imageName = imageName;
- }
- public String getPhrase() {
- return phrase;
- }
- public void setPhrase(String phrase) {
- this.phrase = phrase;
- }
- public String getType() {
- return type;
- }
- public void setType(String type) {
- this.type = type;
- }
- public String getUrl() {
- return url;
- }
- public void setUrl(String url) {
- this.url = url;
- }
- public String getIsHot() {
- return isHot;
- }
- public void setIsHot(String isHot) {
- this.isHot = isHot;
- }
- public String getIsCommon() {
- return isCommon;
- }
- public void setIsCommon(String isCommon) {
- this.isCommon = isCommon;
- }
- public String getOrderNumber() {
- return orderNumber;
- }
- public void setOrderNumber(String orderNumber) {
- this.orderNumber = orderNumber;
- }
- public String getCategory() {
- return category;
- }
- public void setCategory(String category) {
- this.category = category;
- }
- }
3.3xm sax解析l的handler如下:
- package com.uim.microblog.net.handler;
- import java.util.ArrayList;
- import java.util.List;
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.DefaultHandler;
- import com.uim.microblog.model.Emotions;
- import com.uim.microblog.model.ResponseResult;
- public class BlogEmotionsHandler extends DefaultHandler {
- private List<Emotions> list;
- private Emotions emotions;
- private ResponseResult responseresult;
- private String tag = null;//正在解析的元素
- public List<Emotions> getEmotionsList(){
- return list;
- }
- @Override
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- if (tag != null) {
- String textArea = new String(ch,start,length);
- /**开始解析表情数据*/
- if ("phrase".equals(tag)) {
- emotions.setPhrase(textArea);
- } else if ("type".equals(tag)) {
- emotions.setType(textArea);
- } else if ("url".equals(tag)) {
- try {
- emotions.setUrl(textArea);
- String imageName = textArea.substring(textArea.lastIndexOf("/") + 1,textArea.length() - 4);
- emotions.setImageName(imageName);
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else if ("is_hot".equals(tag)) {
- emotions.setIsHot(textArea);
- } else if ("is_common".equals(tag)) {
- emotions.setIsCommon(textArea);
- } else if ("order_number".equals(tag)) {
- emotions.setOrderNumber(textArea);
- } else if ("category".equals(tag)) {
- emotions.setCategory(textArea);
- } else if ("retn".equals(tag)) {
- responseresult.setRetn(textArea);
- } else if ("desc".equals(tag)) {
- responseresult.setDesc(textArea);
- }
- }
- }
- @Override
- public void endDocument() throws SAXException {
- super.endDocument();
- }
- @Override
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
- tag = null;
- if ("mb".equals(localName)) {
- } else if ("emotions".equals(localName)) {
- responseresult =null;
- } else if ("emotion".equals(localName)) {
- list.add(emotions);
- emotions = null;
- }
- }
- @Override
- public void startDocument() throws SAXException {
- list = new ArrayList<Emotions>();
- }
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
- if ("mb".equals(localName)) {
- responseresult = new ResponseResult();
- } else if ("emotions".equals(localName)) {
- } else if ("emotion".equals(localName)) {
- emotions = new Emotions();
- }
- tag = localName;
- }
- }
- package com.uim.microblog.net.handler;
- import java.util.ArrayList;
- import java.util.List;
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.DefaultHandler;
- import com.uim.microblog.model.Emotions;
- import com.uim.microblog.model.ResponseResult;
- public class BlogEmotionsHandler extends DefaultHandler {
- private List<Emotions> list;
- private Emotions emotions;
- private ResponseResult responseresult;
- private String tag = null;//正在解析的元素
- public List<Emotions> getEmotionsList(){
- return list;
- }
- @Override
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- if (tag != null) {
- String textArea = new String(ch,start,length);
- /**开始解析表情数据*/
- if ("phrase".equals(tag)) {
- emotions.setPhrase(textArea);
- } else if ("type".equals(tag)) {
- emotions.setType(textArea);
- } else if ("url".equals(tag)) {
- try {
- emotions.setUrl(textArea);
- String imageName = textArea.substring(textArea.lastIndexOf("/") + 1,textArea.length() - 4);
- emotions.setImageName(imageName);
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else if ("is_hot".equals(tag)) {
- emotions.setIsHot(textArea);
- } else if ("is_common".equals(tag)) {
- emotions.setIsCommon(textArea);
- } else if ("order_number".equals(tag)) {
- emotions.setOrderNumber(textArea);
- } else if ("category".equals(tag)) {
- emotions.setCategory(textArea);
- } else if ("retn".equals(tag)) {
- responseresult.setRetn(textArea);
- } else if ("desc".equals(tag)) {
- responseresult.setDesc(textArea);
- }
- }
- }
- @Override
- public void endDocument() throws SAXException {
- super.endDocument();
- }
- @Override
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
- tag = null;
- if ("mb".equals(localName)) {
- } else if ("emotions".equals(localName)) {
- responseresult =null;
- } else if ("emotion".equals(localName)) {
- list.add(emotions);
- emotions = null;
- }
- }
- @Override
- public void startDocument() throws SAXException {
- list = new ArrayList<Emotions>();
- }
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
- if ("mb".equals(localName)) {
- responseresult = new ResponseResult();
- } else if ("emotions".equals(localName)) {
- } else if ("emotion".equals(localName)) {
- emotions = new Emotions();
- }
- tag = localName;
- }
- }
3.4sax解析
- public List<Emotions> getEmotion(){
- BlogGetData getdata = new BlogGetData();
- String result = getdata.blogEmotionsServlet();
- try {
- //生成SAX解析对象
- parser = SAXParserFactory.newInstance().newSAXParser();
- //生成xml读取器
- reader = parser.getXMLReader();
- BlogEmotionsHandler handler = new BlogEmotionsHandler();
- //设置Handler
- reader.setContentHandler(handler);
- //指定文件,进行解析
- reader.parse(new InputSource(new StringReader(result)));
- //获取 List<Emotions>
- emotionList = handler.getEmotionsList();
- } catch (ParserConfigurationException e) {
- e.printStackTrace();
- } catch (SAXException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return emotionList;
- }
- public List<Emotions> getEmotion(){
- BlogGetData getdata = new BlogGetData();
- String result = getdata.blogEmotionsServlet();
- try {
- //生成SAX解析对象
- parser = SAXParserFactory.newInstance().newSAXParser();
- //生成xml读取器
- reader = parser.getXMLReader();
- BlogEmotionsHandler handler = new BlogEmotionsHandler();
- //设置Handler
- reader.setContentHandler(handler);
- //指定文件,进行解析
- reader.parse(new InputSource(new StringReader(result)));
- //获取 List<Emotions>
- emotionList = handler.getEmotionsList();
- } catch (ParserConfigurationException e) {
- e.printStackTrace();
- } catch (SAXException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return emotionList;
- }
4:
4.1实现表情选择器---GridView
- <GridView
- android:id="@+id/blog_sendmsg_gvemotion"
- android:layout_width="fill_parent"
- android:layout_height="150sp"
- android:scrollbars="vertical"
- android:numColumns="auto_fit"
- android:verticalSpacing="15dp"
- android:background="@color/blog_list_back"
- android:stretchMode="columnWidth"
- android:gravity="center"
- android:visibility="gone"
- android:columnWidth="40dp">
- </GridView>
- <GridView
- android:id="@+id/blog_sendmsg_gvemotion"
- android:layout_width="fill_parent"
- android:layout_height="150sp"
- android:scrollbars="vertical"
- android:numColumns="auto_fit"
- android:verticalSpacing="15dp"
- android:background="@color/blog_list_back"
- android:stretchMode="columnWidth"
- android:gravity="center"
- android:visibility="gone"
- android:columnWidth="40dp">
- </GridView>
4.2 GridView的item-----gridview_emotion_item.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <ImageView
- android:id="@+id/blog_sendmsg_emotion"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="50"
- android:layout_gravity="center">
- </ImageView>
- </LinearLayout>
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <ImageView
- android:id="@+id/blog_sendmsg_emotion"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="50"
- android:layout_gravity="center">
- </ImageView>
- </LinearLayout>
4.3代码加载表情图片到GridView进行显示
- public void addexpression(View view){
- if (expressionGriView.getVisibility() == View.GONE) {
- expressionGriView.setVisibility(View.VISIBLE);
- emotionList = BlogHomeActivity.emotions;
- ArrayList<HashMap<String, Object>> lstImageItem = new ArrayList<HashMap<String, Object>>();
- for(int i=0;i<70;i++)
- {
- emtions = emotionList.get(i);
- if (emtions != null) {
- HashMap<String, Object> map = new HashMap<String, Object>();
- Field f;
- try {
- f = (Field)R.drawable.class.getDeclaredField(emtions.getImageName());
- int j = f.getInt(R.drawable.class);
- map.put("ItemImage", j);//添加图像资源的ID
- lstImageItem.add(map);
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (NoSuchFieldException e) {
- e.printStackTrace();
- }catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- }
- }
- //生成适配器的ImageItem <====> 动态数组的元素,两者一一对应
- SimpleAdapter saImageItems = new SimpleAdapter(this,
- lstImageItem,//数据来源
- R.layout.blog_emotion_list,
- //动态数组与ImageItem对应的子项
- new String[] {"ItemImage"},
- //ImageItem的XML文件里面的一个ImageView
- new int[] {R.id.blog_sendmsg_emotion});
- expressionGriView.setAdapter(saImageItems);
- } else {
- expressionGriView.setVisibility(View.GONE);
- }
- }
- public void addexpression(View view){
- if (expressionGriView.getVisibility() == View.GONE) {
- expressionGriView.setVisibility(View.VISIBLE);
- emotionList = BlogHomeActivity.emotions;
- ArrayList<HashMap<String, Object>> lstImageItem = new ArrayList<HashMap<String, Object>>();
- for(int i=0;i<70;i++)
- {
- emtions = emotionList.get(i);
- if (emtions != null) {
- HashMap<String, Object> map = new HashMap<String, Object>();
- Field f;
- try {
- f = (Field)R.drawable.class.getDeclaredField(emtions.getImageName());
- int j = f.getInt(R.drawable.class);
- map.put("ItemImage", j);//添加图像资源的ID
- lstImageItem.add(map);
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (NoSuchFieldException e) {
- e.printStackTrace();
- }catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- }
- }
- //生成适配器的ImageItem <====> 动态数组的元素,两者一一对应
- SimpleAdapter saImageItems = new SimpleAdapter(this,
- lstImageItem,//数据来源
- R.layout.blog_emotion_list,
- //动态数组与ImageItem对应的子项
- new String[] {"ItemImage"},
- //ImageItem的XML文件里面的一个ImageView
- new int[] {R.id.blog_sendmsg_emotion});
- expressionGriView.setAdapter(saImageItems);
- } else {
- expressionGriView.setVisibility(View.GONE);
- }
- }
5:实现点击GridView的每一个item,处理根据item的index查找对应的表情code,然后再把code利用正则把code转换为相对应的表情图片,最后表情插入EditText进行发送
5.1:code转换为图片:
- public SpannableString txtToImg(String content){
- SpannableString ss = new SpannableString(content);
- int starts = 0;
- int end = 0;
- if(content.indexOf("[", starts) != -1 && content.indexOf("]", end) != -1){
- starts = content.indexOf("[", starts);
- end = content.indexOf("]", end);
- String phrase = content.substring(starts,end + 1);
- String imageName = "";
- List<Emotions> list = BlogHomeActivity.emotions;
- for (Emotions emotions : list) {
- if (emotions.getPhrase().equals(phrase)) {
- imageName = emotions.getImageName();
- }
- }
- try {
- Field f = (Field)R.drawable.class.getDeclaredField(imageName);
- int i= f.getInt(R.drawable.class);
- Drawable drawable = BlogSendMsgActivity.this.getResources().getDrawable(i);
- if (drawable != null) {
- drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
- ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
- ss.setSpan(span, starts,end + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (NoSuchFieldException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- }
- }
- return ss;
- }
- public SpannableString txtToImg(String content){
- SpannableString ss = new SpannableString(content);
- int starts = 0;
- int end = 0;
- if(content.indexOf("[", starts) != -1 && content.indexOf("]", end) != -1){
- starts = content.indexOf("[", starts);
- end = content.indexOf("]", end);
- String phrase = content.substring(starts,end + 1);
- String imageName = "";
- List<Emotions> list = BlogHomeActivity.emotions;
- for (Emotions emotions : list) {
- if (emotions.getPhrase().equals(phrase)) {
- imageName = emotions.getImageName();
- }
- }
- try {
- Field f = (Field)R.drawable.class.getDeclaredField(imageName);
- int i= f.getInt(R.drawable.class);
- Drawable drawable = BlogSendMsgActivity.this.getResources().getDrawable(i);
- if (drawable != null) {
- drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
- ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
- ss.setSpan(span, starts,end + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (NoSuchFieldException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- }
- }
- return ss;
- }
5.2:插入EditText
- emtions = emotionList.get(position);//获取表情bean
- int cursor = etcontent.getSelectionStart();
- etcontent.getText().insert(cursor, txtToImg(emtions.getPhrase()));
- emtions = emotionList.get(position);//获取表情bean
- int cursor = etcontent.getSelectionStart();
- etcontent.getText().insert(cursor, txtToImg(emtions.getPhrase()));
写完收工,给个效果图: