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

QSS样式表的学习 QSS是Qt程序界面中用来设置空间背景图片,字体大小,字体颜色,按钮状态变化等属性,它是用来美化UI界面。实现界面和程序的分离,快速切换皮肤。 语法: 1、 Selector {property:value} ; //Selector 即Qt中的各种控件,如QPushButton、QLable等等 例: QPushButton {color : red} 2、 如果有多个选择器,选择器之间用逗号隔开 例: QPushButton,QLineEdit,QComboBox{color : red... 阅读详情
这是一篇好文章,我转来收藏,技术的最高境界是分享。

最近在搞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工程进行下载)

  1. public void getFriendList()throws Exception { 
  2.         BlogReleaseServiceImpl service = new BlogReleaseServiceImpl(); 
  3.         List<Emotions> list = service.getEmotion(); 
  4.         for (Emotions emotions : list) { 
  5.             String path = emotions.getUrl(); 
  6.             String filename = path.substring(path.lastIndexOf("/") +1,path.length()); 
  7.             URL url =  new URL(path); 
  8.             HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 
  9.             conn.setRequestMethod("GET"); 
  10.             conn.setReadTimeout(5 * 1000); 
  11.             if(conn.getResponseCode() ==200){ 
  12.                 InputStream is = conn.getInputStream(); 
  13.                 byte[] data = readStream(is); 
  14.                 File file = new File("f: \\sina_images\\" + filename); 
  15.                 FileOutputStream fs = new FileOutputStream(file); 
  16.                 fs.write(data); 
  17.                 fs.close(); 
  18.             }else{ 
  19.                 System.out.println("请求失败"); 
  20.             } 
  21.         } 
  22.     } 
  23.      
  24.     public byte[] readStream(InputStream is)throws Exception { 
  25.         ByteArrayOutputStream os = new ByteArrayOutputStream(); 
  26.         byte[] buffer = newbyte[2048]; 
  27.         int len = 0; 
  28.         while((len = is.read(buffer)) != -1){ 
  29.             os.write(buffer,0,len); 
  30.         } 
  31.         is.close(); 
  32.         return os.toByteArray(); 
  33.     } 
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访问新浪的表情接口,把返回的信息如下:

  1.      <emotion> 
  2. <phrase>[嘻嘻]</phrase> 
  3. <type>face</type> 
  4. <url>http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/c2/tooth.gif 
  5. </url> 
  6. <is_hot>false</is_hot> 
  7. <is_common>true</is_common> 
  8. <order_number>0</order_number> 
  9. <category></category> 
  10. 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>
	</emotion>


