How to give this custom Seekbar with image? - android

I would like to make a seek bar something like this :
I have tried few libraries like this :
https://github.com/tankery/CircularSeekBar and https://github.com/devadvance/circularseekbar
but I am unable to achieve what I want.
I have the image of this seekbar, can we achieve anything from drawarc or any other idea?
EDIT(28/09/2017) : :
tried this code, but not able to get desiered result :
public class CustomView extends View{
Bitmap gold,grey;
Paint paint;
Context context;
int progress=0;
private Paint mPaint,mPaint2;
private RectF mOval,mOval2;
public CustomView(Context context) {
super(context);
init(context);
}
public CustomView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CustomView(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public CustomView(Context context, #Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
public void init(Context context)
{
this.context = context;
paint = new Paint();
gold = BitmapFactory.decodeResource(context.getResources(),
R.drawable.timer_golden_full);
grey = BitmapFactory.decodeResource(context.getResources(),
R.drawable.timer_greyline);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mOval = new RectF();
Matrix m = new Matrix();
RectF src = new RectF(0, 0, gold.getWidth(), gold.getHeight());
RectF dst = new RectF(0, 0, 200, 250);
m.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);
Shader shader = new BitmapShader(gold, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
shader.setLocalMatrix(m);
mPaint.setShader(shader);
m.mapRect(mOval, src);
mPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
mOval2 = new RectF();
Matrix m2 = new Matrix();
RectF src2 = new RectF(0, 0, gold.getWidth(), gold.getHeight());
RectF dst2 = new RectF(0, 0, 200, 250);
m2.setRectToRect(src2, dst2, Matrix.ScaleToFit.CENTER);
Shader shader2 = new BitmapShader(grey, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
shader2.setLocalMatrix(m2);
mPaint2.setShader(shader2);
m2.mapRect(mOval2, src2);
}
public void update()
{
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawArc(mOval2, 0, 360, true, mPaint2);
canvas.drawArc(mOval, 0, 360, true, mPaint);
}
}

Related

How to draw bitmap with rounded corners?

I had the image that i get from url and put in the bitmap. Now I need to draw this bitmap with canvas and it required to be with rounded corners.
P.S
ImageView is not option here for me because there would be a lot of such images that should be drawn.
var url = "someurl"
var mediaMetadataRetriever = MediaMetadataRetriever()
mediaMetadataRetriever.setDataSource(url, HashMap<String, String>())
var frame:Bitmap = mediaMetadataRetriever.getFrameAtTime(time) // get image from url
var rect = Rect(left, top, right, bottom) // coordinates for bitmap
canvas.drawBitmap(frame, null, rect, paint)
public class CustomImageView extends ImageView {
public static float cornerRadius = 19.0f;
public CustomImageView(Context context) {
super(context);
}
public CustomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas) {
Path clipPath = new Path();
RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
clipPath.addRoundRect(rect, radius, radius, Path.Direction.CW);
canvas.clipPath(clipPath);
super.onDraw(canvas);
}
}
<CustomImageView
android:id="#+id/selectIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop" />

Draw rounded corner line using canvas

I am trying to draw rounded corner line using canvas. Like eg:
public class MyView extends View {
Paint paint;
Path path;
public MyView(Context context) {
super(context);
init();
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);
path = new Path();
path.moveTo(50, 50);
path.lineTo(50, 500);
path.lineTo(200, 500);
path.lineTo(200, 300);
path.lineTo(350, 300);
float radius = 50.0f;
CornerPathEffect cornerPathEffect =
new CornerPathEffect(radius);
paint.setPathEffect(cornerPathEffect);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(path, paint);
}
}
I am able to draw corner line using paint as shown above, but not from the canvas.
I tried canvas.drawLine() and canvas.drawArc() to achieve the same result but failed to do that.
Can somebody help me to solve the issue?

Draw multiple rectangles

Can you Give me any advice how to draw a list of rectangles?
I have a Rectangle class :
public final class Rectangle extends View {
private Rect rectangle;
private Paint paint;
public Rectangle(Context context) {
super(context);
int x = 50;
int y = 50;
int sideLength = 200;
// create a rectangle that we'll draw later
rectangle = new Rect(x, y, sideLength, sideLength);
// create the Paint and set its color
paint = new Paint();
paint.setColor(Color.GRAY);
}
#Override
protected void onDraw(Canvas canvas) {
//canvas.drawColor(Color.BLUE);
canvas.drawRect(rectangle, paint);
}
}
and a Rectangle instance on activity
setContentView(new Rectangle(this));
Here you have some example three rectangles side by side
public class Rectangles extends View {
private Paint paintBlack;
public Rectangles(Context context) {
super(context);
init();
}
public Rectangles(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Rectangles(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
paintBlack = new Paint();
paintBlack.setColor(Color.BLACK);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawRect(0, 0, 100, 100, paintBlack);
canvas.drawRect(105, 0, 205, 100, paintBlack);
canvas.drawRect(210, 0, 310, 100, paintBlack);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(500, 500);
}
}

Android Custom WebView With Rounded Corners

I'm trying to make a custom WebView that is completely identical to a regular WebView except that it has rounded corners. The rounded corners need to be transparent because I'd like to put this WebView in a Dialog.
I tried making my custom class like so:
public class RoundedWebView extends WebView
{
private Context context;
private int width;
private int height;
public RoundedWebView(Context context)
{
super(context);
initialize(context);
}
public RoundedWebView(Context context, AttributeSet attrs)
{
super(context, attrs);
initialize(context);
}
public RoundedWebView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
initialize(context);
}
private void initialize(Context context)
{
this.context = context;
}
// This method gets called when the view first loads, and also whenever the
// view changes. Use this opportunity to save the view's width and height.
#Override protected void onSizeChanged(int newWidth, int newHeight, int oldWidth, int oldHeight)
{
this.width = newWidth;
this.height = newHeight;
super.onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
}
#Override protected void onDraw(Canvas canvas)
{
int radius = Utilities.dpToPx(context, 5);
Path clipPath = new Path();
clipPath.addRoundRect(new RectF(0, 0, width, height), radius, radius, Path.Direction.CW);
canvas.clipPath(clipPath);
super.onDraw(canvas);
}
}
and this implementation works for the most part. However, as soon as a url finishes loading and displays itself on the screen, I lose the rounded corners from the WebView. Any idea what's going on?
Here was the solution I found. In my onDraw() method, I create an inverted, filled, rounded rectangle, and then use the Porter Duff Xfer Mode to "clear" that area from the screen. This leaves me with a WebView that has nicely bevelled edges, including the case where the WebView finishes loading a url.
public class RoundedWebView extends WebView
{
private Context context;
private int width;
private int height;
private int radius;
public RoundedWebView(Context context)
{
super(context);
initialize(context);
}
public RoundedWebView(Context context, AttributeSet attrs)
{
super(context, attrs);
initialize(context);
}
public RoundedWebView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
initialize(context);
}
private void initialize(Context context)
{
this.context = context;
}
// This method gets called when the view first loads, and also whenever the
// view changes. Use this opportunity to save the view's width and height.
#Override protected void onSizeChanged(int newWidth, int newHeight, int oldWidth, int oldHeight)
{
super.onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
width = newWidth;
height = newHeight;
radius = Utilities.dpToPx(context, 5);
}
#Override protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Path path = new Path();
path.setFillType(Path.FillType.INVERSE_WINDING);
path.addRoundRect(new RectF(0, getScrollY(), width, getScrollY() + height), radius, radius, Path.Direction.CW);
canvas.drawPath(path, createPorterDuffClearPaint());
}
private Paint createPorterDuffClearPaint()
{
Paint paint = new Paint();
paint.setColor(Color.TRANSPARENT);
paint.setStyle(Style.FILL);
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
return paint;
}
}
In onDraw(Canvas canvas) you call the super method at the end. That means that whatever you do in your custom draw method will be undone by the super method. Try calling super first and then doing your custom drawing.
It might help others. Before loading data you need to set
webView.getSettings().setUseWideViewPort(true);
and applied you're drawable in XML file.
It worked for me.
Here's the solution. After three day research.
public class RoundedWebView extends WebView
{
private final static float CORNER_RADIUS = 100.0f;
private Bitmap maskBitmap;
private Paint paint, maskPaint;
private float cornerRadius;
public RoundedWebView(Context context) {
super(context);
init(context, null, 0);
initView(context);
}
public RoundedWebView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
initView(context);
}
public RoundedWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle);
initView(context);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, metrics);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
setWillNotDraw(false);
}
#Override
public void draw(Canvas canvas) {
Bitmap offscreenBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
Canvas offscreenCanvas = new Canvas(offscreenBitmap);
super.draw(offscreenCanvas);
if (maskBitmap == null) {
maskBitmap = createMask(canvas.getWidth(), canvas.getHeight());
}
offscreenCanvas.drawBitmap(maskBitmap, 0f, 0f, maskPaint);
canvas.drawBitmap(offscreenBitmap, 0f, 0f, paint);
}
private Bitmap createMask(int width, int height) {
Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
Canvas canvas = new Canvas(mask);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
canvas.drawRect(0, 0, width, height, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);
return mask;
}
void initView(Context context){
// i am not sure with these inflater lines
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// you should not use a new instance of MyWebView here
// MyWebView view = (MyWebView) inflater.inflate(R.layout.custom_webview, this);
this.getSettings().setUseWideViewPort(true);
this.getSettings().setLoadWithOverviewMode(true);
}
}
Here is the Kotlin version of #Luke answer.
I also improved the code to avoid object allocations during the onDraw method.
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.RectF
import android.util.AttributeSet
import android.webkit.WebView
import net.onefivefour.android.bitpot.extensions.dpToPx
class RoundedWebView : WebView {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
private lateinit var roundedRect: RectF
private val cornerRadius = 10f.dpToPx(context)
private val pathPaint = Path().apply {
fillType = Path.FillType.INVERSE_WINDING
}
private val porterDuffPaint = Paint().apply {
color = Color.TRANSPARENT
style = Paint.Style.FILL
isAntiAlias = true
xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
}
override fun onSizeChanged(newWidth: Int, newHeight: Int, oldWidth: Int, oldHeight: Int) {
super.onSizeChanged(newWidth, newHeight, oldWidth, oldHeight)
roundedRect = RectF(0f, scrollY.toFloat(), width.toFloat(), (scrollY + height).toFloat())
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
pathPaint.reset()
pathPaint.addRoundRect(roundedRect, cornerRadius, cornerRadius, Path.Direction.CW)
canvas.drawPath(pathPaint, porterDuffPaint)
}
}
Also here is the extension method to calculate dp to pixel:
fun Float.dpToPx(context: Context): Float {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, context.resources.displayMetrics)
}

How call onDraw method from another method to draw dynamically?

I want to redraw a view from another method (say setProgress) in a class extending View. How can I do this.
My view class is
public class SpinView extends View {
private Paint paint;
private Context context;
private Canvas canvas;
private RectF arcOval;
public SpinView(Context context) {
super(context);
this.context = context;
}
public SpinView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
this.context = context;
}
public SpinView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
this.canvas = canvas;
Display d = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = d.getWidth();
int height = d.getHeight();
arcOval = new RectF((width/2-50), (height/2-50), (width/2+50), (height/2+50));
// RectF arcOval = new RectF(200, 200, 300, 300);
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(arcOval, 270f, 360, false, paint);
}
protected void setProgress(float angle){
paint = new Paint();
paint.setColor(Color.YELLOW);
paint.setStrokeWidth(10);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(arcOval, 270f, angle, false, paint);
}
}
All I want is to draw a circular arc of yellow color over the initially created arc of Blue color. Any help?
You can use invalidate() method to call ondraw again

Categories

Resources