android 新浪微博客户端的表情功能的实现
16lz
2022-01-19
这是一篇好文章,我转来收藏,技术的最高境界是分享。
最近在搞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工程进行下载)
[java] view plain copy- publicvoidgetFriendList()throwsException{
- BlogReleaseServiceImplservice=newBlogReleaseServiceImpl();
- List<Emotions>list=service.getEmotion();
- for(Emotionsemotions:list){
- Stringpath=emotions.getUrl();
- Stringfilename=path.substring(path.lastIndexOf("/")+1,path.length());
- URLurl=newURL(path);
- HttpURLConnectionconn=(HttpURLConnection)url.openConnection();
- conn.setRequestMethod("GET");
- conn.setReadTimeout(5*1000);
- if(conn.getResponseCode()==200){
- InputStreamis=conn.getInputStream();
- byte[]data=readStream(is);
- Filefile=newFile("f:\\sina_images\\"+filename);
- FileOutputStreamfs=newFileOutputStream(file);
- fs.write(data);
- fs.close();
- }else{
- System.out.println("请求失败");
- }
- }
- }
- publicbyte[]readStream(InputStreamis)throwsException{
- ByteArrayOutputStreamos=newByteArrayOutputStream();
- byte[]buffer=newbyte[2048];
- intlen=0;
- while((len=is.read(buffer))!=-1){
- os.write(buffer,0,len);
- }
- is.close();
- returnos.toByteArray();
- }
2:把本地的表情都放进android的资源文件里----drawable下面(这个就不用多说了,直接选取所有文件复制就行了)
3:
3.1访问新浪的表情接口,把返回的信息如下:
[html] view plain copy- <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代码如下:
[java] view plain copy - packagecom.uim.microblog.model;
- importjava.io.Serializable;
- publicclassEmotionsimplementsSerializable{
- /**
- *
- */
- privatestaticfinallongserialVersionUID=1L;
- privateStringphrase;//表情使用的替代文字
- privateStringtype;
- privateStringurl;//表情图片存放的位置
- privateStringisHot;//是否为热门表情
- privateStringisCommon;//是否属于通用
- privateStringorderNumber;//该表情在系统中的排序号码
- privateStringcategory;//表情分类
- privateStringimageName;//表情名称
- publicStringgetImageName(){
- returnimageName;
- }
- publicvoidsetImageName(StringimageName){
- this.imageName=imageName;
- }
- publicStringgetPhrase(){
- returnphrase;
- }
- publicvoidsetPhrase(Stringphrase){
- this.phrase=phrase;
- }
- publicStringgetType(){
- returntype;
- }
- publicvoidsetType(Stringtype){
- this.type=type;
- }
- publicStringgetUrl(){
- returnurl;
- }
- publicvoidsetUrl(Stringurl){
- this.url=url;
- }
- publicStringgetIsHot(){
- returnisHot;
- }
- publicvoidsetIsHot(StringisHot){
- this.isHot=isHot;
- }
- publicStringgetIsCommon(){
- returnisCommon;
- }
- publicvoidsetIsCommon(StringisCommon){
- this.isCommon=isCommon;
- }
- publicStringgetOrderNumber(){
- returnorderNumber;
- }
- publicvoidsetOrderNumber(StringorderNumber){
- this.orderNumber=orderNumber;
- }
- publicStringgetCategory(){
- returncategory;
- }
- publicvoidsetCategory(Stringcategory){
- this.category=category;
- }
- }
3.2储存在一个Emotion.java里。Emotion.java代码如下:
[java] view plain copy- packagecom.uim.microblog.net.handler;
- importjava.util.ArrayList;
- importjava.util.List;
- importorg.xml.sax.Attributes;
- importorg.xml.sax.SAXException;
- importorg.xml.sax.helpers.DefaultHandler;
- importcom.uim.microblog.model.Emotions;
- importcom.uim.microblog.model.ResponseResult;
- publicclassBlogEmotionsHandlerextendsDefaultHandler{
- privateList<Emotions>list;
- privateEmotionsemotions;
- privateResponseResultresponseresult;
- privateStringtag=null;//正在解析的元素
- publicList<Emotions>getEmotionsList(){
- returnlist;
- }
- @Override
- publicvoidcharacters(char[]ch,intstart,intlength)
- throwsSAXException{
- if(tag!=null){
- StringtextArea=newString(ch,start,length);
- /**开始解析表情数据*/
- if("phrase".equals(tag)){
- emotions.setPhrase(textArea);
- }elseif("type".equals(tag)){
- emotions.setType(textArea);
- }elseif("url".equals(tag)){
- try{
- emotions.setUrl(textArea);
- StringimageName=textArea.substring(textArea.lastIndexOf("/")+1,textArea.length()-4);
- emotions.setImageName(imageName);
- }catch(Exceptione){
- e.printStackTrace();
- }
- }elseif("is_hot".equals(tag)){
- emotions.setIsHot(textArea);
- }elseif("is_common".equals(tag)){
- emotions.setIsCommon(textArea);
- }elseif("order_number".equals(tag)){
- emotions.setOrderNumber(textArea);
- }elseif("category".equals(tag)){
- emotions.setCategory(textArea);
- }elseif("retn".equals(tag)){
- responseresult.setRetn(textArea);
- }elseif("desc".equals(tag)){
- responseresult.setDesc(textArea);
- }
- }
- }
- @Override
- publicvoidendDocument()throwsSAXException{
- super.endDocument();
- }
- @Override
- publicvoidendElement(Stringuri,StringlocalName,StringqName)
- throwsSAXException{
- tag=null;
- if("mb".equals(localName)){
- }elseif("emotions".equals(localName)){
- responseresult=null;
- }elseif("emotion".equals(localName)){
- list.add(emotions);
- emotions=null;
- }
- }
- @Override
- publicvoidstartDocument()throwsSAXException{
- list=newArrayList<Emotions>();
- }
- @Override
- publicvoidstartElement(Stringuri,StringlocalName,StringqName,
- Attributesattributes)throwsSAXException{
- if("mb".equals(localName)){
- responseresult=newResponseResult();
- }elseif("emotions".equals(localName)){
- }elseif("emotion".equals(localName)){
- emotions=newEmotions();
- }
- tag=localName;
- }
- }
3.4sax解析
[java] view plain copy - publicList<Emotions>getEmotion(){
- BlogGetDatagetdata=newBlogGetData();
- Stringresult=getdata.blogEmotionsServlet();
- try{
- //生成SAX解析对象
- parser=SAXParserFactory.newInstance().newSAXParser();
- //生成xml读取器
- reader=parser.getXMLReader();
- BlogEmotionsHandlerhandler=newBlogEmotionsHandler();
- //设置Handler
- reader.setContentHandler(handler);
- //指定文件,进行解析
- reader.parse(newInputSource(newStringReader(result)));
- //获取List<Emotions>
- emotionList=handler.getEmotionsList();
- }catch(ParserConfigurationExceptione){
- e.printStackTrace();
- }catch(SAXExceptione){
- e.printStackTrace();
- }catch(IOExceptione){
- e.printStackTrace();
- }
- returnemotionList;
- }
4:
4.1实现表情选择器---GridView
[html] view plain copy- <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
[html] view plain copy
- <?xmlversion="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进行显示
[java] view plain copy
- publicvoidaddexpression(Viewview){
- if(expressionGriView.getVisibility()==View.GONE){
- expressionGriView.setVisibility(View.VISIBLE);
- emotionList=BlogHomeActivity.emotions;
- ArrayList<HashMap<String,Object>>lstImageItem=newArrayList<HashMap<String,Object>>();
- for(inti=0;i<70;i++)
- {
- emtions=emotionList.get(i);
- if(emtions!=null){
- HashMap<String,Object>map=newHashMap<String,Object>();
- Fieldf;
- try{
- f=(Field)R.drawable.class.getDeclaredField(emtions.getImageName());
- intj=f.getInt(R.drawable.class);
- map.put("ItemImage",j);//添加图像资源的ID
- lstImageItem.add(map);
- }catch(SecurityExceptione){
- e.printStackTrace();
- }catch(NoSuchFieldExceptione){
- e.printStackTrace();
- }catch(IllegalArgumentExceptione){
- e.printStackTrace();
- }catch(IllegalAccessExceptione){
- e.printStackTrace();
- }
- }
- }
- //生成适配器的ImageItem<====>动态数组的元素,两者一一对应
- SimpleAdaptersaImageItems=newSimpleAdapter(this,
- lstImageItem,//数据来源
- R.layout.blog_emotion_list,
- //动态数组与ImageItem对应的子项
- newString[]{"ItemImage"},
- //ImageItem的XML文件里面的一个ImageView
- newint[]{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转换为图片:
[java] view plain copy- publicSpannableStringtxtToImg(Stringcontent){
- SpannableStringss=newSpannableString(content);
- intstarts=0;
- intend=0;
- if(content.indexOf("[",starts)!=-1&&content.indexOf("]",end)!=-1){
- starts=content.indexOf("[",starts);
- end=content.indexOf("]",end);
- Stringphrase=content.substring(starts,end+1);
- StringimageName="";
- List<Emotions>list=BlogHomeActivity.emotions;
- for(Emotionsemotions:list){
- if(emotions.getPhrase().equals(phrase)){
- imageName=emotions.getImageName();
- }
- }
- try{
- Fieldf=(Field)R.drawable.class.getDeclaredField(imageName);
- inti=f.getInt(R.drawable.class);
- Drawabledrawable=BlogSendMsgActivity.this.getResources().getDrawable(i);
- if(drawable!=null){
- drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());
- ImageSpanspan=newImageSpan(drawable,ImageSpan.ALIGN_BASELINE);
- ss.setSpan(span,starts,end+1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- }catch(SecurityExceptione){
- e.printStackTrace();
- }catch(NoSuchFieldExceptione){
- e.printStackTrace();
- }catch(IllegalArgumentExceptione){
- e.printStackTrace();
- }catch(IllegalAccessExceptione){
- }
- }
- returnss;
- }
5.2:插入EditText
[java] view plain copy- emtions=emotionList.get(position);//获取表情bean
- intcursor=etcontent.getSelectionStart();
- etcontent.getText().insert(cursor,txtToImg(emtions.getPhrase()));
写完收工,给个效果图:
转自:http://jspjson.iteye.com/blog/1109222
更多相关文章
- 源码解析Android中View的measure量算过程
- android 新浪微博客户端的表情功能的实现
- android 新浪微博客户端的表情功能的实现
- android 新浪微博客户端的表情功能的实现
- android 安全讲座第四层 手机Root授权原理细节全解析(3)
- android 安全讲座第四层 手机Root授权原理细节全解析(2)
- android 触摸(Touch)事件、点击(Click)事件的区别(详细解析)
- Android异步加载全解析之Bitmap
- [置顶] android 新浪微博客户端的表情功能的实现