3.2 储存在一个Emotion.java里。Emotion.java代码如下:

  1. package com.uim.microblog.model; 
  2.  
  3. import java.io.Serializable; 
  4.  
  5. public class Emotionsimplements Serializable { 
  6.  
  7.     /**
  8.      *
  9.      */ 
  10.     private staticfinal long serialVersionUID = 1L; 
  11.      
  12.     private String phrase;//表情使用的替代文字 
  13.     private String type; 
  14.     private String url;//表情图片存放的位置 
  15.     private String isHot;//是否为热门表情 
  16.     private String isCommon;//是否属于通用 
  17.     private String orderNumber;//该表情在系统中的排序号码 
  18.     private String category;//表情分类 
  19.     private String imageName;//表情名称 
  20.      
  21.     public String getImageName() { 
  22.         return imageName; 
  23.     } 
  24.     public void setImageName(String imageName) { 
  25.         this.imageName = imageName; 
  26.     } 
  27.     public String getPhrase() { 
  28.         return phrase; 
  29.     } 
  30.     public void setPhrase(String phrase) { 
  31.         this.phrase = phrase; 
  32.     } 
  33.     public String getType() { 
  34.         return type; 
  35.     } 
  36.     public void setType(String type) { 
  37.         this.type = type; 
  38.     } 
  39.     public String getUrl() { 
  40.         return url; 
  41.     } 
  42.     public void setUrl(String url) { 
  43.         this.url = url; 
  44.     } 
  45.     public String getIsHot() { 
  46.         return isHot; 
  47.     } 
  48.     public void setIsHot(String isHot) { 
  49.         this.isHot = isHot; 
  50.     } 
  51.     public String getIsCommon() { 
  52.         return isCommon; 
  53.     } 
  54.     public void setIsCommon(String isCommon) { 
  55.         this.isCommon = isCommon; 
  56.     } 
  57.     public String getOrderNumber() { 
  58.         return orderNumber; 
  59.     } 
  60.     public void setOrderNumber(String orderNumber) { 
  61.         this.orderNumber = orderNumber; 
  62.     } 
  63.     public String getCategory() { 
  64.         return category; 
  65.     } 
  66.     public void setCategory(String category) { 
  67.         this.category = category; 
  68.     } 
  69.          
  70. } 
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.2 储存在一个Emotion.java里。Emotion.java代码如下:

  1. package com.uim.microblog.net.handler; 
  2.  
  3. import java.util.ArrayList; 
  4. import java.util.List; 
  5.  
  6. import org.xml.sax.Attributes; 
  7. import org.xml.sax.SAXException; 
  8. import org.xml.sax.helpers.DefaultHandler; 
  9.  
  10. import com.uim.microblog.model.Emotions; 
  11. import com.uim.microblog.model.ResponseResult; 
  12.  
  13. public class BlogEmotionsHandlerextends DefaultHandler { 
  14.      
  15.     private List<Emotions> list; 
  16.      
  17.     private Emotions emotions; 
  18.     private ResponseResult responseresult; 
  19.      
  20.     private String tag = null;//正在解析的元素 
  21.      
  22.      
  23.     public List<Emotions> getEmotionsList(){ 
  24.         return list; 
  25.     } 
  26.  
  27.     @Override 
  28.     public void characters(char[] ch,int start, int length) 
  29.             throws SAXException { 
  30.         if (tag != null) { 
  31.             String textArea = new String(ch,start,length); 
  32.              
  33.             /**开始解析表情数据*/ 
  34.             if ("phrase".equals(tag)) { 
  35.                 emotions.setPhrase(textArea); 
  36.             } else if ("type".equals(tag)) { 
  37.                 emotions.setType(textArea); 
  38.             } else if ("url".equals(tag)) { 
  39.                 try { 
  40.                     emotions.setUrl(textArea); 
  41.                     String imageName = textArea.substring(textArea.lastIndexOf("/") +1,textArea.length() - 4); 
  42.                     emotions.setImageName(imageName); 
  43.                 } catch (Exception e) { 
  44.                     e.printStackTrace(); 
  45.                 } 
  46.             } else if ("is_hot".equals(tag)) { 
  47.                 emotions.setIsHot(textArea); 
  48.             } else if ("is_common".equals(tag)) { 
  49.                 emotions.setIsCommon(textArea); 
  50.             } else if ("order_number".equals(tag)) { 
  51.                 emotions.setOrderNumber(textArea); 
  52.             } else if ("category".equals(tag)) { 
  53.                 emotions.setCategory(textArea); 
  54.             } else if ("retn".equals(tag)) { 
  55.                 responseresult.setRetn(textArea); 
  56.             } else if ("desc".equals(tag)) { 
  57.                 responseresult.setDesc(textArea); 
  58.             } 
  59.         } 
  60.          
  61.     } 
  62.  
  63.     @Override 
  64.     public void endDocument()throws SAXException { 
  65.         super.endDocument(); 
  66.     } 
  67.  
  68.     @Override 
  69.     public void endElement(String uri, String localName, String qName) 
  70.             throws SAXException { 
  71.         tag = null; 
  72.         if ("mb".equals(localName)) { 
  73.              
  74.         } else if ("emotions".equals(localName)) { 
  75.             responseresult =null; 
  76.         } else if ("emotion".equals(localName)) { 
  77.             list.add(emotions); 
  78.              
  79.             emotions = null; 
  80.         }  
  81.     } 
  82.  
  83.     @Override 
  84.     public void startDocument()throws SAXException { 
  85.         list = new ArrayList<Emotions>(); 
  86.     } 
  87.  
  88.     @Override 
  89.     public void startElement(String uri, String localName, String qName, 
  90.             Attributes attributes) throws SAXException { 
  91.         if ("mb".equals(localName)) { 
  92.             responseresult = new ResponseResult(); 
  93.         } else if ("emotions".equals(localName)) { 
  94.              
  95.         } else if ("emotion".equals(localName)) { 
  96.             emotions = new Emotions(); 
  97.         }  
  98.          
  99.         tag = localName; 
  100.     } 
  101.      
  102.      
  103.  
  104. } 
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解析

  1. public List<Emotions> getEmotion(){ 
  2.         BlogGetData getdata = new BlogGetData(); 
  3.         String result = getdata.blogEmotionsServlet(); 
  4.         try { 
  5.             //生成SAX解析对象 
  6.             parser = SAXParserFactory.newInstance().newSAXParser(); 
  7.             //生成xml读取器 
  8.             reader = parser.getXMLReader(); 
  9.             BlogEmotionsHandler handler = new BlogEmotionsHandler(); 
  10.             //设置Handler 
  11.             reader.setContentHandler(handler); 
  12.             //指定文件,进行解析 
  13.             reader.parse(new InputSource(new StringReader(result))); 
  14.             //获取 List<Emotions> 
  15.             emotionList = handler.getEmotionsList(); 
  16.         } catch (ParserConfigurationException e) { 
  17.             e.printStackTrace(); 
  18.         } catch (SAXException e) { 
  19.             e.printStackTrace(); 
  20.         } catch (IOException e) { 
  21.             e.printStackTrace(); 
  22.         } 
  23.          
  24.         return emotionList; 
  25.     } 
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

  1. <GridView 
  2.             android:id="@+id/blog_sendmsg_gvemotion" 
  3.             android:layout_width="fill_parent" 
  4.             android:layout_height="150sp" 
  5.             android:scrollbars="vertical" 
  6.             android:numColumns="auto_fit" 
  7.             android:verticalSpacing="15dp" 
  8.             android:background="@color/blog_list_back" 
  9.             android:stretchMode="columnWidth" 
  10.             android:gravity="center" 
  11.             android:visibility="gone" 
  12.             android:columnWidth="40dp"> 
  13.     </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

  1. <?xmlversion="1.0"encoding="utf-8"?> 
  2. <LinearLayout 
  3.   xmlns:android="http://schemas.android.com/apk/res/android" 
  4.   android:layout_width="fill_parent" 
  5.   android:layout_height="fill_parent"> 
  6.   <ImageView 
  7.     android:id="@+id/blog_sendmsg_emotion" 
  8.     android:layout_width="wrap_content" 
  9.     android:layout_height="wrap_content" 
  10.     android:layout_weight="50" 
  11.     android:layout_gravity="center"> 
  12.   </ImageView> 
  13. </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进行显示

  1. public void addexpression(View view){ 
  2.         if (expressionGriView.getVisibility() == View.GONE) { 
  3.             expressionGriView.setVisibility(View.VISIBLE); 
  4.              
  5.             emotionList = BlogHomeActivity.emotions; 
  6.             ArrayList<HashMap<String, Object>> lstImageItem = new ArrayList<HashMap<String, Object>>(); 
  7.               
  8.               for(int i=0;i<70;i++)   
  9.               {  
  10.                 emtions = emotionList.get(i);    
  11.                 if (emtions !=null) { 
  12.                     HashMap<String, Object> map = new HashMap<String, Object>(); 
  13.                  
  14.                     Field f; 
  15.                     try { 
  16.                         f = (Field)R.drawable.class.getDeclaredField(emtions.getImageName()); 
  17.                         int j = f.getInt(R.drawable.class);  
  18.                         map.put("ItemImage", j);//添加图像资源的ID  
  19.                         lstImageItem.add(map);   
  20.                     } catch (SecurityException e) { 
  21.                         e.printStackTrace(); 
  22.                     } catch (NoSuchFieldException e) { 
  23.                         e.printStackTrace(); 
  24.                     }catch (IllegalArgumentException e) { 
  25.                         e.printStackTrace(); 
  26.                     } catch (IllegalAccessException e) { 
  27.                         e.printStackTrace(); 
  28.                     } 
  29.                      
  30.                 }   
  31.                  
  32.               }   
  33.                
  34.             //生成适配器的ImageItem <====> 动态数组的元素,两者一一对应  
  35.               SimpleAdapter saImageItems = new SimpleAdapter(this,  
  36.                                                         lstImageItem,//数据来源   
  37.                                                         R.layout.blog_emotion_list, 
  38.                                                            
  39.                                                         //动态数组与ImageItem对应的子项           
  40.                                                         new String[] {"ItemImage"},    
  41.                                                            
  42.                                                         //ImageItem的XML文件里面的一个ImageView 
  43.                                                         new int[] {R.id.blog_sendmsg_emotion});   
  44.                
  45.               expressionGriView.setAdapter(saImageItems);   
  46.         } else { 
  47.             expressionGriView.setVisibility(View.GONE); 
  48.         } 
  49.          
  50.     } 
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转换为图片:

  1. public SpannableString txtToImg(String content){ 
  2.         SpannableString ss = new SpannableString(content); 
  3.         int starts = 0; 
  4.         int end = 0; 
  5.          
  6.         if(content.indexOf("[", starts) != -1 && content.indexOf("]", end) != -1){ 
  7.             starts = content.indexOf("[", starts); 
  8.             end = content.indexOf("]", end); 
  9.             String phrase = content.substring(starts,end + 1); 
  10.             String imageName = ""; 
  11.             List<Emotions> list = BlogHomeActivity.emotions; 
  12.             for (Emotions emotions : list) { 
  13.                 if (emotions.getPhrase().equals(phrase)) { 
  14.                     imageName = emotions.getImageName(); 
  15.                 } 
  16.             } 
  17.              
  18.             try { 
  19.                 Field f = (Field)R.drawable.class.getDeclaredField(imageName); 
  20.                 int i= f.getInt(R.drawable.class); 
  21.                 Drawable drawable = BlogSendMsgActivity.this.getResources().getDrawable(i);   
  22.                 if (drawable != null) { 
  23.                     drawable.setBounds(0,0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());  
  24.                     ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);   
  25.                     ss.setSpan(span, starts,end + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);   
  26.                 } 
  27.             } catch (SecurityException e) { 
  28.                 e.printStackTrace(); 
  29.             } catch (NoSuchFieldException e) { 
  30.                 e.printStackTrace(); 
  31.             } catch (IllegalArgumentException e) { 
  32.                 e.printStackTrace(); 
  33.             } catch (IllegalAccessException e) { 
  34.                  
  35.             } 
  36.  
  37.         } 
  38.         return ss; 
  39.     } 
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

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


