Use material chips in tag control set

pull/757/head
Alex Baker 6 years ago
parent f7f03e68ac
commit 57ef0f1088

@ -16,20 +16,11 @@ import static com.todoroo.andlib.utility.AndroidUtilities.atLeastJellybeanMR1;
import android.annotation.SuppressLint;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.appcompat.app.AlertDialog;
import android.text.Editable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextWatcher;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
@ -38,9 +29,15 @@ import android.widget.CheckedTextView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import butterknife.BindView;
import butterknife.OnClick;
import com.google.common.base.Function;
import com.google.android.material.chip.Chip;
import com.google.android.material.chip.ChipGroup;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.Ordering;
@ -61,6 +58,7 @@ import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.FragmentComponent;
import org.tasks.themes.ThemeCache;
import org.tasks.themes.ThemeColor;
import org.tasks.ui.ChipProvider;
import org.tasks.ui.TaskEditControlFragment;
/**
@ -72,27 +70,23 @@ public final class TagsControlSet extends TaskEditControlFragment {
public static final int TAG = R.string.TEA_ctrl_lists_pref;
private static final char SPACE = '\u0020';
private static final char NO_BREAK_SPACE = '\u00a0';
private static final String EXTRA_NEW_TAGS = "extra_new_tags";
private static final String EXTRA_ORIGINAL_TAGS = "extra_original_tags";
private static final String EXTRA_SELECTED_TAGS = "extra_selected_tags";
private final Ordering<TagData> orderByName =
new Ordering<TagData>() {
@Override
public int compare(TagData left, TagData right) {
return left.getName().compareTo(right.getName());
}
};
@Inject TagDao tagDao;
@Inject TagDataDao tagDataDao;
@Inject TagService tagService;
@Inject DialogBuilder dialogBuilder;
@Inject ThemeCache themeCache;
@Inject ChipProvider chipProvider;
@BindView(R.id.display_row_edit)
@BindView(R.id.no_tags)
TextView tagsDisplay;
@BindView(R.id.chip_group)
ChipGroup chipGroup;
private LinearLayout newTagLayout;
private ListView tagListView;
private View dialogView;
@ -100,44 +94,13 @@ public final class TagsControlSet extends TaskEditControlFragment {
private List<TagData> allTags;
private ArrayList<TagData> originalTags;
private ArrayList<TagData> selectedTags;
private Function<TagData, SpannableString> tagToString(final float maxLength) {
return tagData -> {
String tagName = tagData.getName();
tagName =
tagName
.substring(0, Math.min(tagName.length(), (int) maxLength))
.replace(' ', NO_BREAK_SPACE);
SpannableString string = new SpannableString(NO_BREAK_SPACE + tagName + NO_BREAK_SPACE);
int themeIndex = tagData.getColor();
ThemeColor color =
themeIndex >= 0 ? themeCache.getThemeColor(themeIndex) : themeCache.getUntaggedColor();
string.setSpan(
new BackgroundColorSpan(color.getPrimaryColor()),
0,
string.length(),
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
string.setSpan(
new ForegroundColorSpan(color.getActionBarTint()),
0,
string.length(),
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
return string;
};
}
private CharSequence buildTagString() {
List<TagData> sortedTagData = orderByName.sortedCopy(selectedTags);
List<SpannableString> tagStrings = transform(sortedTagData, tagToString(Float.MAX_VALUE));
SpannableStringBuilder builder = new SpannableStringBuilder();
for (SpannableString tagString : tagStrings) {
if (builder.length() > 0) {
builder.append(SPACE);
}
builder.append(tagString);
}
return builder;
}
private final Ordering<TagData> orderByName =
new Ordering<TagData>() {
@Override
public int compare(TagData left, TagData right) {
return left.getName().compareTo(right.getName());
}
};
@Nullable
@Override
@ -190,7 +153,7 @@ public final class TagsControlSet extends TaskEditControlFragment {
}
addTag("");
for (TagData tag : selectedTags) {
setTagSelected(tag);
setTagSelected(tag, true);
}
refreshDisplayView();
return view;
@ -218,8 +181,8 @@ public final class TagsControlSet extends TaskEditControlFragment {
}
}
@OnClick(R.id.display_row_edit)
void openPopup(View view) {
@OnClick(R.id.tag_row)
void onClickRow() {
if (dialog == null) {
dialog = buildDialog();
}
@ -234,10 +197,10 @@ public final class TagsControlSet extends TaskEditControlFragment {
.create();
}
private void setTagSelected(TagData tag) {
private void setTagSelected(TagData tag, boolean selected) {
int index = allTags.indexOf(tag);
if (index >= 0) {
tagListView.setItemChecked(index, true);
tagListView.setItemChecked(index, selected);
}
}
@ -261,7 +224,7 @@ public final class TagsControlSet extends TaskEditControlFragment {
TagData tagByName = tagDataDao.getTagByName(text);
if (tagByName != null) {
if (!isSelected(tags, text)) {
setTagSelected(tagByName);
setTagSelected(tagByName, true);
tags.add(tagByName);
}
newTagLayout.removeViewAt(i);
@ -387,7 +350,26 @@ public final class TagsControlSet extends TaskEditControlFragment {
private void refreshDisplayView() {
selectedTags = getSelectedTags();
tagsDisplay.setText(buildTagString());
if (selectedTags.isEmpty()) {
chipGroup.setVisibility(View.GONE);
tagsDisplay.setVisibility(View.VISIBLE);
} else {
tagsDisplay.setVisibility(View.GONE);
chipGroup.setVisibility(View.VISIBLE);
chipGroup.removeAllViews();
for (TagData tagData : orderByName.sortedCopy(selectedTags)) {
Chip chip = chipProvider.getChip(tagData);
chip.setOnClickListener(view -> {
onClickRow();
});
chip.setOnCloseIconClickListener(
view -> {
setTagSelected(tagData, false);
refreshDisplayView();
});
chipGroup.addView(chip);
}
}
}
private boolean synchronizeTags(long taskId, String taskUuid) {

@ -5,28 +5,44 @@ import static org.tasks.preferences.ResourceResolver.getDimen;
import android.content.Context;
import android.content.res.ColorStateList;
import com.google.android.material.chip.Chip;
import com.google.common.collect.Ordering;
import com.todoroo.astrid.api.Filter;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.data.TagData;
import org.tasks.injection.ForActivity;
import org.tasks.themes.ThemeCache;
import org.tasks.themes.ThemeColor;
public class ChipProvider {
private final Context context;
private final ThemeCache themeCache;
private final int iconAlpha;
@Inject
public ChipProvider(@ForActivity Context context, ThemeCache themeCache) {
this.context = context;
this.themeCache = themeCache;
iconAlpha = (int) (255 * getDimen(context, R.dimen.alpha_secondary));
}
public Chip getChip(TagData tagData) {
Chip chip = new Chip(context);
chip.setCloseIconVisible(true);
apply(chip, tagData.getName(), tagData.getColor());
return chip;
}
public void apply(Chip chip, Filter filter) {
int tint = filter.tint;
ThemeColor color = tint >= 0 ? themeCache.getThemeColor(tint) : themeCache.getUntaggedColor();
chip.setText(filter.listingTitle);
apply(chip, filter.listingTitle, filter.tint);
}
private void apply(Chip chip, String name, int theme) {
ThemeColor color = theme >= 0 ? themeCache.getThemeColor(theme) : themeCache.getUntaggedColor();
chip.setText(name);
chip.setCloseIconTint(
new ColorStateList(new int[][] {new int[] {}}, new int[] {color.getActionBarTint()}));
chip.setTextColor(color.getActionBarTint());

@ -3,11 +3,23 @@
**
** See the file "LICENSE" for the full license governing this code.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/display_row_edit"
style="@style/TaskEditTextPrimary"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tag_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:hint="@string/tag_FEx_untagged"
android:textAlignment="viewStart"/>
android:orientation="vertical">
<TextView
android:id="@+id/no_tags"
style="@style/TaskEditTextPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:hint="@string/tag_FEx_untagged"
android:textAlignment="viewStart"/>
<com.google.android.material.chip.ChipGroup
android:id="@+id/chip_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

Loading…
Cancel
Save