继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Android表情键盘库EmoticonsBoard

慕的地10843
关注TA
已关注
手记 1081
粉丝 200
获赞 962

效果

操作演示

实际看一下效果最直观


webp

overlook.gif


这个效果和XhsEmoticonsKeyboard的没什么区别

表情数据动态刷新

webp

change_data.gif


这里演示了四种刷新方式

  • 增加表情

  • 删除表情

  • 增加表情包

  • 删除表情包
    这里需要说明一下,什么是表情包?
    表情包在代码中对应的类是EmoticonPack。一个EmoticonPack就代表了一个表情集合。比如上图中屏幕最下方的黄色微笑小图标就代表了一个表情包。

整体结构

webp

screenshot的副本.jpg


EmoticonsBoard就是整个键盘库的核心,和表情展示相关的主要有三个部分:EmoticonsFuncView,EmoticonsIndicator和EmoticonsToolBar。

  • EmoticonsFuncView:展示每一页表情,继承自ViewPager

  • EmoticonsIndicator:表情页指示器

  • EmoticonsToolBar:展示表情包图标


webp

core.jpg


这里我们只看一下表情相关的几个类,如果对其它的类有兴趣,可以下载代码自行研究。


刚才我们说了,展示表情的EmoticonsFuncView继承自ViewPager,既然是ViewPager,那么就应该有Adapter,它就是EmoticonPacksAdapter。
EmoticonPacksAdapter保存的是一个EmoticonPack列表。EmoticonPack刚才已经介绍过了,是表情包。EmoticonPack中有一个Emoticon列表。Emoticon就代表一个表情。EmoticonPack中还有一个属性:iconUri,它就是这个表情包图片的uri。每个EmoticonPack的图标最终会设置到EmoticonsToolBar里。而Emoticon列表就通过EmoticonPacksAdapter以页面的方式展示。
EmoticonsToolBar用来展示表情包图标,同时和可以在首尾增加两个View,比如增加和删除两个按钮。

类图中还有一个重要的接口:pageFactory,它的作用是生成ViewPager中每一页的View。通过它就能实现不同的页面展示。比如每页的行列数,点击表情时的效果,图标的大小等。

使用方法

Gradle

allprojects {
    repositories {
        jcenter()
    }
}

and:

dependencies { 
    compile 'im.ll:emoticonsboard:1.0.0'
}

XML

<github.ll.emotionboard.EmoticonsBoard xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <ListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout></github.ll.emotionboard.EmoticonsBoard>

EmoticonsBoard继承自RelativeLayout,所以它里面可以包含子View,但是它的子View只能有一个,多于一个的话会报错。
上面的例子就是包含了一个LinearLayout。

设置 Adapter

Java code:

EmoticonsBoard ekBar;List<EmoticonPack> packs = new ArrayList<EmoticonPack>;// init packs...EmoticonPacksAdapter adapter = new EmoticonPacksAdapter(packs);
ekBar.setAdapter(adapter);

这里很简单,重点是如何构建EmoticonPack

构建

kotlin code

fun getEmoji(context: Context): EmoticonPack<Emoticon> {
        val emojiArray = mutableListOf<Emoticon>()

       
        DefEmoticons.sEmojiArray.take(30).mapTo(emojiArray) {
            val emoticon = Emoticon()
            emoticon.code = it.emoji
            emoticon.uri = context.getResourceUri(it.icon)            return@mapTo emoticon
        }

        val pack = EmoticonPack<Emoticon>()
        pack.emoticons = emojiArray

        pack.iconUri = context.getResourceUri(R.mipmap.icon_emoji)

        val factory = DeleteBtnPageFactory<Emoticon>()
        factory.deleteIconUri = context.getResourceUri(R.mipmap.icon_del)
        factory.line = 3
        factory.row = 7

        pack.pageFactory = factory        return pack
    }

EmoticonPack有三个属性:emoticons就是表情列表。iconUri是这个表情包的图标,上面提到过。pageFactory是View工厂,上面也讲过。
这段代码首先是构造了一个Emoticon列表,Emoticon只有两个属性:code和uri。code是表情代码,uri是图片uri。
然后设置了EmoticonPack的PageFactory,在这用到的是DeleteBtnPageFactory,DeleteBtnPageFactory的功能就是能展示一个删除按钮。
EmoticonPack的创建很简单。这里有一点要注意一下,Emoticon我只提供了uri一个属性统一表示表情图片的地址。不管这个图片是资源,文件,还是网络图片,用一个uri就够了。这里的uri可以用android定义的也可以自己定义,只要能唯一确定图片的位置就行了。这里我写了一个工具类来获取各种uri:
kotlin code

enum class UriType {
    ASSETS,
    DRAWABLE,
    FILE,
    OTHER;
}

object UriUtils {
    fun getUriType(uri: String): UriType {        if (uri.startsWith("android.resource:")) {            return UriType.DRAWABLE
        }        if (uri.startsWith("file:///android_asset/")) {            return UriType.ASSETS
        }        if (uri.startsWith("file://") && !uri.contains("android_asset")) {            return UriType.FILE
        }        return UriType.OTHER
    }

    fun getResourceID(context: Context, uri: String) = uri.substring("android.resource://${context.packageName}/".length)

    fun getFilePath(uri: String): String? {        return if (getUriType(uri) != UriType.FILE) {            null
        } else {
            uri.substring("file://".length)
        }
    }

    fun getAssetsPath(uri: String): String? {        return if (getUriType(uri) != UriType.ASSETS) {            null
        } else {
            uri.substring("file:///android_asset/".length)

现在主流的图片加载库,比如Glide,都可以通过uri加载图片。如果你觉得还是用资源id方便,那么你也可以自己扩展Emoticon。
那么表情图标具体是在哪个地方加载呢?没错,就是在PageFactory里。

刷新数据

kotlin code

// modify mEmojiPackmEmojiPack.isDataChanged = trueadapter?.notifyDataSetChanged()

非常简单,mEmojiPack数据改变后首先标记isDataChanged为true,然后调用notifyDataSetChanged方法就可以了。

这里注意,isDataChanged必须要设置为true



作者:Rocky1982
链接:https://www.jianshu.com/p/fd0a54b3162c


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP