最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android輸入框添加emoje表情圖標(biāo)的實(shí)現(xiàn)代碼

 更新時(shí)間:2016年11月10日 17:16:40   作者:jia-huan  
這篇文章主要為大家詳細(xì)介紹了Android輸入框添加emoje表情圖標(biāo)的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言

再次寫聊天的時(shí)候才發(fā)現(xiàn),代碼積累是一件非常重要的事情,就如這篇博客的意圖其實(shí)就是代碼積累的目的,其實(shí)沒(méi)什么難度,但是一件很瑣碎的事情真的也需要時(shí)間去完成和調(diào)試,所以,獲取你在寫一個(gè)功能的時(shí)候會(huì)覺(jué)得并沒(méi)有多難,但是如果可以最好把代碼整理/積累下來(lái)。

demo描述

demo的功能其實(shí)就是仿照微信的 聊天 emoje 選擇,采用了 viewpager+gridView 的方案,不過(guò)有空我會(huì)補(bǔ)上 recyclerView 的方案,目前還是先把功能實(shí)現(xiàn)了再說(shuō)。另外在 TextView 和 EditText 中添加 emoje ,可以看看這篇博客:Android中使用TextView及EditText來(lái)實(shí)現(xiàn)表情圖標(biāo)的顯示及插入功能 ,這篇博客中介紹了兩種方法:

方法一:使用Html.fromHtml解析, 方法二:使用Bitmap直接畫出來(lái),我采用了第二種方法,使用bitmap畫出來(lái)。

Read the fucking code

思路:既然是 viewpager + gridview 那么,先從大方向入手,完成 viewpager,再去完成 gridview。PS:代碼里面使用了 RxJava、lambda、ButterKnife、EventBus、Glide。

這里將整個(gè)底部布局寫成了一個(gè)組合的ViewGroup – ChatBottomBar,先從布局開(kāi)始。

ChatBottomBar 的 XML – chat_bottom.xml:

<?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="wrap_content"
  android:animateLayoutChanges="true"
  android:orientation="vertical">

  <include layout="@layout/chat_bottom_input"></include>
  <include layout="@layout/chat_bottom_function1"></include>

</LinearLayout>

以下分別是 輸入框的 xml 和 Emoji 的 xml:

chat_bottom_input:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">

  <RelativeLayout
    android:id="@+id/rl_input"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#f0f0f0">

    <ImageView
      android:id="@+id/showMore"
      android:layout_width="42dp"
      android:layout_height="60dp"
      android:paddingBottom="5dp"
      android:paddingLeft="9dp"
      android:paddingTop="9dp"
      android:src="@mipmap/ic_launcher" />


    <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="35dp"
      android:layout_centerVertical="true"
      android:layout_marginRight="15dp"
      android:layout_toRightOf="@+id/showMore"
      android:background="@drawable/shape_white_corner"
      android:gravity="center_vertical"
      android:orientation="horizontal">

      <ImageView
        android:layout_width="45dp"
        android:layout_height="40dp"
        android:paddingBottom="10dp"
        android:paddingLeft="10dp"
        android:paddingRight="5dp"
        android:paddingTop="10dp"
        android:src="@mipmap/ic_launcher" />

      <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginRight="10dp"
        android:background="@null"
        android:gravity="center_vertical"
        android:hint="說(shuō)點(diǎn)什么"
        android:maxLines="3"
        android:textColor="#999999"
        android:textColorHint="#dddddd"
        android:textSize="13sp" />

    </LinearLayout>


  </RelativeLayout>


</merge>

chat_bottom_function1:

<?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="wrap_content"
  android:background="#ffffff"
  android:orientation="vertical">

  <android.support.v4.view.ViewPager
    android:id="@+id/emojes"
    android:layout_width="match_parent"
    android:layout_height="110dp"></android.support.v4.view.ViewPager>

</LinearLayout>

首先是 viewpager 填充 gridView,從 PageAdapter 看起,看看需要哪些數(shù)據(jù):

package cjh.emojicondemo;

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.GridView;

import java.util.ArrayList;

/**
 * Created by cjh on 16-11-8.
 */

