Изображение фона по размеру экрана без использования девяти патчей - PullRequest
1 голос
/ 30 ноября 2011

У меня есть фоновое изображение, подобное первому изображению квадрата: https://market.android.com/details?id=com.squareup.cardcase&hl=fr

Мне нужно отобразить этот фон изображения на экране (fill_parent) для экрана любого размера.

Как я могу это сделать? Я не могу использовать девять патчей из-за геометрической проблемы с изображением. Нужно ли делать изображение во всех размерах?

Спасибо!

1 Ответ

2 голосов
/ 30 ноября 2011

В коде (а не с помощью XML-макета) вы можете создать растровое изображение с правильным соотношением сторон (высота устройства x ширина), обрезав изображение после масштабирования растрового изображения, чтобы оно было достаточно большим для обрезки. Вы должны убедиться, что изображение можно масштабировать вверх / вниз (желательно вниз) без потери резкости. Вы также должны быть уверены, что важная информация не будет потеряна, если изображение обрезается с другими пропорциями.

Как только у вас будет полученное растровое изображение, поместите его на дисплей в качестве содержимого ImageView.

Я считаю, что лучше выбирать размеры логотипов отдельно от нижележащих изображений и слоев изображений друг над другом, чтобы текст оставался четким.

Я создал подкласс класса ImageView для инкапсуляции изменения размера и обрезки. Единственный метод значения - это переопределенный метод onMeasure ():

/**
 * Override the onMeasure method to resize the Bitmap as needed
 */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);


    Drawable currentDrawable = this.getDrawable();
    BitmapDrawable theBitmapDrawable;
    if (BitmapDrawable.class.isInstance(currentDrawable)){
        // We have a bitmap to work with
        theBitmapDrawable = (BitmapDrawable) currentDrawable;
        Bitmap currentBitmap = theBitmapDrawable.getBitmap();
        Bitmap resizedBitmap = null;

        if (currentBitmap != null) {
            int currentHeight = currentBitmap.getHeight();
            int currentWidth = currentBitmap.getWidth();
            int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
            int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
            if ((currentHeight != parentHeight) || (currentWidth != parentWidth)) {
                // The bitmap needs to be resized, and/or cropped to fit
                if ((currentHeight < parentHeight) || (currentWidth < parentWidth)) {
                    // Need to make the bitmap larger
                    float heightFactor = (float) parentHeight / (float) currentHeight;
                    float widthFactor = (float) parentWidth / (float) currentWidth;
                    float scaleFactor;
                    // Choose the largest factor
                    if (Float.compare(heightFactor, widthFactor) < 0) {
                        scaleFactor = widthFactor;
                    } else {
                        scaleFactor = heightFactor;
                    }
                    int dstWidth = (int) (currentWidth * scaleFactor);
                    int dstHeight = (int) (currentHeight * scaleFactor);
                    if (dstWidth < parentWidth) dstWidth = parentWidth;     // Deal with off by one rounding errors
                    if (dstHeight < parentHeight) dstHeight = parentHeight; // Deal with off by one rounding errors
                    resizedBitmap = Bitmap.createScaledBitmap(currentBitmap, dstWidth, dstHeight, true);
                    currentBitmap.recycle();
                } else if ((currentHeight > parentHeight) && (currentWidth > parentWidth)){
                    // Need to make the splash screen bitmap smaller
                    float heightFactor = (float) parentHeight / (float) currentHeight;
                    float widthFactor = (float) parentWidth / (float) currentWidth;
                    float scaleFactor;
                    // Choose the largest factor
                    if (Float.compare(heightFactor, widthFactor) < 0) {
                        scaleFactor = widthFactor;
                    } else {
                        scaleFactor = heightFactor;
                    }
                    int dstWidth = (int) (currentWidth * scaleFactor);
                    int dstHeight = (int) (currentHeight * scaleFactor);
                    if (dstWidth < parentWidth) dstWidth = parentWidth;     // Deal with off by one rounding errors
                    if (dstHeight < parentHeight) dstHeight = parentHeight; // Deal with off by one rounding errors
                    resizedBitmap = Bitmap.createScaledBitmap(currentBitmap, dstWidth, dstHeight, true);
                    currentBitmap.recycle();
                } else {
                    // No need to resize the image - we'll just need to crop it
                    resizedBitmap = currentBitmap;
                }

                // Now crop the image so that it fits the aspect ratio of the screen
                currentHeight = resizedBitmap.getHeight();
                currentWidth = resizedBitmap.getWidth();
                Bitmap newBitmap;
                if ((currentHeight != parentHeight) || (currentWidth != parentWidth)) {
                    // Crop the image to fit exactly
                    int startX = (currentWidth - parentWidth)/2;
                    if (startX < 0) startX = 0; // Hmm!
                    int startY = (currentHeight - parentHeight)/2;
                    if (startY < 0) startY = 0; // Hmm! again
                    newBitmap = Bitmap.createBitmap(resizedBitmap, startX, startY, parentWidth, parentHeight);
                    resizedBitmap.recycle();
                } else {
                    // The resized image is the exact right size
                    newBitmap = resizedBitmap;
                }

                this.setImageBitmap(newBitmap);
            }
        }
    }

}
...