Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
public final class DatePickerWheelView extends LinearLayout {
private static final String TAG = DatePickerWheelView.class.getSimpleName();

private static final String LONG_MONTH_FORMAT = "MMMM";
private static final String SHORT_MONTH_FORMAT = "MMM";
private static final String YEAR_FORMAT = "yyyy";
private static final String MONTH_FORMAT = "MM";
Expand All @@ -49,6 +50,7 @@ public final class DatePickerWheelView extends LinearLayout {

private boolean showDayMonthYear;
private boolean showShortMonths;
private boolean showLongMonths;

@NonNull
private final List<String> years = new ArrayList<>();
Expand All @@ -72,6 +74,8 @@ public final class DatePickerWheelView extends LinearLayout {
private Locale locale = Locale.getDefault();

private View rootView;
private String fontTypeface;
private boolean canLoop;

public DatePickerWheelView(Context context) {
this(context, null, 0);
Expand Down Expand Up @@ -105,13 +109,16 @@ private void takeStyles(@NonNull AttributeSet attrs) {

showDayMonthYear = array.getBoolean(R.styleable.DatePickerWheelView_datePickerWheelViewShowDayMonthYear, false);
showShortMonths = array.getBoolean(R.styleable.DatePickerWheelView_datePickerWheelViewShowShortMonths, false);
showLongMonths = array.getBoolean(R.styleable.DatePickerWheelView_datePickerWheelViewShowLongMonths, false);

textSize = array.getDimension(R.styleable.DatePickerWheelView_datePickerWheelViewTextSize, 16F);

minYear = array.getInt(R.styleable.DatePickerWheelView_datePickerWheelViewMinYear, 1980);
maxYear = array.getInt(R.styleable.DatePickerWheelView_datePickerWheelViewMaxYear, 2100);

initialDate = array.getString(R.styleable.DatePickerWheelView_datePickerWheelViewInitialDate);
fontTypeface = array.getString(R.styleable.DatePickerWheelView_datePickerWheelViewFontTypeface);
canLoop = array.getBoolean(R.styleable.DatePickerWheelView_datePickerWheelViewIsLoopEnabled, false);
}
} finally {
if (null != array) {
Expand Down Expand Up @@ -144,6 +151,10 @@ private void drawDatePickerWheelView() {
monthSpinner.setTextSize(textSize);
daySpinner.setTextSize(textSize);

yearSpinner.setIsLoopEnabled(canLoop);
monthSpinner.setIsLoopEnabled(canLoop);
daySpinner.setIsLoopEnabled(canLoop);

yearSpinner.addOnLoopScrollListener(this::updateYearPosition);
yearSpinner.addOnLoopScrollListener(this::onDateSelected);

Expand All @@ -158,10 +169,13 @@ private void drawDatePickerWheelView() {
drawDayPickerView();

setInitialPositions();
setFontTypeface(fontTypeface);
}

private void updateYearPosition(@NonNull Object item, int position) {
this.yearPos = position;
// Leap years have 29 days in February
drawDayPickerView();
invalidate();
}

Expand All @@ -182,7 +196,8 @@ private void onDateSelected(@NonNull Object item, int position) {

calendar.set(Calendar.YEAR, Integer.valueOf(years.get(yearPos)));
calendar.set(Calendar.MONTH, monthPos);
calendar.set(Calendar.DAY_OF_MONTH, Integer.valueOf(days.get(dayPos)));
// Prevent an IndexOutOfBoundsException
calendar.set(Calendar.DAY_OF_MONTH, Integer.valueOf(days.get(Math.min(days.size() - 1, dayPos))));

final int year = calendar.get(Calendar.YEAR);
final int month = calendar.get(Calendar.MONTH);
Expand All @@ -196,8 +211,14 @@ private void setInitialPositions() {
final Calendar calendar = DateUtils.parseDateString(initialDate);

yearPos = years.indexOf(String.valueOf(calendar.get(Calendar.YEAR)));
monthPos = months.indexOf(String.valueOf(calendar.get(Calendar.MONTH) + 1));
dayPos = days.indexOf(String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)));
String dateFormat = showShortMonths ? SHORT_MONTH_FORMAT : MONTH_FORMAT;
dateFormat = showLongMonths ? LONG_MONTH_FORMAT : dateFormat;
String formattedMonth = formatDate(calendar, locale, dateFormat);
formattedMonth = showShortMonths ? formattedMonth.toUpperCase(locale) : formattedMonth;
// Fixed: months array was accessed without custom format
monthPos = months.indexOf(formattedMonth);
// Fixed: days was accessed without "dd"
dayPos = days.indexOf(formatDate(calendar, locale, DAY_FORMAT));

yearSpinner.setInitialPosition(yearPos);
monthSpinner.setInitialPosition(monthPos);
Expand All @@ -223,7 +244,9 @@ private void drawMonthPickerView() {
deleteAll(months);
calendar = Calendar.getInstance(locale);

final String dateFormat = showShortMonths ? SHORT_MONTH_FORMAT : MONTH_FORMAT;
String dateFormat = showShortMonths ? SHORT_MONTH_FORMAT : MONTH_FORMAT;
// Support long months
dateFormat = showLongMonths ? LONG_MONTH_FORMAT : dateFormat;

for (int j = 0; j <= calendar.getActualMaximum(Calendar.MONTH); j++) {
calendar.set(Calendar.YEAR, Integer.valueOf(years.get(yearPos)));
Expand All @@ -246,6 +269,20 @@ private void drawDayPickerView() {

calendar = Calendar.getInstance(locale);

// Fixed: dayPos while changing to a shorter month
Calendar cl = Calendar.getInstance(locale);
cl.set(Calendar.YEAR, year);
cl.set(Calendar.DAY_OF_MONTH, 1);
cl.set(Calendar.MONTH, monthPos);
int actualMaximum = cl.getActualMaximum(Calendar.DAY_OF_MONTH);

if (dayPos > actualMaximum - 1) {
int delta = dayPos - actualMaximum + 1;
dayPos = delta - 1;
daySpinner.forceScroll(delta);
}
///

for (int i = 0; i < calendar.getActualMaximum(Calendar.DAY_OF_MONTH); i++) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, monthPos);
Expand Down Expand Up @@ -289,6 +326,7 @@ public DatePickerWheelView setMaxYear(int maxYear) {
}

this.maxYear = maxYear;
drawYearPickerView();
invalidate();
return this;
}
Expand All @@ -312,6 +350,13 @@ public DatePickerWheelView setShowShortMonths(boolean showShortMonths) {
return this;
}

public DatePickerWheelView setShowLongMonths(boolean showLongMonths) {
this.showLongMonths = showLongMonths;
drawMonthPickerView();
invalidate();
return this;
}

public DatePickerWheelView setTextSize(float textSize) {
this.textSize = textSize;
invalidate();
Expand Down Expand Up @@ -342,4 +387,11 @@ public DatePickerWheelView setInitialDate(String initialDate) {
invalidate();
return this;
}

public DatePickerWheelView setFontTypeface(String fontTypeface) {
yearSpinner.setFontTypeface(fontTypeface);
monthSpinner.setFontTypeface(fontTypeface);
daySpinner.setFontTypeface(fontTypeface);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public final class WheelView extends View {
private final List<OnLoopScrollListener> listeners = new ArrayList<>();

@NonNull
private final SimpleOnGestureListener onGestureListener = new WheelViewGestureListener();
private final SimpleOnGestureListener onGestureListener = new WheelViewGestureListener();
private GestureDetector gestureDetector;

private final Paint topBottomTextPaint = new Paint(); //paint that draw top and bottom text
Expand Down Expand Up @@ -83,6 +83,8 @@ public final class WheelView extends View {
private int circularRadius;
private int widgetWidth;

private String fontTypeface;

public Handler handler = new Handler(msg -> {
switch (msg.what) {
case MSG_INVALIDATE:
Expand Down Expand Up @@ -162,20 +164,27 @@ private void initData() {
throw new IllegalArgumentException("items list must not be null!");
}

Typeface typeface;
if (fontTypeface != null) {
typeface = Typeface.createFromAsset(getContext().getAssets(), fontTypeface);
} else {
typeface = Typeface.MONOSPACE;
}

topBottomTextPaint.setColor(overflowTextColor);
topBottomTextPaint.setAntiAlias(true);
topBottomTextPaint.setTypeface(Typeface.MONOSPACE);
topBottomTextPaint.setTypeface(typeface);
topBottomTextPaint.setTextSize(textSize);

centerTextPaint.setColor(contentTextColor);
centerTextPaint.setAntiAlias(true);
centerTextPaint.setTextScaleX(1.05F);
centerTextPaint.setTypeface(Typeface.MONOSPACE);
centerTextPaint.setTypeface(typeface);
centerTextPaint.setTextSize(textSize);

centerLinePaint.setColor(lineColor);
centerLinePaint.setAntiAlias(true);
centerLinePaint.setTypeface(Typeface.MONOSPACE);
centerLinePaint.setTypeface(typeface);
centerLinePaint.setTextSize(textSize);

measureTextWidthHeight();
Expand Down Expand Up @@ -203,7 +212,8 @@ private void measureTextWidthHeight() {
final Rect rect = new Rect();

for (int i = 0; i < items.size(); i++) {
final String s1 = (String) items.get(i);
// support lowerCase month names
final String s1 = (String) items.get(i) + "j";

centerTextPaint.getTextBounds(s1, 0, s1.length(), rect);

Expand Down Expand Up @@ -405,7 +415,7 @@ private void itemSelected() {
}

private void onItemSelected() {
for (OnLoopScrollListener onLoopScrollListener: listeners) {
for (OnLoopScrollListener onLoopScrollListener : listeners) {
onLoopScrollListener.onLoopScrollFinish(items.get(selectedIndex), items.indexOf(items.get(selectedIndex)));
}
}
Expand All @@ -429,6 +439,15 @@ private void startSmoothScrollTo(float velocityY) {
scheduledFuture = executorService.scheduleWithFixedDelay(new FlingRunnable(velocityY), 0, velocityFling, TimeUnit.MILLISECONDS);
}

/**
* This fixes the item amount difference
*
* @param delta Number of items
*/
public void forceScroll(int delta) {
totalScrollY += delta * itemHeight;
}

class WheelViewGestureListener extends SimpleOnGestureListener {

@Override
Expand Down Expand Up @@ -528,7 +547,7 @@ class FlingRunnable implements Runnable {
public void run() {
if (velocity == Integer.MAX_VALUE) {
if (Math.abs(velocityY) > 2000F) {
velocity = (velocityY > 0.0F) ? 2000F : - 2000F;
velocity = (velocityY > 0.0F) ? 2000F : -2000F;
} else {
velocity = velocityY;
}
Expand Down Expand Up @@ -562,6 +581,19 @@ public void run() {
}
}

public String getFontTypeface() {
return fontTypeface;
}

public void setFontTypeface(String fontTypeface) {
this.fontTypeface = fontTypeface;
initData();
}

public int getContentTextColor() {
return contentTextColor;
}

public interface OnLoopScrollListener {

void onLoopScrollFinish(@NonNull Object item, int position);
Expand Down
3 changes: 3 additions & 0 deletions materialwheelview/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
<attr name="datePickerWheelViewMinYear" format="integer"/>
<attr name="datePickerWheelViewMaxYear" format="integer"/>
<attr name="datePickerWheelViewShowShortMonths" format="boolean"/>
<attr name="datePickerWheelViewShowLongMonths" format="boolean"/>
<attr name="datePickerWheelViewShowDayMonthYear" format="boolean"/>
<attr name="datePickerWheelViewIsLoopEnabled" format="boolean"/>
<attr name="datePickerWheelViewFontTypeface" format="string"/>
</declare-styleable>
</resources>