Idea-深入github Android(二)

Keywords: Android TextView

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

emojicon開源庫是一個關於表情輸入相關的,主要是Span運用,這裏把代碼分爲兩部分學習emoji、其他。先從emoji包開始,這裏面主要是一些基礎數據和Emojicon類

1240

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就會有警告提示

1240

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


以上內容爲上午學習所得,分享出來,希望各位朋友喜歡。如果你覺得博主這篇博客還行,還請不吝"❤"一個,謝謝!

交流羣初創,歡迎各位加入

1240
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章