Skip to content

Instantly share code, notes, and snippets.

@gnumilanix
Last active May 15, 2017 08:27
Show Gist options
  • Save gnumilanix/3ee3e706d2ef3dc5db0c29c9f06fe8f1 to your computer and use it in GitHub Desktop.
Save gnumilanix/3ee3e706d2ef3dc5db0c29c9f06fe8f1 to your computer and use it in GitHub Desktop.
Implementation of FrameLayout that can wrap any components within with a circle bezel.
<declare-styleable name="CircleLayout">
<attr name="bezelColor" format="color" />
<attr name="bezelSize" format="dimension" />
</declare-styleable>
package com.milanix.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import com.milanix.view.R;
/**
* Implementation of {@link FrameLayout} that can wrap any components within with a circle bezel
*
* @author milan
*/
public class CircleLayout extends FrameLayout {
private Path clipPath;
private int centerX;
private int centerY;
private int radius;
private int bezelColor;
private Paint bezel;
private float bezelSize;
private float bezelRadius;
public CircleLayout(Context context) {
this(context, null);
}
public CircleLayout(Context context, AttributeSet attrs) {
this(context, attrs, -1);
}
public CircleLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setAttributes(context, attrs);
init();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public CircleLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setAttributes(context, attrs);
init();
}
/**
* Sets the required attributes
*
* @param context The application context
* @param attrs The attributes
*/
private void setAttributes(Context context, AttributeSet attrs) {
if (attrs != null) {
final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleLayout);
bezelColor = array.getColor(R.styleable.CircleLayout_bezelColor, 0);
bezelSize = array.getDimension(R.styleable.CircleLayout_bezelSize, 0);
array.recycle();
}
}
/**
* Initializes required atrributes
*/
private void init() {
setWillNotDraw(false);
setLayerType(LAYER_TYPE_HARDWARE, null);
clipPath = new Path();
bezel = new Paint();
bezel.setColor(bezelColor);
bezel.setStyle(Paint.Style.STROKE);
bezel.setStrokeWidth(bezelSize);
bezel.setAntiAlias(true);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
radius = centerX = w / 2;
centerY = h / 2;
bezelRadius = radius - bezelSize / 2;
clipPath.reset();
clipPath.addCircle(centerX, centerY, radius, Path.Direction.CW);
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.clipPath(clipPath);
super.dispatchDraw(canvas);
canvas.drawCircle(centerX, centerY, bezelRadius, bezel);
}
}
<com.milanix.view.CircleLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:bezelColor="@color/com_facebook_messenger_blue"
app:bezelSize="4dp">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/com_facebook_blue" />
</com.milanix.view.CircleLayout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment