Skip to content

Commit 1eefd1e

Browse files
Merge pull request #2729 from nextcloud/style/noid/multi-select
🎨 Update Material Design to be more M3
2 parents 2ffba01 + 32744d0 commit 1eefd1e

32 files changed

+315
-78
lines changed

app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,5 +232,7 @@ public void applyBrand(int color) {
232232
final var util = BrandingUtil.of(color, this);
233233
util.platform.themeStatusBar(this);
234234
util.material.themeToolbar(binding.toolbar);
235+
util.platform.colorViewBackground(getWindow().getDecorView());
236+
util.platform.colorViewBackground(binding.getRoot());
235237
}
236238
}

app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
import android.os.Bundle;
1212

13-
import androidx.annotation.ColorInt;
1413
import androidx.annotation.NonNull;
1514
import androidx.fragment.app.Fragment;
1615
import androidx.fragment.app.FragmentActivity;
@@ -58,6 +57,8 @@ public void applyBrand(int color) {
5857
util.platform.themeStatusBar(this);
5958
util.material.themeToolbar(binding.toolbar);
6059
util.material.themeTabLayoutOnSurface(binding.tabs);
60+
util.platform.colorViewBackground(getWindow().getDecorView());
61+
util.platform.colorViewBackground(binding.getRoot());
6162
}
6263

6364
private static class TabsStateAdapter extends FragmentStateAdapter {

app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
import android.content.res.ColorStateList;
1414
import android.graphics.Color;
1515
import android.graphics.PorterDuff;
16+
import android.graphics.drawable.ColorDrawable;
1617
import android.graphics.drawable.LayerDrawable;
18+
import android.graphics.drawable.StateListDrawable;
1719
import android.util.Log;
1820
import android.view.View;
1921
import android.widget.ImageView;
@@ -26,6 +28,7 @@
2628
import androidx.appcompat.widget.SearchView;
2729
import androidx.appcompat.widget.Toolbar;
2830
import androidx.core.content.ContextCompat;
31+
import androidx.core.content.res.ResourcesCompat;
2932
import androidx.core.graphics.drawable.DrawableCompat;
3033

3134
import com.google.android.material.appbar.AppBarLayout;
@@ -209,4 +212,44 @@ public void themeToolbarSearchView(@NonNull SearchView searchView) {
209212
return searchView;
210213
});
211214
}
215+
216+
public void themeInternalLinkIcon(ImageView view) {
217+
withScheme(view, scheme -> {
218+
view
219+
.getBackground()
220+
.setColorFilter(ResourcesCompat.getColor(view.getContext().getResources(),
221+
R.color.nc_grey,
222+
null),
223+
PorterDuff.Mode.SRC_IN);
224+
view
225+
.getDrawable()
226+
.mutate()
227+
.setColorFilter(ResourcesCompat.getColor(view.getContext().getResources(),
228+
R.color.icon_on_nc_grey,
229+
null),
230+
PorterDuff.Mode.SRC_IN);
231+
return view;
232+
});
233+
}
234+
235+
public void themeBackgroundItemView(View view) {
236+
withScheme(view, scheme -> {
237+
StateListDrawable res = new StateListDrawable();
238+
res.addState(new int[]{android.R.attr.state_activated}, new ColorDrawable(dynamicColor.secondaryContainer().getArgb(scheme)));
239+
res.addState(new int[]{}, new ColorDrawable(dynamicColor.surface().getArgb(scheme)));
240+
view.setBackground(res);
241+
return view;
242+
});
243+
}
244+
245+
public void themeCard(@NonNull MaterialCardView view) {
246+
withScheme(view, scheme -> {
247+
view.setBackgroundTintList(buildColorStateList(
248+
new Pair<>(android.R.attr.state_activated, dynamicColor.secondaryContainer().getArgb(scheme)),
249+
new Pair<>(-android.R.attr.state_activated, dynamicColor.surface().getArgb(scheme)))
250+
);
251+
view.setStrokeColor(dynamicColor.outlineVariant().getArgb(scheme));
252+
return view;
253+
});
254+
}
212255
}

