Chinaunix首页 | 论坛 | 博客
  • 博客访问: 232393
  • 博文数量: 54
  • 博客积分: 2656
  • 博客等级: 少校
  • 技术积分: 1020
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-19 21:06
文章分类

全部博文(54)

文章存档

2016年(3)

2014年(8)

2013年(4)

2012年(2)

2011年(29)

2010年(8)

我的朋友

分类: Java

2011-05-04 15:23:59

最近做会话的功能,需要用到类似于QQ表情的东西,在网上搜索一下,但是基本都是一篇文章写的不错,其他的都是转的,有些更是连转都没有。现在将自己的代码实例发出来,由于是测试,代码写的比较乱,还有很多多余的东西没有去掉,就凑合着看吧:
实现QQ表情我知道的基本有2中方法:
1:研究android短信部分的源码,发现了短信部分其实就已经实现了,具体类是SmileyParser.java,在xml文件里面定义了2个数组default_smiley_texts和default_smiley_names,将default_smiley_texts里面的内容拼成一个正则表达式,类似于(:-)|:-(|...)这样的,然后通过addSmileySpans这个函数进行匹配
builder.setSpan(new ImageSpan(mContext, resId),
                            matcher.start(), matcher.end(),

                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
调用方法很简单  直接调用addSmileySpans方法即可,我用的例子基本都是从android源码里面拿出来的代码,包括图片和xml也是。
2:第二种方法就是通过html的方式来实现,基本如下:Html.fromHtml("噢~好吧,:-):-):-):-)abc@126.com"+"");这个方法也是网上介绍的,现在将我写的源码及其运行效果图贴上来:

package com.shang.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.shang.test.Face.GridAdapter;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Typeface;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.Html.ImageGetter;
import android.text.style.ForegroundColorSpan;
import android.text.style.LeadingMarginSpan;
import android.text.style.LineHeightSpan;
import android.text.style.StyleSpan;
import android.text.style.TextAppearanceSpan;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.QuickContactBadge;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView.OnEditorActionListener;

/**
 *
 * @author qintao
 *
 */

public class TestBaseAdapter extends Activity implements OnEditorActionListener {

    private ListView mListView;
    private View mMms_content;
    private static int i = 0;
    private EditText mTextEditor;
    private TextView mTextCounter;
    Pattern mHighlight;
    private Context contexts;
    private BaseListAdapter baseListAdapter = null;
    private int[] list;
    private GridView gridview ;
    private GridAdapter adapter;
    private EditText mEditText;
    private Button send;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.baseadapterlist);
        this.contexts = this;
        list = Smileys.sIconIds;
        gridview = (GridView) findViewById(R.id.faces);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
        // mTextEditor = (EditText)findViewById(R.id.embedded_text_editor);

        // mTextEditor.requestFocus();

        // mTextEditor.setOnEditorActionListener(this);

        // mTextEditor.addTextChangedListener(mTextEditorWatcher);

        mListView = (ListView) findViewById(R.id.baselist);
        Button face = (Button)findViewById(R.id.face);
        face.setOnClickListener(new OnClickListener() {            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                gridview.setVisibility(View.VISIBLE);
            }
        });
        
        SmileyParser.init(getBaseContext());
        ((ListView) mListView).setDivider(null);
        if(baseListAdapter == null) baseListAdapter = new BaseListAdapter(this);
        mListView.setAdapter(baseListAdapter);
        
        
        
        mEditText = (EditText) findViewById(R.id.edit_text);
        adapter = new GridAdapter(contexts);
        adapter.setList(list);
        gridview.setAdapter(adapter);
        gridview.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
             ImageGetter imageGetter = new ImageGetter() {
                       public Drawable getDrawable(String source) {
                       int id = Integer.parseInt(source);
                       Drawable d = getResources().getDrawable(id);
                       d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
                       return d;
                      }
                   };
            
                  CharSequence cs = Html.fromHtml("",imageGetter, null);
                  mEditText.getText().append(cs);
                  //faceContent =FilterHtml(Html.toHtml(mEditText.getText()));

            }
        });
        
       send = (Button)findViewById(R.id.send);
       send.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            //Toast.makeText(TestBaseAdapter.this, Html.toHtml(mEditText.getText()), Toast.LENGTH_SHORT).show();

            Message msg = new Message();
            msg.what=0;
            mHandler.sendMessage(msg);
        }
       });
        
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub

                try {
                    Thread.sleep(20000);
                    Message msg = new Message();
                    msg.what=0;
                    mHandler.sendMessage(msg);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block

                    e.printStackTrace();
                }
            }
        }).start();
    }


    public Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == 0){
                
                List<HashMap<String, Object>> a = getData();
                if(!"".equals(mEditText.getText())){
                    HashMap<String, Object> bHashMap = new HashMap<String, Object>();
                    bHashMap.put("image", R.drawable.s);
                    bHashMap.put("title", "");
                    bHashMap.put("info", FilterHtml(Html.toHtml(mEditText.getText())));
                    bHashMap.put("times", "cccccccccc");
                    a.add(bHashMap);
                }
                a.get(2).put("info", "aaaaaaaaaaaaa");
                a.get(3).put("info","bbbbbbbbbbbbbbb");
                //BaseListAdapter adapter = new BaseListAdapter(contexts);

                baseListAdapter.reSetList(a);
                baseListAdapter.notifyDataSetChanged();
                System.out.println("ccccccccccccccc");
            }else{
                System.out.println("bbbb");
            }
        }
    };
    
    private void ensureCorrectButtonHeight() {
        int currentTextLines = mTextEditor.getLineCount();
        if (currentTextLines <= 2) {
            mTextCounter.setVisibility(View.GONE);
        } else if (currentTextLines > 2 && mTextCounter.getVisibility() == View.GONE) {
            // Making the counter invisible ensures that it is used to correctly

            // calculate the position of the send button even if we choose not

            // to

            // display the text.

            mTextCounter.setVisibility(View.INVISIBLE);
        }
    }

    private final TextWatcher mTextEditorWatcher = new TextWatcher() {
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // This is a workaround for bug 1609057. Since onUserInteraction()

            // is

            // not called when the user touches the soft keyboard, we pretend it

            // was

            // called when textfields changes. This should be removed when the

            // bug

            // is fixed.

            onUserInteraction();

            // mWorkingMessage.setText(s);


            // updateSendButtonState();


            // updateCounter(s, start, before, count);


            ensureCorrectButtonHeight();
        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub


        }
    };

    private List<HashMap<String, Object>> getData() {
        List<HashMap<String, Object>> maps = new ArrayList<HashMap<String, Object>>();
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("image", R.drawable.s);
        map.put("title", "");
        map.put("info", "噢~好吧,:-):-):-):-)agc@126.com"+""+"");
        map.put("times", "10:30");
        maps.add(map);

        map = new HashMap<String, Object>();
        map.put("image", R.drawable.d);
        map.put("title", "");
        map.put("info", "o_O 13888888888 记住"+"");
        map.put("times", "半天前");
        maps.add(map);

        map = new HashMap<String, Object>();
        map.put("image", R.drawable.s);
        map.put("title", "");
        map.put("info", "O:-)哎呀~别问了!");
        map.put("times", "1天前");
        maps.add(map);

        map = new HashMap<String, Object>();
        map.put("image", R.drawable.d);
        map.put("title", "");
        map.put("info", " 推荐阿");
        map.put("times", "1天前");
        maps.add(map);
        return maps;
    }

    private class BaseListAdapter extends BaseAdapter implements OnClickListener {

        private Context mContext;
        private LayoutInflater inflater;
        private List<HashMap<String, Object>> mList;

        public BaseListAdapter(Context mContext) {
            this.mContext = mContext;
            mList = getData();
            inflater = LayoutInflater.from(mContext);
        }

        public void reSetList(List<HashMap<String, Object>> list){
            Log.v("mlist", list.get(2).get("info")+"********************");
            mList = list;
        }
        
        @Override
        public int getCount() {
            return mList.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder = null;

            // QuickContactBadge mLeft_Avatar = (QuickContactBadge)

            // findViewById(R.id.left_avatar);

            // QuickContactBadge mRight_Avatar = (QuickContactBadge)

            // findViewById(R.id.right_avatar);


            // mMms_content.setBackgroundResource(R.drawable.droid_widget_focused);

            // mMms_content.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.droid_widget_focused));

            QuickContactBadge mLeft_Avatar = null;
            QuickContactBadge mRight_Avatar = null;
            if (convertView == null) {
                viewHolder = new ViewHolder();
                convertView = inflater.inflate(R.layout.testbaseadapter, null);
                viewHolder.img = (ImageView) convertView.findViewById(R.id.img);
                viewHolder.title = (TextView) convertView.findViewById(R.id.title);
                viewHolder.info = (TextView) convertView.findViewById(R.id.info);
                viewHolder.times = (TextView) convertView.findViewById(R.id.times);
                // viewHolder.button = (Button)

                // convertView.findViewById(R.id.basebutton);

                mMms_content = (View) convertView.findViewById(R.id.mms_content);
                mMms_content.setBackgroundResource(R.drawable.droid_widget_focused);
                mLeft_Avatar = (QuickContactBadge) convertView.findViewById(R.id.left_avatar);
                mRight_Avatar = (QuickContactBadge) convertView.findViewById(R.id.right_avatar);

                mLeft_Avatar.setImageDrawable(getResources().getDrawable(R.drawable.icon));
                mRight_Avatar.setImageDrawable(getResources().getDrawable(R.drawable.icon));
                convertView.setTag(viewHolder);
                if (i % 2 == 0) {
                    mLeft_Avatar.setVisibility(View.GONE);
                    mRight_Avatar.setVisibility(View.VISIBLE);
                    // viewHolder.times.setVisibility(View.GONE);

                    viewHolder.times.setText((CharSequence) mList.get(position).get("times"));
                    mMms_content.setBackgroundResource(R.drawable.droid_widget_focused);

                } else {
                    mLeft_Avatar.setVisibility(View.VISIBLE);
                    mRight_Avatar.setVisibility(View.GONE);
                    viewHolder.times.setVisibility(View.GONE);
                    // viewHolder.times.setText((CharSequence)

                    // getData().get(position).get("times"));

                    mMms_content.setBackgroundResource(R.drawable.droid_widget_focused_left);
                    Log.v("++++++++++++", "aaaaaaaa");
                }

            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            Log.v("i----", "" + i);
            i++;
            System.out.println("viewHolder = " + viewHolder);
            CharSequence formattedMessage;
            formattedMessage = formatMessage((String) mList.get(position).get("info"),mHighlight);
            viewHolder.img.setBackgroundResource((Integer) mList.get(position).get("image"));
            viewHolder.title.setText((CharSequence) mList.get(position).get("title"));
            //viewHolder.info.setText((CharSequence) getData().get(position).get("info"));

            //viewHolder.info.setText(formattedMessage);

            // viewHolder.button.setOnClickListener(this);


         ImageGetter imageGetter = new ImageGetter() {
                   public Drawable getDrawable(String source) {
                   int id = Integer.parseInt(source);
                   Drawable d = getResources().getDrawable(id);
                   d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
                   return d;
                  }
               };
        
              CharSequence cs = Html.fromHtml(mList.get(position).get("info").toString(),imageGetter, null);
              //mEditText.getText().append(cs);

              viewHolder.info.setText(cs);
            
            return convertView;
        }

        class ViewHolder {
            ImageView img;
            TextView title;
            TextView info;
            TextView times;
            // Button button;

        }

        @Override
        public void onClick(View v) {
            int id = v.getId();
            switch (id) {
            case R.id.basebutton:
                showInfo();
                break;
            }
        }

        private void showInfo() {
            new AlertDialog.Builder(TestBaseAdapter.this).setTitle("my listview").setMessage("introduce....").setPositiveButton("OK",
                    new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // TODO Auto-generated method stub


                        }
                    }).show();
        }
    }

    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (event != null) {
            // if shift key is down, then we want to insert the '\n' char in the

            // TextView;

            // otherwise, the default action is to send the message.

            // dengll 20110228 modify for PROD02224767 begin

            /*
             * if (!event.isShiftPressed()) {
             */

            if (!event.isShiftPressed() && event.getKeyCode() != KeyEvent.KEYCODE_ENTER) {
                // dengll 20110228 modify for PROD02224767 end

                // if (isPreparedForSending()) {

                // confirmSendMessageIfNeeded();

                // }

                return true;
            }
            return false;
        }

        // if (isPreparedForSending()) {

        // confirmSendMessageIfNeeded();

        // }

        return true;
    }
    
    private LeadingMarginSpan mLeadingMarginSpan;

    private LineHeightSpan mSpan = new LineHeightSpan() {
        public void chooseHeight(CharSequence text, int start,
                int end, int spanstartv, int v, FontMetricsInt fm) {
            fm.ascent -= 10;
        }
    };


    ForegroundColorSpan mColorSpan = null;
    private CharSequence formatMessage(String body,Pattern highlight) {
        //CharSequence template = getResources().getText(R.string.name_colon);

        SpannableStringBuilder buf = new SpannableStringBuilder();

//        boolean hasSubject = !TextUtils.isEmpty(subject);

//        if (hasSubject) {

//            buf.append(getResources().getString(R.string.inline_subject, subject));

//        }

        String contentType = null;
        if (!TextUtils.isEmpty(body)) {
            // Converts html to spannable if ContentType is "text/html".

            if (contentType != null ) {
                buf.append("\n");
                buf.append(Html.fromHtml(body));
            } else {
//                if (hasSubject) {

//                    buf.append(" - ");

//                }

                SmileyParser parser = SmileyParser.getInstance();
                buf.append(parser.addSmileySpans(body));
            }
        }
        // If we're in the process of sending a message (i.e. pending), then we

        // show a "Sending..."

        // string in place of the timestamp.


        // We always show two lines because the optional icon bottoms are

        // aligned with the

        // bottom of the text field, assuming there are two lines for the

        // message and the sent time.

        int startOffset = buf.length();
        StringBuilder sentTo = new StringBuilder();
        try {
//            ContactList recipients = ((ComposeMessageActivity) mContext).mConversation.getRecipients();

//            if (recipients.size() != 1 && !msgItem.isMms()) {

//                boolean fromcontact = false;

//                Iterator it = recipients.iterator();

//

//                while (it.hasNext()) {

//                    Contact recipient = it.next();

//                    if (recipient.getNumber().equals(msgItem.getmSentTo().toString())) {

//                        sentTo.append("<" + recipient.getNameAndNumber() + ">");

//                        fromcontact = true;

//                        break;

//                    }

//

//                }

//                if (!fromcontact) {

//                    sentTo.append("<" + msgItem.getmSentTo() + ">");

//                }

//            }

        } catch (Exception e) {
        }
        if (sentTo.length() > 0) {
            buf.append("\n");
            buf.append(sentTo);
            buf.setSpan(null, startOffset, buf.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            buf.setSpan(mSpan, startOffset + 1, buf.length(), 0);

            // Make the timestamp text not as dark

            buf.setSpan(mColorSpan, startOffset, buf.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }

        if (highlight != null) {
            Matcher m = highlight.matcher(buf.toString());
            while (m.find()) {
                buf.setSpan(new StyleSpan(Typeface.BOLD), m.start(), m.end(), 0);
            }
        }
        buf.setSpan(mLeadingMarginSpan, 0, buf.length(), 0);
        return buf;
    }
    
     public class GridAdapter extends BaseAdapter {

         private class GridHolder {
             ImageView appImage;
         }

         private Context context;

         private LayoutInflater mInflater;

            private int[] list;

         public GridAdapter(Context c) {
             super();
             this.context = c;
         }

         public void setList(int[] list) {
             this.list = list;
             mInflater = (LayoutInflater) context
                     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

         }

         public int getCount() {
             // TODO Auto-generated method stub

             return list.length;
         }

         @Override
         public Object getItem(int index) {

             return list[index];
         }

         @Override
         public long getItemId(int index) {
             return index;
         }

         @Override
         public View getView(int index, View convertView, ViewGroup parent) {
             GridHolder holder;
             if (convertView == null) {
                 convertView = mInflater.inflate(R.layout.face_item, null);
                 holder = new GridHolder();
                 holder.appImage = (ImageView)convertView.findViewById(R.id.itemImage);
                 convertView.setTag(holder);
                 holder.appImage.setImageDrawable(context.getResources()
                         .getDrawable(list[index]));
             }else{
                  holder = (GridHolder) convertView.getTag();
             }
        
             return convertView;
         }

     }
    
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            // 按下键盘上返回按钮

            if (keyCode == KeyEvent.KEYCODE_BACK) {
                gridview.setVisibility(View.GONE);
                return true;
            } else {

                return super.onKeyDown(keyCode, event);

            }
        }
        
        public static String UnicodeToGBK2(String s){
     String[] k = s.split(";") ;
     String rs = "" ;
     for(int i=0;i<k.length;i++) {
     int strIndex=k[i].indexOf("&#");
     String newstr = k[i];
     if(strIndex>-1) {
     String kstr = "";
     if(strIndex>0) {
     kstr = newstr.substring(0,strIndex);
     rs+=kstr;
     newstr = newstr.substring(strIndex);
     }
     int m = Integer.parseInt(newstr.replace("&#",""));
     char c = (char)m ;
     rs+= c ;
     } else {
     rs+=k;
     }
     }
     return rs;
     }
        
        public static String FilterHtml(String str){
     str = str .replaceAll("<(?!br|img)[^>]+>", "").trim();
     return UnicodeToGBK2(str);
     }


}

 

 

如有问题,请联系,谢谢!

阅读(7599) | 评论(10) | 转发(0) |
给主人留下些什么吧!~~

yulanfeiyang2013-01-19 16:48:34

哥,源码给一份吧!谢谢,谢谢!  506546254@qq.com

yulanfeiyang2013-01-19 16:47:33

哥,源码给一份吧!谢谢,谢谢!

天天相守902012-06-18 19:49:14

给发分源码吧!有急用!

天天相守902012-06-14 20:16:19

大侠,可不可以给我发一份源码?912161136@qq.com。万分感谢!

a_4509172422012-03-24 20:08:57

你好,能发一份源码吗,1132315438@qq.com,谢谢