public class EmojiPageAdapter extends PagerAdapter {

  private ArrayList<GridView> mLists;

  public EmojiPageAdapter(Context context, ArrayList<GridView> array) {
    this.mLists = array;
  }

  @Override
  public int getCount() {
    return mLists.size();
  }

  @Override
  public boolean isViewFromObject(View arg0, Object arg1) {

    return arg0 == arg1;
  }

  @Override
  public Object instantiateItem(View arg0, int arg1) {
    ((ViewPager) arg0).addView(mLists.get(arg1));
    return mLists.get(arg1);
  }

  @Override
  public void destroyItem(View arg0, int arg1, Object arg2) {
    ((ViewPager) arg0).removeView((View) arg2);
  }
}

其實(shí)基本就是PagerAdapter的模板代碼,需要的僅僅只是 gridView,看下在ChatbottomBar中的代碼:

@BindView(R.id.emojes)
android.support.v4.view.ViewPager emojes;
....
//每一頁(yè)有24個(gè)表情,然后使用Math的ceil函數(shù),計(jì)算出我們需要的最小頁(yè)數(shù)
 private void initEmoje() {
    int pageCount = (int) Math.ceil(EmojiUtils.emojis.length / 24.0f);
    ArrayList<GridView> pageData = new ArrayList<>();
    for (int i = 0; i < pageCount; i++) {
      GridView gv = getGridView(i);
      pageData.add(gv);
    }
    emojes.setAdapter(new EmojiPageAdapter(context, pageData));
  }  

大結(jié)構(gòu)基本就是這樣了,接著就是小細(xì)節(jié)了,比如gridView的創(chuàng)建和展示:

 @NonNull
  private GridView getGridView(int i) {
    GridView gv = new GridView(context);
    gv.setVerticalScrollBarEnabled(false);
    gv.setAdapter(new EmojiGridAdapter(context, i));
    gv.setGravity(Gravity.CENTER);
    gv.setClickable(true);
    gv.setFocusable(true);
    gv.setNumColumns(8);
    return gv;
  }

adapter:

package cjh.emojicondemo;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

import org.greenrobot.eventbus.EventBus;

/**
 * Created by cjh on 16-11-8.
 */

public class EmojiGridAdapter extends BaseAdapter {

  private Context context;
  private int page;

  public EmojiGridAdapter(Context context, int page) {
    this.context = context;
    this.page = page;
  }

  @Override
  public int getCount() {
    return 24;
  }

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

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

  @Override
  public View getView(int i, View view, ViewGroup viewGroup) {

    ViewHolder holder = null;
    if (view == null) {
      view = LayoutInflater.from(context).inflate(R.layout.chat_emoji, null);
      holder = new ViewHolder();
      holder.image = (ImageView) view.findViewById(R.id.image);
      view.setTag(holder);
    }

    holder = (ViewHolder) view.getTag();
    int position = page * 23 + i;
    if (position < EmojiUtils.emojis.length)
      ImageLoader.load(context, EmojiUtils.icons[position], holder.image);
    else
      holder.image.setVisibility(View.GONE);
    holder.image.setOnClickListener(view1 -> EventBus.getDefault().post(new EmojiEvent(EmojiUtils.emojis[page * 23 + i])));

    return view;
  }

  static class ViewHolder {
    public ImageView image;
  }
}

在這里,點(diǎn)擊時(shí)間的傳遞我使用的是EventBus。

大結(jié)構(gòu)基本已經(jīng)OK了,接著就要看比較核心的部分,Emoji 的處理,在接收到Event事件時(shí),調(diào)用了chatBottomBar.appandEmoje(emojiEvent.s)

@Subscribe
  public void onEmojiEvent(EmojiEvent emojiEvent) {
    chatBottomBar.appandEmoje(emojiEvent.s);
  }

那么來(lái)看看ChatBottomBar的代碼:

public void appandEmoje(String s) {
    rx.Observable
        .just(s)
        .subscribeOn(Schedulers.io())
        .map(s1 -> {
          SpannableString emojeText = EmojiUtils.getEmojiText(editText.getText().toString() + s1);
          return emojeText;
        })
        .unsubscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(s2 -> {
          editText.setText("");
          editText.append(s2);
        });
  }

