1. 程式人生 > >自定義帶圖片的TextView,(setcompounddrawables 不顯示)

自定義帶圖片的TextView,(setcompounddrawables 不顯示)

今天在做一個介面的時候,碰到了一個需求是要在一個文字旁邊放一個小圖示, 在這裡插入圖片描述 本來想用一個TextView和一個ImageView橫向佈局然後作為一個整體來做,但是我發現有很多地方有著這樣的小按鈕,(圖片+文字的形式),所以本著怎麼懶怎麼寫的原則,就想找有沒有更簡潔一點的辦法,比如能不能再TextView中新增一個圖示呢,隨便輸入一個drawable以後,自動出現了很多如下屬性: 在這裡插入圖片描述 一看這應該是新增圖片的,再隨便新增一個,發現真的把圖片加上來了.但是我們又發現,新增圖片的屬性就那麼四個drawableTop,drawableBottom,drawableLeft,drawableRight 意思分別是將圖片新增到文字的上,下,左,右側,這也挺方便的,而且也發現還能隨著父元素的大小來設定圖片的大小.但是發現裡面有一個按鈕是TextView中沒有文字,只想加一個圖示,就會發現用這幾個方法以後,圖示會在邊框裡面上下左右對齊,沒辦法居中.這還不是重點, 重點是我沒辦法設定圖片的尺寸,可能我可以去設定父元素的padding,但是這時候會將文字一起壓縮了. 這時候我又去苦苦尋找看看有沒有辦法設定這個圖示自己的padding,發現裡面有一個在這裡插入圖片描述

這個屬性,當時以為是用來設定圖示的padding的,最後試了一下,發現這個值只會影響圖片和文字之間的距離,另外三邊的padding則不會設定. 所以最後苦尋無果後,只能繼續百度看看怎麼設定TextView的圖片,網上一大片都是說自定義TextView,那好吧,自定義一個TextView. 先將最後完成的程式碼交上,然後說一下在定義這個View中間發生的問題: 1.這是自定義view中需要自定義的屬性檔案:

<!--圖片按鈕-->
    <declare-styleable name="RichText">
        <attr name="drawableSrc" format="reference" />
        <attr name="drawableWidth" format="dimension" />
        <attr name="drawableHeight" format="dimension" />
        <attr name="drawableLocation">
            <enum name="left" value="1" />
            <enum name="top" value="2" />
            <enum name="right" value="3" />
            <enum name="bottom" value="4" />
        </attr>
    </declare-styleable>

2.繼承自TextView

@SuppressLint("AppCompatCustomView")
public class RichText extends TextView {
    public static final int LEFT = 1, TOP = 2, RIGHT = 3, BOTTOM = 4;
    private int mHeight, mWidth;
    private Drawable mDrawable;
    private int mLocation;


    public RichText(Context context) {
        this(context, null);
    }

    public RichText(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RichText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RichText, defStyleAttr, 0);
        mDrawable = array.getDrawable(R.styleable.RichText_drawableSrc);
        mWidth = array.getDimensionPixelSize(R.styleable.RichText_drawableWidth, 0);
        mHeight = array.getDimensionPixelSize(R.styleable.RichText_drawableHeight, 0);
        mLocation = array.getIndex(R.styleable.RichText_drawableLocation);
        array.recycle();
        drawDrawable();
    }


    public void drawDrawable() {
        if (mDrawable != null) {
            Bitmap bitmap = ((BitmapDrawable) mDrawable).getBitmap();
            Drawable drawable;
            if (mWidth != 0 && mHeight != 0) {
                drawable = new BitmapDrawable(getResources(), ImageUtils.getBitmap(bitmap, mWidth, mHeight));
            } else {
                drawable = new BitmapDrawable(getResources(),
                        Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(),
                                bitmap.getHeight(), true));
            }
            //在程式碼中設定元件的drawable的時候如果單純的使用setCompoundDrawables是不會有效果的,
            // 因為沒有指定drawable的大小,即Bound,具體程式碼如下:
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
            switch (mLocation) {
                case LEFT:
                    Log.i("TAG", "新增在左邊");
                    setCompoundDrawables(drawable, null, null, null);
                    break;
                case TOP:
                    Log.i("TAG", "新增在頂部");
                    setCompoundDrawables(null, drawable, null, null);
                    break;
                case RIGHT:
                    Log.i("TAG", "新增在右側");
                    setCompoundDrawables(null, null, drawable, null);
                    break;
                case BOTTOM:
                    Log.i("TAG", "新增在底部");
                    setCompoundDrawables(null, null, null, drawable);
                    break;
            }
        }
    }
    
}

