码迷,mamicode.com
首页 > 其他好文 > 详细

QQ表情

时间:2015-08-07 19:53:36      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

源码

activity_main.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"
    android:background="@color/white"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/tweet_pub_form"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="0.22"
        android:orientation="vertical" >

        <EditText
            android:id="@+id/tweet_pub_content"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:autoLink="web"
            android:background="@null"
            android:gravity="top"
            android:hint="请输入动弹内容" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/widget_bar_bg"
        android:gravity="center_horizontal"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/tweet_pub_footbar_face"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:clickable="true"
            android:src="@drawable/widget_bar_face_over" />
    </LinearLayout>

    <GridView
        android:id="@+id/tweet_pub_faces"
        android:layout_width="fill_parent"
        android:layout_height="220dip"
        android:background="@color/face_bg"
        android:columnWidth="50dip"
        android:fadingEdge="none"
        android:gravity="center"
        android:numColumns="auto_fit"
        android:scrollingCache="false"
        android:stretchMode="columnWidth"
        android:visibility="gone" />

</LinearLayout>

brow_item.xml(GridView的每个表情的布局)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
<ImageView
    android:id="@+id/iv_brow"
    android:layout_gravity="center"
    android:layout_width="26dip"
    android:layout_height="26dip"/>
</LinearLayout>

另外在assets中

brow.xml(一部分)

<?xml version="1.0" encoding="utf-8"?>
<brows>
	<brow>
		<code><![CDATA[[em:1:]]]></code>
		<name>f001</name>
	</brow>
	<brow>
		<code><![CDATA[[em:2:]]]></code>
		<name>f002</name>
	</brow>
</brows>

对象封装类

Smile

package com.example.edit_with_expression;

public class Smile {
	private String code; // 表情代码

	private String name; // 表情名字

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

}

ParserBrowXml

package com.example.edit_with_expression;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import android.util.Xml;

public class ParserBrowXml {
	public static List<Smile> getInfo(InputStream inputStream) {

		XmlPullParser parser = Xml.newPullParser();
		int eventType = 0;
		List<Smile> smiles = null;
		Smile smile = null;
		try {
			parser.setInput(inputStream, "UTF-8");
			eventType = parser.getEventType();
			while (eventType != XmlPullParser.END_DOCUMENT) {

				switch (eventType) {
				case XmlPullParser.START_DOCUMENT:

					smiles = new ArrayList<Smile>();
					break;
				case XmlPullParser.START_TAG:
					if ("brow".equals(parser.getName())) {
						smile = new Smile();

					} else if ("code".equals(parser.getName())) {
						smile.setCode(parser.nextText());
					} else if ("name".equals(parser.getName())) {
						smile.setName(parser.nextText());
					}
					break;
				case XmlPullParser.END_TAG:
					if ("brow".equals(parser.getName())) {
						smiles.add(smile);
						smile = null;
					}
					break;

				default:
					break;
				}

				eventType = parser.next();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return smiles;
	}
}

MainActivity

package com.example.edit_with_expression;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

	private List<Smile> smiles = null; // 表情集合

	private EditText ET_content; // 显示框
	private GridView GV_faceView;// 存放表情列表的GridView
	private ImageView IV_face; // 表情显示按钮
	private InputMethodManager inputManager;// 软键盘管理类

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// 和 各个组件变量初始化
		InitVariable();
		// 初始化GridView,将其与Adapter绑定
		InitGridView();
		// 表情显示图片点击监听
		IV_face.setOnClickListener(faceClickListener);
		// EditText点击监听
		ET_content.setOnClickListener(EditContentClickListener);
		// 监听点击了表情的哪一项
		GV_faceView.setOnItemClickListener(gridViewFaceItemClickListener);
	}

	/**
	 * 初始化变量
	 */
	private void InitVariable() {
		// 软键盘管理类
		inputManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
		// 取得放置表情的gridView组件
		GV_faceView = (GridView) this.findViewById(R.id.tweet_pub_faces);
		// 显示表情框
		ET_content = (EditText) findViewById(R.id.tweet_pub_content);
		// 表情显示按钮
		IV_face = (ImageView) findViewById(R.id.tweet_pub_footbar_face);
	}

