Android圖片底部對齊(scaleType底部對齊)

背景

今天在討論UI優(yōu)化的時候,首頁有個控件支持動態(tài)切換背景圖,但是該控件的高度并不固定贺拣,如果直接使用圖片背景的話會照成圖片失真鸦难,如下圖(子控件顯示條數(shù)不固定)

在這里插入圖片描述

這時候ui妹子突然說圖片由下往上展示,上面超出部分就不顯示了 iOS妹子和小程序小伙異口同聲說“沒問題”片林,但是又不能說Android搞不了端盆,只能笑著說沒問題(MMP),然后就開始研究起方案费封。

嘗試方案一(失敾烂睢)(scaleType)

第一個嘗試方案肯定是scaleType了,記得有個fitEnd的屬性平時用的少弓摘,然后發(fā)現(xiàn)并不符合預期焚鹊,全部效果如下

在這里插入圖片描述

嘗試方案二(失敗)-自定義Glide的Transform

思路:自定義Transform韧献,等Glide下載完圖片的時候回調(diào)transform接口末患,通過修改Bitmap的RectF區(qū)域來進行顯示部分圖片,然后scaleType用fitXY,代碼如下

@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
    return Crop(pool, toTransform);
}

private Bitmap Crop(BitmapPool pool, Bitmap toTransform) {
    if (toTransform == null) {
        return null;
    }
    int bpWidth = toTransform.getWidth();
    int bpHeight = toTransform.getHeight();
    float bpRatio = (bpWidth * 1f) / bpHeight;
    Bitmap result = pool.get(toTransform.getWidth(), toTransform.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setShader(new BitmapShader(toTransform, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
    RectF rectF;
    if (targetRatio > bpRatio) {
        float top = (bpWidth * height * 1f / width);
        rectF = new RectF(0f, top, bpWidth, bpHeight);
    } else {
        rectF = new RectF(0f, 0f, bpWidth, bpHeight);
    }
    canvas.drawRect(rectF, paint);
    return result;
}

但通過實際發(fā)現(xiàn)锤窑,設置成scaleType:fitXY 璧针,這樣實際操作還會存在圖片失真的情況,且裁剪的區(qū)域是已經(jīng)顯示在imageView上面的圖片渊啰,還要考慮縮放等問題探橱,到這里久放棄了申屹。

嘗試方案三(有效)-自定義View修改Matrix

思路:因為圖片的寬度會比View的寬度寬或者窄,所以要考慮縮放隧膏,然后把縮放后的圖片平移到控件底部独柑,這時候想到的是修改Canvas的Matrix。


在這里插入圖片描述

相關代碼

xml(scaleType設置為matrix私植,不要問為什么忌栅,問就是比較好處理)
    <com.study.MatrixBottomImageView
        android:layout_width="200dp"
        android:layout_height="100dp"
        android:background="@android:color/holo_red_dark"
        android:scaleType="matrix"
        android:src="@drawable/icon_dog_bg" />
java代碼也比較簡單
/**
 * 底部對齊控件
 */
public class MatrixBottomImageView extends androidx.appcompat.widget.AppCompatImageView {
    /**
     * 控件寬高
     */
    private int width, height;
    /**
     * 控件矩陣
     */
    private Matrix matrix;

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

    public MatrixBottomImageView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MatrixBottomImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (width != w || height != h) {//寬高改變時需刷新值
            width = w;
            height = h;
        }
    }

    private void init() {
        matrix = new Matrix();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Drawable drawable = getDrawable();
        if (drawable != null) {
            int intrinsicWidth = drawable.getIntrinsicWidth();//獲取圖片寬度
            int intrinsicHeight = drawable.getIntrinsicHeight();//獲取圖片高度
            matrix.reset();
            float sx = width * 1f / intrinsicWidth;//求出縮放比例
            matrix.postScale(sx, sx, 0, 0);//以左上角為原點,進行縮放
            intrinsicHeight = (int) (intrinsicHeight * sx);//求出縮放后的圖片高度
            int dy = -intrinsicHeight + height;//實際的偏移量(往上移需要為負數(shù))
            matrix.postTranslate(0, dy);//進行平移
            canvas.setMatrix(matrix);//設置畫布矩陣
        }
        super.onDraw(canvas);
    }
}

實際效果如下:


最終效果

總結:

問題的難度不高曲稼,但可以鍛煉解決問題思路索绪,還是要多點動手才行,今天也是搬磚的一天 要元氣滿滿哦贫悄。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瑞驱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子窄坦,更是在濱河造成了極大的恐慌唤反,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸭津,死亡現(xiàn)場離奇詭異彤侍,居然都是意外死亡,警方通過查閱死者的電腦和手機逆趋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門盏阶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人闻书,你說我怎么就攤上這事名斟。” “怎么了魄眉?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵砰盐,是天一觀的道長。 經(jīng)常有香客問我坑律,道長岩梳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任脾歇,我火速辦了婚禮蒋腮,結果婚禮上,老公的妹妹穿的比我還像新娘藕各。我一直安慰自己池摧,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布激况。 她就那樣靜靜地躺著作彤,像睡著了一般膘魄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上竭讳,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天创葡,我揣著相機與錄音,去河邊找鬼绢慢。 笑死灿渴,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的胰舆。 我是一名探鬼主播骚露,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼缚窿!你這毒婦竟也來了棘幸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤倦零,失蹤者是張志新(化名)和其女友劉穎误续,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扫茅,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蹋嵌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了诞帐。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片欣尼。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖停蕉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情钙态,我是刑警寧澤慧起,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站册倒,受9級特大地震影響蚓挤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜驻子,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一灿意、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧崇呵,春花似錦缤剧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汗销。三九已至,卻和暖如春抵窒,著一層夾襖步出監(jiān)牢的瞬間弛针,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工李皇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留削茁,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓掉房,卻偏偏與公主長得像茧跋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子圃阳,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容