上面代碼使用了RXJAVA,可以看到真正的核心是在
EmojiUtils.getEmojiText(editText.getText().toString() + s1);
return emojeText;這行代碼里面。

那么就來(lái)看看 EmojiUtils 的代碼吧:

package cjh.emojicondemo;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ImageSpan;
import android.text.style.RelativeSizeSpan;
import android.util.SparseArray;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.Inflater;

/**
 * Created by cjh on 16-11-7.
 */

public class EmojiUtils {

  private static HashMap<Pattern, Integer> emoMap = new HashMap<>();

  public static final String DELETE_KEY = "em_delete_delete_expression";

  public static String[] emojis = new String[]{
      "[微笑]",
      "[撇嘴]",
      "[色]",
      "[發(fā)呆]",
      "[得意]",
      "[流淚]",
      "[害羞]",
      "[閉嘴]",
      "[睡]",
      "[大哭]",
      "[尷尬]",
      "[發(fā)怒]",
      "[調(diào)皮]",
      "[呲牙]",
      "[驚訝]",
      "[難過(guò)]",
      "[酷]",
      "[冷汗]",
      "[抓狂]",
      "[吐]",
      "[偷笑]",
      "[愉快]",
      "[白眼]",
      "[傲慢]",
      "[饑餓]",
      "[困]",
      "[驚恐]",
      "[流汗]",
      "[憨笑]",
      "[悠閑]",
      "[奮斗]",
      "[咒罵]",
      "[疑問(wèn)]",
      "[噓]",
      "[暈]",
      "[瘋了]",
      "[衰]",
      "[骷髏]",
      "[敲打]",
      "[再見(jiàn)]",
      "[擦汗]",
      "[摳鼻]",
      "[鼓掌]",
      "[糗大了]",
      "[壞笑]",
      "[左哼哼]",
      "[右哼哼]",
      "[哈欠]",
      "[鄙視]",
      "[委屈]",
      "[快哭了]",
      "[陰險(xiǎn)]",
      "[親親]",
      "[嚇]",
      "[可憐]",
      "[菜刀]",
      "[西瓜]",
      "[啤酒]",
      "[籃球]",
      "[乒乓]",
      "[咖啡]",
      "[飯]",
      "[豬頭]",
      "[玫瑰]",
      "[凋謝]",
      "[嘴唇]",
      "[愛(ài)心]",
      "[心碎]",
      "[蛋糕]",
      "[閃電]",
      "[炸彈]",
      "[刀]",
      "[足球]",
      "[瓢蟲(chóng)]",
      "[便便]",
      "[月亮]",
      "[太陽(yáng)]",
      "[禮物]",
      "[擁抱]",
      "[強(qiáng)]",
      "[弱]",
      "[握手]",
      "[勝利]",
      "[抱拳]",
      "[勾引]",
      "[拳頭]",
      "[差勁]",
      "[愛(ài)你]",
      "[NO]",
      "[OK]"
  };

