[英]Android round a Layouts background image, only top or bottom corners
我希望能夠擁有一個具有多個RelativeLayouts的屏幕,並且我希望頂部布局和底部布局具有圓角,因此頂部布局將具有圓角的前2個角,並且底部布局將具有圓形的底部2個角。
我的問題是,我在網上找到的所有例子都使用shape.xml來創建一個圓角並給它一個漸變,這還不夠好,因為我想給relativeLayout一個背景圖像,並將該圖像舍入,我似乎無法做到這兩點。
任何幫助將非常感激!!
編輯 - 賞金開始
好吧,在這個問題上,我多年來一直在撞牆。 我目前正在使用名為UITableView的第三方工具,主要是測試一些東西。
https://github.com/thiagolocatelli/android-uitableview
它設置tableView類似於iPhone表格的方式,我希望能夠為每一行提供背景圖像,並使頂部和底部行彎曲。 在這個UITableView類中,在commit下,調用此代碼
public void commit()
{
mIndexController = 0;
if (mItemList.size() > 1)
{
// when the list has more than one item
for (IListItem obj : mItemList)
{
View tempItemView;
if (mIndexController == 0)
{
//tempItemView = new RoundedView(context_i, this);
tempItemView = mInflater.inflate(R.layout.list_item_top,null);
}
else if (mIndexController == mItemList.size() - 1)
{
tempItemView = mInflater.inflate(R.layout.list_item_bottom,null);
}
else
{
tempItemView = mInflater.inflate(R.layout.list_item_middle,null);
}
setupItem(tempItemView, obj, mIndexController);
tempItemView.setClickable(obj.isClickable());
mListContainer.addView(tempItemView);
mIndexController++;
}
}
else if (mItemList.size() == 1)
{
// when the list has only one item
View tempItemView = mInflater.inflate(R.layout.list_item_single,
null);
IListItem obj = mItemList.get(0);
setupItem(tempItemView, obj, mIndexController);
tempItemView.setClickable(obj.isClickable());
mListContainer.addView(tempItemView);
}
}
他有一個頂部中間和底部行的布局樣式,頂部和底部圓形使用XML,但問題是,我想給每一行一個圖像。 所以我添加了這段代碼
tempItemView.setBackgroundResource(R.drawable.background);
但問題是,這會消除頂部和底部行的彎曲角落,因為角落使用XML並使用白色漸變而不是圖像。 我需要能夠給布局充氣,然后彎曲頂角和底角。 我看了很多裁剪角落的例子,甚至嘗試了不同的第三方工具,但還沒有找到一個例子,它顯示了將背景圖像應用到容器,然后將角落四舍五入。
有沒有人對如何做到這一點有任何想法?
編輯:
在iPhone上,你可以做這樣的事情
UIColor *color = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"image.png"]];
將圖像轉換為顏色的位置。 Android有相同的功能嗎?
編輯:
感謝ACheese的回答,我修改了他的代碼並將其分為3種方法,一種用於頂部圓角,一種用於完全圓角,一種用於底部圓角,並想出了這個
public void setBackgroundRounded(int resID, int w, int h, View v)
{
DisplayMetrics metrics = getResources().getDisplayMetrics();
double dH = (metrics.heightPixels / 100) * 1.5;
int iHeight = (int)dH;
Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmp);
Shader shader = new BitmapShader(BitmapFactory.decodeResource(
getResources(), resID), Shader.TileMode.MIRROR,
Shader.TileMode.MIRROR);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
paint.setAntiAlias(true);
paint.setShader(shader);
RectF rec = new RectF(0, 0, w, h);
c.drawRoundRect(rec, iHeight, iHeight, paint);
v.setBackgroundDrawable(new BitmapDrawable(getResources(), bmp));
}
public void setTopRounded(int resID, int w, int h, View v)
{
Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmp);
Shader shader = new BitmapShader(BitmapFactory.decodeResource(
getResources(), resID), Shader.TileMode.MIRROR,
Shader.TileMode.MIRROR);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
paint.setAntiAlias(true);
paint.setShader(shader);
RectF rec = new RectF(0, 0, w, h - 20);
c.drawRect(new RectF(0, 20, w, h), paint);
c.drawRoundRect(rec, 20, 20, paint);
v.setBackgroundDrawable(new BitmapDrawable(getResources(), bmp));
}
public void setBottomRounded(int id, int w, int h, View v)
{
DisplayMetrics metrics = getResources().getDisplayMetrics();
double dH = (metrics.heightPixels / 100) * 1.5;
int iHeight = (int)dH;
Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmp);
Shader shader = new BitmapShader(BitmapFactory.decodeResource(
getResources(), id), Shader.TileMode.MIRROR,
Shader.TileMode.MIRROR);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
paint.setAntiAlias(true);
paint.setShader(shader);
RectF rec = new RectF(0, 0, w, h);
c.drawRoundRect(rec, iHeight, iHeight, paint);
c.drawRect(new RectF(0, 0, w, h-iHeight), paint);
v.setBackgroundDrawable(new BitmapDrawable(getResources(), bmp));
}
我使用指標來設置視圖的四舍五入,因此它可以根據不同的屏幕尺寸進行縮放。
希望能幫助其他人解決這個問題!!
所以你嘗試過這樣的事情:
例如,這是您的主要布局:
RelativeLayout myMainRelLAyout = (RelativeLayout) findViewById(R.id.my_layout);
並做MyMainRelLAyout.setBackgroundResource(R.drawable.mydrawable);
其中mydrawable.xml如下所示:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="@android:color/white" />
<corners
android:bottomLeftRadius="0dip"
android:bottomRightRadius="0dip"
android:topLeftRadius="5dip"
android:topRightRadius="5dip" />
</shape>
根據下面的評論,我可以建議你這個鏈接: Romain Guy - 帶圓角的圖像 ,在那里你可以找到答案,我認為這將有助於你如何做到這一點。
這是另一個使用ImageView的有用庫,但您可以更改它並將其用於任何類型的View,鏈接: RoundedImageView 。
檢查我的解決方案是否適用於您的案例:通過擴展RelativeLayout來定義您自己的布局。 您只需添加以下代碼
@SuppressWarnings("deprecation")
public void setBackground(int id){
Bitmap bmp = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmp);
Shader shader = new BitmapShader(BitmapFactory.decodeResource(getResources(), id), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
paint.setAntiAlias(true);
paint.setShader(shader);
RectF rec = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight());
// you may need this for only top round corner
// RectF rec = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight()-20);
// c.drawRect(new RectF(0, 20, getMeasuredWidth(), getMeasuredHeight()), paint);
c.drawRoundRect(rec, 20, 20, paint);
this.setBackgroundDrawable(new BitmapDrawable(getResources(), bmp));
}
從您的活動中調用此方法。 您無法從onCreate()調用,因為getMeasuredWidth()和getMeasuredHeight()尚未就緒。 通過設置自己的drawable id覆蓋並調用onWindowFocusChanged(boolean hasFocused)。 這將重復將您的圖像設置為帶圓角的背景。
好的,我終於找到了解決方案。 要使圓角變圓,請使用此方法
public Bitmap getTopRoundedCorner(Bitmap bitmap, DisplayMetrics metrics) {
//Using this so it scales with different screen sizes
double dH = (metrics.heightPixels / 100.0) * 3;
int iHeight = (int) dH;
//Subtract this from bitmap height
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight()-iHeight, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
//Again used so it scales with diff screen sizes
//Can play around with this value, depending on how rounded you wanted the corner
dH = (metrics.heightPixels / 100.0) * 3.5;
iHeight = (int) dH;
final RectF rectF = new RectF(rect);
final float roundPx = iHeight;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
如果您只想圓角,請使用此方法
public Bitmap getBottomRoundedCorner(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
//Again play around with this to get the rounded value you require
double dH = (metrics.heightPixels / 100.0) * 2.5;
int iHeight = (int) dH;
final float roundPx = iHeight;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
//Draw second rectangle over the top of the first one
//So it hides the top rounded corners
iHeight = (int) dH;
final int color2 = 0xff424242;
final Paint paint2 = new Paint();
Canvas canvas2 = new Canvas(output);
final Rect testRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()-iHeight);
final RectF testF = new RectF(testRect);
paint2.setAntiAlias(true);
canvas2.drawARGB(0, 0, 0, 0);
paint2.setColor(color2);
canvas2.drawRoundRect(testF, roundPx, roundPx, paint2);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas2.drawBitmap(bitmap, testRect, testRect, paint2);
return output;
}
此外,如果您傳入不同大小的不同圖像,我建議您先使用此方法
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
在應用圓角方法之前將圖像縮放到相同的大小,否則如果傳入具有不同寬度/高度的不同圖像,則圓角將根據傳入的圖像看起來完全不同。如果縮放圖像首先,這意味着無論你傳入什么樣的圖像,都應該看起來相當一致。
然后你可以做這樣的事情
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.tablebackground);
bmp = getResizedBitmap(bmp, 200, 300);
bmp = getTopRoundedCorner(bmp);
BitmapDrawable backgroundDrawable = new BitmapDrawable(getResources(),bmp);
subLayout = (RelativeLayout) findViewById(R.id.subLayout);
subLayout.setBackgroundDrawable(backgroundDrawable);
希望能幫助其他有同樣問題的人!
如何使用LayerList設置位圖,其圓角,然后將其設置為相對布局背景?
該文檔包括如何執行此操作的一步一步。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.