自定義Drawable:實現文字生成圖片

騎著小貓碼程式碼丶發表於2017-10-23

一 、寫在正文前

  作為一個初來乍到的非資深android從業者,這是本人第一次在掘金裝逼,哦不,發表文章,因此有點小緊張以及難以掩飾的小激動[手動滑稽],若是有什麼寫的有問題的,沒錯,是本人技術問題,還望多多見諒。

二、概述

  二話不說反手就是一個超連結:下載地址
一言不合反手又是一個超連結:github地址
本文將介紹的是一款在googleplay上線的APP:TextImageMaker
主要功能:將使用者輸入的文字製作成圖片,讓博主在朋友圈發表動態時不在因沒有趁手的圖而苦惱。

三、分析

  前面已經提到app的初衷是滿足博主在朋友圈日常發圖的需求,因此功能上的核心就是如何將文字製作成圖片,當然為了滿足花式裝逼,這裡還要考慮的有,如何控制文字在圖片中的顯示位置,也就是align方式。那麼問題來了,有哪些方案可行呢?
我能想到的大致為兩個方案:
  1. 自定義View,通過重寫onDraw方法將獲取的文字畫出來
  2. 自定義一個Drawable將文字畫出來,再作為src設定到ImageView中
本文使用的就是第二種方式。

四、具體實現

到了這步其實問題已經很簡單了,相信大部分看官已經能自己實現了,無非就是重寫onDraw方法將傳進來的文字畫出來,嗯,的確如此,不過這裡可能會遇到換行符無法被畫出來的情況喲,好了,不瞎比比了,直接上程式碼:

    @Override
    public void draw(@NonNull Canvas canvas) {
        switch (mAlign) {
            case ALIGN_NORMAL:
                break;
            case ALIGN_OPPOSITE:
                mContent = StringUtil.reverseString(mContent);
                break;
            case ALIGN_CENTER:
                break;
        }
        // 文字回車換行
        StaticLayout layout = new StaticLayout(mContent, mPaint, canvas.getWidth(), mAlign, 1.0F, 0.0F,true);
        canvas.save();
        int y = (canvas.getHeight() - layout.getHeight()) / 2;
        canvas.translate(0, y);
        float textWidth =  mPaint.measureText(mContent);
        layout.draw(canvas);
        canvas.restore();
    }複製程式碼

在獲得了Drawable之後就可以直接在外面想要顯示的地方通過ImageView#setImageDrawable將圖片顯示出來了。
到這裡文字製作圖片算是大功告成了,剩下的就是文字對齊的控制了。在碼程式碼的時候博主當時就會心一笑so easy使用EditView的setGravity與getGravity不就輕輕鬆鬆對使用者的動作做出了響應嗎?然而現實很骨感。
當博主信誓旦旦的使用switch(EditView#getGravity)去判斷當前的對齊方式時,獲得的值一直是57...我的法克兒,這個問題,博主至今沒搞明白,也試圖通過原始碼去分析一波...還是有點沒摸清就是了[生無可戀臉],所以這裡我就不班門弄釜了(有知道的還請告知一二)

那麼現在能做的就是繞過這個問題,曲線救國
博主想到的是,通過LinearLayout.LayoutParam mParam記錄使用者的操作,然後通過判斷mParam的值,好了,廢話不多說,直接上程式碼:

    @Override
    public void updateAlignPolicy() {
        switch (mParams.gravity) {
            case Gravity.CENTER:
                mAlignPolicyIv.setImageResource(R.drawable.align_right);
                mParams.gravity = Gravity.RIGHT;
                mEdit.setGravity(Gravity.RIGHT);
                break;
            case Gravity.LEFT:
                mAlignPolicyIv.setImageResource(R.drawable.align_center);
                mParams.gravity = Gravity.CENTER;
                mEdit.setGravity(Gravity.CENTER);
                break;
            case Gravity.RIGHT:
                mAlignPolicyIv.setImageResource(R.drawable.align_left);
                mParams.gravity = Gravity.LEFT;
                mEdit.setGravity(Gravity.LEFT);
                break;
        }
    }複製程式碼
    @Override
    public int getAlignPolicy() {
        return mParams.gravity;
    }複製程式碼
    private Layout.Alignment verifyAlignment(int gravity) {
        Layout.Alignment alignment;
        switch (gravity) {
            case Gravity.CENTER:
                alignment = Layout.Alignment.ALIGN_CENTER;
                break;
            case Gravity.LEFT:
                alignment = Layout.Alignment.ALIGN_NORMAL;
                break;
            case Gravity.RIGHT:
                alignment = Layout.Alignment.ALIGN_OPPOSITE;
                break;
            default:
                alignment = Layout.Alignment.ALIGN_CENTER;
                break;
        }
        return alignment;
    }複製程式碼

專案比較簡單,因此適當加了些動畫效果加強使用者互動感,有興趣的可以去github上看看原始碼,至於圖片的本地儲存和分享就不做贅述了。

五、結語

嘿,man,沒錯,說的就是你,雞蛋別扔了。

相關文章