app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,5 +448,7 @@ public void applyBrand(int color) {
448448
final var util = BrandingUtil.of(color, this);
449449
util.platform.themeStatusBar(this);
450450
util.material.themeToolbar(binding.toolbar);
451+
util.platform.colorViewBackground(getWindow().getDecorView());
452+
util.platform.colorViewBackground(binding.getRoot());
451453
}
452454
}

app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ public void onSelectionChanged() {
519519
super.onSelectionChanged();
520520
if (tracker.hasSelection() && mActionMode == null) {
521521
mActionMode = startSupportActionMode(new MultiSelectedActionModeCallback(MainActivity.this,MainActivity.this, coordinatorLayout, binding.activityNotesListView.fabCreate, mainViewModel, MainActivity.this, canMoveNoteToAnotherAccounts, tracker, getSupportFragmentManager()));
522+
adapter.setMultiSelect(true);
522523
}
523524
if (mActionMode != null) {
524525
if (tracker.hasSelection()) {
@@ -527,6 +528,7 @@ public void onSelectionChanged() {
527528
} else {
528529
mActionMode.finish();
529530
mActionMode = null;
531+
adapter.setMultiSelect(false);
530532
}
531533
}
532534
}
@@ -604,6 +606,9 @@ public void applyBrand(int color) {
604606
util.platform.colorNavigationView(binding.navigationView);
605607
util.material.themeFAB(activityBinding.fabCreate);
606608
util.notes.themeSearchCardView(binding.activityNotesListView.searchBarWrapper);
609+
util.platform.colorViewBackground(getWindow().getDecorView());
610+
util.platform.colorViewBackground(binding.getRoot());
611+
util.platform.colorViewBackground(binding.activityNotesListView.activityNotesListView);
607612
util.platform.colorTextView(binding.activityNotesListView.searchText, ColorRole.ON_SURFACE_VARIANT);
608613
util.notes.themeSearchToolbar(binding.activityNotesListView.searchToolbar);
609614
util.notes.themeToolbarSearchView(binding.activityNotesListView.searchView);

app/src/main/java/it/niedermann/owncloud/notes/main/items/ItemAdapter.java

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,15 @@
88

99
import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences;
1010

11+
import android.annotation.SuppressLint;
1112
import android.content.Context;
13+
import android.os.Handler;
14+
import android.os.Looper;
1215
import android.text.TextUtils;
1316
import android.view.LayoutInflater;
17+
import android.view.View;
1418
import android.view.ViewGroup;
19+
import android.widget.ImageView;
1520

1621
import androidx.annotation.ColorInt;
1722
import androidx.annotation.IntRange;
@@ -23,11 +28,14 @@
2328
import androidx.recyclerview.selection.SelectionTracker;
2429
import androidx.recyclerview.widget.RecyclerView;
2530

31+
import com.nextcloud.android.common.ui.theme.utils.ColorRole;
32+
2633
import java.util.ArrayList;
2734
import java.util.List;
2835

2936
import it.niedermann.owncloud.notes.R;
3037
import it.niedermann.owncloud.notes.branding.Branded;
38+
import it.niedermann.owncloud.notes.branding.BrandingUtil;
3139
import it.niedermann.owncloud.notes.databinding.ItemNotesListNoteItemGridBinding;
3240
import it.niedermann.owncloud.notes.databinding.ItemNotesListNoteItemGridOnlyTitleBinding;
3341
import it.niedermann.owncloud.notes.databinding.ItemNotesListNoteItemWithExcerptBinding;
@@ -66,6 +74,8 @@ public class ItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> i
6674
@Nullable
6775
private Integer swipedPosition;
6876

77+
private boolean isMultiSelect = false;
78+
6979
public <T extends Context & NoteClickListener> ItemAdapter(@NonNull T context, boolean gridView) {
7080
this.noteClickListener = context;
7181
this.gridView = gridView;
@@ -104,13 +114,19 @@ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int
104114
if (gridView) {
105115
switch (viewType) {
106116
case TYPE_SECTION -> {
107-
return new SectionViewHolder(ItemNotesListSectionItemBinding.inflate(inflater));
117+
ItemNotesListSectionItemBinding binding = ItemNotesListSectionItemBinding.inflate(inflater);
118+
BrandingUtil.of(color, parent.getContext()).platform.colorTextView(binding.sectionTitle);
119+
return new SectionViewHolder(binding);
108120
}
109121
case TYPE_NOTE_ONLY_TITLE -> {
110-
return new NoteViewGridHolderOnlyTitle(ItemNotesListNoteItemGridOnlyTitleBinding.inflate(inflater, parent, false), noteClickListener, monospace, fontSize);
122+
ItemNotesListNoteItemGridOnlyTitleBinding binding = ItemNotesListNoteItemGridOnlyTitleBinding.inflate(inflater, parent, false);
123+
BrandingUtil.of(color, parent.getContext()).notes.themeCard(binding.card);
124+
return new NoteViewGridHolderOnlyTitle(binding, noteClickListener, monospace, fontSize);
111125
}
112126
case TYPE_NOTE_WITH_EXCERPT, TYPE_NOTE_WITHOUT_EXCERPT -> {
113-
return new NoteViewGridHolder(ItemNotesListNoteItemGridBinding.inflate(inflater, parent, false), noteClickListener, monospace, fontSize);
127+
ItemNotesListNoteItemGridBinding binding = ItemNotesListNoteItemGridBinding.inflate(inflater, parent, false);
128+
BrandingUtil.of(color, parent.getContext()).notes.themeCard(binding.card);
129+
return new NoteViewGridHolder(binding, noteClickListener, monospace, fontSize);
114130
}
115131
default -> {
116132
throw new IllegalArgumentException("Not supported viewType: " + viewType);
@@ -119,13 +135,19 @@ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int
119135
} else {
120136
switch (viewType) {
121137
case TYPE_SECTION -> {
122-
return new SectionViewHolder(ItemNotesListSectionItemBinding.inflate(inflater));
138+
ItemNotesListSectionItemBinding binding = ItemNotesListSectionItemBinding.inflate(inflater);
139+
BrandingUtil.of(color, parent.getContext()).platform.colorTextView(binding.sectionTitle);
140+
return new SectionViewHolder(binding);
123141
}
124142
case TYPE_NOTE_WITH_EXCERPT -> {
125-
return new NoteViewHolderWithExcerpt(ItemNotesListNoteItemWithExcerptBinding.inflate(inflater, parent, false), noteClickListener);
143+
ItemNotesListNoteItemWithExcerptBinding binding = ItemNotesListNoteItemWithExcerptBinding.inflate(inflater, parent, false);
144+
BrandingUtil.of(color, parent.getContext()).notes.themeBackgroundItemView(binding.noteSwipeable);
145+
return new NoteViewHolderWithExcerpt(binding, noteClickListener);
126146
}
127147
case TYPE_NOTE_ONLY_TITLE, TYPE_NOTE_WITHOUT_EXCERPT -> {
128-
return new NoteViewHolderWithoutExcerpt(ItemNotesListNoteItemWithoutExcerptBinding.inflate(inflater, parent, false), noteClickListener);
148+
ItemNotesListNoteItemWithoutExcerptBinding binding = ItemNotesListNoteItemWithoutExcerptBinding.inflate(inflater, parent, false);
149+
BrandingUtil.of(color, parent.getContext()).notes.themeBackgroundItemView(binding.noteSwipeable);
150+
return new NoteViewHolderWithoutExcerpt(binding, noteClickListener);
129151
}
130152
default -> {
131153
throw new IllegalArgumentException("Not supported viewType: " + viewType);
@@ -149,17 +171,37 @@ public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int
149171
switch (getItemViewType(position)) {
150172
case TYPE_SECTION ->
151173
((SectionViewHolder) holder).bind((SectionItem) itemList.get(position));
152-
case TYPE_NOTE_WITH_EXCERPT,
153-
TYPE_NOTE_WITHOUT_EXCERPT,
154-
TYPE_NOTE_ONLY_TITLE ->
155-
((NoteViewHolder) holder).bind(isSelected, (Note) itemList.get(position), showCategory, color, searchQuery);
174+
case TYPE_NOTE_WITH_EXCERPT, TYPE_NOTE_WITHOUT_EXCERPT, TYPE_NOTE_ONLY_TITLE -> {
175+
holder.itemView.findViewById(R.id.custom_checkbox).setVisibility(tracker != null && tracker.hasSelection() ? View.VISIBLE : View.GONE);
176+
if (isSelected) {
177+
holder.itemView.setBackgroundColor(ContextCompat.getColor(holder.itemView.getContext(), R.color.bg_highlighted));
178+
((ImageView) holder.itemView.findViewById(R.id.custom_checkbox)).setImageDrawable(BrandingUtil.getInstance(holder.itemView.getContext()).platform.tintDrawable(holder.itemView.getContext(), R.drawable.ic_checkbox_marked, ColorRole.PRIMARY));
179+
} else {
180+
holder.itemView.setBackgroundColor(holder.itemView.getContext().getColor(com.nextcloud.android.common.ui.R.color.bg_default));
181+
((ImageView) holder.itemView.findViewById(R.id.custom_checkbox)).setImageResource(R.drawable.ic_checkbox_blank_outline);
182+
}
183+
holder.itemView.findViewById(R.id.custom_checkbox).setVisibility(isMultiSelect ? View.VISIBLE : View.GONE);
184+
((NoteViewHolder) holder).bind(isSelected, (Note) itemList.get(position), showCategory, color, searchQuery);
185+
}
156186
}
157187
}
158188

159189
public void setTracker(SelectionTracker<Long> tracker) {
160190
this.tracker = tracker;
161191
}
162192

193+
@SuppressLint("NotifyDataSetChanged")
194+
public void setMultiSelect(boolean bool) {
195+
if (isMultiSelect != bool) {
196+
isMultiSelect = bool;
197+
new Handler(Looper.getMainLooper()).post(this::notifyDataSetChanged);
198+
}
199+
}
200+
201+
public boolean isMultiSelect() {
202+
return this.isMultiSelect;
203+
}
204+
163205
public Item getItem(int notePosition) {
164206
return itemList.get(notePosition);
165207
}

app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public NoteViewHolder(@NonNull View v, @NonNull NoteClickListener noteClickListe
4545

4646
@CallSuper
4747
public void bind(boolean isSelected, @NonNull Note note, boolean showCategory, @ColorInt int color, @Nullable CharSequence searchQuery) {
48+
itemView.setActivated(isSelected);
4849
itemView.setSelected(isSelected);
4950
itemView.setOnClickListener((view) -> noteClickListener.onNoteClick(getLayoutPosition(), view));
5051
}

app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsActivity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,5 +228,7 @@ public void applyBrand(int color) {
228228
final var util = BrandingUtil.of(color, this);
229229
util.platform.themeStatusBar(this);
230230
util.material.themeToolbar(binding.toolbar);
231+
util.platform.colorViewBackground(getWindow().getDecorView());
232+
util.platform.colorViewBackground(binding.getRoot());
231233
}
232234
}

app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,7 @@ public void applyBrand(int color) {
4141
final var util = BrandingUtil.of(color, this);
4242
util.platform.themeStatusBar(this);
4343
util.material.themeToolbar(binding.toolbar);
44+
util.platform.colorViewBackground(getWindow().getDecorView());
45+
util.platform.colorViewBackground(binding.getRoot());
4446
}
4547
}

app/src/main/java/it/niedermann/owncloud/notes/share/NoteShareActivity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,9 @@ public void applyBrand(int color) {
789789
util.platform.themeStatusBar(this);
790790
util.androidx.themeToolbarSearchView(binding.searchView);
791791
util.platform.themeHorizontalProgressBar(binding.progressBar);
792+
util.platform.colorViewBackground(getWindow().getDecorView());
793+
util.platform.colorViewBackground(binding.getRoot());
794+
util.platform.colorTextButtons(binding.btnShareButton);
792795
}
793796

794797
@Override

0 commit comments

Comments
 (0)