写完收工,给个效果图:


转自:http://jspjson.iteye.com/blog/1109222

Qt QLabel实现工业级状态指示灯:从静态到动态闪烁的完整方案 在桌面软件开发中,状态指示灯是人机交互界面的核心视觉反馈组件,用于直观展示设备运行、报警等状态。其实现原理通常基于控件的样式动态切换,通过改变颜色、形状等属性来传递状态信息。在Qt框架中,QLabel控件凭借其高效的显示渲染机制和对样式表的完善支持,成为实现自定义指示灯的技术优选。通过QSS(Qt Style Sheets)可灵活定义圆角、背景色与边框,模拟工业场景中的红绿灯效果,而结合QTimer定时器则能轻松实现闪烁、呼吸等动态效果,技术价值在于以纯代码方式构建高性能、可定制化的UI组件,无需依赖外部资 阅读详情

相关推荐

Qt6工业深色主题实战:QSS适配、光学可靠性与产线部署

深色主题在工业人机界面(HMI)中并非视觉偏好,而是基于人因工程与光学安全的刚性需求。其核心原理在于控制背景亮度、保障色彩可辨识性(尤其在强光、远距、色弱场景),并适配嵌入式GPU渲染管线。技术价值体现在降低误操作率、提升长时间作业稳定性及满足ISO/IEC/IEC 62366等合规要求。典型应用场景包括PLC监控、轨道信号系统、半导体AOI检测等高可靠性工控软件。本文聚焦Qt6平台,深入解析QSS在暗色主题下的底层约束、CIE色域配色工程及从开发到产线的全链路验证方法。

