Loading app/src/main/java/it/niedermann/owncloud/notes/model/ItemAdapter.java +2 −2 Original line number Diff line number Diff line Loading @@ -100,11 +100,11 @@ public class ItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> i break; } case TYPE_NOTE_WITH_EXCERPT: { ((NoteViewHolderWithExcerpt) holder).bind((DBNote) itemList.get(position), noteClickListener, showCategory, mainColor, textColor, searchQuery); ((NoteViewHolderWithExcerpt) holder).bind((DBNote) itemList.get(position), showCategory, mainColor, textColor, searchQuery); break; } case TYPE_NOTE_WITHOUT_EXCERPT: { ((NoteViewHolderWithoutExcerpt) holder).bind((DBNote) itemList.get(position), noteClickListener, showCategory, mainColor, textColor, searchQuery); ((NoteViewHolderWithoutExcerpt) holder).bind((DBNote) itemList.get(position), showCategory, mainColor, textColor, searchQuery); break; } } Loading app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolder.java +105 −1 Original line number Diff line number Diff line package it.niedermann.owncloud.notes.model; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; import android.os.Build; import android.text.SpannableString; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; import android.text.style.ForegroundColorSpan; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.drawable.DrawableCompat; import androidx.recyclerview.widget.RecyclerView; import java.util.regex.Matcher; import java.util.regex.Pattern; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.util.Notes; import static androidx.recyclerview.widget.RecyclerView.NO_POSITION; import static it.niedermann.owncloud.notes.util.ColorUtil.contrastRatioIsSufficient; import static it.niedermann.owncloud.notes.util.ColorUtil.isColorDark; public abstract class NoteViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener { private final NoteClickListener noteClickListener; public NoteViewHolder(View v, NoteClickListener noteClickListener) { public NoteViewHolder(@NonNull View v, @NonNull NoteClickListener noteClickListener) { super(v); this.noteClickListener = noteClickListener; v.setOnClickListener(this); Loading @@ -29,6 +52,87 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder implements return noteClickListener.onNoteLongClick(getAdapterPosition(), v); } protected void bindCategory(Context context, TextView noteCategory, boolean showCategory, String category, int mainColor) { final boolean isDarkThemeActive = Notes.isDarkThemeActive(context); noteCategory.setVisibility(showCategory && !category.isEmpty() ? View.VISIBLE : View.GONE); noteCategory.setText(category); @ColorInt int categoryForeground; @ColorInt int categoryBackground; if (isDarkThemeActive) { if (isColorDark(mainColor)) { if (contrastRatioIsSufficient(mainColor, Color.BLACK)) { categoryBackground = mainColor; categoryForeground = Color.WHITE; } else { categoryBackground = Color.WHITE; categoryForeground = mainColor; } } else { categoryBackground = mainColor; categoryForeground = Color.BLACK; } } else { categoryForeground = Color.BLACK; if (isColorDark(mainColor) || contrastRatioIsSufficient(mainColor, Color.WHITE)) { categoryBackground = mainColor; } else { categoryBackground = Color.BLACK; } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { DrawableCompat.setTint(noteCategory.getBackground(), categoryBackground); } else { final GradientDrawable drawable = (GradientDrawable) noteCategory.getBackground(); drawable.setStroke(1, categoryBackground); drawable.setColor(isDarkThemeActive ? categoryBackground : Color.TRANSPARENT); } noteCategory.setTextColor(categoryForeground); } protected void bindFavorite(ImageView noteFavorite, boolean isFavorite) { noteFavorite.setImageResource(isFavorite ? R.drawable.ic_star_yellow_24dp : R.drawable.ic_star_grey_ccc_24dp); noteFavorite.setOnClickListener(view -> noteClickListener.onNoteFavoriteClick(getAdapterPosition(), view)); } protected void bindTitleAndExcerpt(Context context, TextView noteTitle, @Nullable TextView noteExcerpt, CharSequence searchQuery, DBNote note, int mainColor) { if (!TextUtils.isEmpty(searchQuery)) { @ColorInt final int searchBackground = context.getResources().getColor(R.color.bg_highlighted); @ColorInt final int searchForeground = BrandingUtil.getSecondaryForegroundColorDependingOnTheme(context, mainColor); // The Pattern.quote method will add \Q to the very beginning of the string and \E to the end of the string // It implies that the string between \Q and \E is a literal string and thus the reserved keyword in such string will be ignored. // See https://stackoverflow.com/questions/15409296/what-is-the-use-of-pattern-quote-method final Pattern pattern = Pattern.compile("(" + Pattern.quote(searchQuery.toString()) + ")", Pattern.CASE_INSENSITIVE); SpannableString spannableString = new SpannableString(note.getTitle()); Matcher matcher = pattern.matcher(spannableString); while (matcher.find()) { spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); } noteTitle.setText(spannableString); spannableString = new SpannableString(note.getExcerpt()); matcher = pattern.matcher(spannableString); while (matcher.find()) { spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); } if (noteExcerpt != null) { noteExcerpt.setText(spannableString); } } else { noteTitle.setText(note.getTitle()); if (noteExcerpt != null) { noteExcerpt.setText(note.getExcerpt()); } } } public abstract void showSwipe(boolean left); public abstract View getNoteSwipeable(); Loading app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolderWithExcerpt.java +4 −89 Original line number Diff line number Diff line package it.niedermann.owncloud.notes.model; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; import android.os.Build; import android.text.SpannableString; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; import android.text.style.ForegroundColorSpan; import android.view.View; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.drawable.DrawableCompat; import java.util.regex.Matcher; import java.util.regex.Pattern; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ItemNotesListNoteItemWithExcerptBinding; import it.niedermann.owncloud.notes.util.Notes; import static it.niedermann.owncloud.notes.util.ColorUtil.contrastRatioIsSufficient; import static it.niedermann.owncloud.notes.util.ColorUtil.isColorDark; public class NoteViewHolderWithExcerpt extends NoteViewHolder { @NonNull Loading @@ -43,81 +26,13 @@ public class NoteViewHolderWithExcerpt extends NoteViewHolder { binding.noteSwipeFrame.setBackgroundResource(left ? R.color.bg_warning : R.color.bg_attention); } public void bind(DBNote note, NoteClickListener noteClickListener, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { public void bind(DBNote note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { @NonNull final Context context = itemView.getContext(); final boolean isDarkThemeActive = Notes.isDarkThemeActive(context); binding.noteSwipeable.setAlpha(DBStatus.LOCAL_DELETED.equals(note.getStatus()) ? 0.5f : 1.0f); binding.noteCategory.setVisibility(showCategory && !note.getCategory().isEmpty() ? View.VISIBLE : View.GONE); binding.noteCategory.setText(note.getCategory()); @ColorInt int categoryForeground; @ColorInt int categoryBackground; if (isDarkThemeActive) { if (isColorDark(mainColor)) { if (contrastRatioIsSufficient(mainColor, Color.BLACK)) { categoryBackground = mainColor; categoryForeground = Color.WHITE; } else { categoryBackground = Color.WHITE; categoryForeground = mainColor; } } else { categoryBackground = mainColor; categoryForeground = Color.BLACK; } } else { categoryForeground = Color.BLACK; if (isColorDark(mainColor) || contrastRatioIsSufficient(mainColor, Color.WHITE)) { categoryBackground = mainColor; } else { categoryBackground = Color.BLACK; } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { DrawableCompat.setTint(binding.noteCategory.getBackground(), categoryBackground); } else { final GradientDrawable drawable = (GradientDrawable) binding.noteCategory.getBackground(); drawable.setStroke(1, categoryBackground); drawable.setColor(isDarkThemeActive ? categoryBackground : Color.TRANSPARENT); } binding.noteCategory.setTextColor(categoryForeground); bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), mainColor); binding.noteStatus.setVisibility(DBStatus.VOID.equals(note.getStatus()) ? View.INVISIBLE : View.VISIBLE); binding.noteFavorite.setImageResource(note.isFavorite() ? R.drawable.ic_star_yellow_24dp : R.drawable.ic_star_grey_ccc_24dp); binding.noteFavorite.setOnClickListener(view -> noteClickListener.onNoteFavoriteClick(getAdapterPosition(), view)); if (!TextUtils.isEmpty(searchQuery)) { @ColorInt final int searchBackground = context.getResources().getColor(R.color.bg_highlighted); @ColorInt final int searchForeground = BrandingUtil.getSecondaryForegroundColorDependingOnTheme(context, mainColor); // The Pattern.quote method will add \Q to the very beginning of the string and \E to the end of the string // It implies that the string between \Q and \E is a literal string and thus the reserved keyword in such string will be ignored. // See https://stackoverflow.com/questions/15409296/what-is-the-use-of-pattern-quote-method final Pattern pattern = Pattern.compile("(" + Pattern.quote(searchQuery.toString()) + ")", Pattern.CASE_INSENSITIVE); SpannableString spannableString = new SpannableString(note.getTitle()); Matcher matcher = pattern.matcher(spannableString); while (matcher.find()) { spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); } binding.noteTitle.setText(spannableString); spannableString = new SpannableString(note.getExcerpt()); matcher = pattern.matcher(spannableString); while (matcher.find()) { spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); } binding.noteExcerpt.setText(spannableString); } else { binding.noteTitle.setText(note.getTitle()); binding.noteExcerpt.setText(note.getExcerpt()); } bindFavorite(binding.noteFavorite, note.isFavorite()); bindTitleAndExcerpt(context, binding.noteTitle, binding.noteExcerpt, searchQuery, note, mainColor); } public View getNoteSwipeable() { Loading app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolderWithoutExcerpt.java +4 −88 Original line number Diff line number Diff line package it.niedermann.owncloud.notes.model; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; import android.os.Build; import android.text.SpannableString; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; import android.text.style.ForegroundColorSpan; import android.view.View; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.drawable.DrawableCompat; import java.util.regex.Matcher; import java.util.regex.Pattern; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ItemNotesListNoteItemWithoutExcerptBinding; import it.niedermann.owncloud.notes.util.Notes; import static it.niedermann.owncloud.notes.util.ColorUtil.contrastRatioIsSufficient; import static it.niedermann.owncloud.notes.util.ColorUtil.isColorDark; public class NoteViewHolderWithoutExcerpt extends NoteViewHolder { @NonNull Loading @@ -44,80 +27,13 @@ public class NoteViewHolderWithoutExcerpt extends NoteViewHolder { binding.noteSwipeFrame.setBackgroundResource(left ? R.color.bg_warning : R.color.bg_attention); } public void bind(DBNote note, NoteClickListener noteClickListener, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { public void bind(DBNote note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { @NonNull final Context context = itemView.getContext(); final boolean isDarkThemeActive = Notes.isDarkThemeActive(context); binding.noteSwipeable.setAlpha(DBStatus.LOCAL_DELETED.equals(note.getStatus()) ? 0.5f : 1.0f); binding.noteCategory.setVisibility(showCategory && !note.getCategory().isEmpty() ? View.VISIBLE : View.GONE); binding.noteCategory.setText(note.getCategory()); @ColorInt int categoryForeground; @ColorInt int categoryBackground; if (isDarkThemeActive) { if (isColorDark(mainColor)) { if (contrastRatioIsSufficient(mainColor, Color.BLACK)) { categoryBackground = mainColor; categoryForeground = Color.WHITE; } else { categoryBackground = Color.WHITE; categoryForeground = mainColor; } } else { categoryBackground = mainColor; categoryForeground = Color.BLACK; } } else { categoryForeground = Color.BLACK; if (isColorDark(mainColor) || contrastRatioIsSufficient(mainColor, Color.WHITE)) { categoryBackground = mainColor; } else { categoryBackground = Color.BLACK; } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { DrawableCompat.setTint(binding.noteCategory.getBackground(), categoryBackground); } else { final GradientDrawable drawable = (GradientDrawable) binding.noteCategory.getBackground(); drawable.setStroke(1, categoryBackground); drawable.setColor(isDarkThemeActive ? categoryBackground : Color.TRANSPARENT); } binding.noteCategory.setTextColor(categoryForeground); bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), mainColor); binding.noteStatus.setVisibility(DBStatus.VOID.equals(note.getStatus()) ? View.INVISIBLE : View.VISIBLE); binding.noteFavorite.setImageResource(note.isFavorite() ? R.drawable.ic_star_yellow_24dp : R.drawable.ic_star_grey_ccc_24dp); binding.noteFavorite.setOnClickListener(view -> noteClickListener.onNoteFavoriteClick(getAdapterPosition(), view)); if (!TextUtils.isEmpty(searchQuery)) { @ColorInt final int searchBackground = context.getResources().getColor(R.color.bg_highlighted); @ColorInt final int searchForeground = BrandingUtil.getSecondaryForegroundColorDependingOnTheme(context, mainColor); // The Pattern.quote method will add \Q to the very beginning of the string and \E to the end of the string // It implies that the string between \Q and \E is a literal string and thus the reserved keyword in such string will be ignored. // See https://stackoverflow.com/questions/15409296/what-is-the-use-of-pattern-quote-method final Pattern pattern = Pattern.compile("(" + Pattern.quote(searchQuery.toString()) + ")", Pattern.CASE_INSENSITIVE); SpannableString spannableString = new SpannableString(note.getTitle()); Matcher matcher = pattern.matcher(spannableString); while (matcher.find()) { spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); } binding.noteTitle.setText(spannableString); spannableString = new SpannableString(note.getExcerpt()); matcher = pattern.matcher(spannableString); while (matcher.find()) { spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); } } else { binding.noteTitle.setText(note.getTitle()); } bindFavorite(binding.noteFavorite, note.isFavorite()); bindTitleAndExcerpt(context, binding.noteTitle, null, searchQuery, note, mainColor); } public View getNoteSwipeable() { Loading Loading
app/src/main/java/it/niedermann/owncloud/notes/model/ItemAdapter.java +2 −2 Original line number Diff line number Diff line Loading @@ -100,11 +100,11 @@ public class ItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> i break; } case TYPE_NOTE_WITH_EXCERPT: { ((NoteViewHolderWithExcerpt) holder).bind((DBNote) itemList.get(position), noteClickListener, showCategory, mainColor, textColor, searchQuery); ((NoteViewHolderWithExcerpt) holder).bind((DBNote) itemList.get(position), showCategory, mainColor, textColor, searchQuery); break; } case TYPE_NOTE_WITHOUT_EXCERPT: { ((NoteViewHolderWithoutExcerpt) holder).bind((DBNote) itemList.get(position), noteClickListener, showCategory, mainColor, textColor, searchQuery); ((NoteViewHolderWithoutExcerpt) holder).bind((DBNote) itemList.get(position), showCategory, mainColor, textColor, searchQuery); break; } } Loading
app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolder.java +105 −1 Original line number Diff line number Diff line package it.niedermann.owncloud.notes.model; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; import android.os.Build; import android.text.SpannableString; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; import android.text.style.ForegroundColorSpan; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.drawable.DrawableCompat; import androidx.recyclerview.widget.RecyclerView; import java.util.regex.Matcher; import java.util.regex.Pattern; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.util.Notes; import static androidx.recyclerview.widget.RecyclerView.NO_POSITION; import static it.niedermann.owncloud.notes.util.ColorUtil.contrastRatioIsSufficient; import static it.niedermann.owncloud.notes.util.ColorUtil.isColorDark; public abstract class NoteViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener { private final NoteClickListener noteClickListener; public NoteViewHolder(View v, NoteClickListener noteClickListener) { public NoteViewHolder(@NonNull View v, @NonNull NoteClickListener noteClickListener) { super(v); this.noteClickListener = noteClickListener; v.setOnClickListener(this); Loading @@ -29,6 +52,87 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder implements return noteClickListener.onNoteLongClick(getAdapterPosition(), v); } protected void bindCategory(Context context, TextView noteCategory, boolean showCategory, String category, int mainColor) { final boolean isDarkThemeActive = Notes.isDarkThemeActive(context); noteCategory.setVisibility(showCategory && !category.isEmpty() ? View.VISIBLE : View.GONE); noteCategory.setText(category); @ColorInt int categoryForeground; @ColorInt int categoryBackground; if (isDarkThemeActive) { if (isColorDark(mainColor)) { if (contrastRatioIsSufficient(mainColor, Color.BLACK)) { categoryBackground = mainColor; categoryForeground = Color.WHITE; } else { categoryBackground = Color.WHITE; categoryForeground = mainColor; } } else { categoryBackground = mainColor; categoryForeground = Color.BLACK; } } else { categoryForeground = Color.BLACK; if (isColorDark(mainColor) || contrastRatioIsSufficient(mainColor, Color.WHITE)) { categoryBackground = mainColor; } else { categoryBackground = Color.BLACK; } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { DrawableCompat.setTint(noteCategory.getBackground(), categoryBackground); } else { final GradientDrawable drawable = (GradientDrawable) noteCategory.getBackground(); drawable.setStroke(1, categoryBackground); drawable.setColor(isDarkThemeActive ? categoryBackground : Color.TRANSPARENT); } noteCategory.setTextColor(categoryForeground); } protected void bindFavorite(ImageView noteFavorite, boolean isFavorite) { noteFavorite.setImageResource(isFavorite ? R.drawable.ic_star_yellow_24dp : R.drawable.ic_star_grey_ccc_24dp); noteFavorite.setOnClickListener(view -> noteClickListener.onNoteFavoriteClick(getAdapterPosition(), view)); } protected void bindTitleAndExcerpt(Context context, TextView noteTitle, @Nullable TextView noteExcerpt, CharSequence searchQuery, DBNote note, int mainColor) { if (!TextUtils.isEmpty(searchQuery)) { @ColorInt final int searchBackground = context.getResources().getColor(R.color.bg_highlighted); @ColorInt final int searchForeground = BrandingUtil.getSecondaryForegroundColorDependingOnTheme(context, mainColor); // The Pattern.quote method will add \Q to the very beginning of the string and \E to the end of the string // It implies that the string between \Q and \E is a literal string and thus the reserved keyword in such string will be ignored. // See https://stackoverflow.com/questions/15409296/what-is-the-use-of-pattern-quote-method final Pattern pattern = Pattern.compile("(" + Pattern.quote(searchQuery.toString()) + ")", Pattern.CASE_INSENSITIVE); SpannableString spannableString = new SpannableString(note.getTitle()); Matcher matcher = pattern.matcher(spannableString); while (matcher.find()) { spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); } noteTitle.setText(spannableString); spannableString = new SpannableString(note.getExcerpt()); matcher = pattern.matcher(spannableString); while (matcher.find()) { spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); } if (noteExcerpt != null) { noteExcerpt.setText(spannableString); } } else { noteTitle.setText(note.getTitle()); if (noteExcerpt != null) { noteExcerpt.setText(note.getExcerpt()); } } } public abstract void showSwipe(boolean left); public abstract View getNoteSwipeable(); Loading
app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolderWithExcerpt.java +4 −89 Original line number Diff line number Diff line package it.niedermann.owncloud.notes.model; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; import android.os.Build; import android.text.SpannableString; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; import android.text.style.ForegroundColorSpan; import android.view.View; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.drawable.DrawableCompat; import java.util.regex.Matcher; import java.util.regex.Pattern; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ItemNotesListNoteItemWithExcerptBinding; import it.niedermann.owncloud.notes.util.Notes; import static it.niedermann.owncloud.notes.util.ColorUtil.contrastRatioIsSufficient; import static it.niedermann.owncloud.notes.util.ColorUtil.isColorDark; public class NoteViewHolderWithExcerpt extends NoteViewHolder { @NonNull Loading @@ -43,81 +26,13 @@ public class NoteViewHolderWithExcerpt extends NoteViewHolder { binding.noteSwipeFrame.setBackgroundResource(left ? R.color.bg_warning : R.color.bg_attention); } public void bind(DBNote note, NoteClickListener noteClickListener, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { public void bind(DBNote note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { @NonNull final Context context = itemView.getContext(); final boolean isDarkThemeActive = Notes.isDarkThemeActive(context); binding.noteSwipeable.setAlpha(DBStatus.LOCAL_DELETED.equals(note.getStatus()) ? 0.5f : 1.0f); binding.noteCategory.setVisibility(showCategory && !note.getCategory().isEmpty() ? View.VISIBLE : View.GONE); binding.noteCategory.setText(note.getCategory()); @ColorInt int categoryForeground; @ColorInt int categoryBackground; if (isDarkThemeActive) { if (isColorDark(mainColor)) { if (contrastRatioIsSufficient(mainColor, Color.BLACK)) { categoryBackground = mainColor; categoryForeground = Color.WHITE; } else { categoryBackground = Color.WHITE; categoryForeground = mainColor; } } else { categoryBackground = mainColor; categoryForeground = Color.BLACK; } } else { categoryForeground = Color.BLACK; if (isColorDark(mainColor) || contrastRatioIsSufficient(mainColor, Color.WHITE)) { categoryBackground = mainColor; } else { categoryBackground = Color.BLACK; } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { DrawableCompat.setTint(binding.noteCategory.getBackground(), categoryBackground); } else { final GradientDrawable drawable = (GradientDrawable) binding.noteCategory.getBackground(); drawable.setStroke(1, categoryBackground); drawable.setColor(isDarkThemeActive ? categoryBackground : Color.TRANSPARENT); } binding.noteCategory.setTextColor(categoryForeground); bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), mainColor); binding.noteStatus.setVisibility(DBStatus.VOID.equals(note.getStatus()) ? View.INVISIBLE : View.VISIBLE); binding.noteFavorite.setImageResource(note.isFavorite() ? R.drawable.ic_star_yellow_24dp : R.drawable.ic_star_grey_ccc_24dp); binding.noteFavorite.setOnClickListener(view -> noteClickListener.onNoteFavoriteClick(getAdapterPosition(), view)); if (!TextUtils.isEmpty(searchQuery)) { @ColorInt final int searchBackground = context.getResources().getColor(R.color.bg_highlighted); @ColorInt final int searchForeground = BrandingUtil.getSecondaryForegroundColorDependingOnTheme(context, mainColor); // The Pattern.quote method will add \Q to the very beginning of the string and \E to the end of the string // It implies that the string between \Q and \E is a literal string and thus the reserved keyword in such string will be ignored. // See https://stackoverflow.com/questions/15409296/what-is-the-use-of-pattern-quote-method final Pattern pattern = Pattern.compile("(" + Pattern.quote(searchQuery.toString()) + ")", Pattern.CASE_INSENSITIVE); SpannableString spannableString = new SpannableString(note.getTitle()); Matcher matcher = pattern.matcher(spannableString); while (matcher.find()) { spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); } binding.noteTitle.setText(spannableString); spannableString = new SpannableString(note.getExcerpt()); matcher = pattern.matcher(spannableString); while (matcher.find()) { spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); } binding.noteExcerpt.setText(spannableString); } else { binding.noteTitle.setText(note.getTitle()); binding.noteExcerpt.setText(note.getExcerpt()); } bindFavorite(binding.noteFavorite, note.isFavorite()); bindTitleAndExcerpt(context, binding.noteTitle, binding.noteExcerpt, searchQuery, note, mainColor); } public View getNoteSwipeable() { Loading
app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolderWithoutExcerpt.java +4 −88 Original line number Diff line number Diff line package it.niedermann.owncloud.notes.model; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.GradientDrawable; import android.os.Build; import android.text.SpannableString; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; import android.text.style.ForegroundColorSpan; import android.view.View; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.drawable.DrawableCompat; import java.util.regex.Matcher; import java.util.regex.Pattern; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ItemNotesListNoteItemWithoutExcerptBinding; import it.niedermann.owncloud.notes.util.Notes; import static it.niedermann.owncloud.notes.util.ColorUtil.contrastRatioIsSufficient; import static it.niedermann.owncloud.notes.util.ColorUtil.isColorDark; public class NoteViewHolderWithoutExcerpt extends NoteViewHolder { @NonNull Loading @@ -44,80 +27,13 @@ public class NoteViewHolderWithoutExcerpt extends NoteViewHolder { binding.noteSwipeFrame.setBackgroundResource(left ? R.color.bg_warning : R.color.bg_attention); } public void bind(DBNote note, NoteClickListener noteClickListener, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { public void bind(DBNote note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { @NonNull final Context context = itemView.getContext(); final boolean isDarkThemeActive = Notes.isDarkThemeActive(context); binding.noteSwipeable.setAlpha(DBStatus.LOCAL_DELETED.equals(note.getStatus()) ? 0.5f : 1.0f); binding.noteCategory.setVisibility(showCategory && !note.getCategory().isEmpty() ? View.VISIBLE : View.GONE); binding.noteCategory.setText(note.getCategory()); @ColorInt int categoryForeground; @ColorInt int categoryBackground; if (isDarkThemeActive) { if (isColorDark(mainColor)) { if (contrastRatioIsSufficient(mainColor, Color.BLACK)) { categoryBackground = mainColor; categoryForeground = Color.WHITE; } else { categoryBackground = Color.WHITE; categoryForeground = mainColor; } } else { categoryBackground = mainColor; categoryForeground = Color.BLACK; } } else { categoryForeground = Color.BLACK; if (isColorDark(mainColor) || contrastRatioIsSufficient(mainColor, Color.WHITE)) { categoryBackground = mainColor; } else { categoryBackground = Color.BLACK; } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { DrawableCompat.setTint(binding.noteCategory.getBackground(), categoryBackground); } else { final GradientDrawable drawable = (GradientDrawable) binding.noteCategory.getBackground(); drawable.setStroke(1, categoryBackground); drawable.setColor(isDarkThemeActive ? categoryBackground : Color.TRANSPARENT); } binding.noteCategory.setTextColor(categoryForeground); bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), mainColor); binding.noteStatus.setVisibility(DBStatus.VOID.equals(note.getStatus()) ? View.INVISIBLE : View.VISIBLE); binding.noteFavorite.setImageResource(note.isFavorite() ? R.drawable.ic_star_yellow_24dp : R.drawable.ic_star_grey_ccc_24dp); binding.noteFavorite.setOnClickListener(view -> noteClickListener.onNoteFavoriteClick(getAdapterPosition(), view)); if (!TextUtils.isEmpty(searchQuery)) { @ColorInt final int searchBackground = context.getResources().getColor(R.color.bg_highlighted); @ColorInt final int searchForeground = BrandingUtil.getSecondaryForegroundColorDependingOnTheme(context, mainColor); // The Pattern.quote method will add \Q to the very beginning of the string and \E to the end of the string // It implies that the string between \Q and \E is a literal string and thus the reserved keyword in such string will be ignored. // See https://stackoverflow.com/questions/15409296/what-is-the-use-of-pattern-quote-method final Pattern pattern = Pattern.compile("(" + Pattern.quote(searchQuery.toString()) + ")", Pattern.CASE_INSENSITIVE); SpannableString spannableString = new SpannableString(note.getTitle()); Matcher matcher = pattern.matcher(spannableString); while (matcher.find()) { spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); } binding.noteTitle.setText(spannableString); spannableString = new SpannableString(note.getExcerpt()); matcher = pattern.matcher(spannableString); while (matcher.find()) { spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); } } else { binding.noteTitle.setText(note.getTitle()); } bindFavorite(binding.noteFavorite, note.isFavorite()); bindTitleAndExcerpt(context, binding.noteTitle, null, searchQuery, note, mainColor); } public View getNoteSwipeable() { Loading