You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tasks/app/src/main/java/org/tasks/tasklist/ViewHolder.java

317 lines
8.9 KiB
Java

package org.tasks.tasklist;
import static com.google.common.collect.Lists.newArrayList;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastKitKat;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop;
8 years ago
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Paint;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnLongClick;
import com.google.android.material.chip.Chip;
import com.google.android.material.chip.ChipGroup;
import com.google.common.collect.Lists;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.activity.MainActivity;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.ui.CheckableImageView;
import java.util.List;
import org.tasks.R;
import org.tasks.preferences.Preferences;
import org.tasks.ui.CheckBoxes;
import org.tasks.ui.ChipProvider;
class ViewHolder extends RecyclerView.ViewHolder {
private final Context context;
private final Preferences preferences;
private final CheckBoxes checkBoxes;
private final int textColorSecondary;
private final int textColorPrimary;
private final TaskDao taskDao;
private final ViewHolderCallbacks callback;
private final DisplayMetrics metrics;
private final int background;
private final int selectedColor;
private final int textColorOverdue;
private final ChipProvider chipProvider;
private final int fontSizeDetails;
@BindView(R.id.row)
public ViewGroup row;
@BindView(R.id.due_date)
public TextView dueDate;
public Task task;
@BindView(R.id.rowBody)
ViewGroup rowBody;
@BindView(R.id.title)
TextView nameView;
@BindView(R.id.description)
TextView description;
@BindView(R.id.completeBox)
CheckableImageView completeBox;
@BindView(R.id.chip_scroll)
HorizontalScrollView chipScroll;
@BindView(R.id.chip_group)
ChipGroup chipGroup;
@BindView(R.id.hidden_status)
ImageView hidden;
private int indent;
private boolean selected;
private boolean moving;
ViewHolder(
Context context,
ViewGroup view,
Preferences preferences,
int fontSize,
CheckBoxes checkBoxes,
ChipProvider chipProvider,
int textColorOverdue,
int textColorSecondary,
int textColorPrimary,
TaskDao taskDao,
ViewHolderCallbacks callback,
DisplayMetrics metrics,
int background,
int selectedColor,
int rowPadding) {
super(view);
this.context = context;
this.preferences = preferences;
this.checkBoxes = checkBoxes;
this.chipProvider = chipProvider;
this.textColorOverdue = textColorOverdue;
this.textColorSecondary = textColorSecondary;
this.textColorPrimary = textColorPrimary;
this.taskDao = taskDao;
this.callback = callback;
this.metrics = metrics;
this.background = background;
this.selectedColor = selectedColor;
ButterKnife.bind(this, view);
if (preferences.getBoolean(R.string.p_fullTaskTitle, false)) {
nameView.setMaxLines(Integer.MAX_VALUE);
nameView.setSingleLine(false);
nameView.setEllipsize(null);
}
if (preferences.getBoolean(R.string.p_show_full_description, false)) {
description.setMaxLines(Integer.MAX_VALUE);
description.setSingleLine(false);
description.setEllipsize(null);
}
if (atLeastKitKat()) {
rowBody.setPadding(0, rowPadding, 0, rowPadding);
} else {
ViewGroup.MarginLayoutParams layoutParams =
(ViewGroup.MarginLayoutParams) rowBody.getLayoutParams();
layoutParams.setMargins(
layoutParams.leftMargin, rowPadding, layoutParams.rightMargin, rowPadding);
}
nameView.setTextSize(fontSize);
description.setTextSize(fontSize);
fontSizeDetails = Math.max(10, fontSize - 2);
dueDate.setTextSize(fontSizeDetails);
view.setTag(this);
for (int i = 0; i < view.getChildCount(); i++) {
view.getChildAt(i).setTag(this);
}
}
void setMoving(boolean moving) {
this.moving = moving;
updateBackground();
}
boolean isMoving() {
return moving;
}
private void updateBackground() {
if (selected || moving) {
rowBody.setBackgroundColor(selectedColor);
} else {
rowBody.setBackgroundResource(background);
rowBody.getBackground().jumpToCurrentState();
}
}
public void setSelected(boolean selected) {
this.selected = selected;
updateBackground();
}
@SuppressLint("NewApi")
public void setIndent(int indent) {
this.indent = indent;
int indentSize = getIndentSize(indent);
if (atLeastLollipop()) {
ViewGroup.MarginLayoutParams layoutParams =
(ViewGroup.MarginLayoutParams) row.getLayoutParams();
layoutParams.setMarginStart(indentSize);
} else {
rowBody.setPadding(indentSize, rowBody.getPaddingTop(), 0, rowBody.getPaddingBottom());
}
}
float getShiftSize() {
return 20 * metrics.density;
}
private int getIndentSize(int indent) {
return Math.round(indent * getShiftSize());
}
boolean isIndented() {
return indent > 0;
}
void bindView(Task task) {
this.task = task;
setFieldContentsAndVisibility();
setTaskAppearance();
if (preferences.getBoolean(R.string.p_show_description, true)) {
description.setText(task.getNotes());
description.setVisibility(task.hasNotes() ? View.VISIBLE : View.GONE);
}
}
/** Helper method to set the contents and visibility of each field */
private synchronized void setFieldContentsAndVisibility() {
nameView.setText(task.getTitle());
hidden.setVisibility(task.isHidden() ? View.VISIBLE : View.GONE);
setupDueDateAndTags();
}
private void setTaskAppearance() {
if (task.isCompleted()) {
nameView.setTextColor(textColorSecondary);
nameView.setPaintFlags(nameView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
} else {
nameView.setTextColor(task.isHidden() ? textColorSecondary : textColorPrimary);
nameView.setEnabled(true);
nameView.setPaintFlags(nameView.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
}
setupDueDateAndTags();
setupCompleteBox();
}
private void setupCompleteBox() {
// complete box
final CheckableImageView checkBoxView = completeBox;
boolean completed = task.isCompleted();
checkBoxView.setChecked(completed);
if (completed) {
checkBoxView.setImageDrawable(checkBoxes.getCompletedCheckbox(task.getPriority()));
} else if (TextUtils.isEmpty(task.getRecurrence())) {
checkBoxView.setImageDrawable(checkBoxes.getCheckBox(task.getPriority()));
} else {
checkBoxView.setImageDrawable(checkBoxes.getRepeatingCheckBox(task.getPriority()));
}
checkBoxView.invalidate();
}
private void setupDueDateAndTags() {
// due date / completion date
if (!task.isCompleted() && task.hasDueDate()) {
if (task.isOverdue()) {
dueDate.setTextColor(textColorOverdue);
} else {
dueDate.setTextColor(textColorSecondary);
}
String dateValue = DateUtilities.getRelativeDateStringWithTime(context, task.getDueDate());
dueDate.setText(dateValue);
dueDate.setVisibility(View.VISIBLE);
} else {
dueDate.setVisibility(View.GONE);
}
String tags = task.getTagsString();
List<String> tagUuids = tags != null ? newArrayList(tags.split(",")) : Lists.newArrayList();
List<Chip> chips = chipProvider.getChips(task.getCaldav(), task.getGoogleTaskList(), tagUuids);
if (chips.isEmpty()) {
chipScroll.setVisibility(View.GONE);
} else {
chipGroup.removeAllViews();
for (Chip chip : chips) {
chip.setTextSize(fontSizeDetails);
chip.setOnClickListener(view -> callback.onClick((Filter) view.getTag()));
chipGroup.addView(chip);
}
chipScroll.setVisibility(View.VISIBLE);
}
}
@OnClick(R.id.rowBody)
void onRowBodyClick() {
callback.onClick(this);
}
@OnLongClick(R.id.rowBody)
boolean onRowBodyLongClick() {
return callback.onLongPress(this);
}
@OnClick(R.id.completeBox)
void onCompleteBoxClick(View v) {
if (task == null) {
return;
}
boolean newState = completeBox.isChecked();
if (newState != task.isCompleted()) {
callback.onCompletedTask(task, newState);
taskDao.setComplete(task, newState);
}
// set check box to actual action item state
setTaskAppearance();
}
interface ViewHolderCallbacks {
void onCompletedTask(Task task, boolean newState);
void onClick(ViewHolder viewHolder);
void onClick(Filter filter);
boolean onLongPress(ViewHolder viewHolder);
}
}