weixin_34072458的博客 301

新浪微博的表情实现

NULL 博文链接:https://phenom.iteye.com/blog/1686742

Qt登录界面设计:从信号槽到QSS的工业级实践

登录界面是桌面应用最基础也最关键的交互入口,其背后涉及GUI框架的核心机制——信号与槽通信、事件循环调度、UI线程安全及样式系统(QSS)控制。理解QWidget生命周期、父子关系与资源管理策略,是避免野指针、样式失效和跨平台异常的前提;掌握Qt 6现代CMake构建、qrc资源打包与windeployqt部署流程,则直接决定应用能否稳定交付。本文以Qt登录模块为切口,系统解析UI/Controller/Model三层架构、密码框深度定制、按钮状态机与高DPI适配等工程细节,覆盖从零编码、调试排错到打包发布

weixin_33798152的博客 357

微博API发表情

moamao_jishuyuan的博客 319

PyQt QSS自定义QSpinBox:从原理到实战打造现代化UI控件

在GUI开发中,样式定制是提升用户体验的关键环节。Qt Style Sheets(QSS)作为Qt框架的样式表系统,其原理类似于Web开发中的CSS,通过声明式语法实现界面逻辑与视觉表现的解耦。这项技术的核心价值在于,开发者无需修改底层控件代码,即可灵活定制组件的外观与交互状态,大幅提升开发效率和UI一致性。在PyQt/PySide等Python GUI项目中,QSS广泛应用于按钮、输入框、滑块等控件的视觉优化,尤其适用于需要适配不同主题(如暗黑模式)或实现特定设计语言的场景。本文聚焦于QSpinBox(数

weixin_33910759的博客 371

Qt QLineEdit控件深度解析:从基础使用到高级定制与性能优化

在GUI应用开发中,文本输入框是用户交互的核心组件,其设计与实现直接关系到用户体验与数据有效性。Qt框架中的QLineEdit控件作为单行文本编辑的基石,通过信号槽机制、属性管理与事件处理,实现了文本输入、验证与显示的完整逻辑。理解其设计哲学与内部原理,对于构建响应迅速、行为可靠的界面至关重要。在工程实践中,开发者常面临输入验证、实时搜索、样式定制等需求,这需要综合运用验证器、事件过滤与样式表等技术。本文聚焦QLineEdit,深入探讨其核心功能、高级定制方法及常见问题解决方案,旨在帮助开发者掌握从基础文本

weixin_30808693的博客 438

匹配微博表情包

【代码】匹配微博表情包。

s8806479的博客 268

Qt按钮控件深度解析:从QPushButton到自定义绘制的GUI开发实战

在图形用户界面(GUI)开发中,控件是构建交互体验的基础单元,其核心原理在于事件处理与状态管理。Qt框架通过信号与槽机制实现了控件间的高效通信,而样式系统则提供了灵活的外观定制能力。这些技术的价值在于能够帮助开发者构建响应迅速、视觉统一且易于维护的跨平台应用程序。在桌面软件、嵌入式界面等应用场景中,按钮作为最频繁使用的交互控件,其实现质量直接影响用户体验。本文聚焦于Qt按钮控件家族,深入探讨了QPushButton、QRadioButton等核心组件的信号槽高级用法、样式表(QSS)定制以及通过重写pain

weixin_30706691的博客 348

新浪微博表情代码以及对应的gif图片url

新浪微博表情代码以及对应的gif图片url api:https://api.weibo.com/2/emotions.json?source=1362404091 var c = [{ icon : "http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/7a/shenshou_thumb.gif", ...

:) 8194

