Idea-深入github Android(二)

来源:互联网 发布:java 获取pdf的页数 编辑:程序博客网 时间:2024/05/18 01:38

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 文本超链接


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

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


0 0