Idea-深入github Android(二)

作者: AnalyzeSystem | 来源:发表于2017-04-21 12:40 被阅读58次

    Keywords: Android TextView

    github:https://github.com/rockerhieu/emojicon

    emojicon开源库是一个关于表情输入相关的,主要是Span运用,这里把代码分为两部分学习emoji、其他。先从emoji包开始,这里面主要是一些基础数据和Emojicon类

    Nature、Objects、People、Places、Symbols都是基础数据略过,Emojicon类提供了上面这些基础数据的转换方法,实现了序列化,那么,为什么要序列化?

    • 永久性保存对象,保存对象的字节序列到本地文件中;

    • 通过序列化对象在网络中传递对象;

    • 通过序列化在进程间传递对象。

    以上都不是重点,重点是在Emojicon类中发现了一段诡异的代码(对自己而言),枚举为什么要这样用呢,为什么要用注解呢?

    
    @IntDef({DynamicDrawableSpan.ALIGN_BASELINE, DynamicDrawableSpan.ALIGN_BOTTOM})
    public @interface Alignment {
     
        }
    
    @IntDef({TYPE_UNDEFINED, TYPE_PEOPLE, TYPE_NATURE, TYPE_OBJECTS, TYPE_PLACES, TYPE_SYMBOLS})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Type {
    
        }
    public static final int TYPE_UNDEFINED = 0;
    public static final int TYPE_PEOPLE = 1;
    public static final int TYPE_NATURE = 2;
    public static final int TYPE_OBJECTS = 3;
    public static final int TYPE_PLACES = 4;
    public static final int TYPE_SYMBOLS = 5;
    
    public static Emojicon[] getEmojicons(@Type int type) {
        switch (type) {
            case TYPE_PEOPLE:
                return People.DATA;
            case TYPE_NATURE:
                return Nature.DATA;
            case TYPE_OBJECTS:
                return Objects.DATA;
            case TYPE_PLACES:
                return Places.DATA;
            case TYPE_SYMBOLS:
                return Symbols.DATA;
            }
        throw new IllegalArgumentException("Invalid emojicon type: " + type);
            
        }
    

    带着疑问差了些许资料,从内存效率方面考虑,上面这种方式最优,这里不再重复叙述,提供相关资料链接,有兴趣者可以自行参阅

    http://developer.android.com/training/articles/memory.html#Overhead

    https://noobcoderblog.wordpress.com/2015/04/12/java-enum-and-android-intdefstringdef-annotation/

    这里再多提一点,注解在开发中有很大用处,android-support-annotations库用处很大,例如@Nullable 会对代码进行检查,如果传入值为null就会有警告提示


    Utils类主要是关于keyboardView 、屏幕的宽高获取,还有个生成viewId方法,这里面用到了一个相对陌生的类AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。

    AtomicInteger相关API

     //获取当前的值
     
     public final int get()
     
     //取当前的值,并设置新的值
     
      public final int getAndSet(int newValue)
     
     //获取当前的值,并自增
     
      public final int getAndIncrement() 
     
     //获取当前的值,并自减
     
     public final int getAndDecrement()
     
     //获取当前的值,并加上预期的值
     
     public final int getAndAdd(int delta)
    
    

    Emojicon库主要用的控件组合:Fragment+ViewPager+GridView,这个流程大致梳理一下:Tab被点击了执行ViewPager的Item切换,即切换Fragment,表情GridViewItem被点击了执行回调函数

     @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            if (mOnEmojiconClickedListener != null) {
                mOnEmojiconClickedListener.onEmojiconClicked((Emojicon) parent.getItemAtPosition(position));
            }
        }
    
    

    onEmojiconClicked主要是回调输入内容,我们通过EmojiconsFragment.input(mEditEmojicon, emojicon)方法完成Text赋值

    public static void input(EditText editText, Emojicon emojicon) {
            if (editText == null || emojicon == null) {
                return;
            }
    
            int start = editText.getSelectionStart();
            int end = editText.getSelectionEnd();
            if (start < 0) {
                editText.append(emojicon.getEmoji());
            } else {
                editText.getText().replace(Math.min(start, end), Math.max(start, end), emojicon.getEmoji(), 0, emojicon.getEmoji().length());
            }
        }
    
    

    以上流程主要是对于直接的EditText而言,而他的直接、间接子类TextView 、AppCompatMultiAutoCompleteTextView又略有不同,提供了自定义控件:EmojiconTextView、EmojiconMultiAutoCompleteTextView,他们主要是修改setText、setEmojiconSize方法实现,这两个方法都涉及到一个类EmojiconHandler,他们都调用了EmojiconHandler.addEmojis(),由于addEmojis函数过长就不贴代码了,这里面主要是Span的包装,最后设置到控件,所以得出一个结论:

    Emojicon库的核心就是自定义EmojiconSpan和自定义组合控件。

    EmojiconSpan继承DynamicDrawableSpan,那么问题来了,Span的直接子类那么多为什么非要DynamicDrawableSpan?我们来看看Span的一些子类的具体用途,看过之后真相即将明了

    • BackgroundColorSpan 背景色

    • ClickableSpan 文本可点击,有点击事件

    • ForegroundColorSpan 文本颜色(前景色)

    • MaskFilterSpan 修饰效果,如模糊(BlurMaskFilter)、浮雕(EmbossMaskFilter)

    • MetricAffectingSpan 父类,一般不用

    • RasterizerSpan 光栅效果

    • StrikethroughSpan 删除线(中划线)

    • SuggestionSpan 相当于占位符

    • UnderlineSpan 下划线

    • AbsoluteSizeSpan 绝对大小(文本字体)

    • DynamicDrawableSpan 设置图片,基于文本基线或底部对齐。

    • ImageSpan 图片

    • RelativeSizeSpan 相对大小(文本字体)

    • ReplacementSpan 父类,一般不用

    • ScaleXSpan 基于x轴缩放

    • StyleSpan 字体样式:粗体、斜体等

    • SubscriptSpan 下标(数学公式会用到)

    • SuperscriptSpan 上标(数学公式会用到)

    • TextAppearanceSpan 文本外貌(包括字体、大小、样式和颜色)

    • TypefaceSpan 文本字体

    • URLSpan 文本超链接


    以上内容为上午学习所得,分享出来,希望各位朋友喜欢。如果你觉得博主这篇博客还行,还请不吝"❤"一个,谢谢!

    交流群初创,欢迎各位加入

    相关文章

      网友评论

        本文标题:Idea-深入github Android(二)

        本文链接:https://www.haomeiwen.com/subject/vefdzttx.html