Qt QPushButton深度解析:从基础使用到高级定制与性能优化

在GUI开发中,按钮控件是构建用户交互界面的基础元素,其核心功能是响应用户点击并触发特定操作。其工作原理涉及事件处理、状态管理和视觉渲染等多个层面,良好的按钮实现能显著提升应用的用户体验和操作效率。在工程实践中,开发者不仅需要掌握其基本属性和信号槽机制,还需深入理解样式定制、性能优化以及多线程环境下的正确用法。本文聚焦于Qt框架中的QPushButton控件,通过剖析其构造方式、default与autoDefault属性、以及checkable状态管理等热词,并结合样式表定制与事件处理等高频技术点,系统讲解

afhu47033的博客 401

深入解析QT QLCDNumber控件:工业仪表盘与数值显示实战指南

在QT图形界面开发中,数值显示是一个基础且普遍的需求,尤其在工业监控、仪表盘和数据采集等应用场景中。七段数码管风格的显示控件通过高对比度和易读性,能够直观地突显关键数据,如温度、转速和电压等。QLCDNumber作为QT框架内置的控件,提供了数字、十六进制、二进制等多种显示模式,并支持动态数据绑定与样式自定义。其核心原理在于通过digitCount控制显示位数,利用segmentStyle调整视觉风格,并能通过信号槽机制实现实时数据更新。在工程实践中,QLCDNumber不仅解决了基础数值展示问题,还能通过

congbao6525的博客 526

EditText插入表情,模仿聊天页面

自己找了论坛里前辈研究过的结论和一些demo,自己参考也写了一个sample,为项目做准备,分享下。表情是从QQ的apk里拿出来借用。

C++ Qt实战:仿制Win11日历应用,掌握桌面GUI开发核心技能

C++作为一门强大的系统编程语言,其应用领域远不止算法和后端。通过图形用户界面(GUI)开发,开发者能将复杂的逻辑转化为直观的桌面应用,极大地提升软件的交互性和实用性。在众多GUI框架中,Qt凭借其跨平台特性、丰富的控件库和高效的信号槽机制,成为C++桌面开发的主流选择。它通过封装底层系统API,让开发者能更专注于业务逻辑与用户体验设计,从而高效构建具有现代感的原生应用。本文将以创建一个仿Win11风格的日历应用为具体项目,深入讲解如何运用Qt进行界面绘制、事件处理、数据模型构建及样式美化,涵盖从开发环境搭

weixin_34111790的博客 381

如何写一个发微博的页面(包括插入图片,插入表情,插入话题,插入Location)

见博客:http://blog.youkuaiyun.com/baidu_nod/article/details/38355279

pgAdmin 4 服务器模式部署全指南:Apache+WSGI+PostgreSQL生产实践

pgAdmin 4 本质是一个基于 Flask 和 SQLAlchemy 的 Web 应用,其‘桌面模式’仅限单机调试,而真正支持多用户协同、HTTPS、LDAP集成与审计合规的,是可部署于标准 Web 容器的‘服务器模式’。该模式依托 WSGI 协议实现 Python 应用与 Apache/Nginx 的高效通信,核心价值在于可运维性、权限可控性与企业级安全能力。典型应用场景包括金融级 PostgreSQL 运维平台、混合数据库管理门户及与现有 Apache 生态(如 phpMyAdmin、SSO)深度集

闲谈 463

新浪微博表情1640个,带json引用

新浪微博表情,带json引用,适合手机端、桌面等开发。

上一篇: Android基础类之BaseAdapter
下一篇: 浅谈android的selector,背景选择器
Jymot
博客等级 码龄14年 6粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值