  public static int[] icons = new int[]{
      R.drawable.ee_1,
      R.drawable.ee_2,
      R.drawable.ee_3,
      R.drawable.ee_4,
      R.drawable.ee_5,
      R.drawable.ee_6,
      R.drawable.ee_7,
      R.drawable.ee_8,
      R.drawable.ee_9,
      R.drawable.ee_10,
      R.drawable.ee_11,
      R.drawable.ee_12,
      R.drawable.ee_13,
      R.drawable.ee_14,
      R.drawable.ee_15,
      R.drawable.ee_16,
      R.drawable.ee_17,
      R.drawable.ee_18,
      R.drawable.ee_19,
      R.drawable.ee_20,
      R.drawable.ee_21,
      R.drawable.ee_22,
      R.drawable.ee_23,
      R.drawable.ee_24,
      R.drawable.ee_25,
      R.drawable.ee_26,
      R.drawable.ee_27,
      R.drawable.ee_28,
      R.drawable.ee_29,
      R.drawable.ee_30,
      R.drawable.ee_31,
      R.drawable.ee_32,
      R.drawable.ee_33,
      R.drawable.ee_34,
      R.drawable.ee_35,
      R.drawable.ee_36,
      R.drawable.ee_37,
      R.drawable.ee_38,
      R.drawable.ee_39,
      R.drawable.ee_40,
      R.drawable.ee_41,
      R.drawable.ee_42,
      R.drawable.ee_43,
      R.drawable.ee_44,
      R.drawable.ee_45,
      R.drawable.ee_46,
      R.drawable.ee_47,
      R.drawable.ee_48,
      R.drawable.ee_49,
      R.drawable.ee_50,
      R.drawable.ee_51,
      R.drawable.ee_52,
      R.drawable.ee_53,
      R.drawable.ee_54,
      R.drawable.ee_55,
      R.drawable.ee_56,
      R.drawable.ee_57,
      R.drawable.ee_58,
      R.drawable.ee_59,
      R.drawable.ee_60,
      R.drawable.ee_61,
      R.drawable.ee_62,
      R.drawable.ee_63,
      R.drawable.ee_64,
      R.drawable.ee_65,
      R.drawable.ee_66,
      R.drawable.ee_67,
      R.drawable.ee_68,
      R.drawable.ee_69,
      R.drawable.ee_70,
      R.drawable.ee_71,
      R.drawable.ee_72,
      R.drawable.ee_73,
      R.drawable.ee_74,
      R.drawable.ee_75,
      R.drawable.ee_76,
      R.drawable.ee_77,
      R.drawable.ee_78,
      R.drawable.ee_79,
      R.drawable.ee_80,
      R.drawable.ee_81,
      R.drawable.ee_82,
      R.drawable.ee_83,
      R.drawable.ee_84,
      R.drawable.ee_85,
      R.drawable.ee_86,
      R.drawable.ee_87,
      R.drawable.ee_88,
      R.drawable.ee_89,
      R.drawable.ee_90,
  };

  static {
    for (int i = 0; i < emojis.length; i++) {
      emoMap.put(Pattern.compile(Pattern.quote(emojis[i])), icons[i]);
    }
  }

  public static SpannableString getEmojiText(String s) {
    SpannableString spannable = new SpannableString(s);
    for (Map.Entry<Pattern, Integer> entry : emoMap.entrySet()) {
      Matcher matcher = entry.getKey().matcher(spannable);
      while (matcher.find()) {
        for (ImageSpan span : spannable.getSpans(matcher.start(),
            matcher.end(), ImageSpan.class))
          if (spannable.getSpanStart(span) >= matcher.start()
              && spannable.getSpanEnd(span) <= matcher.end())
            spannable.removeSpan(span);
          else
            break;
        Drawable drawable = MainActivity.context.getResources().getDrawable(entry.getValue());
        drawable.setBounds(0, 0, 60, 60);
        ImageSpan imageSpan = new ImageSpan(drawable);
        spannable.setSpan(imageSpan,
            matcher.start(), matcher.end(),
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
      }
    }
    return spannable;
  }
}

這里為了方便知道插入表情的位置,我將emoji對(duì)應(yīng)的中文轉(zhuǎn)化成了Pattern對(duì)象,在getEmojiText里面做了遍歷查詢比對(duì),這也就是為什么我會(huì)使用RX來(lái)異步操作。

基本就到這里了,回過(guò)來(lái)看寫的內(nèi)容,自己都懶得吐槽,不過(guò),好在只要有具體的demo,能讀代碼,有沒(méi)有講解其實(shí)都還好,也不用怕自己之后看不懂了。

源碼下載:https://github.com/cjhandroid/EmojiInputDemo

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android制作漂亮自適布局鍵盤的方法

    Android制作漂亮自適布局鍵盤的方法

    最近做了個(gè)自定義鍵盤,但面對(duì)不同分辨率的機(jī)型其中數(shù)字鍵盤不能根據(jù)界面大小自已鋪滿,但又不能每種機(jī)型都做一套吧,所以要做成自適應(yīng),那這里主講思路,感興趣的朋友一起學(xué)習(xí)吧
    2015-12-12
  • 淺談Android開(kāi)發(fā)系列網(wǎng)絡(luò)篇之Retrofit

