From 15b3906b0edde550a566181472f0e9059e2dc731 Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Wed, 10 Jun 2020 14:33:42 +0200 Subject: Use proper ItemDecoration class for defining gutter --- .../android/activity/NotesListViewActivity.java | 17 ++++---- .../owncloud/notes/model/GridItemDecoration.java | 47 ++++++++++++++++++++++ .../owncloud/notes/model/ItemAdapter.java | 12 ++++++ .../owncloud/notes/model/NoteViewGridHolder.java | 3 +- .../owncloud/notes/model/NoteViewHolder.java | 27 +++++-------- .../notes/model/NoteViewHolderWithExcerpt.java | 3 +- .../notes/model/NoteViewHolderWithoutExcerpt.java | 3 +- .../owncloud/notes/model/SectionViewHolder.java | 3 -- .../res/layout/item_notes_list_note_item_grid.xml | 1 - 9 files changed, 81 insertions(+), 35 deletions(-) create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/model/GridItemDecoration.java (limited to 'app/src/main') diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java index c6b14fef..ef940a63 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java @@ -64,6 +64,7 @@ import it.niedermann.owncloud.notes.formattinghelp.FormattingHelpActivity; import it.niedermann.owncloud.notes.model.Capabilities; import it.niedermann.owncloud.notes.model.Category; import it.niedermann.owncloud.notes.model.DBNote; +import it.niedermann.owncloud.notes.model.GridItemDecoration; import it.niedermann.owncloud.notes.model.ISyncCallback; import it.niedermann.owncloud.notes.model.Item; import it.niedermann.owncloud.notes.model.ItemAdapter; @@ -600,13 +601,15 @@ public class NotesListViewActivity extends LockedActivity implements NoteClickLi adapter = new ItemAdapter(this, gridView); listView.setAdapter(adapter); - final DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); - int spanCount = (int) ((displayMetrics.widthPixels / displayMetrics.density) / getResources().getInteger(R.integer.max_dp_grid_view)); - listView.setLayoutManager( - gridView - ? new StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.VERTICAL) - : new LinearLayoutManager(this) - ); + if (gridView) { + final DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); + int spanCount = (int) ((displayMetrics.widthPixels / displayMetrics.density) / getResources().getInteger(R.integer.max_dp_grid_view)); + StaggeredGridLayoutManager gridLayoutManager = new StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.VERTICAL); + listView.setLayoutManager(gridLayoutManager); + listView.addItemDecoration(new GridItemDecoration(adapter, getResources().getDimensionPixelSize(R.dimen.spacer_2x))); + } else { + listView.setLayoutManager(new LinearLayoutManager(this)); + } } private void refreshLists() { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/model/GridItemDecoration.java b/app/src/main/java/it/niedermann/owncloud/notes/model/GridItemDecoration.java new file mode 100644 index 00000000..3d7ae944 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/model/GridItemDecoration.java @@ -0,0 +1,47 @@ +package it.niedermann.owncloud.notes.model; + +import android.graphics.Rect; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.StaggeredGridLayoutManager; + +public class GridItemDecoration extends RecyclerView.ItemDecoration { + + @NonNull + private final ItemAdapter adapter; + private final int gutter; + + public GridItemDecoration(@NonNull ItemAdapter adapter, int gutter) { + this.adapter = adapter; + this.gutter = gutter; + } + + public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { + final int position = parent.getChildAdapterPosition(view); + final StaggeredGridLayoutManager.LayoutParams lp = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams(); + + if (adapter.getItemViewType(position) == ItemAdapter.TYPE_SECTION) { + lp.setFullSpan(true); + } else { + final int spanIndex = lp.getSpanIndex(); + + if (position >= 0) { + // First row gets some spacing at the top + if (position < adapter.getFirstPositionOfViewType(ItemAdapter.TYPE_SECTION)) { + outRect.top = gutter; + } + + // First column gets some spacing at the left and the right side + if (spanIndex == 0) { + outRect.left = gutter; + } + + // All columns get some spacing at the bottom and at the right side + outRect.right = gutter; + outRect.bottom = gutter; + } + } + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/model/ItemAdapter.java b/app/src/main/java/it/niedermann/owncloud/notes/model/ItemAdapter.java index 0bba4f33..92635564 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/model/ItemAdapter.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/model/ItemAdapter.java @@ -209,4 +209,16 @@ public class ItemAdapter extends RecyclerView.Adapter i public void setHighlightSearchQuery(CharSequence searchQuery) { this.searchQuery = searchQuery; } + + /** + * @return the position of the first item which matches the given viewtype, -1 if not available + */ + public int getFirstPositionOfViewType(@IntRange(from = 0, to = 2) int viewType) { + for (int i = 0; i < itemList.size(); i++) { + if (getItemViewType(i) == viewType) { + return i; + } + } + return -1; + } } \ No newline at end of file diff --git a/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewGridHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewGridHolder.java index 7091d87e..22062832 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewGridHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewGridHolder.java @@ -16,8 +16,6 @@ public class NoteViewGridHolder extends NoteViewHolder { public NoteViewGridHolder(@NonNull ItemNotesListNoteItemGridBinding binding, @NonNull NoteClickListener noteClickListener) { super(binding.getRoot(), noteClickListener, true); this.binding = binding; - itemView.setOnClickListener(this); - itemView.setOnLongClickListener(this); } public void showSwipe(boolean left) { @@ -25,6 +23,7 @@ public class NoteViewGridHolder extends NoteViewHolder { } public void bind(@NonNull DBNote note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { + super.bind(note, showCategory, mainColor, textColor, searchQuery); @NonNull final Context context = itemView.getContext(); bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), mainColor); binding.noteStatus.setVisibility(DBStatus.VOID.equals(note.getStatus()) ? View.INVISIBLE : View.VISIBLE); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolder.java index 2c6a339a..f063167a 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolder.java @@ -14,6 +14,7 @@ import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.CallSuper; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -31,14 +32,15 @@ import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.util.MarkDownUtil; 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; import static it.niedermann.owncloud.notes.util.MarkDownUtil.parseCompat; -public abstract class NoteViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener { +public abstract class NoteViewHolder extends RecyclerView.ViewHolder { + @NonNull private final NoteClickListener noteClickListener; private final boolean renderMarkdown; + @Nullable private MarkdownProcessor markdownProcessor; public NoteViewHolder(@NonNull View v, @NonNull NoteClickListener noteClickListener, boolean renderMarkdown) { @@ -50,25 +52,14 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder implements markdownProcessor.factory(TextFactory.create()); markdownProcessor.config(MarkDownUtil.getMarkDownConfiguration(itemView.getContext()).build()); } - v.setOnClickListener(this); - v.setOnLongClickListener(this); } - @Override - public void onClick(View v) { - final int adapterPosition = getAdapterPosition(); - if (adapterPosition != NO_POSITION) { - noteClickListener.onNoteClick(adapterPosition, v); - } - } - - @Override - public boolean onLongClick(View v) { - return noteClickListener.onNoteLongClick(getAdapterPosition(), v); + @CallSuper + public void bind(@NonNull DBNote note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { + itemView.setOnClickListener((view) -> noteClickListener.onNoteClick(getAdapterPosition(), view)); + itemView.setOnLongClickListener((view) -> noteClickListener.onNoteLongClick(getAdapterPosition(), view)); } - public abstract void bind(@NonNull DBNote note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery); - protected void bindCategory(@NonNull Context context, @NonNull TextView noteCategory, boolean showCategory, @NonNull String category, int mainColor) { final boolean isDarkThemeActive = Notes.isDarkThemeActive(context); noteCategory.setVisibility(showCategory && !category.isEmpty() ? View.VISIBLE : View.GONE); @@ -138,7 +129,7 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder implements } private void bindContent(@NonNull TextView textView, @NonNull CharSequence charSequence) { - if (renderMarkdown) { + if (renderMarkdown && markdownProcessor != null) { new Thread(() -> { try { final CharSequence parsedCharSequence = parseCompat(markdownProcessor, charSequence); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolderWithExcerpt.java b/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolderWithExcerpt.java index 05a743ab..a4ab40a2 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolderWithExcerpt.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolderWithExcerpt.java @@ -16,8 +16,6 @@ public class NoteViewHolderWithExcerpt extends NoteViewHolder { public NoteViewHolderWithExcerpt(@NonNull ItemNotesListNoteItemWithExcerptBinding binding, @NonNull NoteClickListener noteClickListener) { super(binding.getRoot(), noteClickListener, false); this.binding = binding; - itemView.setOnClickListener(this); - itemView.setOnLongClickListener(this); } public void showSwipe(boolean left) { @@ -27,6 +25,7 @@ public class NoteViewHolderWithExcerpt extends NoteViewHolder { } public void bind(@NonNull DBNote note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { + super.bind(note, showCategory, mainColor, textColor, searchQuery); @NonNull final Context context = itemView.getContext(); binding.noteSwipeable.setAlpha(DBStatus.LOCAL_DELETED.equals(note.getStatus()) ? 0.5f : 1.0f); bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), mainColor); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolderWithoutExcerpt.java b/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolderWithoutExcerpt.java index 59a42f5c..ef56acbb 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolderWithoutExcerpt.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/model/NoteViewHolderWithoutExcerpt.java @@ -16,8 +16,6 @@ public class NoteViewHolderWithoutExcerpt extends NoteViewHolder { public NoteViewHolderWithoutExcerpt(@NonNull ItemNotesListNoteItemWithoutExcerptBinding binding, @NonNull NoteClickListener noteClickListener) { super(binding.getRoot(), noteClickListener, false); this.binding = binding; - itemView.setOnClickListener(this); - itemView.setOnLongClickListener(this); } @@ -28,6 +26,7 @@ public class NoteViewHolderWithoutExcerpt extends NoteViewHolder { } public void bind(@NonNull DBNote note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { + super.bind(note, showCategory, mainColor, textColor, searchQuery); @NonNull final Context context = itemView.getContext(); binding.noteSwipeable.setAlpha(DBStatus.LOCAL_DELETED.equals(note.getStatus()) ? 0.5f : 1.0f); bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), mainColor); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/model/SectionViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/model/SectionViewHolder.java index 801ea822..eccdd7d9 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/model/SectionViewHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/model/SectionViewHolder.java @@ -15,8 +15,5 @@ public class SectionViewHolder extends RecyclerView.ViewHolder { public void bind(SectionItem item) { binding.sectionTitle.setText(item.getTitle()); - if (itemView.getLayoutParams() != null && itemView.getLayoutParams() instanceof StaggeredGridLayoutManager.LayoutParams) { - ((StaggeredGridLayoutManager.LayoutParams) itemView.getLayoutParams()).setFullSpan(true); - } } } \ No newline at end of file diff --git a/app/src/main/res/layout/item_notes_list_note_item_grid.xml b/app/src/main/res/layout/item_notes_list_note_item_grid.xml index 98b6cb2b..3fe1c09e 100644 --- a/app/src/main/res/layout/item_notes_list_note_item_grid.xml +++ b/app/src/main/res/layout/item_notes_list_note_item_grid.xml @@ -5,7 +5,6 @@ android:id="@+id/card" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_margin="@dimen/spacer_1x" android:focusable="true">