3.佈局檔案:

<com.example.loomc.myapplication.weight.RichText
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/radio_button"
                    android:gravity="center"
                    android:paddingBottom="2dp"
                    android:paddingLeft="10dp"
                    android:paddingRight="10dp"
                    android:paddingTop="2dp"
                    android:textSize="@dimen/font_size1"
                    app:drawableHeight="20dp"
                    app:drawableLocation="left"
                    app:drawableSrc="@mipmap/icon_male"
                    app:drawableWidth="20dp" />

上面三個就是自定義這個圖片TextView用到的 下面就來說一下中間遇到的問題.之前在沒有解決問題之前,我定義的View的圖片是怎麼都沒有顯示出來的.

問題1.當時自定義的TextView的類名叫做ImageTextView 但是,屬性檔案中declare-styleable name=“RichText” name屬性設定為RichText跟類名不一樣,最後出現的情況就是在佈局檔案去獲取屬性的時候,IDE就是沒辦法自動彈出我定義的這個類View的屬性名,而且又在名稱空間這裡卡了好久,因為他老是提示我用view: 這個標籤,但是我在前面定義的view好像自定義屬性都是用app:這個標籤來呼叫的,最後各種百度,就是沒找到,我也不知道是啥原因,強迫症的我就是想把這個問題解決掉,我就去看之前定義的view跟我這個定義的view有什麼區別,最後不懈努力加上靈光一閃,把這個declare-styleable name=“RichText” 中的name引數改成自定義View的類名一樣的名字,發現果然就可以讓IDE自動的顯示出來,就是類似下圖中的提示方式,之前是怎麼都沒有這幾個屬性的.而且打日誌的時候mWidth,mDrawable等值都是獲取不到的,所以這裡肯定是獲取自定義屬性的時候出了問題,沒有獲取到. 在這裡插入圖片描述 解決完這個問題後,圖片還是沒有顯示.繼續

問題2.自定義View中,我用的也是很傳統的三個建構函式內部呼叫,的方式,然後view的初始化或者顯示的任務都放在最後一個建構函式中. 貌似這裡也沒有啥問題,然後我用Log.i()打日誌的方式,檢視這時候mWidth這些值都是有的,mDrawable也獲取到了,說明圖片是設定進來了,但是為啥顯示不了.弄了一個下午,快絕望了, 在這裡插入圖片描述 在這裡插入圖片描述 程式到這裡的時候,drawable是獲取到了而且尺寸也都有,我就想呀,這圖片都有,再怎麼,你也要在介面顯示一點點出來呀,可是毛都沒有,後面就只剩一個方法了, 在這裡插入圖片描述 可這個方法是Android自己的,出問題也不可能是那裡面出問題了吧,所以我一直就沒去調查那個方法,一直在看我前面是不是出了什麼問題,最後到了這裡沒辦法,只好來看看這個方法是幹嘛的,其實這個方法前面我也瞭解了,就是在周圍新增圖片的功能,方法四個引數分別是左上右下.後來就百度了一下 “setcompounddrawables 不顯示” 發現網上很多這個問題,我一下驚喜了,心裡有預感就是這裡出問題了,說不定是我哪裡沒有配置,所以才會導致這個方法沒起作用(當然肯定不是這個方法有問題了,這還是有自知之明的).找了幾個終於找到關鍵點了,也是我在程式碼中註釋好的那句話:“在程式碼中設定元件的drawable的時候如果單純的使用setCompoundDrawables是不會有效果的” 所以在呼叫setcompounddrawables ()這個方法之前加了一句drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); 這個方法就是對drawable進行設定寬高,心裡想這下百分之九十應該是可以看到我的圖標出來了,開啟檢視一看,果然出來了,所以就來這裡把這個問題記錄了一下