Skip to content

Commit

Permalink
Change layout of collapsed and expanded alarms
Browse files Browse the repository at this point in the history
- Inspired by Google clock
  • Loading branch information
BlackyHawky committed Apr 5, 2024
1 parent b68a785 commit 543b202
Show file tree
Hide file tree
Showing 14 changed files with 266 additions and 287 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
import com.best.deskclock.ItemAdapter;
import com.best.deskclock.ItemAnimator;
import com.best.deskclock.R;
import com.best.deskclock.Utils;
import com.best.deskclock.alarms.AlarmTimeClickHandler;
import com.best.deskclock.bedtime.BedtimeFragment;
import com.best.deskclock.data.DataModel;
import com.best.deskclock.data.Weekdays;
import com.best.deskclock.provider.Alarm;
Expand All @@ -43,6 +44,7 @@ public abstract class AlarmItemViewHolder extends ItemAdapter.ItemViewHolder<Ala
public static final float CLOCK_ENABLED_ALPHA = 1f;
public static final float CLOCK_DISABLED_ALPHA = 0.63f;

private final TextView editLabel;
public final TextTime clock;
public final CompoundButton onOff;
public final TextView daysOfWeek;
Expand All @@ -52,14 +54,19 @@ public abstract class AlarmItemViewHolder extends ItemAdapter.ItemViewHolder<Ala
public AlarmItemViewHolder(View itemView) {
super(itemView);

itemView.setBackground(Utils.cardBackground(itemView.getContext()));

editLabel = itemView.findViewById(R.id.edit_label);
clock = itemView.findViewById(R.id.digital_clock);
onOff = itemView.findViewById(R.id.onoff);
daysOfWeek = itemView.findViewById(R.id.days_of_week);
upcomingInstanceLabel = itemView.findViewById(R.id.upcoming_instance_label);
arrow = itemView.findViewById(R.id.arrow);

editLabel.setOnClickListener(view -> {
if (!getItemHolder().item.equals(Alarm.getAlarmByLabel(itemView.getContext().getContentResolver(), BedtimeFragment.BEDLABEL))) {
getAlarmTimeClickHandler().onEditLabelClicked(getItemHolder().item);
}
});

onOff.setOnCheckedChangeListener((compoundButton, checked) ->
getItemHolder().getAlarmTimeClickHandler().setAlarmEnabled(getItemHolder().item, checked));
}
Expand All @@ -68,13 +75,31 @@ public AlarmItemViewHolder(View itemView) {
protected void onBindItemView(final AlarmItemHolder itemHolder) {
final Alarm alarm = itemHolder.item;
final Context context = itemView.getContext();
bindEditLabel(context, alarm);
bindOnOffSwitch(alarm);
bindClock(alarm);
bindRepeatText(context, alarm);
bindUpcomingInstance(context, alarm);
itemView.setContentDescription(clock.getText() + " " + alarm.getLabelOrDefault(context));
}

private void bindEditLabel(Context context, Alarm alarm) {
if (alarm.label.length() == 0) {
editLabel.setText(context.getString(R.string.add_label));
editLabel.setTypeface(Typeface.DEFAULT);
editLabel.setAlpha(CLOCK_DISABLED_ALPHA);
} else {
editLabel.setText(alarm.equals(Alarm.getAlarmByLabel(context.getContentResolver(), BedtimeFragment.BEDLABEL))
? context.getString(R.string.wakeup_alarm_label_visible)
: alarm.label);
editLabel.setContentDescription(alarm.label != null && alarm.label.length() > 0
? context.getString(R.string.label_description) + " " + alarm.label
: context.getString(R.string.no_label_specified));
editLabel.setTypeface(Typeface.DEFAULT_BOLD);
editLabel.setAlpha(alarm.enabled ? CLOCK_ENABLED_ALPHA : CLOCK_DISABLED_ALPHA);
}
}

protected void bindOnOffSwitch(Alarm alarm) {
if (onOff.isChecked() != alarm.enabled) {
onOff.setChecked(alarm.enabled);
Expand Down Expand Up @@ -123,4 +148,8 @@ private void bindUpcomingInstance(Context context, Alarm alarm) {
}
}

private AlarmTimeClickHandler getAlarmTimeClickHandler() {
return getItemHolder().getAlarmTimeClickHandler();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,16 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView.ViewHolder;

import com.best.deskclock.AnimatorUtils;
import com.best.deskclock.ItemAdapter;
import com.best.deskclock.R;
import com.best.deskclock.bedtime.BedtimeFragment;
import com.best.deskclock.events.Events;
import com.best.deskclock.provider.Alarm;

import java.util.List;

Expand All @@ -45,13 +39,11 @@ public final class CollapsedAlarmViewHolder extends AlarmItemViewHolder {

public static final int VIEW_TYPE = R.layout.alarm_time_collapsed;

private final TextView alarmLabel;


private CollapsedAlarmViewHolder(View itemView) {
super(itemView);

alarmLabel = itemView.findViewById(R.id.label);

// Expand handler
itemView.setOnClickListener(v -> {
Events.sendAlarmEvent(R.string.action_expand_implied, R.string.label_deskclock);
Expand All @@ -76,24 +68,6 @@ private CollapsedAlarmViewHolder(View itemView) {
@Override
protected void onBindItemView(AlarmItemHolder itemHolder) {
super.onBindItemView(itemHolder);
final Alarm alarm = itemHolder.item;
final Context context = itemView.getContext();
bindReadOnlyLabel(context, alarm);
}

private void bindReadOnlyLabel(Context context, Alarm alarm) {
if (alarm.label != null && alarm.label.length() != 0) {
alarmLabel.setVisibility(View.VISIBLE);
if (alarm.equals(Alarm.getAlarmByLabel(context.getContentResolver(), BedtimeFragment.BEDLABEL))) {
alarmLabel.setText(R.string.wakeup_alarm_label_visible);
} else {
alarmLabel.setText(alarm.label);
}
alarmLabel.setAlpha(alarm.enabled ? CLOCK_ENABLED_ALPHA : CLOCK_DISABLED_ALPHA);
alarmLabel.setContentDescription(context.getString(R.string.label_description) + " " + alarm.label);
} else {
alarmLabel.setVisibility(View.GONE);
}
}

@Override
Expand All @@ -118,8 +92,6 @@ public Animator onAnimateChange(final ViewHolder oldHolder, ViewHolder newHolder
changeAnimatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animator) {
arrow.setVisibility(View.VISIBLE);
arrow.setTranslationY(0f);
arrow.jumpDrawablesToCurrentState();
}
});
Expand All @@ -128,8 +100,6 @@ public void onAnimationEnd(Animator animator) {
}

private Animator createExpandingAnimator(AlarmItemViewHolder newHolder, long duration) {
arrow.setVisibility(View.INVISIBLE);

final View oldView = itemView;
final Animator boundsAnimator = AnimatorUtils.getBoundsAnimator(oldView, oldView, newHolder.itemView).setDuration(duration);
boundsAnimator.setInterpolator(AnimatorUtils.INTERPOLATOR_FAST_OUT_SLOW_IN);
Expand All @@ -140,25 +110,12 @@ private Animator createExpandingAnimator(AlarmItemViewHolder newHolder, long dur
}

private Animator createCollapsingAnimator(AlarmItemViewHolder oldHolder, long duration) {
final View oldView = oldHolder.itemView;
final View newView = itemView;
final Animator boundsAnimator = AnimatorUtils.getBoundsAnimator(newView, oldView, newView).setDuration(duration);
final Animator boundsAnimator = AnimatorUtils.getBoundsAnimator(newView, oldHolder.itemView, newView).setDuration(duration);
boundsAnimator.setInterpolator(AnimatorUtils.INTERPOLATOR_FAST_OUT_SLOW_IN);

final View oldArrow = oldHolder.arrow;
final Rect oldArrowRect = new Rect(0, 0, oldArrow.getWidth(), oldArrow.getHeight());
final Rect newArrowRect = new Rect(0, 0, arrow.getWidth(), arrow.getHeight());
((ViewGroup) newView).offsetDescendantRectToMyCoords(arrow, newArrowRect);
((ViewGroup) oldView).offsetDescendantRectToMyCoords(oldArrow, oldArrowRect);
final float arrowTranslationY = oldArrowRect.bottom - newArrowRect.bottom;
arrow.setTranslationY(arrowTranslationY);
arrow.setVisibility(View.VISIBLE);

final Animator arrowAnimation = ObjectAnimator.ofFloat(arrow, View.TRANSLATION_Y, 0f).setDuration(duration);
arrowAnimation.setInterpolator(AnimatorUtils.INTERPOLATOR_FAST_OUT_SLOW_IN);

final AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(boundsAnimator, arrowAnimation);
animatorSet.playTogether(boundsAnimator);

animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Vibrator;
import android.view.LayoutInflater;
Expand All @@ -42,7 +40,6 @@
import com.best.deskclock.R;
import com.best.deskclock.Utils;
import com.best.deskclock.alarms.AlarmTimeClickHandler;
import com.best.deskclock.bedtime.BedtimeFragment;
import com.best.deskclock.data.DataModel;
import com.best.deskclock.events.Events;
import com.best.deskclock.provider.Alarm;
Expand All @@ -60,7 +57,6 @@ public final class ExpandedAlarmViewHolder extends AlarmItemViewHolder {
public final CheckBox vibrate;
public final TextView ringtone;
public final TextView delete;
private final TextView editLabel;
private final CompoundButton[] dayButtons = new CompoundButton[7];

private final boolean mHasVibrator;
Expand All @@ -73,7 +69,6 @@ private ExpandedAlarmViewHolder(View itemView, boolean hasVibrator) {
delete = itemView.findViewById(R.id.delete);
vibrate = itemView.findViewById(R.id.vibrate_onoff);
ringtone = itemView.findViewById(R.id.choose_ringtone);
editLabel = itemView.findViewById(R.id.edit_label);
repeatDays = itemView.findViewById(R.id.repeat_days_alarm);

final Context context = itemView.getContext();
Expand Down Expand Up @@ -106,13 +101,6 @@ private ExpandedAlarmViewHolder(View itemView, boolean hasVibrator) {
// Edit time handler
clock.setOnClickListener(v -> getAlarmTimeClickHandler().onClockClicked(getItemHolder().item));

// Edit label handler
editLabel.setOnClickListener(view -> {
if (!getItemHolder().item.equals(Alarm.getAlarmByLabel(context.getContentResolver(), BedtimeFragment.BEDLABEL))) {
getAlarmTimeClickHandler().onEditLabelClicked(getItemHolder().item);
}
});

// Vibrator checkbox handler
vibrate.setOnClickListener(v ->
getAlarmTimeClickHandler().setAlarmVibrationEnabled(getItemHolder().item, ((CheckBox) v).isChecked()));
Expand Down Expand Up @@ -144,7 +132,6 @@ protected void onBindItemView(final AlarmItemHolder itemHolder) {

final Alarm alarm = itemHolder.item;
final Context context = itemView.getContext();
bindEditLabel(context, alarm);
bindDaysOfWeekButtons(alarm, context);
bindVibrator(alarm);
bindRingtone(context, alarm);
Expand Down Expand Up @@ -178,17 +165,6 @@ private void bindDaysOfWeekButtons(Alarm alarm, Context context) {
}
}

private void bindEditLabel(Context context, Alarm alarm) {
if (alarm.equals(Alarm.getAlarmByLabel(context.getContentResolver(), BedtimeFragment.BEDLABEL))) {
editLabel.setText(R.string.wakeup_alarm_label_visible);
} else {
editLabel.setText(alarm.label);
editLabel.setContentDescription(alarm.label != null && alarm.label.length() > 0
? context.getString(R.string.label_description) + " " + alarm.label
: context.getString(R.string.no_label_specified));
}
}

private void bindVibrator(Alarm alarm) {
if (!mHasVibrator) {
vibrate.setVisibility(View.INVISIBLE);
Expand Down Expand Up @@ -224,8 +200,6 @@ public Animator onAnimateChange(final ViewHolder oldHolder, ViewHolder newHolder
changeAnimatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animator) {
arrow.setVisibility(View.VISIBLE);
arrow.setTranslationY(0f);
arrow.jumpDrawablesToCurrentState();
}
});
Expand All @@ -234,8 +208,6 @@ public void onAnimationEnd(Animator animator) {
}

private Animator createCollapsingAnimator(AlarmItemViewHolder newHolder, long duration) {
arrow.setVisibility(View.INVISIBLE);

final View oldView = itemView;
final Animator boundsAnimator = AnimatorUtils.getBoundsAnimator(oldView, oldView, newHolder.itemView).setDuration(duration);
boundsAnimator.setInterpolator(AnimatorUtils.INTERPOLATOR_FAST_OUT_SLOW_IN);
Expand All @@ -246,25 +218,12 @@ private Animator createCollapsingAnimator(AlarmItemViewHolder newHolder, long du
}

private Animator createExpandingAnimator(AlarmItemViewHolder oldHolder, long duration) {
final View oldView = oldHolder.itemView;
final View newView = itemView;
final Animator boundsAnimator = AnimatorUtils.getBoundsAnimator(newView, oldView, newView).setDuration(duration);
final Animator boundsAnimator = AnimatorUtils.getBoundsAnimator(newView, oldHolder.itemView, newView).setDuration(duration);
boundsAnimator.setInterpolator(AnimatorUtils.INTERPOLATOR_FAST_OUT_SLOW_IN);

final View oldArrow = oldHolder.arrow;
final Rect oldArrowRect = new Rect(0, 0, oldArrow.getWidth(), oldArrow.getHeight());
final Rect newArrowRect = new Rect(0, 0, arrow.getWidth(), arrow.getHeight());
((ViewGroup) newView).offsetDescendantRectToMyCoords(arrow, newArrowRect);
((ViewGroup) oldView).offsetDescendantRectToMyCoords(oldArrow, oldArrowRect);
final float arrowTranslationY = oldArrowRect.bottom - newArrowRect.bottom;
arrow.setTranslationY(arrowTranslationY);
arrow.setVisibility(View.VISIBLE);

final Animator arrowAnimation = ObjectAnimator.ofFloat(arrow, View.TRANSLATION_Y, 0f).setDuration(duration);
arrowAnimation.setInterpolator(AnimatorUtils.INTERPOLATOR_FAST_OUT_SLOW_IN);

final AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(boundsAnimator, arrowAnimation);
animatorSet.playTogether(boundsAnimator);

animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
limitations under the License.
-->
<objectAnimator xmlns:android="https://schemas.android.com/apk/res/android"
android:duration="300"
android:duration="500"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:pathData="M 12.0,15.0 c 0.0,-1.0 0.0,-5.33 0.0,-6.0"
android:propertyXName="translateX"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
limitations under the License.
-->
<objectAnimator xmlns:android="https://schemas.android.com/apk/res/android"
android:duration="300"
android:duration="500"
android:interpolator="@anim/caret_toclose_animation_interpolator_0"
android:propertyName="rotation"
android:valueFrom="45.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
limitations under the License.
-->
<objectAnimator xmlns:android="https://schemas.android.com/apk/res/android"
android:duration="300"
android:duration="500"
android:interpolator="@anim/caret_toclose_animation_interpolator_0"
android:propertyName="rotation"
android:valueFrom="-45.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
limitations under the License.
-->
<objectAnimator xmlns:android="https://schemas.android.com/apk/res/android"
android:duration="300"
android:duration="500"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:pathData="M 12.0,9.0 c 0.0,0.67 0.0,5.0 0.0,6.0"
android:propertyXName="translateX"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/animator-v22/caret_expand_l_animation.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
limitations under the License.
-->
<objectAnimator xmlns:android="https://schemas.android.com/apk/res/android"
android:duration="300"
android:duration="500"
android:interpolator="@anim/caret_toopen_animation_interpolator_0"
android:propertyName="rotation"
android:valueFrom="-45.0"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/animator-v22/caret_expand_r_animation.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
limitations under the License.
-->
<objectAnimator xmlns:android="https://schemas.android.com/apk/res/android"
android:duration="300"
android:duration="500"
android:interpolator="@anim/caret_toopen_animation_interpolator_0"
android:propertyName="rotation"
android:valueFrom="45.0"
Expand Down
Loading

0 comments on commit 543b202

Please sign in to comment.