Использование закругленных углов
Существует хороший пост, сделанный популярным разработчиком Google Romain Guy, который показывает, как использовать закругленные углы, которые можно легко вырезать (называемый "StreamDrawable" в его код).
Сам образец очень хорошо работает на моей Galaxy S3 в портретном режиме, но у меня есть несколько проблем с ним:
-
если экран небольшой (например, на экранах qvga), показанные изображения обрезаются.
-
Если у меня есть бит-карта ввода, которая слишком мала, как я хочу ее показать, на выходном изображении будут размыты края. Даже на Galaxy S3, когда вы запускаете образец кода, и он на пейзаже, он выглядит ужасно:
![enter image description here]()
-
Я все еще не уверен в этом (так как я использую обходное решение для масштабирования изображения для использования примерного кода), но он считает, что даже это решение немного медленнее при использовании в listView. Может быть, для этого есть решение renderscript?
Не имеет значения, использую ли setImageDrawable или setBackgroundDrawable. Это должно быть что-то само по себе.
Я пытался играть с переменными и bitmapShader, но ничего не получилось. К сожалению, TileMode не имеет значения только для растягивания изображения, только с его черепицей.
В качестве обходного пути я могу создать новое масштабированное растровое изображение, но это просто обходной путь. Конечно, есть лучший способ, который также не будет использовать больше памяти, чем он должен.
Как исправить эти проблемы и использовать этот отличный код?
Ответы
Ответ 1
Я думаю, что решение, представленное на на этом веб-сайте, работает хорошо.
в отличие от других решений, он не вызывает утечки памяти, хотя он основан на решении Ромен Гай.
EDIT: теперь в библиотеке поддержки вы также можете использовать RoundedBitmapDrawable (используя RoundedBitmapDrawableFactory).
Ответ 2
У меня были некоторые проблемы с этим кодом, и я решил это.
Возможно, это тоже поможет:
1) в конструкторе хранят битмап в локальной переменной (например, private Bitmap bmp;)
2) переопределить еще два метода:
@Override
public int getIntrinsicWidth() {
return bmp.getWidth();
}
@Override
public int getIntrinsicHeight() {
return bmp.getHeight();
}
С уважением,
DaRolla
Ответ 3
Основная проблема заключается в том, что у BitmapShader TileMode
нет опции масштабирования. Вы заметили в источнике, что он установлен в Shader.TileMode.CLAMP
, и документы описывают это как:
реплицируйте цвет края, если шейдер рисует вне своих исходных границ
Чтобы обойти это, есть три решения:
- Ограничьте размер представления, в котором drawable используется для размера растрового изображения.
-
Ограничить область рисования; например, изменить:
int width = bounds.width() - mMargin;
int height = bounds.height() - mMargin;
mRect.set(mMargin, mMargin, width, height);
To:
int width = Math.min(mBitmap.getWidth(), bounds.width()) - mMargin;
int height = Math.min(mBitmap.getHeight(), bounds.height()) - mMargin;
mRect.set(mMargin, mMargin, width, height);
-
Масштабируйте растровое изображение до размера извлекаемого. Я переместил создание шейдера в onBoundsChange() и решил создать новое растровое изображение здесь:
bitmap = Bitmap.createScaledBitmap(mBitmap, width, height, true);
mBitmapShader = new BitmapShader(bitmap,
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Обратите внимание, что это потенциально медленная операция и будет работать в основном потоке. Возможно, вам захочется тщательно рассмотреть, как вы хотите реализовать его, прежде чем идти на это последнее решение.