Separate light and dark widget row layouts

pull/996/head
Alex Baker 6 years ago
parent 136d78fff9
commit 05802ddfc3

@ -1,13 +1,10 @@
package org.tasks.widget;
import static androidx.core.content.ContextCompat.getColor;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.DisplayMetrics;
import android.view.View;
@ -46,7 +43,7 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
private boolean isDark;
private boolean showDueDates;
private boolean bottomDueDate;
private boolean endDueDate;
private boolean showCheckboxes;
private float textSize;
private float dueDateTextSize;
@ -56,10 +53,11 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
private boolean showFullTaskTitle;
private boolean showDescription;
private boolean showFullDescription;
private Bitmap divider;
private int vPad;
private int hPad;
private boolean handleDueDateClick;
private boolean showDividers;
private boolean isRtl;
private List<TaskContainer> tasks = new ArrayList<>();
@ -113,7 +111,7 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
@Override
public RemoteViews getLoadingView() {
return new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.widget_row);
return newRemoteView();
}
@Override
@ -136,6 +134,11 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
return checkBoxProvider.getWidgetCheckBox(task);
}
private RemoteViews newRemoteView() {
return new RemoteViews(
BuildConfig.APPLICATION_ID, isDark ? R.layout.widget_row_dark : R.layout.widget_row_light);
}
private RemoteViews buildUpdate(int position) {
try {
TaskContainer taskContainer = getTask(position);
@ -143,17 +146,13 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
return null;
}
Task task = taskContainer.getTask();
String textContent;
int textColorTitle = textColorPrimary;
textContent = task.getTitle();
RemoteViews row = new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.widget_row);
RemoteViews row = newRemoteView();
if (task.isHidden()) {
textColorTitle = textColorSecondary;
row.setViewVisibility(R.id.hidden_icon, View.VISIBLE);
row.setInt(R.id.hidden_icon, "setColorFilter", textColorSecondary);
} else {
row.setViewVisibility(R.id.hidden_icon, View.GONE);
}
@ -166,7 +165,6 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
row.setInt(R.id.widget_text, "setPaintFlags", Paint.ANTI_ALIAS_FLAG);
}
row.setFloat(R.id.widget_text, "setTextSize", textSize);
row.setFloat(R.id.widget_description, "setTextSize", textSize);
if (showDueDates) {
formatDueDate(row, task);
} else {
@ -176,71 +174,54 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
textColorTitle = getColor(context, R.color.overdue);
}
}
row.setInt(R.id.widget_text, "setMaxLines", showFullTaskTitle ? Integer.MAX_VALUE : 1);
if (showFullTaskTitle) {
row.setInt(R.id.widget_text, "setMaxLines", Integer.MAX_VALUE);
}
row.setTextViewText(R.id.widget_text, task.getTitle());
row.setTextColor(R.id.widget_text, textColorTitle);
if (showDescription && task.hasNotes()) {
row.setFloat(R.id.widget_description, "setTextSize", textSize);
row.setTextViewText(R.id.widget_description, task.getNotes());
row.setViewVisibility(R.id.widget_description, View.VISIBLE);
row.setTextColor(R.id.widget_description, textColorSecondary);
row.setInt(
R.id.widget_description, "setMaxLines", showFullDescription ? Integer.MAX_VALUE : 2);
if (showFullDescription) {
row.setInt(R.id.widget_description, "setMaxLines", Integer.MAX_VALUE);
}
} else {
row.setViewVisibility(R.id.widget_description, View.GONE);
}
row.setTextViewText(R.id.widget_text, textContent);
row.setTextColor(R.id.widget_text, textColorTitle);
row.setImageViewBitmap(R.id.widget_complete_box, getCheckbox(task));
Intent editIntent = new Intent(WidgetClickActivity.EDIT_TASK);
editIntent.putExtra(WidgetClickActivity.EXTRA_FILTER, filter);
editIntent.putExtra(WidgetClickActivity.EXTRA_TASK, task);
row.setOnClickFillInIntent(R.id.widget_row, editIntent);
if (atLeastLollipop()) {
row.setInt(
R.id.widget_row,
"setBackgroundResource",
isDark ? R.drawable.widget_ripple_dark : R.drawable.widget_ripple_light);
}
row.setOnClickFillInIntent(
R.id.widget_row,
new Intent(WidgetClickActivity.EDIT_TASK)
.putExtra(WidgetClickActivity.EXTRA_FILTER, filter)
.putExtra(WidgetClickActivity.EXTRA_TASK, task));
row.setViewPadding(R.id.widget_complete_box, hPad, vPad, hPad, vPad);
row.setViewPadding(R.id.widget_due_end, hPad, vPad, hPad, vPad);
if (showCheckboxes) {
row.setViewVisibility(R.id.widget_complete_box, View.VISIBLE);
Intent completeIntent = new Intent(WidgetClickActivity.COMPLETE_TASK);
completeIntent.putExtra(WidgetClickActivity.EXTRA_TASK, task);
row.setOnClickFillInIntent(R.id.widget_complete_box, completeIntent);
row.setViewPadding(R.id.start_padding, 0, 0, 0, 0);
row.setInt(
row.setViewPadding(R.id.widget_complete_box, hPad, vPad, hPad, vPad);
row.setImageViewBitmap(R.id.widget_complete_box, getCheckbox(task));
row.setOnClickFillInIntent(
R.id.widget_complete_box,
"setBackgroundResource",
isDark ? R.drawable.widget_ripple_circle_dark : R.drawable.widget_ripple_circle_light);
new Intent(WidgetClickActivity.COMPLETE_TASK)
.putExtra(WidgetClickActivity.EXTRA_TASK, task));
} else {
row.setViewVisibility(R.id.widget_complete_box, View.GONE);
row.setViewPadding(R.id.start_padding, hPad, 0, 0, 0);
row.setViewPadding(R.id.widget_complete_box, hPad, 0, 0, 0);
row.setInt(R.id.widget_complete_box, "setBackgroundResource", 0);
}
row.setViewPadding(R.id.top_padding, 0, vPad, 0, 0);
row.setViewPadding(R.id.bottom_padding, 0, vPad, 0, 0);
if (divider == null) {
if (!showDividers) {
row.setViewVisibility(R.id.divider, View.GONE);
} else {
row.setViewVisibility(R.id.divider, View.VISIBLE);
row.setImageViewBitmap(R.id.divider, divider);
}
if (taskContainer.hasChildren()) {
Intent toggleSubtasks = new Intent(WidgetClickActivity.TOGGLE_SUBTASKS);
toggleSubtasks.putExtra(WidgetClickActivity.EXTRA_TASK, task);
toggleSubtasks.putExtra(WidgetClickActivity.EXTRA_COLLAPSED, !taskContainer.isCollapsed());
row.setOnClickFillInIntent(R.id.subtask_button, toggleSubtasks);
row.setInt(
row.setOnClickFillInIntent(
R.id.subtask_button,
"setBackgroundResource",
isDark ? R.drawable.widget_chip_dark : R.drawable.widget_chip_light);
row.setTextColor(R.id.subtask_text, textColorSecondary);
new Intent(WidgetClickActivity.TOGGLE_SUBTASKS)
.putExtra(WidgetClickActivity.EXTRA_TASK, task)
.putExtra(WidgetClickActivity.EXTRA_COLLAPSED, !taskContainer.isCollapsed()));
row.setTextViewText(
R.id.subtask_text,
context
@ -252,20 +233,14 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
taskContainer.isCollapsed()
? R.drawable.ic_keyboard_arrow_up_black_18dp
: R.drawable.ic_keyboard_arrow_down_black_18dp);
row.setInt(R.id.subtask_icon, "setColorFilter", textColorSecondary);
row.setViewVisibility(R.id.subtask_button, View.VISIBLE);
} else {
row.setViewVisibility(R.id.subtask_button, View.GONE);
}
row.setInt(
R.id.widget_row, "setLayoutDirection", Locale.getInstance(context).getDirectionality());
row.setInt(R.id.widget_row, "setLayoutDirection", locale.getDirectionality());
row.setViewPadding(
R.id.widget_row,
taskContainer.getIndent() * indentPadding,
0,
0,
0);
int startPad = taskContainer.getIndent() * indentPadding;
row.setViewPadding(R.id.widget_row, isRtl ? 0 : startPad, 0, isRtl ? startPad : 0, 0);
return row;
} catch (Exception e) {
@ -290,12 +265,15 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
}
private void formatDueDate(RemoteViews row, Task task) {
int dueDateRes = bottomDueDate ? R.id.widget_due_bottom : R.id.widget_due_end;
row.setViewVisibility(bottomDueDate ? R.id.widget_due_end : R.id.widget_due_bottom, View.GONE);
if (task.hasDueDate()) {
// if (!bottomDueDate) {
// row.setViewPadding(R.id.widget_text, 0, 0, 0, 0);
// }
int dueDateRes = endDueDate ? R.id.widget_due_end : R.id.widget_due_bottom;
row.setViewVisibility(endDueDate ? R.id.widget_due_bottom : R.id.widget_due_end, View.GONE);
boolean hasDueDate = task.hasDueDate();
int endPad = hasDueDate && endDueDate ? 0 : hPad;
row.setViewPadding(R.id.widget_text, isRtl ? endPad : 0, 0, isRtl ? 0 : endPad, 0);
if (hasDueDate) {
if (endDueDate) {
row.setViewPadding(R.id.widget_due_end, hPad, vPad, hPad, vPad);
}
row.setViewVisibility(dueDateRes, View.VISIBLE);
row.setTextViewText(
dueDateRes,
@ -305,18 +283,17 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
dueDateRes,
task.isOverdue() ? getColor(context, R.color.overdue) : textColorSecondary);
row.setFloat(dueDateRes, "setTextSize", dueDateTextSize);
if (handleDueDateClick) {
row.setOnClickFillInIntent(
dueDateRes,
new Intent(WidgetClickActivity.RESCHEDULE_TASK)
.putExtra(WidgetClickActivity.EXTRA_TASK, task));
} else {
row.setInt(dueDateRes, "setBackgroundResource", 0);
}
} else {
row.setViewVisibility(dueDateRes, View.GONE);
}
if (handleDueDateClick) {
row.setInt(
dueDateRes,
"setBackgroundResource",
isDark ? R.drawable.widget_ripple_circle_dark : R.drawable.widget_ripple_circle_light);
Intent intent = new Intent(WidgetClickActivity.RESCHEDULE_TASK);
intent.putExtra(WidgetClickActivity.EXTRA_TASK, task);
row.setOnClickFillInIntent(dueDateRes, intent);
}
}
private void updateSettings() {
@ -334,17 +311,12 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
ContextCompat.getColor(context, isDark ? R.color.white_60 : R.color.black_60);
int dueDatePosition = widgetPreferences.getDueDatePosition();
showDueDates = dueDatePosition != 2;
bottomDueDate = dueDatePosition == 1;
endDueDate = dueDatePosition != 1;
showCheckboxes = widgetPreferences.showCheckboxes();
textSize = widgetPreferences.getFontSize();
dueDateTextSize = Math.max(10, textSize - 2);
filter = defaultFilterProvider.getFilterFromPreference(widgetPreferences.getFilterId());
if (widgetPreferences.showDividers()) {
divider = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888); // Create a Bitmap
int bgColor = ContextCompat.getColor(context, isDark ? R.color.white_12 : R.color.black_12);
new Canvas(divider).drawColor(bgColor); // Set the color
} else {
divider = null;
}
showDividers = widgetPreferences.showDividers();
isRtl = locale.getDirectionality() == View.LAYOUT_DIRECTION_RTL;
}
}

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/widget_row"
android:background="@drawable/widget_ripple_dark"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:background="@color/md_background_dark">
<ImageView
android:id="@+id/widget_complete_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:padding="@dimen/widget_padding"
android:background="@drawable/widget_ripple_circle_dark"
tools:src="@drawable/ic_outline_check_box_outline_blank_24px"
tools:tint="@color/grey_500"/>
<ImageView
android:id="@+id/top_padding"
android:layout_alignParentTop="true"
android:layout_alignStart="@id/widget_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/widget_padding"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/widget_due_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/widget_text"
android:layout_alignParentEnd="true"
android:ellipsize="end"
android:gravity="start|center_vertical"
android:singleLine="true"
android:textAlignment="viewStart"
android:textSize="14sp"
android:background="@drawable/widget_ripple_circle_dark"
tools:text="Tomorrow"
tools:paddingEnd="@dimen/widget_padding"
tools:textColor="@color/white_60"/>
<ImageView
android:id="@+id/hidden_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/widget_complete_box"
android:layout_below="@id/top_padding"
android:paddingStart="0dp"
android:paddingEnd="2dp"
android:visibility="gone"
android:src="@drawable/ic_outline_visibility_off_24px"
android:tint="@color/icon_tint_dark_alpha"
tools:visibility="visible"/>
<TextView
android:id="@+id/widget_text"
android:layout_toEndOf="@id/hidden_icon"
android:layout_toStartOf="@id/widget_due_end"
android:layout_below="@id/top_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="@dimen/widget_padding"
android:paddingStart="0dp"
android:gravity="start|center_vertical"
android:maxLines="1"
android:ellipsize="end"
android:textAlignment="viewStart"
android:textSize="16sp"
tools:text="Task title"
tools:textColor="@color/white_87"/>
<TextView
android:id="@+id/widget_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/widget_text"
android:layout_toEndOf="@id/widget_complete_box"
android:paddingTop="2dp"
android:paddingStart="0dp"
android:paddingEnd="@dimen/widget_padding"
android:maxLines="2"
android:ellipsize="end"
android:textAlignment="viewStart"
android:textSize="16sp"
android:textColor="@color/white_60"
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean tristique magna mauris, vel vulputate elit varius sit amet. Etiam sed nisl diam. Aenean vulputate ex nec ex condimentum commodo. Nunc faucibus augue in lacus tincidunt pretium. Donec mollis ex a ipsum semper, faucibus viverra turpis consequat. Donec id suscipit est. Duis a consectetur justo. Nunc in diam urna." />
<TextView
android:id="@+id/widget_due_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/widget_description"
android:layout_toEndOf="@id/widget_complete_box"
android:ellipsize="end"
android:gravity="start|center_vertical"
android:singleLine="true"
android:textAlignment="viewStart"
android:textSize="14sp"
android:background="@drawable/widget_ripple_circle_dark"
tools:text="Tomorrow"
tools:textColor="@color/white_60"/>
<LinearLayout
android:id="@+id/subtask_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/widget_due_bottom"
android:layout_marginTop="2dp"
android:layout_toEndOf="@id/widget_complete_box"
android:background="@drawable/widget_chip_dark"
android:orientation="horizontal"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="@+id/subtask_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="5dp"
android:paddingEnd="0dp"
android:layout_gravity="center_vertical"
android:tint="@color/icon_tint_dark_alpha"
tools:src="@drawable/ic_keyboard_arrow_up_black_18dp" />
<TextView
android:id="@+id/subtask_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="14sp"
android:maxLines="1"
android:ellipsize="end"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:paddingStart="0dp"
android:paddingEnd="8dp"
android:textColor="@color/white_60"
tools:text="4 subtasks"/>
</LinearLayout>
<ImageView
android:id="@+id/bottom_padding"
android:layout_below="@id/subtask_button"
android:layout_alignStart="@id/widget_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/widget_padding"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/divider"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:scaleType="fitXY"
android:layout_height=".5dp"
android:background="@color/white_12"
tools:ignore="ContentDescription" />
</RelativeLayout>

