Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android round a Layouts background image, only top or bottom corners

Tags:

java

android

I want to be able to have a screen with multiple RelativeLayouts, and I want the top layout and the bottom layout to have rounded corners, so top layout would have top 2 corners rounded, and bottom layout would have bottom 2 corners rounded.

My issue is, all the examples I find online are using shape.xml to create a rounded corner and gave it a gradient and that is not good enough, because I want to to give the relativeLayout a background image, and have that image rounded, and I can't seem to do both.

Any help would be much appreciated!!

EDIT - Bounty Started

Okay, I have been banging my head against the wall for ages on this one. I am using a 3rd party tool called UITableView at the moment, mainly just testing something out.

https://github.com/thiagolocatelli/android-uitableview

It sets up tableView similar to the way iPhone table is, and I want to be able to give each row a background image, and have the top and bottom rows curved. In this UITableView class, under commit, this code is called

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);
    }
}

He has a layout style for top middle and bottom rows, top and bottom rounded used XML, but the problem is, I want to give each row an image. So I added this code

tempItemView.setBackgroundResource(R.drawable.background);

But the problem is, this removes the curved corners for the top and bottom rows as the corners are rounded using XML and using white gradients, not an image. I need to be able to inflate the layout, then curve the top and bottom corners. I have looked at so many examples of cropping corners, and even tried out different 3rd party tools, but have yet to find a single example which shows applying a background image to a container, and then rounding the corners.

Does anyone have any ideas on how to do this??

Edit:

On iPhone, you can do something like this

UIColor *color = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"image.png"]];

Where you convert an image into a colour. Does Android have an equivalent?

Edit:

Thanks to ACheese for the answer, I modified his code and separated it into 3 methods, one for top rounded corners, one for fully rounded corners, and one for bottom rounded corners, and came up with this

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));
    }

I use metrics to set up how much to round the view, so it scales with different screen sizes.

Hope that helps others who were having this issue!!

like image 809
AdamM Avatar asked Mar 13 '13 12:03

AdamM


People also ask

How do I round corners in Android?

xml file and add an attribute to that TextView, for which you want to add rounded corners. The attribute is android: background=”@drawable/rounded_corner_view”.

How do I make an image circular in Android Studio?

Simply put a circular_crop. png in your drawable folder which is in the shape of your image dimensions (a square in my case) with a white background and a transparent circle in the center. You can use this image if you have want a square imageview. Just download the picture above.


2 Answers

So did you tried something like this :

For example this is your main layout :

RelativeLayout myMainRelLAyout = (RelativeLayout) findViewById(R.id.my_layout);

and do MyMainRelLAyout.setBackgroundResource(R.drawable.mydrawable);

where mydrawable.xml look like this :

    <?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>

Depending on the comments below I can suggest you this link : Romain Guy - image with rounded corners , where you can find an answer which I think will help you how to do this.

And here is another useful library which is using ImageView, but you can change it and use it for any kind of View, link : RoundedImageView .

like image 130
hardartcore Avatar answered Oct 14 '22 03:10

hardartcore


Check if my solution work for your case : Define your own layout by extending RelativeLayout. You only need to add the following code

@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));

}

call this method from your activity. You cannot call from onCreate() because getMeasuredWidth() and getMeasuredHeight() are not ready. Override and call from onWindowFocusChanged(boolean hasFocused) by setting your own drawable id. This will repeating setting your image as the background with round corners.

like image 35
Acheese Avatar answered Oct 14 '22 03:10

Acheese