Сделать растровую плитку с возможностью рисования по x, но растянуть по y

У меня есть изображение, которое я использую в качестве фона для RelativeLayout. Изображение должно быть расположено горизонтально, чтобы получился узор.

Я могу заставить изображение располагаться горизонтально, используя этот код:

BitmapDrawable b3 = (BitmapDrawable)getResources().getDrawable(R.drawable.background);

b3.setTileModeX(Shader.TileMode.REPEAT);

v.findViewById(R.id.layout).setBackgroundDrawable(b3);

Проблема в том, что изображение также мозаично по вертикали. Вроде плитка в режиме "зажима" по вертикали, а в режиме "повтор" по горизонтали. Вот скриншот:

TileMode

Как видите, изображение чуть меньше занимаемого им места, а нижний край «зажат».

Как я могу настроить изображение так, чтобы оно растягивалось по вертикали, но располагалось горизонтально?


person howettl    schedule 16.09.2011    source источник


Ответы (4)


Этот метод вызывает создание нового растрового изображения, но похоже, что он достигает вашей цели.

        View view = findViewById(R.id.layout);
        BitmapDrawable bd = (BitmapDrawable) getResources().getDrawable(R.drawable.tile);
        int width = view.getWidth();
        int intrinsicHeight = bd.getIntrinsicHeight();
        Rect bounds = new Rect(0,0,width,intrinsicHeight);
        bd.setTileModeX(TileMode.REPEAT);
        bd.setBounds(bounds);
        Bitmap bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), bd.getBitmap().getConfig());
        Canvas canvas = new Canvas(bitmap);
        bd.draw(canvas);
        BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap);
        view.setBackground(bitmapDrawable);

Обратите внимание, что он работает только в том случае, если представление уже было размечено, поэтому метод onWindowFocusChanged является хорошим местом для этого кода.

person Nikolay Ivanov    schedule 12.10.2011
comment
Возможно ли это сделать только путем объединения рисунков XML? - person neworld; 18.09.2012
comment
Спасибо за элегантное решение, Николай. Нужно ли нам заботиться о растровых изображениях, или сборщик мусора справится с этим после уничтожения активности? - person Chitrang; 03.12.2018

Я чувствую, что это прямолинейно: (Этот код будет повторяться в Y и повторяться в x)

В вашем onWindowFoucsChanged вы звоните:

 public void onWindowFocusChanged(boolean hasFocus) {
        // TODO Auto-generated method stub
        super.onWindowFocusChanged(hasFocus);
        Drawable d = getRepeatingBG(this, R.drawable.image_that_you_want_to_repeat);
        body_view.setBackgroundDrawable(d);

    }

private Drawable getRepeatingBG(Activity activity, int center)
    {   

        DisplayMetrics dm = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled=true;

        Bitmap center_bmp = BitmapFactory.decodeResource(activity.getResources(), center, options);
        center_bmp.setDensity(Bitmap.DENSITY_NONE);
        center_bmp=Bitmap.createScaledBitmap(center_bmp, dm.widthPixels , center_bmp.getHeight(), true);

        BitmapDrawable center_drawable = new BitmapDrawable(activity.getResources(),center_bmp);
//change here setTileModeY to setTileModeX if you want to repear in X
        center_drawable.setTileModeY(Shader.TileMode.REPEAT);

        return center_drawable;
    }
person Ali Ashraf    schedule 26.06.2013

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

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

public class RepeatingXImageView extends View {

Bitmap bitmap;
Paint paint;

public RepeatingXImageView(Context context) {
    super(context);
}

public RepeatingXImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public RepeatingXImageView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    if(changed) {
        paint = new Paint();
        bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.seekbar_overlay);
        bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bottom - top, false);
    }
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if(bitmap == null) return;
    int left = 0;
    while(left < getWidth()) {
        canvas.drawBitmap(bitmap, left, 0, paint);
        left += bitmap.getWidth();
    }
}
}
person Graeme    schedule 21.02.2016

Сам имею такую ​​же проблему. Пытался использовать изображение 9patch, но кажется, что вы не можете использовать изображения 9patch вместе с плиткой, 9patch растягивает изображение независимо от того, что вы определяете в свойстве плитки. В конце я попрошу создателя изображения растянуть его по вертикали или сделаю это сам. Я хотел бы лучшее решение, если кто-нибудь найдет его.

person Yoel Gluschnaider    schedule 12.10.2011