Skip to content

Instantly share code, notes, and snippets.

@vijaysharm
Last active August 29, 2015 14:22
Show Gist options
  • Save vijaysharm/4cfaa575e7c618cdc549 to your computer and use it in GitHub Desktop.
Save vijaysharm/4cfaa575e7c618cdc549 to your computer and use it in GitHub Desktop.
A Caldendar Drawable (a la Google Calendar)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
final MenuItem menuItem = menu.add("Jump to Today");
menuItem.setIcon(new CalendarDrawable(24));
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
return true;
}
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
public class CalendarDrawable extends Drawable {
private final int day;
private final Paint outsideBox;
private final Paint insideBox;
private final Paint datePaint;
private final Paint handles;
public CalendarDrawable(int day) {
this.day = day;
this.outsideBox = new Paint();
this.outsideBox.setAntiAlias(true);
this.outsideBox.setColor(Color.WHITE);
this.outsideBox.setStyle(Paint.Style.STROKE);
this.outsideBox.setStrokeWidth(4);
this.insideBox = new Paint(outsideBox);
this.insideBox.setStyle(Paint.Style.FILL);
this.datePaint = new Paint(outsideBox);
this.datePaint.setStrokeWidth(2);
this.datePaint.setTextSize(24);
this.handles = new Paint(outsideBox);
this.handles.setStyle(Paint.Style.FILL);
}
@Override
public void draw(Canvas canvas) {
String text = String.valueOf(day);
int width = 21;
int height = 19;
int handleWidth = 4;
int handleHeight = 8;
int leftHandleStart = -width + 6;
int leftHandleEnd = leftHandleStart + handleWidth;
int rightHandleStart = width - 6 - handleWidth;
int rightHandleEnd = rightHandleStart + handleWidth;
int handleTop = -height - handleHeight;
int baseline = 8;
int dayString = text.length() == 1 ? -7 : -13;
float cornerRadius = 1.5f;
canvas.drawRoundRect(new RectF(-width, -height, width, height), cornerRadius, cornerRadius, outsideBox);
canvas.drawRoundRect(new RectF(-width, -height, width, -11), cornerRadius, cornerRadius, insideBox);
canvas.drawRect(new RectF(leftHandleStart, handleTop, leftHandleEnd, -height), handles);
canvas.drawRect(new RectF(rightHandleStart, handleTop, rightHandleEnd, -height), handles);
canvas.drawText(text, dayString, height - baseline, datePaint);
}
@Override
public void setAlpha(int alpha) {
outsideBox.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
outsideBox.setColorFilter(cf);
}
@Override
public int getOpacity() {
return PixelFormat.OPAQUE;
}
}
@vijaysharm
Copy link
Author

There's this little Calendar drawable that shows up in the top right of the Google calendar app that I really love. It's a menu item that immediately takes you to "Today". What I love about it has to do with the fact that no one really does "dynamic" icons on Android, especially not in the toolbar. In the Google app, that little button displays today's date, and changes as the days go by. I wanted something similar in an app I was building, but wasn't sure how to do it. If I had to guess how Google did it, I'd say it's some kind of TextView with a calendar image as a background. But I don't got time for that. So I just spun together my own drawable class, which takes in the int value you want to display.

It's got a ton of magic numbers in it to get the look right. I wish I had a better answer, but this worked just fine for me. If someone has a better way of doing it, please share!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment