Skip to content

Commit

Permalink
add calendar attrs
Browse files Browse the repository at this point in the history
  • Loading branch information
RomanTsarou committed Apr 28, 2019
1 parent 1c4f49f commit 49f8220
Show file tree
Hide file tree
Showing 16 changed files with 443 additions and 185 deletions.
13 changes: 6 additions & 7 deletions app/src/main/java/bz/kakadu/calendar/example/MainActivity.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package bz.kakadu.calendar.example;

import android.os.Bundle;
import android.support.v4.graphics.ColorUtils;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import bz.kakadu.calendar.CalendarTheme;
import bz.kakadu.calendar.CalendarViewPager;
import bz.kakadu.calendar.Day;
import bz.kakadu.calendar.DrawUtils;
import bz.kakadu.calendar.RangeCellDecoration;

public class MainActivity extends AppCompatActivity {
Expand All @@ -19,17 +18,17 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CalendarViewPager monthView = findViewById(R.id.monthView);
rangeCellDecoration = new RangeCellDecoration(this);
rangeCellDecoration = new RangeCellDecoration();
Day day1 = Day.today().add(-10);
Day day2 = Day.today().add(50);
rangeCellDecoration.setBoundsRange(day1, day2);
int color = DrawUtils.getAttrColor(this, R.attr.colorPrimary);
rangeCellDecoration.rangeEdgesColor = color;
rangeCellDecoration.rangeColor = ColorUtils.setAlphaComponent(color, 127);
// int color = DrawUtils.getAttrColor(this, R.attr.colorPrimary);
// rangeCellDecoration.rangeEdgesColor = color;
// rangeCellDecoration.rangeColor = ColorUtils.setAlphaComponent(color, 127);
monthView.setCurrentMonth(day1, false);
monthView.addDecoration(rangeCellDecoration);
monthView.onDayClickListener = rangeCellDecoration;

CalendarTheme ct = new CalendarTheme(this);
}

public void dialog(View view) {
Expand Down
17 changes: 17 additions & 0 deletions app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="calendarTheme">@style/CalendarTheme.App</item>
</style>

<style name="CalendarTheme.App">
<item name="calendarRangeColor">?colorPrimary</item>
<item name="calendarRangeScale">80%</item>
<item name="calendarRangeEdgesColor">?colorPrimary</item>
<item name="calendarTodayBold">true</item>
<item name="calendarTodayCircleStrokeWidth">3dp</item>
<item name="calendarTodayCircleStrokeColor">?colorAccent</item>
<item name="calendarTodayTextColor">?colorAccent</item>
<item name="calendarTitleLayoutStyle">@style/CalendarTitleLayoutStyle.App</item>
</style>

<style name="CalendarTitleLayoutStyle.App">
<item name="android:theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
<item name="android:background">?colorPrimary</item>
<item name="android:elevation">4dp</item>
</style>
</resources>
2 changes: 1 addition & 1 deletion calendarpro/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
resourcePrefix 'cal_'
resourcePrefix 'calendar'
}

dependencies {
Expand Down
97 changes: 97 additions & 0 deletions calendarpro/src/main/java/bz/kakadu/calendar/CalendarTheme.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package bz.kakadu.calendar;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Color;

public class CalendarTheme {
public static final int[] STATE_ENABLED = {android.R.attr.state_enabled};
public static final int[] STATE_DISABLED = {-android.R.attr.state_enabled};
private static final int defaultColor = Color.MAGENTA;
public final int calendarTheme; // @style/CalendarTheme
public boolean alwaysSixWeeks; // false
public boolean headerShow; // true
public boolean headerTextBold; // true
public int headerTextColor; // ?android:textColorSecondary
public float headerTextScale; // 20%
public boolean dateTextBold; // false
public ColorStateList dateTextColor; // ?android:textColorPrimary
public float dateTextScale; // 34%
public int rangeTextColor; // ?android:textColorPrimaryInverse
public int rangeEdgesColor; // ?colorAccent
public int rangeEdgesTextColor; // ?android:textColorPrimaryInverse
public int rangeColor; // ?calendarRangeEdgesColor
public float rangeAlpha; // 50%
public boolean rangeEdgesShow; // true
public float rangeEdgesScale; // ?calendarTodayCircleScale
public float rangeScale; // 75%
public boolean todayShow; // true
public boolean todayBold; // false
public ColorStateList todayTextColor; // ?android:textColorPrimary
public ColorStateList todayCircleStrokeColor; // ?android:textColorPrimary
public float todayCircleStrokeWidth; // 1dp
public float todayCircleScale; // 80%
public String calendarTitleDateFormat; // "LLLL, yyyy"

public CalendarTheme(Context context) {
TypedArray themeArray = context.getTheme().obtainStyledAttributes(new int[]{R.attr.calendarTheme});
try {
calendarTheme = themeArray.getResourceId(0, R.style.CalendarTheme);
themeArray.recycle();
themeArray = context.obtainStyledAttributes(null, R.styleable.CalendarTheme, R.attr.calendarTheme, R.style.CalendarTheme);
alwaysSixWeeks = themeArray.getBoolean(R.styleable.CalendarTheme_calendarAlwaysSixWeeks, false);
headerShow = themeArray.getBoolean(R.styleable.CalendarTheme_calendarHeaderShow, true);
headerTextBold = themeArray.getBoolean(R.styleable.CalendarTheme_calendarHeaderTextBold, true);
dateTextBold = themeArray.getBoolean(R.styleable.CalendarTheme_calendarDateTextBold, false);
rangeEdgesShow = themeArray.getBoolean(R.styleable.CalendarTheme_calendarRangeEdgesShow, true);
todayShow = themeArray.getBoolean(R.styleable.CalendarTheme_calendarTodayShow, true);
todayBold = themeArray.getBoolean(R.styleable.CalendarTheme_calendarTodayBold, false);
dateTextColor = getColorStateList(themeArray, R.styleable.CalendarTheme_calendarDateTextColor);
rangeTextColor = getColor(themeArray, R.styleable.CalendarTheme_calendarRangeTextColor);
rangeEdgesTextColor = getColor(themeArray, R.styleable.CalendarTheme_calendarRangeEdgesTextColor);
todayTextColor = getColorStateList(themeArray, R.styleable.CalendarTheme_calendarTodayTextColor);
todayCircleStrokeColor = getColorStateList(themeArray, R.styleable.CalendarTheme_calendarTodayCircleStrokeColor);
headerTextColor = getColor(themeArray, R.styleable.CalendarTheme_calendarHeaderTextColor);
rangeEdgesColor = getColor(themeArray, R.styleable.CalendarTheme_calendarRangeEdgesColor);
rangeColor = getColor(themeArray, R.styleable.CalendarTheme_calendarRangeColor);
todayCircleStrokeWidth = themeArray.getDimension(R.styleable.CalendarTheme_calendarTodayCircleStrokeWidth, 1);
headerTextScale = themeArray.getFraction(R.styleable.CalendarTheme_calendarHeaderTextScale, 1, 1, 1);
dateTextScale = themeArray.getFraction(R.styleable.CalendarTheme_calendarDateTextScale, 1, 1, 1);
rangeAlpha = themeArray.getFraction(R.styleable.CalendarTheme_calendarRangeAlpha, 1, 1, 1);
rangeEdgesScale = themeArray.getFraction(R.styleable.CalendarTheme_calendarRangeEdgesScale, 1, 1, 1);
rangeScale = themeArray.getFraction(R.styleable.CalendarTheme_calendarRangeScale, 1, 1, 1);
todayCircleScale = themeArray.getFraction(R.styleable.CalendarTheme_calendarTodayCircleScale, 1, 1, 1);
calendarTitleDateFormat = themeArray.getString(R.styleable.CalendarTheme_calendarTitleDateFormat);
} finally {
themeArray.recycle();
}
}

public static int getColor(ColorStateList colorStateList, boolean isEnabled) {
return colorStateList.getColorForState(isEnabled ? STATE_ENABLED : STATE_DISABLED, defaultColor);
}

private static ColorStateList getColorStateList(TypedArray themeArray, int attr) {
ColorStateList stateList = themeArray.getColorStateList(attr);
if (stateList != null) {
return stateList;
} else {
return ColorStateList.valueOf(themeArray.getColor(attr, defaultColor));
}
}

private static int getColor(TypedArray themeArray, int attr) {
ColorStateList stateList = themeArray.getColorStateList(attr);
if (stateList != null) {
return stateList.getDefaultColor();
} else {
return themeArray.getColor(attr, defaultColor);
}
}

Context getThemedContext(Context context) {
context.getTheme().applyStyle(calendarTheme, false);
return context;
}
}
39 changes: 17 additions & 22 deletions calendarpro/src/main/java/bz/kakadu/calendar/CalendarViewPager.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package bz.kakadu.calendar;

import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
Expand All @@ -22,26 +21,30 @@
public class CalendarViewPager extends FrameLayout {
private final int startYear = 1900;
private final int endYear = 2100;
private final SimpleDateFormat titleFormat = new SimpleDateFormat("MMMM, yyyy", Locale.getDefault());
private final ViewPager viewPager;
private final View header;
private final View prevBtn;
private final View nextBtn;
public final ViewPager viewPager;
public final View header;
public final View prevBtn;
public final View nextBtn;
public final CalendarTheme theme;
public OnDayClickListener onDayClickListener;
private List<ICellDecoration> decorations = new ArrayList<>();
private Calendar calendar = Calendar.getInstance();
public SimpleDateFormat titleFormat;

public CalendarViewPager(@NonNull Context context) {
this(context, null);
}

public CalendarViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
inflate(context, R.layout.view_calendar_pager, this);
theme = new CalendarTheme(context);
theme.alwaysSixWeeks = true;
titleFormat = new SimpleDateFormat(theme.calendarTitleDateFormat, Locale.getDefault());
inflate(theme.getThemedContext(context), R.layout.calendar_view_pager, this);
viewPager = findViewById(R.id.view_pager);
header = findViewById(R.id.month_page_header);
prevBtn = header.findViewById(R.id.prev_month_btn);
nextBtn = header.findViewById(R.id.next_month_btn);
header = findViewById(R.id.calendar_month_title_layout);
prevBtn = header.findViewById(R.id.calendar_prev_month_btn);
nextBtn = header.findViewById(R.id.calendar_next_month_btn);
viewPager.setAdapter(new MonthAdapter());
viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
Expand Down Expand Up @@ -103,11 +106,11 @@ public Object instantiateItem(@NonNull ViewGroup container, int position) {
calendar.add(Calendar.MONTH, position);
day.set(calendar);
View page = LayoutInflater.from(container.getContext()).inflate(R.layout.calendar_pager_page, container, false);
MonthView monthView = page.findViewById(R.id.month_view);
TextView title = page.findViewById(R.id.month_title);
TextView title = page.findViewById(R.id.calendar_month_title);
title.setText(getPageTitle(position));
MonthView monthView = page.findViewById(R.id.calendar_month_view);
monthView.setCalendarTheme(theme);
monthView.setMonth(day);
monthView.alwaysSixWeekRows = true;
monthView.setOnDayClickListener(onDayClickListener);
for (ICellDecoration decoration : decorations) {
monthView.addDecoration(decoration);
Expand Down Expand Up @@ -136,15 +139,7 @@ public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
public CharSequence getPageTitle(int position) {
calendar.set(startYear, 0, 1);
calendar.add(Calendar.MONTH, position);
String title;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String name = calendar.getDisplayName(Calendar.MONTH, Calendar.LONG_STANDALONE, Locale.getDefault());
title = name + ", " + calendar.get(Calendar.YEAR);
} else {
title = titleFormat.format(calendar.getTime());
}
title = title.substring(0, 1).toUpperCase() + title.substring(1);
return title;
return titleFormat.format(calendar.getTime());
}
}
}
22 changes: 17 additions & 5 deletions calendarpro/src/main/java/bz/kakadu/calendar/DrawUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* @author Roman Tsarou
*/
public final class DrawUtils {
public static final int START = 0, MIDDLE = 1, END = 2;
public static final int START = 0, MIDDLE = 1, END = 2, SINGLE = 3;
private static final Paint PAINT = new Paint(Paint.ANTI_ALIAS_FLAG);
private static final Path PATH = new Path();
private static final Path PATH2 = new Path();
Expand Down Expand Up @@ -99,6 +99,10 @@ public static void drawPeriodArc(@PeriodType int periodType, @ColorInt int color
}

public static void drawPeriod(@PeriodType int periodType, Paint paint, Canvas canvas, RectF bounds, float scale) {
if (periodType == SINGLE) {
drawCircle(paint, canvas, bounds, scale);
return;
}
final float size = Math.min(bounds.height(), bounds.width()) * scale;
final float paddingHor = (1f * bounds.width() - size) / 2f;
final float paddingVer = (1f * bounds.height() - size) / 2f;
Expand Down Expand Up @@ -144,7 +148,7 @@ public static void drawPeriodArc(@PeriodType int periodType, Paint paint, Canvas
case START:
PATH2.lineTo(bounds.centerX(), bounds.top);
PATH2.lineTo(bounds.right, bounds.top);
drawCircle(paint, canvas, bounds, scale);
// drawCircle(paint, canvas, bounds, scale);
break;
case MIDDLE:
PATH2.lineTo(bounds.right, bounds.top);
Expand All @@ -153,22 +157,29 @@ public static void drawPeriodArc(@PeriodType int periodType, Paint paint, Canvas
case END:
PATH2.lineTo(bounds.centerX(), bounds.top);
PATH2.lineTo(bounds.left, bounds.top);
drawCircle(paint, canvas, bounds, scale);
// drawCircle(paint, canvas, bounds, scale);
break;
case SINGLE:
break;
default:
throw new IllegalArgumentException();
}
PATH.op(PATH2, Path.Op.INTERSECT);
if (periodType != SINGLE) {
PATH.op(PATH2, Path.Op.INTERSECT);
}
canvas.drawPath(PATH, paint);
}

@ColorInt
public static int getPrimaryTextColor(Context context, boolean enabled) {
return getAttrColor(context, android.R.attr.textColorPrimary, enabled);
}

@ColorInt
public static int getSecondaryTextColor(Context context, boolean enabled) {
return getAttrColor(context, android.R.attr.textColorSecondary, enabled);
}

@ColorInt
public static int getAttrColor(Context context, @AttrRes int attr, boolean enabled) {
TypedArray themeArray = context.getTheme().obtainStyledAttributes(new int[]{attr});
Expand All @@ -185,12 +196,13 @@ public static int getAttrColor(Context context, @AttrRes int attr, boolean enabl
themeArray.recycle();
}
}

@ColorInt
public static int getAttrColor(Context context, @AttrRes int attr) {
return getAttrColor(context, attr, true);
}

@IntDef({START, MIDDLE, END})
@IntDef({START, MIDDLE, END, SINGLE})
@Retention(RetentionPolicy.SOURCE)
@interface PeriodType {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.graphics.Canvas;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import android.view.View;

/**
Expand All @@ -10,6 +11,8 @@
* @author Roman Tsarou
*/
public interface ICellDecoration {
void setCalendarTheme(@NonNull CalendarTheme theme);

void onPreDraw(View parent, Canvas canvas, float cellWidth, float cellHeight);

void onCellDraw(View parent, Cell cell, Canvas canvas, RectF bounds);
Expand Down
Loading

0 comments on commit 49f8220

Please sign in to comment.