当前位置: 代码迷 >> Android >> android 新浪微博客户端的神情功能的实现
  详细解决方案

android 新浪微博客户端的神情功能的实现

热度:46   发布时间:2016-05-01 17:13:02.0
android 新浪微博客户端的表情功能的实现

最近在搞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();	}

?

?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>	</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;	}				}
?

?

??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;	}		}

?

?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;	}

?

?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>

?

?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>

?

?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);		}			}

?

?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;	}
?

?

?

5.2:插入EditText

?

emtions = emotionList.get(position);//获取表情bean	              int cursor = etcontent.getSelectionStart();	              etcontent.getText().insert(cursor, txtToImg(emtions.getPhrase()));
?

?

写完收工,给个效果图:


?

?

1 楼 kenaky 2011-10-04  
  :haha
2 楼 lisi806 2011-10-27  
有没有源码 ,发我看下
3 楼 greenboy1 2011-11-28  
楼主思路不错,谢谢了
4 楼 ctfzh 2011-12-02  
是呀。楼主把源码发出来让大家学习学习就好了。谢谢
5 楼 jspjson 2011-12-02  
上面的几乎就是源码了。认真看,其实可以复制了的
6 楼 codeMoe 2012-03-01  
最后一个插入EditText 请问 etcontent是EditText吗?还有txtToImg(String content)只能识别第一个。。后面连续的表情都直接为文字。。没有识别出来
7 楼 codeMoe 2012-03-01  
codeMoe 写道
最后一个插入EditText 请问 etcontent是EditText吗?还有txtToImg(String content)只能识别第一个。。后面连续的表情都直接为文字。。没有识别出来

这情况是指发出表情后,在textView显示时的情况
8 楼 codeMoe 2012-03-01  
codeMoe 写道
codeMoe 写道
最后一个插入EditText 请问 etcontent是EditText吗?还有txtToImg(String content)只能识别第一个。。后面连续的表情都直接为文字。。没有识别出来

这情况是指发出表情后,在textView显示时的情况

额~~解决了已经
9 楼 2006003845 2012-06-02  
额...楼主可有简易源码demo?点击表情表情列表如软键盘的效果这个怎么做啊 ?
10 楼 jspjson 2012-06-15  
2006003845 写道
额...楼主可有简易源码demo?点击表情表情列表如软键盘的效果这个怎么做啊 ?

就是控件的显示隐藏嘛。。
  相关解决方案