Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a40704a7 authored by Stefan Niedermann's avatar Stefan Niedermann
Browse files

feat(theming): Theme NavigationView

parent 05a4fad5
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import android.util.Log;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LiveData;
import androidx.preference.PreferenceManager;

@@ -57,14 +58,14 @@ public class BrandingUtil extends ViewThemeUtilsBase {
    public static LiveData<Integer> readBrandMainColorLiveData(@NonNull Context context) {
        final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
        Log.v(TAG, "--- Read: shared_preference_theme_main");
        return new SharedPreferenceIntLiveData(sharedPreferences, pref_key_branding_main, context.getApplicationContext().getResources().getColor(R.color.defaultBrand));
        return new SharedPreferenceIntLiveData(sharedPreferences, pref_key_branding_main, ContextCompat.getColor(context, R.color.defaultBrand));
    }

    @ColorInt
    public static int readBrandMainColor(@NonNull Context context) {
        final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
        Log.v(TAG, "--- Read: shared_preference_theme_main");
        return sharedPreferences.getInt(pref_key_branding_main, context.getApplicationContext().getResources().getColor(R.color.defaultBrand));
        return sharedPreferences.getInt(pref_key_branding_main, ContextCompat.getColor(context, R.color.defaultBrand));
    }

    public static void saveBrandColor(@NonNull Context context, @ColorInt int color) {
+59 −1
Original line number Diff line number Diff line
package it.niedermann.owncloud.notes.branding;

import static com.nextcloud.android.common.ui.util.ColorStateListUtilsKt.buildColorStateList;
import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive;

import android.content.Context;
@@ -7,6 +8,9 @@ import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.LayerDrawable;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.ColorInt;
import androidx.annotation.IdRes;
@@ -16,20 +20,27 @@ import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;

import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.navigation.NavigationView;
import com.nextcloud.android.common.ui.theme.MaterialSchemes;
import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase;
import com.nextcloud.android.common.ui.theme.utils.MaterialViewThemeUtils;

import it.niedermann.android.util.ColorUtil;
import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.main.navigation.NavigationItem;
import it.niedermann.owncloud.notes.shared.util.NotesColorUtil;
import kotlin.Pair;
import scheme.Scheme;

public class NotesViewThemeUtils extends ViewThemeUtilsBase {

    private static final String TAG = NotesViewThemeUtils.class.getSimpleName();
    private final MaterialSchemes schemes;

    public NotesViewThemeUtils(@NonNull MaterialSchemes schemes) {
        super(schemes);
        this.schemes = schemes;
    }

    @ColorInt
@@ -37,6 +48,51 @@ public class NotesViewThemeUtils extends ViewThemeUtilsBase {
        return withScheme(context, Scheme::getOnPrimaryContainer);
    }

    /**
     * The Notes app uses custom navigation view items because they have several features which are
     * not covered by {@link NavigationItem}.
     */
    public void colorNavigationViewItem(@NonNull View view) {
        withScheme(view, scheme -> {
            view.setBackgroundTintList(buildColorStateList(
                    new Pair<>(android.R.attr.state_selected, scheme.getSecondaryContainer()),
                    new Pair<>(-android.R.attr.state_selected, Color.TRANSPARENT)
            ));
            return view;
        });
    }

    /**
     * The Notes app uses custom navigation view items because they have several features which are
     * not covered by {@link NavigationItem}.
     */
    public void colorNavigationViewItemIcon(@NonNull ImageView view) {
        withScheme(view, scheme -> {
            view.setImageTintList(buildColorStateList(
                    new Pair<>(android.R.attr.state_selected, scheme.getOnSecondaryContainer()),
                    new Pair<>(-android.R.attr.state_selected, scheme.getOnSurfaceVariant())
            ));
            return view;
        });
    }

    /**
     * The Notes app uses custom navigation view items because they have several features which are
     * not covered by {@link NavigationItem}.
     */
    public void colorNavigationViewItemText(@NonNull TextView view) {
        withScheme(view, scheme -> {
            view.setTextColor(buildColorStateList(
                    new Pair<>(android.R.attr.state_selected, scheme.getOnSecondaryContainer()),
                    new Pair<>(-android.R.attr.state_selected, scheme.getOnSurfaceVariant())
            ));
            return view;
        });
    }

    /**
     * @deprecated should be replaced by {@link MaterialViewThemeUtils#themeToolbar(MaterialToolbar)}.
     */
    @Deprecated(forRemoval = true)
    public void applyBrandToPrimaryToolbar(@NonNull AppBarLayout appBarLayout, @NonNull Toolbar toolbar, @ColorInt int color) {
        // FIXME Workaround for https://github.com/nextcloud/notes-android/issues/889
@@ -55,7 +111,9 @@ public class NotesViewThemeUtils extends ViewThemeUtilsBase {
        }
    }

    @Deprecated(forRemoval = true)
    /**
     * Colorizes only a specific part of a drawable
     */
    public void colorLayerDrawable(@NonNull LayerDrawable check, @IdRes int areaToColor, @ColorInt int mainColor) {
        final var drawable = check.findDrawableByLayerId(areaToColor);
        if (drawable == null) {
+6 −1
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A

    protected ItemAdapter adapter;
    private NavigationAdapter adapterCategories;
    @Nullable
    private MenuAdapter menuAdapter;

    private SelectionTracker<Long> tracker;
@@ -351,7 +352,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A
                    } else {
                        startActivityForResult(menuItem.getIntent(), resultCode);
                    }
                });
                }, nextAccount.getColor());

                binding.navigationMenu.setAdapter(menuAdapter);
            } else {
@@ -596,6 +597,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A
        final var util = BrandingUtil.of(color, this);
        util.material.themeFAB(activityBinding.fabCreate);
        util.platform.colorCircularProgressBar(activityBinding.progressCircular);
        util.platform.colorNavigationView(binding.navigationView);
        util.notes.applyBrandToPrimaryToolbar(activityBinding.appBar, activityBinding.searchToolbar, colorAccent);

        binding.headerView.setBackgroundColor(color);
@@ -608,6 +610,9 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A

        adapter.applyBrand(color);
        adapterCategories.applyBrand(color);
        if (menuAdapter != null) {
            menuAdapter.applyBrand(color);
        }
        invalidateOptionsMenu();
    }