    淺談Android開(kāi)發(fā)系列網(wǎng)絡(luò)篇之Retrofit

    這篇文章主要介紹了淺談Android開(kāi)發(fā)系列網(wǎng)絡(luò)篇之Retrofit,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2016-12-12
  • Flutter利用Canvas繪制精美表盤效果詳解

    Flutter利用Canvas繪制精美表盤效果詳解

    這篇文章主要介紹了如何利用Flutter中的Canvas繪制一個(gè)精美的表盤效果,文中的實(shí)現(xiàn)步驟講解詳細(xì),快跟隨小編一起動(dòng)手嘗試一下
    2022-03-03
  • clipse項(xiàng)目遷移到android studio的方法(圖文最新版)

    clipse項(xiàng)目遷移到android studio的方法(圖文最新版)

    這篇文章主要介紹了clipse項(xiàng)目遷移到android studio(圖文最新版),需要的朋友可以參考下
    2015-10-10
  • Android中三種onClick的實(shí)現(xiàn)方式與對(duì)比

    Android中三種onClick的實(shí)現(xiàn)方式與對(duì)比

    這篇文章主要為大家詳細(xì)介紹了Android中三種onClick的實(shí)現(xiàn)方式以及詳細(xì)對(duì)比,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-04-04
  • Android中HttpURLConnection類使用介紹

    Android中HttpURLConnection類使用介紹

    早些時(shí)候其實(shí)我們都習(xí)慣性使用HttpClient,但是后來(lái)Android6.0之后不再支持HttpClient,需要添加Apache的jar才行,所以,就有很多開(kāi)發(fā)者放棄使用HttpClient了,HttpURLConnection畢竟是標(biāo)準(zhǔn)Java接口(java.net) ,適配性還是很強(qiáng)的
    2022-12-12
  • Android Coil對(duì)比Glide深入分析探究

    Android Coil對(duì)比Glide深入分析探究

    這篇文章主要介紹了Android Coil對(duì)比Glide,Coil是Android上的一個(gè)全新的圖片加載框架,它的全名叫做coroutine image loader,即協(xié)程圖片加載庫(kù)
    2023-02-02
  • Android應(yīng)用App更新實(shí)例詳解

    Android應(yīng)用App更新實(shí)例詳解

    現(xiàn)在一般的Android軟件都是需要不斷更新的,當(dāng)你打開(kāi)某個(gè)app的時(shí)候,如果有新的版本,它會(huì)提示你有新版本需要更新。該項(xiàng)目實(shí)現(xiàn)的就是這個(gè)功能。下面跟著小編一起來(lái)看下吧
    2017-03-03
  • Android中View跟隨手指移動(dòng)效果

    Android中View跟隨手指移動(dòng)效果

    這篇文章主要介紹了Android中View跟隨手指移動(dòng)效果,代碼簡(jiǎn)單易懂,非常不錯(cuò),需要的朋友參考下
    2017-01-01
  • Flutter中漸變色的使用案例分享

    Flutter中漸變色的使用案例分享

    在日常的開(kāi)發(fā)中,UI為了讓界面更加吸引人往往會(huì)在界面上用到大量的漸變色,本文將通過(guò)幾個(gè)案例更好的去了解Flutter中漸變色的使用,需要的可以參考一下
    2023-06-06

最新評(píng)論

昂仁县| 星座| 本溪市| 庐江县| 霸州市| 百色市| 长春市| 开封县| 井研县| 长丰县| 云南省| 阿克陶县| 弋阳县| 施秉县| 外汇| 黄平县| 北京市| 宣恩县| 增城市| 荥阳市| 济南市| 彭阳县| 大关县| 屯昌县| 横峰县| 石嘴山市| 祥云县| 高陵县| 汶川县| 潮安县| 于都县| 新建县| 灵寿县| 尉犁县| 武陟县| 嫩江县| 福海县| 安阳县| 肃南| 常熟市| 邻水|