	private void InitGridView() {
		try {
			// 取得assets中的borw.xml文件
			InputStream inputStream = this.getResources().getAssets()
					.open("brow.xml");
			// 解析borw.xml
			smiles = ParserBrowXml.getInfo(inputStream);
			// 调用生情表情的方法
			addexpression(this, smiles, GV_faceView);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 根据SMILE列表找到对应的SORCE ID,生成simpleAdatper 传到GrideView中 生成表情的方法
	 * 
	 * @param context
	 *            要传入的上下文
	 * @param smiles
	 *            表情集合
	 * @param gridView
	 *            要显示器的grildView
	 * @throws Exception
	 *             异常
	 */
	public void addexpression(Context context, List<Smile> smiles,
			GridView gridView) throws Exception {

		/**
		 * 每个表情封装为一个map集合,在将每个表情放到arraylist集合中
		 */
		ArrayList<HashMap<String, Object>> lstImageItem = new ArrayList<HashMap<String, Object>>();
		for (int i = 0; i < 50; i++) {
			// 获取每个表情对象
			Smile smile = smiles.get(i);
			if (smile != null) {
				HashMap<String, Object> map = new HashMap<String, Object>();
				// 指定要获取的字段名
				Field f = (Field) R.drawable.class.getDeclaredField(smile
						.getName());
				// 获取每个表情在资源文件中的id
				int j = f.getInt(R.drawable.class);
				// 添加图像资源的ID
				map.put("ItemImage", j);
				lstImageItem.add(map);

			}
		}

		// 生成适配器的ImageItem <====> 动态数组的元素,两者一一对应
		// 动态数组与ImageItem对应的子项
		// ImageItem的XML文件里面的一个ImageView
		SimpleAdapter saImageItems = new SimpleAdapter(context, lstImageItem,
				R.layout.brow_item, new String[] { "ItemImage" },
				new int[] { R.id.iv_brow });
		gridView.setSelector(new ColorDrawable(Color.TRANSPARENT));// 解决点击GridView背景变黑的情况
		gridView.setAdapter(saImageItems);
	}

	/**
	 * 点击EditText的监听器,当用户点击EditText的时候显示键盘
	 */
	private View.OnClickListener EditContentClickListener = new View.OnClickListener() {

		@Override
		public void onClick(View v) {
			// 显示软键盘
			showIMM();
		}
	};

	// 以下显示隐藏软键或表情的方法集合
	private void showIMM() {
		IV_face.setTag(1);
		showOrHideIMM();
	}

	private void showOrHideIMM() {
		if (IV_face.getTag() == null) {
			// 隐藏软键盘
			inputManager.hideSoftInputFromWindow(IV_face.getWindowToken(), 0);
			// 显示表情
			showFace();
		} else {
			// 显示软键盘
			inputManager.showSoftInput(ET_content, 0);
			// 隐藏表情
			hideFace();
		}
	}

	private void showFace() {
		IV_face.setTag(1);
		GV_faceView.setVisibility(View.VISIBLE);
	}

	private void hideFace() {
		IV_face.setTag(null);
		GV_faceView.setVisibility(View.GONE);
	}

	/**
	 * 点击显示表情的监听器,当用户点击时显示表示列表
	 */
	private View.OnClickListener faceClickListener = new View.OnClickListener() {

		@Override
		public void onClick(View v) {
			try {
				showOrHideIMM();
			} catch (Exception e) {
				Log.w("msg", e.getMessage());
			}
		}

	};

	/**
	 * 点击表情GRIDVIEW中的某一项的监听器
	 */
	private OnItemClickListener gridViewFaceItemClickListener = new AdapterView.OnItemClickListener() {

		@Override
		public void onItemClick(AdapterView<?> arg0, View view, int position,
				long id) {
			// 首先得到当前用户点击的表情的信息
			Smile smile = smiles.get(position);
			// 得到当前CURSOR位置
			int cursor = ET_content.getSelectionStart();
			Field f;
			try {
				// 根据资源名字得到Resource和对应的Drawable
				f = (Field) R.drawable.class.getDeclaredField(smile.getName());
				int j = f.getInt(R.drawable.class);
				Drawable drawable = getResources().getDrawable(j);
				drawable.setBounds(0, 0, 35, 35);// 设置表情图片的显示大小

				// 显示在EditText中
				String str = "img";
				// 需要处理的文本,[smile]是需要被替代的文本
				SpannableString ss = new SpannableString(str);
				// 要让图片替代指定的文字就要用ImageSpan
				ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM);
				// 开始替换,注意第2和第3个参数表示从哪里开始替换到哪里替换结束
				ss.setSpan(span, 0, str.length(),
						Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

				ET_content.getText().insert(cursor, ss);
			} catch (Exception e) {
				e.printStackTrace();
			}

		}

	};

}


版权声明:本文为博主原创文章,未经博主允许不得转载。

QQ表情

标签:

原文地址:http://blog.csdn.net/u013210620/article/details/47342919

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!