+12 −2
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ import android.net.Uri;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.core.util.Consumer;
import androidx.recyclerview.widget.RecyclerView;
@@ -17,6 +18,7 @@ import com.nextcloud.android.sso.helper.VersionCheckHelper;
import it.niedermann.owncloud.notes.FormattingHelpActivity;
import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.about.AboutActivity;
import it.niedermann.owncloud.notes.branding.BrandingUtil;
import it.niedermann.owncloud.notes.databinding.ItemNavigationBinding;
import it.niedermann.owncloud.notes.persistence.entity.Account;
import it.niedermann.owncloud.notes.preferences.PreferencesActivity;
@@ -25,10 +27,12 @@ public class MenuAdapter extends RecyclerView.Adapter<MenuViewHolder> {

    @NonNull
    private final MenuItem[] menuItems;
    @ColorInt
    private int color;
    @NonNull
    private final Consumer<MenuItem> onClick;

    public MenuAdapter(@NonNull Context context, @NonNull Account account, int settingsRequestCode, @NonNull Consumer<MenuItem> onClick) {
    public MenuAdapter(@NonNull Context context, @NonNull Account account, int settingsRequestCode, @NonNull Consumer<MenuItem> onClick, @ColorInt int color) {
        this.menuItems = new MenuItem[]{
                new MenuItem(new Intent(context, FormattingHelpActivity.class), R.string.action_formatting_help, R.drawable.ic_baseline_help_outline_24),
                new MenuItem(generateTrashbinIntent(context, account), R.string.action_trashbin, R.drawable.ic_delete_grey600_24dp),
@@ -36,9 +40,15 @@ public class MenuAdapter extends RecyclerView.Adapter<MenuViewHolder> {
                new MenuItem(new Intent(context, AboutActivity.class), R.string.simple_about, R.drawable.ic_info_outline_grey600_24dp)
        };
        this.onClick = onClick;
        this.color = color;
        setHasStableIds(true);
    }

    public void applyBrand(int color) {
        this.color = color;
        notifyDataSetChanged();
    }

    @Override
    public long getItemId(int position) {
        return position;
@@ -52,7 +62,7 @@ public class MenuAdapter extends RecyclerView.Adapter<MenuViewHolder> {

    @Override
    public void onBindViewHolder(@NonNull MenuViewHolder holder, int position) {
        holder.bind(menuItems[position], onClick);
        holder.bind(menuItems[position], color, onClick);
    }

    public void updateAccount(@NonNull Context context, @NonNull Account account) {
+12 −2
Original line number Diff line number Diff line
@@ -2,12 +2,14 @@ package it.niedermann.owncloud.notes.main.menu;

import android.content.Context;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.util.Consumer;
import androidx.recyclerview.widget.RecyclerView;

import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.branding.BrandingUtil;
import it.niedermann.owncloud.notes.databinding.ItemNavigationBinding;

import static android.view.View.GONE;
@@ -21,11 +23,19 @@ public class MenuViewHolder extends RecyclerView.ViewHolder {
        this.binding = binding;
    }

    public void bind(@NonNull MenuItem menuItem, @NonNull Consumer<MenuItem> onClick) {
    public void bind(@NonNull MenuItem menuItem, @ColorInt int color, @NonNull Consumer<MenuItem> onClick) {
        @NonNull Context context = itemView.getContext();
        binding.navigationItemLabel.setText(context.getString(menuItem.getLabelResource()));

        binding.navigationItemIcon.setImageDrawable(ContextCompat.getDrawable(context, menuItem.getDrawableResource()));
        binding.navigationItemLabel.setText(context.getString(menuItem.getLabelResource()));
        binding.navigationItemCount.setVisibility(GONE);
        binding.getRoot().setOnClickListener((v) -> onClick.accept(menuItem));

        final var util = BrandingUtil.of(color, binding.getRoot().getContext());

        util.notes.colorNavigationViewItem(binding.getRoot());
        util.notes.colorNavigationViewItemIcon(binding.navigationItemIcon);
        util.notes.colorNavigationViewItemText(binding.navigationItemCount);
        util.notes.colorNavigationViewItemText(binding.navigationItemLabel);
    }
}
Loading