@ -1,29 +1,22 @@
<?xml version="1.0" encoding="utf-8"?><!--
** Copyright (c) 2012 Todoroo Inc
**
** See the file "LICENSE" for the full license governing this code.
-->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/widget_row"
android:background="@drawable/widget_ripple_light"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/start_padding"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
tools:ignore="ContentDescription" />
android:layout_height="wrap_content"
tools:background="@android:color/white">
<ImageView
android:id="@+id/widget_complete_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/start_padding"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:padding="@dimen/widget_padding"
tools:src="@drawable/ic_outline_check_box_outline_blank_24px" />
android:background="@drawable/widget_ripple_circle_light"
tools:src="@drawable/ic_outline_check_box_outline_blank_24px"
tools:tint="@color/grey_500"/>
<ImageView
android:id="@+id/top_padding"
@ -45,8 +38,10 @@
android:singleLine="true"
android:textAlignment="viewStart"
android:textSize="14sp"
android:background="@drawable/widget_ripple_circle_light"
tools:text="Tomorrow"
tools:paddingEnd="@dimen/widget_padding"/>
tools:paddingEnd="@dimen/widget_padding"
tools:textColor="@color/black_60"/>
<ImageView
android:id="@+id/hidden_icon"
@ -56,7 +51,10 @@
android:layout_below="@id/top_padding"
android:paddingStart="0dp"
android:paddingEnd="2dp"
android:src="@drawable/ic_outline_visibility_off_24px" />
android:visibility="gone"
android:src="@drawable/ic_outline_visibility_off_24px"
android:alpha="@dimen/alpha_disabled"
tools:visibility="visible"/>
<TextView
android:id="@+id/widget_text"
@ -72,7 +70,8 @@
android:ellipsize="end"
android:textAlignment="viewStart"
android:textSize="16sp"
tools:text="Task title" />
tools:text="Task title"
tools:textColor="@color/black_87"/>
<TextView
android:id="@+id/widget_description"
@ -87,6 +86,7 @@
android:ellipsize="end"
android:textAlignment="viewStart"
android:textSize="16sp"
android:textColor="@color/black_60"
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean tristique magna mauris, vel vulputate elit varius sit amet. Etiam sed nisl diam. Aenean vulputate ex nec ex condimentum commodo. Nunc faucibus augue in lacus tincidunt pretium. Donec mollis ex a ipsum semper, faucibus viverra turpis consequat. Donec id suscipit est. Duis a consectetur justo. Nunc in diam urna." />
<TextView
@ -100,7 +100,9 @@
android:singleLine="true"
android:textAlignment="viewStart"
android:textSize="14sp"
tools:text="Tomorrow" />
android:background="@drawable/widget_ripple_circle_light"
tools:text="Tomorrow"
tools:textColor="@color/black_60"/>
<LinearLayout
android:id="@+id/subtask_button"
@ -111,7 +113,8 @@
android:layout_toEndOf="@id/widget_complete_box"
android:background="@drawable/widget_chip_light"
android:orientation="horizontal"
tools:background="@drawable/widget_chip_light">
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="@+id/subtask_icon"
@ -120,8 +123,8 @@
android:paddingStart="5dp"
android:paddingEnd="0dp"
android:layout_gravity="center_vertical"
tools:src="@drawable/ic_keyboard_arrow_up_black_18dp"
tools:tint="@color/icon_tint_light_alpha" />
android:alpha="@dimen/alpha_disabled"
tools:src="@drawable/ic_keyboard_arrow_up_black_18dp" />
<TextView
android:id="@+id/subtask_text"
@ -135,6 +138,7 @@
android:paddingBottom="2dp"
android:paddingStart="0dp"
android:paddingEnd="8dp"
android:textColor="@color/black_60"
tools:text="4 subtasks"/>
</LinearLayout>
@ -154,6 +158,7 @@
android:layout_width="match_parent"
android:scaleType="fitXY"
android:layout_height=".5dp"
android:background="@color/black_12"
tools:ignore="ContentDescription" />
</RelativeLayout>

@ -119,7 +119,6 @@
<color name="md_background_light">@color/design_default_color_background</color>
<color name="md_background_dark">#202124</color>
<color name="widget_background_black">#000000</color>
<color name="icon_tint_light">@android:color/black</color>
<color name="icon_tint_dark">@android:color/white</color>
<color name="icon_tint_light_alpha">@color/black_60</color>

Loading…
Cancel
Save