Switch UI to Material 3 and support dynamic colors

This commit is contained in:
Arjan Schrijver 2023-07-22 21:23:27 +02:00 committed by Arjan Schrijver
parent 5a1e56a81e
commit b6e252c4c1
62 changed files with 1167 additions and 281 deletions

View File

@ -213,22 +213,22 @@ dependencies {
testImplementation "org.mockito:mockito-core:1.10.19"
testImplementation "org.robolectric:robolectric:4.8.2"
testImplementation "org.hamcrest:hamcrest-library:1.3"
testImplementation "com.google.code.gson:gson:2.8.6"
testImplementation "com.google.code.gson:gson:2.8.8"
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "androidx.appcompat:appcompat:1.3.1"
implementation "androidx.appcompat:appcompat:1.4.1"
implementation "androidx.preference:preference:1.1.1"
implementation "androidx.cardview:cardview:1.0.0"
implementation "androidx.recyclerview:recyclerview:1.2.1"
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.gridlayout:gridlayout:1.0.0"
implementation "androidx.palette:palette:1.0.0"
implementation "androidx.activity:activity:1.4.0"
implementation "androidx.fragment:fragment:1.4.0"
implementation "androidx.activity:activity:1.5.1"
implementation "androidx.fragment:fragment:1.4.1"
implementation "com.google.android.material:material:1.4.0"
implementation "com.google.android.material:material:1.6.1"
implementation 'com.google.android.flexbox:flexbox:3.0.0'
implementation "com.google.code.gson:gson:2.8.6"
implementation "com.google.code.gson:gson:2.8.8"
implementation "no.nordicsemi.android:dfu:1.12.0"
implementation("com.github.tony19:logback-android:2.0.0") {

View File

@ -7,7 +7,7 @@ import android.widget.LinearLayout;
public class CheckableLinearLayout extends LinearLayout implements Checkable {
private static final int CHECKABLE_CHILD_INDEX = 1;
private static final int CHECKABLE_CHILD_INDEX = 0;
private Checkable child;
public CheckableLinearLayout(Context context, AttributeSet attrs) {

View File

@ -49,18 +49,19 @@ import android.view.View;
import android.widget.ArrayAdapter;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.ListPreference;
import androidx.preference.ListPreferenceDialogFragmentCompat;
import androidx.preference.Preference;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.util.dialogs.MaterialListPreferenceDialogFragment;
public class DragSortListPreferenceFragment extends ListPreferenceDialogFragmentCompat implements ListPreference.TargetFragment {
public class DragSortListPreferenceFragment extends MaterialListPreferenceDialogFragment implements ListPreference.TargetFragment {
protected DragSortListView mListView;
protected ArrayAdapter<CharSequence> mAdapter;
@ -112,7 +113,7 @@ public class DragSortListPreferenceFragment extends ListPreferenceDialogFragment
}
@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
protected void onPrepareDialogBuilder(MaterialAlertDialogBuilder builder) {
// must be empty
}

View File

@ -132,6 +132,7 @@ public class GBApplication extends Application {
public static final String ACTION_QUIT
= "nodomain.freeyourgadget.gadgetbridge.gbapplication.action.quit";
public static final String ACTION_LANGUAGE_CHANGE = "nodomain.freeyourgadget.gadgetbridge.gbapplication.action.language_change";
public static final String ACTION_THEME_CHANGE = "nodomain.freeyourgadget.gadgetbridge.gbapplication.action.theme_change";
public static final String ACTION_NEW_DATA = "nodomain.freeyourgadget.gadgetbridge.action.new_data";
private static GBApplication app;
@ -1311,7 +1312,7 @@ public class GBApplication extends Application {
Resources resources = context.getResources();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
selectedTheme.equals(context.getString(R.string.pref_theme_value_system))) {
(selectedTheme.equals(context.getString(R.string.pref_theme_value_system)) || selectedTheme.equals(context.getString(R.string.pref_theme_value_dynamic)))) {
return (resources.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
} else {
return selectedTheme.equals(context.getString(R.string.pref_theme_value_dark));
@ -1322,6 +1323,11 @@ public class GBApplication extends Application {
return prefs.getBoolean("pref_key_theme_amoled_black", false);
}
public static boolean areDynamicColorsEnabled() {
String selectedTheme = prefs.getString("pref_key_theme", context.getString(R.string.pref_theme_value_system));
return selectedTheme.equals(context.getString(R.string.pref_theme_value_dynamic));
}
public static int getTextColor(Context context) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();

View File

@ -24,10 +24,11 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import java.util.Locale;
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import java.util.Locale;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
@ -50,6 +51,9 @@ public abstract class AbstractGBActivity extends AppCompatActivity implements GB
case GBApplication.ACTION_LANGUAGE_CHANGE:
setLanguage(GBApplication.getLanguage(), true);
break;
case GBApplication.ACTION_THEME_CHANGE:
recreate();
break;
case GBApplication.ACTION_QUIT:
finish();
break;
@ -69,7 +73,27 @@ public abstract class AbstractGBActivity extends AppCompatActivity implements GB
}
public static void init(GBActivity activity, int flags) {
if (GBApplication.isDarkThemeEnabled()) {
if (GBApplication.areDynamicColorsEnabled()) {
if (GBApplication.isDarkThemeEnabled()) {
if ((flags & NO_ACTIONBAR) != 0) {
if (GBApplication.isAmoledBlackEnabled())
activity.setTheme(R.style.GadgetbridgeThemeDynamicDarkAmoled_NoActionBar);
else
activity.setTheme(R.style.GadgetbridgeThemeDynamicDark_NoActionBar);
} else {
if (GBApplication.isAmoledBlackEnabled())
activity.setTheme(R.style.GadgetbridgeThemeDynamicDarkAmoled);
else
activity.setTheme(R.style.GadgetbridgeThemeDynamicDark);
}
} else {
if ((flags & NO_ACTIONBAR) != 0) {
activity.setTheme(R.style.GadgetbridgeThemeDynamicLight_NoActionBar);
} else {
activity.setTheme(R.style.GadgetbridgeThemeDynamicLight);
}
}
} else if (GBApplication.isDarkThemeEnabled()) {
if ((flags & NO_ACTIONBAR) != 0) {
if (GBApplication.isAmoledBlackEnabled())
activity.setTheme(R.style.GadgetbridgeThemeBlack_NoActionBar);
@ -96,6 +120,7 @@ public abstract class AbstractGBActivity extends AppCompatActivity implements GB
IntentFilter filterLocal = new IntentFilter();
filterLocal.addAction(GBApplication.ACTION_QUIT);
filterLocal.addAction(GBApplication.ACTION_LANGUAGE_CHANGE);
filterLocal.addAction(GBApplication.ACTION_THEME_CHANGE);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
init(this);

View File

@ -22,6 +22,7 @@ import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
import androidx.preference.MultiSelectListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
@ -40,10 +41,11 @@ import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.Set;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsActivity;
import nodomain.freeyourgadget.gadgetbridge.util.XTimePreference;
import nodomain.freeyourgadget.gadgetbridge.util.XTimePreferenceFragment;
import nodomain.freeyourgadget.gadgetbridge.util.dialogs.MaterialEditTextPreferenceDialogFragment;
import nodomain.freeyourgadget.gadgetbridge.util.dialogs.MaterialListPreferenceDialogFragment;
import nodomain.freeyourgadget.gadgetbridge.util.dialogs.MaterialMultiSelectListPreferenceDialogFragment;
public abstract class AbstractPreferenceFragment extends PreferenceFragmentCompat {
protected static final Logger LOG = LoggerFactory.getLogger(AbstractPreferenceFragment.class);
@ -92,24 +94,24 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragmentCompa
DialogFragment dialogFragment;
if (preference instanceof XTimePreference) {
dialogFragment = new XTimePreferenceFragment();
final Bundle bundle = new Bundle(1);
bundle.putString("key", preference.getKey());
dialogFragment.setArguments(bundle);
dialogFragment.setTargetFragment(this, 0);
if (getFragmentManager() != null) {
dialogFragment.show(getFragmentManager(), "androidx.preference.PreferenceFragment.DIALOG");
}
} else if (preference instanceof DragSortListPreference) {
dialogFragment = new DragSortListPreferenceFragment();
final Bundle bundle = new Bundle(1);
bundle.putString("key", preference.getKey());
dialogFragment.setArguments(bundle);
dialogFragment.setTargetFragment(this, 0);
if (getFragmentManager() != null) {
dialogFragment.show(getFragmentManager(), "androidx.preference.PreferenceFragment.DIALOG");
}
} else if (preference instanceof EditTextPreference) {
dialogFragment = MaterialEditTextPreferenceDialogFragment.newInstance(preference.getKey());
} else if (preference instanceof ListPreference) {
dialogFragment = MaterialListPreferenceDialogFragment.newInstance(preference.getKey());
} else if (preference instanceof MultiSelectListPreference) {
dialogFragment = MaterialMultiSelectListPreferenceDialogFragment.newInstance(preference.getKey());
} else {
super.onDisplayPreferenceDialog(preference);
return;
}
final Bundle bundle = new Bundle(1);
bundle.putString("key", preference.getKey());
dialogFragment.setArguments(bundle);
dialogFragment.setTargetFragment(this, 0);
if (getFragmentManager() != null) {
dialogFragment.show(getFragmentManager(), "androidx.preference.PreferenceFragment.DIALOG");
}
}

View File

@ -17,7 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -44,6 +43,7 @@ import androidx.core.content.FileProvider;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.slf4j.Logger;
@ -241,7 +241,7 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
}
}
new AlertDialog.Builder(ActivitySummariesActivity.this)
new MaterialAlertDialogBuilder(ActivitySummariesActivity.this)
.setTitle(ActivitySummariesActivity.this.getString(R.string.sports_activity_confirm_delete_title, toDelete.size()))
.setMessage(ActivitySummariesActivity.this.getString(R.string.sports_activity_confirm_delete_description, toDelete.size()))
.setIcon(R.drawable.ic_delete_forever)

View File

@ -18,7 +18,6 @@
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
@ -48,8 +47,11 @@ import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.FileProvider;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -260,7 +262,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
input.setLayoutParams(params);
container.addView(input);
new AlertDialog.Builder(ActivitySummaryDetail.this)
new MaterialAlertDialogBuilder(ActivitySummaryDetail.this)
.setView(container)
.setCancelable(true)
.setTitle(ActivitySummaryDetail.this.getString(R.string.activity_summary_edit_name_title))
@ -292,7 +294,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
export_path = get_path();
filesGpxList = get_gpx_file_list();
AlertDialog.Builder builder = new AlertDialog.Builder(ActivitySummaryDetail.this);
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(ActivitySummaryDetail.this);
builder.setTitle(R.string.activity_summary_detail_select_gpx_track);
ArrayAdapter<String> directory_listing = new ArrayAdapter<String>(ActivitySummaryDetail.this, android.R.layout.simple_list_item_1, filesGpxList);
builder.setSingleChoiceItems(directory_listing, 0, new DialogInterface.OnClickListener() {
@ -306,7 +308,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
message = String.format("%s?", getString(R.string.activity_summary_detail_clear_gpx_track));
}
new AlertDialog.Builder(ActivitySummaryDetail.this)
new MaterialAlertDialogBuilder(ActivitySummaryDetail.this)
.setCancelable(true)
.setIcon(R.drawable.ic_warning)
.setTitle(R.string.activity_summary_detail_editing_gpx_track)

View File

@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;
@ -25,6 +24,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.slf4j.Logger;
@ -80,7 +80,7 @@ public class ConfigureContacts extends AbstractGBActivity {
if (mGBContactListAdapter.getItemCount() >= deviceSlots) {
// No more free slots
new AlertDialog.Builder(v.getContext())
new MaterialAlertDialogBuilder(v.getContext())
.setTitle(R.string.reminder_no_free_slots_title)
.setMessage(getBaseContext().getString(R.string.contact_no_free_slots_description, String.format(Locale.getDefault(), "%d", deviceSlots)))
.setIcon(R.drawable.ic_warning)

View File

@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
@ -27,6 +26,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.slf4j.Logger;
@ -90,7 +90,7 @@ public class ConfigureReminders extends AbstractGBActivity {
if (mGBReminderListAdapter.getItemCount() >= deviceSlots) {
// No more free slots
new AlertDialog.Builder(v.getContext())
new MaterialAlertDialogBuilder(v.getContext())
.setTitle(R.string.reminder_no_free_slots_title)
.setMessage(getBaseContext().getString(R.string.reminder_no_free_slots_description, String.format(Locale.getDefault(), "%d", deviceSlots)))
.setIcon(R.drawable.ic_warning)

View File

@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
@ -30,12 +29,12 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
@ -92,7 +91,7 @@ public class ConfigureWorldClocks extends AbstractGBActivity {
if (mGBWorldClockListAdapter.getItemCount() >= deviceSlots) {
// No more free slots
new AlertDialog.Builder(v.getContext())
new MaterialAlertDialogBuilder(v.getContext())
.setTitle(R.string.world_clock_no_free_slots_title)
.setMessage(getBaseContext().getString(R.string.world_clock_no_free_slots_description, String.format(Locale.getDefault(), "%d", deviceSlots)))
.setIcon(R.drawable.ic_warning)

View File

@ -17,11 +17,11 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT;
import static nodomain.freeyourgadget.gadgetbridge.util.GB.toast;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.NotificationManager;
import android.content.ActivityNotFoundException;
@ -31,25 +31,27 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.TypedValue;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.view.menu.MenuItemImpl;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
@ -60,6 +62,9 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.color.DynamicColors;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
@ -77,10 +82,9 @@ import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import de.cketti.library.changelog.ChangeLog;
import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
import nodomain.freeyourgadget.gadgetbridge.adapter.GBDeviceAdapterv2;
import nodomain.freeyourgadget.gadgetbridge.database.DBAccess;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
@ -91,12 +95,11 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.DailyTotals;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.util.ChangeLog;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT;
//TODO: extend AbstractGBActivity, but it requires actionbar that is not available
public class ControlCenterv2 extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, GBActivity {
@ -119,6 +122,7 @@ public class ControlCenterv2 extends AppCompatActivity
private RecyclerView deviceListView;
private FloatingActionButton fab;
private boolean isLanguageInvalid = false;
private boolean isThemeInvalid = false;
List<GBDevice> deviceList;
private HashMap<String,long[]> deviceActivityHashMap = new HashMap();
@ -130,6 +134,9 @@ public class ControlCenterv2 extends AppCompatActivity
case GBApplication.ACTION_LANGUAGE_CHANGE:
setLanguage(GBApplication.getLanguage(), true);
break;
case GBApplication.ACTION_THEME_CHANGE:
isThemeInvalid = true;
break;
case GBApplication.ACTION_QUIT:
finish();
break;
@ -179,9 +186,20 @@ public class ControlCenterv2 extends AppCompatActivity
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_controlcenterv2);
Toolbar toolbar = findViewById(R.id.toolbar);
MaterialToolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (GBApplication.areDynamicColorsEnabled()) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = getTheme();
theme.resolveAttribute(R.attr.colorSurface, typedValue, true);
@ColorInt int toolbarBackground = typedValue.data;
toolbar.setBackgroundColor(toolbarBackground);
} else {
toolbar.setBackgroundColor(getResources().getColor(R.color.primarydark_light));
toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
}
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.controlcenter_navigation_drawer_open, R.string.controlcenter_navigation_drawer_close);
@ -264,6 +282,7 @@ public class ControlCenterv2 extends AppCompatActivity
IntentFilter filterLocal = new IntentFilter();
filterLocal.addAction(GBApplication.ACTION_LANGUAGE_CHANGE);
filterLocal.addAction(GBApplication.ACTION_THEME_CHANGE);
filterLocal.addAction(GBApplication.ACTION_QUIT);
filterLocal.addAction(GBApplication.ACTION_NEW_DATA);
filterLocal.addAction(DeviceManager.ACTION_DEVICES_CHANGED);
@ -346,7 +365,7 @@ public class ControlCenterv2 extends AppCompatActivity
ChangeLog cl = createChangeLog();
if (cl.isFirstRun()) {
try {
cl.getLogDialog().show();
cl.getMaterialLogDialog().show();
} catch (Exception ignored) {
GB.toast(getBaseContext(), "Error showing Changelog", Toast.LENGTH_LONG, GB.ERROR);
}
@ -365,8 +384,9 @@ public class ControlCenterv2 extends AppCompatActivity
protected void onResume() {
super.onResume();
handleShortcut(getIntent());
if (isLanguageInvalid) {
if (isLanguageInvalid || isThemeInvalid) {
isLanguageInvalid = false;
isThemeInvalid = false;
recreate();
}
}
@ -434,7 +454,7 @@ public class ControlCenterv2 extends AppCompatActivity
case R.id.external_changelog:
ChangeLog cl = createChangeLog();
try {
cl.getLogDialog().show();
cl.getMaterialLogDialog().show();
} catch (Exception ignored) {
GB.toast(getBaseContext(), "Error showing Changelog", Toast.LENGTH_LONG, GB.ERROR);
}
@ -658,7 +678,7 @@ public class ControlCenterv2 extends AppCompatActivity
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
final Context context = getContext();
builder.setMessage(context.getString(R.string.permission_notification_policy_access,
getContext().getString(R.string.app_name),
@ -682,7 +702,7 @@ public class ControlCenterv2 extends AppCompatActivity
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
final Context context = getContext();
builder.setMessage(context.getString(R.string.permission_notification_listener,
getContext().getString(R.string.app_name),
@ -705,7 +725,7 @@ public class ControlCenterv2 extends AppCompatActivity
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
Context context = getContext();
builder.setMessage(context.getString(R.string.permission_display_over_other_apps,
getContext().getString(R.string.app_name),
@ -729,7 +749,7 @@ public class ControlCenterv2 extends AppCompatActivity
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
Context context = getContext();
builder.setMessage(context.getString(R.string.permission_location,
getContext().getString(R.string.app_name),
@ -769,7 +789,7 @@ public class ControlCenterv2 extends AppCompatActivity
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
Context context = getContext();
builder.setMessage(context.getString(R.string.permission_request,
getContext().getString(R.string.app_name),

View File

@ -17,7 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@ -35,8 +34,11 @@ import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.NavUtils;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -98,7 +100,7 @@ public class DataManagementActivity extends AbstractGBActivity {
e.printStackTrace();
}
AlertDialog.Builder builder = new AlertDialog.Builder(DataManagementActivity.this);
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(DataManagementActivity.this);
builder.setTitle("Export/Import directory content:");
ArrayAdapter<String> directory_listing = new ArrayAdapter<String>(DataManagementActivity.this, android.R.layout.simple_list_item_1, export_path.list());
@ -328,7 +330,7 @@ public class DataManagementActivity extends AbstractGBActivity {
}
private void exportDB() {
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setCancelable(true)
.setIcon(R.drawable.ic_warning)
.setTitle(R.string.dbmanagementactivity_export_data_title)
@ -356,7 +358,7 @@ public class DataManagementActivity extends AbstractGBActivity {
}
private void importDB() {
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setCancelable(true)
.setIcon(R.drawable.ic_warning)
.setTitle(R.string.dbmanagementactivity_import_data_title)
@ -387,7 +389,7 @@ public class DataManagementActivity extends AbstractGBActivity {
}
private void deleteActivityDatabase() {
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setCancelable(true)
.setIcon(R.drawable.ic_warning)
.setTitle(R.string.dbmanagementactivity_delete_activity_data_title)
@ -411,7 +413,7 @@ public class DataManagementActivity extends AbstractGBActivity {
}
private void deleteOldActivityDbFile() {
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setCancelable(true)
.setTitle(R.string.dbmanagementactivity_delete_old_activity_db)
.setIcon(R.drawable.ic_warning)
@ -426,16 +428,16 @@ public class DataManagementActivity extends AbstractGBActivity {
}
}
});
new AlertDialog.Builder(this).setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
new MaterialAlertDialogBuilder(this).setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
new AlertDialog.Builder(this).show();
new MaterialAlertDialogBuilder(this).show();
}
private void cleanExportDirectory() {
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setCancelable(true)
.setIcon(R.drawable.ic_warning)
.setTitle(R.string.activity_DB_clean_export_directory_warning_title)

View File

@ -22,7 +22,6 @@ import static android.content.Intent.EXTRA_SUBJECT;
import static nodomain.freeyourgadget.gadgetbridge.util.GB.NOTIFICATION_CHANNEL_ID;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.PendingIntent;
import android.appwidget.AppWidgetHost;
@ -63,6 +62,7 @@ import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NavUtils;
import androidx.core.app.NotificationCompat;
@ -70,6 +70,8 @@ import androidx.core.app.RemoteInput;
import androidx.core.content.FileProvider;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -271,7 +273,7 @@ public class DebugActivity extends AbstractGBActivity {
factoryResetButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder(DebugActivity.this)
new MaterialAlertDialogBuilder(DebugActivity.this)
.setCancelable(true)
.setTitle(R.string.debugactivity_really_factoryreset_title)
.setMessage(R.string.debugactivity_really_factoryreset)
@ -491,7 +493,7 @@ public class DebugActivity extends AbstractGBActivity {
removeDevicePreferencesButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder(DebugActivity.this)
new MaterialAlertDialogBuilder(DebugActivity.this)
.setCancelable(true)
.setTitle(R.string.debugactivity_confirm_remove_device_preferences_title)
.setMessage(R.string.debugactivity_confirm_remove_device_preferences)
@ -569,7 +571,7 @@ public class DebugActivity extends AbstractGBActivity {
linearLayout.addView(deviceListSpinner);
linearLayout.addView(macLayout);
new AlertDialog.Builder(DebugActivity.this)
new MaterialAlertDialogBuilder(DebugActivity.this)
.setCancelable(true)
.setTitle(R.string.add_test_device)
.setView(linearLayout)
@ -644,7 +646,7 @@ public class DebugActivity extends AbstractGBActivity {
companionDevicesList += "\n\n" + StringUtils.join("\n", associations.toArray(new String[0]));
}
new AlertDialog.Builder(DebugActivity.this)
new MaterialAlertDialogBuilder(DebugActivity.this)
.setCancelable(false)
.setTitle("Companion Devices")
.setMessage(companionDevicesList)
@ -674,7 +676,7 @@ public class DebugActivity extends AbstractGBActivity {
@Override
public void onClick(View v) {
final AlertDialog.Builder fitnesStatusBuilder = new AlertDialog.Builder(DebugActivity.this);
final MaterialAlertDialogBuilder fitnesStatusBuilder = new MaterialAlertDialogBuilder(DebugActivity.this);
fitnesStatusBuilder
.setCancelable(false)
.setTitle("openTracksObserver Status")
@ -857,7 +859,7 @@ public class DebugActivity extends AbstractGBActivity {
}
private void showLogSharingNotEnabledAlert() {
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setTitle(R.string.note)
.setPositiveButton(R.string.ok, null)
.setMessage(R.string.share_log_not_enabled_message)
@ -865,7 +867,7 @@ public class DebugActivity extends AbstractGBActivity {
}
private void showLogSharingWarning() {
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setCancelable(true)
.setTitle(R.string.warning)
.setMessage(R.string.share_log_warning)

View File

@ -18,9 +18,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import static nodomain.freeyourgadget.gadgetbridge.util.GB.toast;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
@ -64,6 +65,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -94,8 +97,6 @@ import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.util.GB.toast;
public class DiscoveryActivity extends AbstractGBActivity implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener, BondingInterface {
private static final Logger LOG = LoggerFactory.getLogger(DiscoveryActivity.class);
@ -834,7 +835,7 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView
linearLayout.addView(deviceListSpinner);
linearLayout.addView(macLayout);
new AlertDialog.Builder(DiscoveryActivity.this)
new MaterialAlertDialogBuilder(DiscoveryActivity.this)
.setCancelable(true)
.setTitle(R.string.add_test_device)
.setView(linearLayout)

View File

@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
@ -34,6 +33,7 @@ import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.slf4j.Logger;
@ -98,7 +98,7 @@ public class ReminderDetails extends AbstractGBActivity implements TimePickerDia
cardRepeat.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new AlertDialog.Builder(ReminderDetails.this).setAdapter(repeatAdapter, new DialogInterface.OnClickListener() {
new MaterialAlertDialogBuilder(ReminderDetails.this).setAdapter(repeatAdapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
reminder.setRepetition(i);

View File

@ -19,9 +19,7 @@
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
@ -44,10 +42,13 @@ import android.widget.Spinner;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -390,6 +391,16 @@ public class SettingsActivity extends AbstractSettingsActivityV2 {
amoled_black.setEnabled(false);
else
amoled_black.setEnabled(true);
amoled_black.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
// Signal activities that the theme has changed
Intent intent = new Intent();
intent.setAction(GBApplication.ACTION_THEME_CHANGE);
LocalBroadcastManager.getInstance(requireContext()).sendBroadcast(intent);
return true;
}
});
}
if (theme != null) {
@ -403,6 +414,10 @@ public class SettingsActivity extends AbstractSettingsActivityV2 {
else
amoled_black.setEnabled(true);
}
// Signal activities that the theme has changed
Intent intent = new Intent();
intent.setAction(GBApplication.ACTION_THEME_CHANGE);
LocalBroadcastManager.getInstance(requireContext()).sendBroadcast(intent);
return true;
}
});
@ -448,7 +463,7 @@ public class SettingsActivity extends AbstractSettingsActivityV2 {
outerLayout.addView(selectionListSpinner);
outerLayout.addView(innerLayout);
new AlertDialog.Builder(requireContext())
new MaterialAlertDialogBuilder(requireContext())
.setCancelable(true)
.setTitle(R.string.pref_title_opentracks_packagename)
.setView(outerLayout)

View File

@ -1,7 +1,6 @@
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.Activity;
import android.app.AlertDialog;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.DialogInterface;
@ -10,6 +9,10 @@ import android.os.Bundle;
import android.util.Pair;
import android.widget.ListView;
import androidx.appcompat.app.AlertDialog;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -64,7 +67,7 @@ public class SleepAlarmWidgetConfigurationActivity extends Activity {
finish();
}
AlertDialog.Builder builder = new AlertDialog.Builder(SleepAlarmWidgetConfigurationActivity.this);
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(SleepAlarmWidgetConfigurationActivity.this);
builder.setTitle(R.string.widget_settings_select_device_title);
allDevices = getAllDevices(getApplicationContext());

View File

@ -1,7 +1,6 @@
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.Activity;
import android.app.AlertDialog;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.DialogInterface;
@ -10,6 +9,10 @@ import android.os.Bundle;
import android.util.Pair;
import android.widget.ListView;
import androidx.appcompat.app.AlertDialog;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -20,7 +23,6 @@ import java.util.Map;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.Widget;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
@ -59,7 +61,7 @@ public class WidgetConfigurationActivity extends Activity {
finish();
}
AlertDialog.Builder builder = new AlertDialog.Builder(WidgetConfigurationActivity.this);
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(WidgetConfigurationActivity.this);
builder.setTitle(R.string.widget_settings_select_device_title);
allDevices = getAllDevices(getApplicationContext());

View File

@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.Editable;
@ -30,6 +29,7 @@ import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.slf4j.Logger;
@ -89,7 +89,7 @@ public class WorldClockDetails extends AbstractGBActivity {
cardTimezone.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new AlertDialog.Builder(WorldClockDetails.this).setAdapter(timezoneAdapter, new DialogInterface.OnClickListener() {
new MaterialAlertDialogBuilder(WorldClockDetails.this).setAdapter(timezoneAdapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
worldClock.setTimeZoneId(timezoneIDs[i]);

View File

@ -20,7 +20,6 @@ package nodomain.freeyourgadget.gadgetbridge.activities.appmanager;
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.QHYBRID_ACTION_DOWNLOADED_FILE;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -39,6 +38,13 @@ import android.view.ViewGroup;
import android.widget.PopupMenu;
import android.widget.Toast;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.apache.commons.lang3.StringUtils;
@ -55,21 +61,14 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.ExternalPebbleJSActivity;
import nodomain.freeyourgadget.gadgetbridge.adapter.GBDeviceAppAdapter;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.FileManagementActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.FossilFileReader;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.FossilHRInstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.QHybridConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.QHybridCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
@ -661,7 +660,7 @@ public abstract class AbstractAppManagerFragment extends Fragment {
}
private void deleteAppConfirm(final GBDeviceApp selectedApp, final boolean deleteFromCache) {
new AlertDialog.Builder(getContext())
new MaterialAlertDialogBuilder(getContext())
.setTitle(R.string.Delete)
.setMessage(requireContext().getString(R.string.contact_delete_confirm_description, selectedApp.getName()))
.setIcon(R.drawable.ic_warning)

View File

@ -13,7 +13,6 @@ import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import org.slf4j.Logger;
@ -22,7 +21,6 @@ import org.slf4j.LoggerFactory;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
@ -36,15 +34,15 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySession;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.dialogs.MaterialDialogFragment;
public class ActivityListingDashboard extends DialogFragment {
public class ActivityListingDashboard extends MaterialDialogFragment {
protected static final Logger LOG = LoggerFactory.getLogger(ActivityListingDashboard.class);
GBDevice gbDevice;
ActivityListingAdapter stepListAdapter;
ActivitySession stepSessionsSummary;
private int timeFrom;
private int timeTo;
private View fragmentView;
public ActivityListingDashboard() {
@ -91,19 +89,18 @@ public class ActivityListingDashboard extends DialogFragment {
throw new IllegalArgumentException("Must provide a device when invoking this activity");
}
stepListAdapter = new ActivityListingAdapter(getContext());
fragmentView = view;
final TextView battery_status_date_from_text = (TextView) view.findViewById(R.id.battery_status_date_from_text);
final TextView battery_status_date_to_text = (TextView) view.findViewById(R.id.battery_status_date_to_text);
LinearLayout battery_status_date_to_layout = (LinearLayout) view.findViewById(R.id.battery_status_date_to_layout);
final SeekBar battery_status_time_span_seekbar = (SeekBar) view.findViewById(R.id.battery_status_time_span_seekbar);
final TextView battery_status_date_from_text = (TextView) getView().findViewById(R.id.battery_status_date_from_text);
final TextView battery_status_date_to_text = (TextView) getView().findViewById(R.id.battery_status_date_to_text);
LinearLayout battery_status_date_to_layout = (LinearLayout) getView().findViewById(R.id.battery_status_date_to_layout);
final SeekBar battery_status_time_span_seekbar = (SeekBar) getView().findViewById(R.id.battery_status_time_span_seekbar);
boolean activity_list_debug_extra_time_range_value = GBApplication.getPrefs().getPreferences().getBoolean("activity_list_debug_extra_time_range", false);
if (!activity_list_debug_extra_time_range_value) {
battery_status_time_span_seekbar.setMax(3);
}
final TextView battery_status_time_span_text = (TextView) view.findViewById(R.id.battery_status_time_span_text);
final TextView battery_status_time_span_text = (TextView) getView().findViewById(R.id.battery_status_time_span_text);
battery_status_time_span_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@ -223,8 +220,8 @@ public class ActivityListingDashboard extends DialogFragment {
}
void indicate_progress(boolean inProgress) {
LinearLayout activity_list_dashboard_results_layout = fragmentView.findViewById(R.id.activity_list_dashboard_results_layout);
RelativeLayout activity_list_dashboard_loading_layout = fragmentView.findViewById(R.id.activity_list_dashboard_loading_layout);
LinearLayout activity_list_dashboard_results_layout = getView().findViewById(R.id.activity_list_dashboard_results_layout);
RelativeLayout activity_list_dashboard_loading_layout = getView().findViewById(R.id.activity_list_dashboard_loading_layout);
if (inProgress) {
activity_list_dashboard_results_layout.setVisibility(View.GONE);
activity_list_dashboard_loading_layout.setVisibility(View.VISIBLE);
@ -235,16 +232,16 @@ public class ActivityListingDashboard extends DialogFragment {
}
void populateData(ActivitySession item) {
TextView stepLabel = fragmentView.findViewById(R.id.line_layout_step_label);
TextView stepTotalLabel = fragmentView.findViewById(R.id.line_layout_total_step_label);
TextView distanceLabel = fragmentView.findViewById(R.id.line_layout_distance_label);
TextView durationLabel = fragmentView.findViewById(R.id.line_layout_duration_label);
TextView sessionCountLabel = fragmentView.findViewById(R.id.line_layout_count_label);
LinearLayout durationLayout = fragmentView.findViewById(R.id.line_layout_duration);
LinearLayout countLayout = fragmentView.findViewById(R.id.line_layout_count);
LinearLayout stepsLayout = fragmentView.findViewById(R.id.line_layout_step);
LinearLayout stepsTotalLayout = fragmentView.findViewById(R.id.line_layout_total_step);
LinearLayout distanceLayout = fragmentView.findViewById(R.id.line_layout_distance);
TextView stepLabel = getView().findViewById(R.id.line_layout_step_label);
TextView stepTotalLabel = getView().findViewById(R.id.line_layout_total_step_label);
TextView distanceLabel = getView().findViewById(R.id.line_layout_distance_label);
TextView durationLabel = getView().findViewById(R.id.line_layout_duration_label);
TextView sessionCountLabel = getView().findViewById(R.id.line_layout_count_label);
LinearLayout durationLayout = getView().findViewById(R.id.line_layout_duration);
LinearLayout countLayout = getView().findViewById(R.id.line_layout_count);
LinearLayout stepsLayout = getView().findViewById(R.id.line_layout_step);
LinearLayout stepsTotalLayout = getView().findViewById(R.id.line_layout_total_step);
LinearLayout distanceLayout = getView().findViewById(R.id.line_layout_distance);
stepLabel.setText(stepListAdapter.getStepLabel(item));
stepTotalLabel.setText(stepListAdapter.getStepTotalLabel(item));

View File

@ -23,7 +23,6 @@ import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import org.slf4j.Logger;
@ -45,14 +44,14 @@ import nodomain.freeyourgadget.gadgetbridge.model.DailyTotals;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.dialogs.MaterialDialogFragment;
public class StepStreaksDashboard extends DialogFragment {
public class StepStreaksDashboard extends MaterialDialogFragment {
protected static final Logger LOG = LoggerFactory.getLogger(StepStreaksDashboard.class);
GBDevice gbDevice;
int stepsGoal;
boolean cancelTasks = false;
boolean backgroundTaskFinished = false;
private View fragmentView;
private StepsStreaks stepsStreaks = new StepsStreaks();
private static final String GOAL = "goal";
private static final String STREAKS = "streaks";
@ -113,7 +112,6 @@ public class StepStreaksDashboard extends DialogFragment {
stepsGoal = getArguments().getInt(GOAL, 0);
gbDevice = getArguments().getParcelable(GBDevice.EXTRA_DEVICE);
fragmentView = view;
if (gbDevice == null) {
throw new IllegalArgumentException("Must provide a device when invoking this activity");
}
@ -133,7 +131,7 @@ public class StepStreaksDashboard extends DialogFragment {
}
void indicate_progress(boolean inProgress) {
ProgressBar step_streak_dashboard_loading_circle = fragmentView.findViewById(R.id.step_streak_dashboard_loading_circle);
ProgressBar step_streak_dashboard_loading_circle = getView().findViewById(R.id.step_streak_dashboard_loading_circle);
if (inProgress) {
step_streak_dashboard_loading_circle.setAlpha(0.4f); //make it a bit softer
} else {

View File

@ -17,7 +17,6 @@
package nodomain.freeyourgadget.gadgetbridge.adapter;
import android.app.AlertDialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
@ -28,6 +27,8 @@ import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList;
import java.util.List;
@ -69,7 +70,7 @@ public class GBContactListAdapter extends RecyclerView.Adapter<GBContactListAdap
holder.container.setOnClickListener(v -> ((ConfigureContacts) mContext).configureContact(contact));
holder.container.setOnLongClickListener(v -> {
new AlertDialog.Builder(v.getContext())
new MaterialAlertDialogBuilder(v.getContext())
.setTitle(R.string.contact_delete_confirm_title)
.setMessage(mContext.getString(R.string.contact_delete_confirm_description, contact.getName()))
.setIcon(R.drawable.ic_warning)

View File

@ -17,8 +17,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.adapter;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@ -58,6 +59,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.cardview.widget.CardView;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@ -71,6 +73,7 @@ import com.github.mikephil.charting.data.PieDataSet;
import com.github.mikephil.charting.data.PieEntry;
import com.github.mikephil.charting.utils.MPPointF;
import com.google.android.flexbox.FlexboxLayout;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
import com.jaredrummler.android.colorpicker.ColorPickerDialog;
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener;
@ -120,8 +123,6 @@ import nodomain.freeyourgadget.gadgetbridge.util.FormatUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT;
/**
* Adapter for displaying GBDevice instances.
*/
@ -548,7 +549,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
holder.findDevice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder(context)
new MaterialAlertDialogBuilder(context)
.setCancelable(true)
.setTitle(context.getString(R.string.controlcenter_find_device))
.setMessage(context.getString(R.string.find_lost_device_message, device.getName()))
@ -626,7 +627,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
@Override
public void onClick(View view) {
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
final LayoutInflater inflater = LayoutInflater.from(context);
final View frequency_picker_view = inflater.inflate(R.layout.dialog_frequency_picker, null);
builder.setTitle(R.string.preferences_fm_frequency);
@ -714,7 +715,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
public void onClick(DialogInterface dialog, int which) {
float frequency = (float) (frequency_decimal_picker.getValue() + (0.1 * frequency_fraction_picker.getValue()));
if (frequency < FREQ_MIN || frequency > FREQ_MAX) {
new AlertDialog.Builder(context)
new MaterialAlertDialogBuilder(context)
.setTitle(R.string.pref_invalid_frequency_title)
.setMessage(R.string.pref_invalid_frequency_message)
.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@ -796,7 +797,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
holder.powerOff.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new AlertDialog.Builder(context)
new MaterialAlertDialogBuilder(context)
.setTitle(R.string.controlcenter_power_off_confirm_title)
.setMessage(R.string.controlcenter_power_off_confirm_description)
.setIcon(R.drawable.ic_power_settings_new)
@ -898,7 +899,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
}
private void showRemoveDeviceDialog(final GBDevice device) {
new AlertDialog.Builder(context)
new MaterialAlertDialogBuilder(context)
.setCancelable(true)
.setTitle(context.getString(R.string.controlcenter_delete_device_name, device.getName()))
.setMessage(R.string.controlcenter_delete_device_dialogmessage)
@ -1019,7 +1020,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
linearLayout.addView(deviceListSpinner);
linearLayout.addView(newFolderLayout);
new AlertDialog.Builder(context)
new MaterialAlertDialogBuilder(context)
.setCancelable(true)
.setTitle(R.string.controlcenter_set_folder_title)
.setView(linearLayout)
@ -1079,7 +1080,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
container.addView(input);
// Specify the type of input expected; this, for example, sets the input as a password, and will mask the text
new AlertDialog.Builder(context)
new MaterialAlertDialogBuilder(context)
.setView(container)
.setCancelable(true)
.setTitle(context.getString(R.string.controlcenter_set_alias))

View File

@ -17,7 +17,6 @@
package nodomain.freeyourgadget.gadgetbridge.adapter;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
@ -29,6 +28,8 @@ import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
@ -80,7 +81,7 @@ public class GBReminderListAdapter extends RecyclerView.Adapter<GBReminderListAd
holder.container.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
new AlertDialog.Builder(v.getContext())
new MaterialAlertDialogBuilder(v.getContext())
.setTitle(R.string.reminder_delete_confirm_title)
.setMessage(R.string.reminder_delete_confirm_description)
.setIcon(R.drawable.ic_warning)

View File

@ -17,7 +17,6 @@
package nodomain.freeyourgadget.gadgetbridge.adapter;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
@ -29,12 +28,13 @@ import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
@ -83,7 +83,7 @@ public class GBWorldClockListAdapter extends RecyclerView.Adapter<GBWorldClockLi
holder.container.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
new AlertDialog.Builder(v.getContext())
new MaterialAlertDialogBuilder(v.getContext())
.setTitle(v.getContext().getString(R.string.world_clock_delete_confirm_title, worldClock.getLabel()))
.setMessage(R.string.world_clock_delete_confirm_description)
.setIcon(R.drawable.ic_warning)

View File

@ -16,12 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
@ -30,6 +24,14 @@ import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import androidx.appcompat.app.AlertDialog;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.json.JSONArray;
import org.json.JSONException;
import org.slf4j.Logger;
@ -104,7 +106,7 @@ public class CommuteActionsActivity extends AbstractGBActivity implements Commut
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setView(input)
.setNegativeButton(R.string.fossil_hr_new_action_cancel, null)
.setPositiveButton(R.string.ok, this)
@ -123,7 +125,7 @@ public class CommuteActionsActivity extends AbstractGBActivity implements Commut
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setView(input)
.setNegativeButton(R.string.fossil_hr_edit_action_delete, new DialogInterface.OnClickListener() {
@Override

View File

@ -17,7 +17,6 @@
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
@ -56,8 +55,11 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.json.JSONArray;
import org.json.JSONException;
@ -132,7 +134,7 @@ public class ConfigActivity extends AbstractGBActivity {
layout2.setGravity(Gravity.CENTER);
new AlertDialog.Builder(ConfigActivity.this)
new MaterialAlertDialogBuilder(ConfigActivity.this)
.setTitle(getString(R.string.qhybrid_offset_time_by))
.setView(layout2)
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
@ -177,7 +179,7 @@ public class ConfigActivity extends AbstractGBActivity {
layout2.setGravity(Gravity.CENTER);
new AlertDialog.Builder(ConfigActivity.this)
new MaterialAlertDialogBuilder(ConfigActivity.this)
.setTitle(getString(R.string.qhybrid_offset_timezone))
.setView(layout2)
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
@ -387,7 +389,7 @@ public class ConfigActivity extends AbstractGBActivity {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean checked) {
if (!device.getDeviceInfo(QHybridSupport.ITEM_STEP_GOAL).getDetails().equals("1000000")) {
new AlertDialog.Builder(ConfigActivity.this)
new MaterialAlertDialogBuilder(ConfigActivity.this)
.setMessage(getString(R.string.qhybrid_prompt_million_steps))
.setPositiveButton("ok", null)
.show();
@ -449,7 +451,7 @@ public class ConfigActivity extends AbstractGBActivity {
buttonTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog dialog = new AlertDialog.Builder(ConfigActivity.this)
AlertDialog dialog = new MaterialAlertDialogBuilder(ConfigActivity.this)
.setItems(names, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

View File

@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@ -32,6 +31,8 @@ import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.io.FileInputStream;
import java.io.IOException;
@ -145,7 +146,7 @@ public class FileManagementActivity extends AbstractGBActivity implements View.O
if (!handleFound)
text = "File does not start with a known handle. Are you sure the header is already generated?";
text += " Repeat to continue anyway.";
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setTitle("warning")
.setMessage(text)
.setPositiveButton("ok", null)

View File

@ -16,7 +16,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
import android.app.AlertDialog;
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.QHYBRID_COMMAND_UPDATE_WIDGETS;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
@ -35,6 +36,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -57,8 +60,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.Version;
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.QHYBRID_COMMAND_UPDATE_WIDGETS;
public class HRConfigActivity extends AbstractGBActivity {
private SharedPreferences sharedPreferences;
private WidgetListAdapter widgetListAdapter;
@ -110,7 +111,7 @@ public class HRConfigActivity extends AbstractGBActivity {
findViewById(R.id.qhybrid_set_background).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new AlertDialog.Builder(HRConfigActivity.this)
new MaterialAlertDialogBuilder(HRConfigActivity.this)
.setTitle("whoop whoop")
.setMessage("background has to be pushed every time a custom widget changes, causing traffic and battery drain. Consider that when using custom widgets.")
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
@ -153,7 +154,7 @@ public class HRConfigActivity extends AbstractGBActivity {
}
final String[] nameStrings = names.toArray(new String[0]);
new AlertDialog.Builder(HRConfigActivity.this)
new MaterialAlertDialogBuilder(HRConfigActivity.this)
.setItems(
nameStrings,
new DialogInterface.OnClickListener() {

View File

@ -17,7 +17,6 @@
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@ -31,7 +30,6 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@ -41,20 +39,17 @@ import android.view.DragEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -68,10 +63,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.TimeZone;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
@ -115,7 +107,7 @@ public class HybridHRWatchfaceDesignerActivity extends AbstractGBActivity implem
}
} else {
readyToCloseActivity = false;
new AlertDialog.Builder(HybridHRWatchfaceDesignerActivity.this)
new MaterialAlertDialogBuilder(HybridHRWatchfaceDesignerActivity.this)
.setMessage(R.string.watchface_upload_failed)
.setPositiveButton(R.string.ok, null)
.show();
@ -223,7 +215,7 @@ public class HybridHRWatchfaceDesignerActivity extends AbstractGBActivity implem
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setView(input)
.setNegativeButton(R.string.fossil_hr_new_action_cancel, null)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@ -605,7 +597,7 @@ public class HybridHRWatchfaceDesignerActivity extends AbstractGBActivity implem
File cacheDir = mCoordinator.getAppCacheDir();
File destFile = new File(cacheDir, app.getUUID().toString() + mCoordinator.getAppFileExtension());
if (destFile.exists()) {
new AlertDialog.Builder(this)
new MaterialAlertDialogBuilder(this)
.setMessage(R.string.watchface_cache_confirm_overwrite)
.setNegativeButton(R.string.no, null)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {

View File

@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageInfo;
@ -37,9 +36,13 @@ import android.widget.RadioGroup;
import android.widget.ScrollView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
public class TimePicker extends AlertDialog.Builder {
public class TimePicker extends MaterialAlertDialogBuilder {
ImageView pickerView;
Canvas pickerCanvas;
Bitmap pickerBitmap;

View File

@ -23,8 +23,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioButton;
@ -36,6 +34,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.R;
@ -114,7 +114,7 @@ public class WidgetSettingsActivity extends AbstractGBActivity {
}
private void showElementDialog(@Nullable final CustomWidgetElement element){
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(WidgetSettingsActivity.this)
MaterialAlertDialogBuilder dialogBuilder = new MaterialAlertDialogBuilder(WidgetSettingsActivity.this)
.setView(R.layout.qhybrid_element_popup_view);
if(element == null) {

View File

@ -34,18 +34,17 @@ import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.Dev
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_SOUND_POSITION;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SONY_SURROUND_MODE;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Parcel;
import androidx.preference.EditTextPreference;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -154,7 +153,7 @@ public class SonyHeadphonesSettingsCustomizer implements DeviceSpecificSettingsC
final Context context = preference.getContext();
new AlertDialog.Builder(context)
new MaterialAlertDialogBuilder(context)
.setTitle(R.string.sony_anc_optimize_confirmation_title)
.setMessage(R.string.sony_anc_optimize_confirmation_description)
.setIcon(R.drawable.ic_hearing)

View File

@ -23,6 +23,7 @@ import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
@ -39,6 +40,8 @@ import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.material.color.DynamicColors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -113,7 +116,18 @@ public class AndroidUtils {
*/
public static String getTextColorHex(Context context) {
int color;
if (GBApplication.isDarkThemeEnabled()) {
if (DynamicColors.isDynamicColorAvailable() && GBApplication.areDynamicColorsEnabled()) {
Context dynamicColorContext;
if (GBApplication.isDarkThemeEnabled()) {
dynamicColorContext = DynamicColors.wrapContextIfAvailable(context, R.style.GadgetbridgeThemeDynamicDark);
} else {
dynamicColorContext = DynamicColors.wrapContextIfAvailable(context, R.style.GadgetbridgeThemeDynamicLight);
}
int[] attrsToResolve = {R.attr.colorOnSurface};
TypedArray ta = dynamicColorContext.obtainStyledAttributes(attrsToResolve);
color = ta.getColor(0, 0);
ta.recycle();
} else if (GBApplication.isDarkThemeEnabled()) {
color = context.getResources().getColor(R.color.primarytext_dark);
} else {
color = context.getResources().getColor(R.color.primarytext_light);
@ -127,7 +141,18 @@ public class AndroidUtils {
*/
public static String getBackgroundColorHex(Context context) {
int color;
if (GBApplication.isDarkThemeEnabled()) {
if (DynamicColors.isDynamicColorAvailable() && GBApplication.areDynamicColorsEnabled()) {
Context dynamicColorContext;
if (GBApplication.isDarkThemeEnabled()) {
dynamicColorContext = DynamicColors.wrapContextIfAvailable(context, R.style.GadgetbridgeThemeDynamicDark);
} else {
dynamicColorContext = DynamicColors.wrapContextIfAvailable(context, R.style.GadgetbridgeThemeDynamicLight);
}
int[] attrsToResolve = {R.attr.colorSurface};
TypedArray ta = dynamicColorContext.obtainStyledAttributes(attrsToResolve);
color = ta.getColor(0, 0);
ta.recycle();
} else if (GBApplication.isDarkThemeEnabled()) {
color = context.getResources().getColor(R.color.cardview_dark_background);
} else {
color = context.getResources().getColor(R.color.cardview_light_background);

View File

@ -20,7 +20,6 @@ import static androidx.core.app.ActivityCompat.startIntentSenderForResult;
import static nodomain.freeyourgadget.gadgetbridge.util.GB.toast;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.companion.AssociationRequest;
@ -38,6 +37,8 @@ import android.widget.Toast;
import androidx.annotation.RequiresApi;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -195,7 +196,7 @@ public class BondingUtil {
// Do nothing
return;
} else if (bondingStyle == DeviceCoordinator.BONDING_STYLE_ASK) {
new AlertDialog.Builder(bondingInterface.getContext())
new MaterialAlertDialogBuilder(bondingInterface.getContext())
.setCancelable(true)
.setTitle(bondingInterface.getContext().getString(R.string.discovery_pair_title, deviceCandidate.getName()))
.setMessage(bondingInterface.getContext().getString(R.string.discovery_pair_question))

View File

@ -0,0 +1,78 @@
/* Copyright (C) 2023 Arjan Schrijver
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util;
import android.content.Context;
import android.content.DialogInterface;
import android.webkit.WebView;
import androidx.appcompat.app.AlertDialog;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import nodomain.freeyourgadget.gadgetbridge.R;
public class ChangeLog extends de.cketti.library.changelog.ChangeLog {
public ChangeLog(Context context, String css) {
super(context, css);
}
public AlertDialog getMaterialLogDialog() {
return getMaterialDialog(isFirstRunEver());
}
public AlertDialog getMaterialFullLogDialog() {
return getMaterialDialog(true);
}
protected AlertDialog getMaterialDialog(boolean full) {
WebView wv = new WebView(mContext);
//wv.setBackgroundColor(0); // transparent
wv.loadDataWithBaseURL(null, getLog(full), "text/html", "UTF-8", null);
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(mContext);
builder.setTitle(
mContext.getResources().getString(
full ? R.string.changelog_full_title : R.string.changelog_title))
.setView(wv)
.setCancelable(false)
// OK button
.setPositiveButton(
mContext.getResources().getString(R.string.changelog_ok_button),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// The user clicked "OK" so save the current version code as
// "last version code".
updateVersionInPreferences();
}
});
if (!full) {
// Show "More…" button if we're only displaying a partial change log.
builder.setNegativeButton(R.string.changelog_show_full,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
getMaterialFullLogDialog().show();
}
});
}
return builder.create();
}
}

View File

@ -23,9 +23,10 @@ import android.widget.TimePicker;
import androidx.preference.DialogPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceDialogFragmentCompat;
public class XTimePreferenceFragment extends PreferenceDialogFragmentCompat implements DialogPreference.TargetFragment {
import nodomain.freeyourgadget.gadgetbridge.util.dialogs.MaterialPreferenceDialogFragment;
public class XTimePreferenceFragment extends MaterialPreferenceDialogFragment implements DialogPreference.TargetFragment {
private TimePicker picker = null;
@Override

View File

@ -0,0 +1,46 @@
/* Copyright (C) 2023 Arjan Schrijver
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util.dialogs;
import android.app.Dialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
public class MaterialDialogFragment extends DialogFragment {
View theDialogView;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
theDialogView = onCreateView(LayoutInflater.from(requireContext()), null, savedInstanceState);
builder.setView(theDialogView);
return builder.create();
}
@Override
public View getView() {
return theDialogView;
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of and modified for Gadgetbridge.
*/
package nodomain.freeyourgadget.gadgetbridge.util.dialogs;
import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.preference.EditTextPreference;
public class MaterialEditTextPreferenceDialogFragment extends MaterialPreferenceDialogFragment {
private static final String SAVE_STATE_TEXT = "EditTextPreferenceDialogFragment.text";
private EditText mEditText;
private CharSequence mText;
public static MaterialEditTextPreferenceDialogFragment newInstance(String key) {
final MaterialEditTextPreferenceDialogFragment
fragment = new MaterialEditTextPreferenceDialogFragment();
final Bundle b = new Bundle(1);
b.putString(ARG_KEY, key);
fragment.setArguments(b);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
mText = getEditTextPreference().getText();
} else {
mText = savedInstanceState.getCharSequence(SAVE_STATE_TEXT);
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putCharSequence(SAVE_STATE_TEXT, mText);
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
mEditText = view.findViewById(android.R.id.edit);
if (mEditText == null) {
throw new IllegalStateException("Dialog view must contain an EditText with id" +
" @android:id/edit");
}
mEditText.requestFocus();
mEditText.setText(mText);
// Place cursor at the end
mEditText.setSelection(mEditText.getText().length());
// if (getEditTextPreference().getOnBindEditTextListener() != null) {
// getEditTextPreference().getOnBindEditTextListener().onBindEditText(mEditText);
// }
}
private EditTextPreference getEditTextPreference() {
return (EditTextPreference) getPreference();
}
/** @hide */
@RestrictTo(LIBRARY)
@Override
protected boolean needInputMethod() {
// We want the input method to show, if possible, when dialog is displayed
return true;
}
@Override
public void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
String value = mEditText.getText().toString();
final EditTextPreference preference = getEditTextPreference();
if (preference.callChangeListener(value)) {
preference.setText(value);
}
}
}
}

View File

@ -0,0 +1,117 @@
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of and modified for Gadgetbridge.
*/
package nodomain.freeyourgadget.gadgetbridge.util.dialogs;
import android.content.DialogInterface;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.preference.ListPreference;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
public class MaterialListPreferenceDialogFragment extends MaterialPreferenceDialogFragment {
private static final String SAVE_STATE_INDEX = "ListPreferenceDialogFragment.index";
private static final String SAVE_STATE_ENTRIES = "ListPreferenceDialogFragment.entries";
private static final String SAVE_STATE_ENTRY_VALUES =
"ListPreferenceDialogFragment.entryValues";
@SuppressWarnings("WeakerAccess") /* synthetic access */
int mClickedDialogEntryIndex;
private CharSequence[] mEntries;
private CharSequence[] mEntryValues;
public static MaterialListPreferenceDialogFragment newInstance(String key) {
final MaterialListPreferenceDialogFragment fragment =
new MaterialListPreferenceDialogFragment();
final Bundle b = new Bundle(1);
b.putString(ARG_KEY, key);
fragment.setArguments(b);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
final ListPreference preference = getListPreference();
if (preference.getEntries() == null || preference.getEntryValues() == null) {
throw new IllegalStateException(
"ListPreference requires an entries array and an entryValues array.");
}
mClickedDialogEntryIndex = preference.findIndexOfValue(preference.getValue());
mEntries = preference.getEntries();
mEntryValues = preference.getEntryValues();
} else {
mClickedDialogEntryIndex = savedInstanceState.getInt(SAVE_STATE_INDEX, 0);
mEntries = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRIES);
mEntryValues = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRY_VALUES);
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(SAVE_STATE_INDEX, mClickedDialogEntryIndex);
outState.putCharSequenceArray(SAVE_STATE_ENTRIES, mEntries);
outState.putCharSequenceArray(SAVE_STATE_ENTRY_VALUES, mEntryValues);
}
private ListPreference getListPreference() {
return (ListPreference) getPreference();
}
@Override
protected void onPrepareDialogBuilder(MaterialAlertDialogBuilder builder) {
super.onPrepareDialogBuilder(builder);
builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mClickedDialogEntryIndex = which;
// Clicking on an item simulates the positive button click, and dismisses
// the dialog.
MaterialListPreferenceDialogFragment.this.onClick(dialog,
DialogInterface.BUTTON_POSITIVE);
dialog.dismiss();
}
});
// The typical interaction for list-based dialogs is to have click-on-an-item dismiss the
// dialog instead of the user having to press 'Ok'.
builder.setPositiveButton(null, null);
}
@Override
public void onDialogClosed(boolean positiveResult) {
if (positiveResult && mClickedDialogEntryIndex >= 0) {
String value = mEntryValues[mClickedDialogEntryIndex].toString();
final ListPreference preference = getListPreference();
if (preference.callChangeListener(value)) {
preference.setValue(value);
}
}
}
}

View File

@ -0,0 +1,136 @@
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of and modified for Gadgetbridge.
*/
package nodomain.freeyourgadget.gadgetbridge.util.dialogs;
import android.content.DialogInterface;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.preference.MultiSelectListPreference;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class MaterialMultiSelectListPreferenceDialogFragment extends MaterialPreferenceDialogFragment {
private static final String SAVE_STATE_VALUES =
"MultiSelectListPreferenceDialogFragmentCompat.values";
private static final String SAVE_STATE_CHANGED =
"MultiSelectListPreferenceDialogFragmentCompat.changed";
private static final String SAVE_STATE_ENTRIES =
"MultiSelectListPreferenceDialogFragmentCompat.entries";
private static final String SAVE_STATE_ENTRY_VALUES =
"MultiSelectListPreferenceDialogFragmentCompat.entryValues";
@SuppressWarnings("WeakerAccess") /* synthetic access */
Set<String> mNewValues = new HashSet<>();
@SuppressWarnings("WeakerAccess") /* synthetic access */
boolean mPreferenceChanged;
@SuppressWarnings("WeakerAccess") /* synthetic access */
CharSequence[] mEntries;
@SuppressWarnings("WeakerAccess") /* synthetic access */
CharSequence[] mEntryValues;
public static MaterialMultiSelectListPreferenceDialogFragment newInstance(String key) {
final MaterialMultiSelectListPreferenceDialogFragment fragment =
new MaterialMultiSelectListPreferenceDialogFragment();
final Bundle b = new Bundle(1);
b.putString(ARG_KEY, key);
fragment.setArguments(b);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
final MultiSelectListPreference preference = getListPreference();
if (preference.getEntries() == null || preference.getEntryValues() == null) {
throw new IllegalStateException(
"MultiSelectListPreference requires an entries array and " +
"an entryValues array.");
}
mNewValues.clear();
mNewValues.addAll(preference.getValues());
mPreferenceChanged = false;
mEntries = preference.getEntries();
mEntryValues = preference.getEntryValues();
} else {
mNewValues.clear();
mNewValues.addAll(savedInstanceState.getStringArrayList(SAVE_STATE_VALUES));
mPreferenceChanged = savedInstanceState.getBoolean(SAVE_STATE_CHANGED, false);
mEntries = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRIES);
mEntryValues = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRY_VALUES);
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList(SAVE_STATE_VALUES, new ArrayList<>(mNewValues));
outState.putBoolean(SAVE_STATE_CHANGED, mPreferenceChanged);
outState.putCharSequenceArray(SAVE_STATE_ENTRIES, mEntries);
outState.putCharSequenceArray(SAVE_STATE_ENTRY_VALUES, mEntryValues);
}
private MultiSelectListPreference getListPreference() {
return (MultiSelectListPreference) getPreference();
}
@Override
protected void onPrepareDialogBuilder(MaterialAlertDialogBuilder builder) {
super.onPrepareDialogBuilder(builder);
final int entryCount = mEntryValues.length;
final boolean[] checkedItems = new boolean[entryCount];
for (int i = 0; i < entryCount; i++) {
checkedItems[i] = mNewValues.contains(mEntryValues[i].toString());
}
builder.setMultiChoiceItems(mEntries, checkedItems,
new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
if (isChecked) {
mPreferenceChanged |= mNewValues.add(
mEntryValues[which].toString());
} else {
mPreferenceChanged |= mNewValues.remove(
mEntryValues[which].toString());
}
}
});
}
@Override
public void onDialogClosed(boolean positiveResult) {
if (positiveResult && mPreferenceChanged) {
final MultiSelectListPreference preference = getListPreference();
if (preference.callChangeListener(mNewValues)) {
preference.setValues(mNewValues);
}
}
mPreferenceChanged = false;
}
}

View File

@ -0,0 +1,269 @@
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of and modified for Gadgetbridge.
*/
package nodomain.freeyourgadget.gadgetbridge.util.dialogs;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.preference.DialogPreference;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
/**
* Abstract base class which presents a dialog associated with a {@link DialogPreference}. Since
* the preference object may not be available during fragment re-creation, the necessary
* information for displaying the dialog is read once during the initial call to
* {@link #onCreate(Bundle)} and saved/restored in the saved instance state. Custom subclasses
* should also follow this pattern.
*/
public abstract class MaterialPreferenceDialogFragment extends DialogFragment implements
DialogInterface.OnClickListener {
protected static final String ARG_KEY = "key";
private static final String SAVE_STATE_TITLE = "PreferenceDialogFragment.title";
private static final String SAVE_STATE_POSITIVE_TEXT = "PreferenceDialogFragment.positiveText";
private static final String SAVE_STATE_NEGATIVE_TEXT = "PreferenceDialogFragment.negativeText";
private static final String SAVE_STATE_MESSAGE = "PreferenceDialogFragment.message";
private static final String SAVE_STATE_LAYOUT = "PreferenceDialogFragment.layout";
private static final String SAVE_STATE_ICON = "PreferenceDialogFragment.icon";
private DialogPreference mPreference;
private CharSequence mDialogTitle;
private CharSequence mPositiveButtonText;
private CharSequence mNegativeButtonText;
private CharSequence mDialogMessage;
private @LayoutRes int mDialogLayoutRes;
private BitmapDrawable mDialogIcon;
/** Which button was clicked. */
private int mWhichButtonClicked;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Fragment rawFragment = getTargetFragment();
if (!(rawFragment instanceof DialogPreference.TargetFragment)) {
throw new IllegalStateException("Target fragment must implement TargetFragment" +
" interface");
}
final DialogPreference.TargetFragment fragment =
(DialogPreference.TargetFragment) rawFragment;
final String key = getArguments().getString(ARG_KEY);
if (savedInstanceState == null) {
mPreference = fragment.findPreference(key);
mDialogTitle = mPreference.getDialogTitle();
mPositiveButtonText = mPreference.getPositiveButtonText();
mNegativeButtonText = mPreference.getNegativeButtonText();
mDialogMessage = mPreference.getDialogMessage();
mDialogLayoutRes = mPreference.getDialogLayoutResource();
final Drawable icon = mPreference.getDialogIcon();
if (icon == null || icon instanceof BitmapDrawable) {
mDialogIcon = (BitmapDrawable) icon;
} else {
final Bitmap bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(),
icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
icon.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
icon.draw(canvas);
mDialogIcon = new BitmapDrawable(getResources(), bitmap);
}
} else {
mDialogTitle = savedInstanceState.getCharSequence(SAVE_STATE_TITLE);
mPositiveButtonText = savedInstanceState.getCharSequence(SAVE_STATE_POSITIVE_TEXT);
mNegativeButtonText = savedInstanceState.getCharSequence(SAVE_STATE_NEGATIVE_TEXT);
mDialogMessage = savedInstanceState.getCharSequence(SAVE_STATE_MESSAGE);
mDialogLayoutRes = savedInstanceState.getInt(SAVE_STATE_LAYOUT, 0);
final Bitmap bitmap = savedInstanceState.getParcelable(SAVE_STATE_ICON);
if (bitmap != null) {
mDialogIcon = new BitmapDrawable(getResources(), bitmap);
}
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putCharSequence(SAVE_STATE_TITLE, mDialogTitle);
outState.putCharSequence(SAVE_STATE_POSITIVE_TEXT, mPositiveButtonText);
outState.putCharSequence(SAVE_STATE_NEGATIVE_TEXT, mNegativeButtonText);
outState.putCharSequence(SAVE_STATE_MESSAGE, mDialogMessage);
outState.putInt(SAVE_STATE_LAYOUT, mDialogLayoutRes);
if (mDialogIcon != null) {
outState.putParcelable(SAVE_STATE_ICON, mDialogIcon.getBitmap());
}
}
@Override
public @NonNull
Dialog onCreateDialog(Bundle savedInstanceState) {
final Context context = getActivity();
mWhichButtonClicked = DialogInterface.BUTTON_NEGATIVE;
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context)
.setTitle(mDialogTitle)
.setIcon(mDialogIcon)
.setPositiveButton(mPositiveButtonText, this)
.setNegativeButton(mNegativeButtonText, this);
View contentView = onCreateDialogView(context);
if (contentView != null) {
onBindDialogView(contentView);
builder.setView(contentView);
} else {
builder.setMessage(mDialogMessage);
}
onPrepareDialogBuilder(builder);
// Create the dialog
final Dialog dialog = builder.create();
if (needInputMethod()) {
requestInputMethod(dialog);
}
return dialog;
}
/**
* Get the preference that requested this dialog. Available after {@link #onCreate(Bundle)} has
* been called on the {@link PreferenceFragmentCompat} which launched this dialog.
*
* @return The {@link DialogPreference} associated with this dialog
*/
public DialogPreference getPreference() {
if (mPreference == null) {
final String key = getArguments().getString(ARG_KEY);
final DialogPreference.TargetFragment fragment =
(DialogPreference.TargetFragment) getTargetFragment();
mPreference = fragment.findPreference(key);
}
return mPreference;
}
/**
* Prepares the dialog builder to be shown when the preference is clicked.
* Use this to set custom properties on the dialog.
*
* <p>Do not {@link MaterialAlertDialogBuilder#create()} or {@link MaterialAlertDialogBuilder#show()}.
*/
protected void onPrepareDialogBuilder(MaterialAlertDialogBuilder builder) {}
/**
* Returns whether the preference needs to display a soft input method when the dialog is
* displayed. Default is false. Subclasses should override this method if they need the soft
* input method brought up automatically.
*
* <p>Note: If your application targets P or above, ensure your subclass manually requests
* focus (ideally in {@link #onBindDialogView(View)}) for the input field in order to
* correctly attach the input method to the field.
*
* @hide
*/
protected boolean needInputMethod() {
return false;
}
/**
* Sets the required flags on the dialog window to enable input method window to show up.
*/
private void requestInputMethod(Dialog dialog) {
Window window = dialog.getWindow();
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
/**
* Creates the content view for the dialog (if a custom content view is required).
* By default, it inflates the dialog layout resource if it is set.
*
* @return The content view for the dialog
* @see DialogPreference#setLayoutResource(int)
*/
protected View onCreateDialogView(Context context) {
final int resId = mDialogLayoutRes;
if (resId == 0) {
return null;
}
return getLayoutInflater().inflate(resId, null);
}
/**
* Binds views in the content view of the dialog to data.
*
* <p>Make sure to call through to the superclass implementation.
*
* @param view The content view of the dialog, if it is custom
*/
protected void onBindDialogView(View view) {
View dialogMessageView = view.findViewById(android.R.id.message);
if (dialogMessageView != null) {
final CharSequence message = mDialogMessage;
int newVisibility = View.GONE;
if (!TextUtils.isEmpty(message)) {
if (dialogMessageView instanceof TextView) {
((TextView) dialogMessageView).setText(message);
}
newVisibility = View.VISIBLE;
}
if (dialogMessageView.getVisibility() != newVisibility) {
dialogMessageView.setVisibility(newVisibility);
}
}
}
@Override
public void onClick(DialogInterface dialog, int which) {
mWhichButtonClicked = which;
}
@Override
public void onDismiss(@NonNull DialogInterface dialog) {
super.onDismiss(dialog);
onDialogClosed(mWhichButtonClicked == DialogInterface.BUTTON_POSITIVE);
}
public abstract void onDialogClosed(boolean positiveResult);
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorAccent" android:state_checked="true" />
<item android:color="?attr/textColorPrimary" />
<item android:color="?attr/colorPrimary" android:state_checked="true" />
<item android:color="?attr/textColorTertiary" />
</selector>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@ -12,11 +13,11 @@
android:layout_height="wrap_content"
android:theme="@style/GadgetbridgeTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:background="?attr/colorPrimaryDark"
app:popupTheme="@style/GadgetbridgeTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>

View File

@ -16,7 +16,6 @@
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:alpha="0.1"
android:tint="?attr/textColorPrimary"
app:srcCompat="@drawable/gadgetbridge_img" />
<androidx.recyclerview.widget.RecyclerView

View File

@ -209,12 +209,9 @@
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_marginTop="7dp"
android:background="@color/accent"
android:buttonTint="@color/btn_dark"
android:padding="4dp"
android:paddingLeft="10dp"
android:text="Activity summary extra date range (takes long to generate when used)"
android:textColor="@android:color/white"
android:textStyle="bold"
grid:layout_columnSpan="2" />
<Button

View File

@ -6,7 +6,7 @@
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -534,7 +534,7 @@
</LinearLayout>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -4,15 +4,11 @@
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
<com.google.android.material.card.MaterialCardView
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:foreground="?android:attr/selectableItemBackground"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="4dp"
card_view:contentPadding="8dp">
android:layout_margin="8dp">
<RelativeLayout
android:layout_width="match_parent"
@ -137,6 +133,6 @@
</LinearLayout>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/appmanager_item_card_view"
@ -98,4 +98,4 @@
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</com.google.android.material.card.MaterialCardView>

View File

@ -5,24 +5,24 @@
android:layout_height="48dp"
android:orientation="horizontal">
<CheckedTextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_weight="1"
android:drawableStart="?android:attr/listChoiceIndicatorMultiple"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="@+id/drag_handle"
android:layout_width="36dp"
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:contentDescription="drag handle"
android:contentDescription="@string/drag_handle"
app:srcCompat="@drawable/ic_drag_handle"
app:tint="@color/secondarytext" />
<CheckedTextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_weight="1"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:gravity="center_vertical"
android:paddingStart="8dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
</com.mobeta.android.dslv.CheckableLinearLayout>

View File

@ -3,14 +3,14 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/side_nav_bar"
android:background="?attr/drawer_header_color"
android:gravity="bottom"
android:orientation="vertical"
android:layout_marginTop="16dp"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
android:paddingTop="@dimen/activity_vertical_margin">
<ImageView
android:id="@+id/imageView"
@ -24,7 +24,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:textAppearance="@style/TextAppearance.Material3.ActionBar.Title"
android:text="@string/app_name" />
</LinearLayout>

View File

@ -3,13 +3,15 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dslv="http://schemas.android.com/apk/res-auto"
android:id="@android:id/list"
android:divider="@null"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="3dp"
android:choiceMode="multipleChoice"
android:paddingTop="12dp"
dslv:sort_enabled="true"
dslv:remove_enabled="false"
dslv:float_background_color="@color/accent"
dslv:drag_handle_id="@id/drag_handle" />
dslv:drag_handle_id="@id/drag_handle" />

View File

@ -6,14 +6,12 @@
android:id="@+id/activity_action_filter"
android:icon="@drawable/ic_filter_alt"
android:title="@string/pref_header_filter"
app:iconTint="@color/primarytext_dark"
app:showAsAction="always" />
<item
android:id="@+id/overflowMenu"
android:icon="@drawable/ic_menu"
android:title="@string/menuitem_more"
app:iconTint="@color/primarytext_dark"
app:showAsAction="always">
<menu>

View File

@ -6,7 +6,6 @@
android:id="@+id/activity_detail_overflowMenu"
android:icon="@drawable/ic_share"
android:title="@string/share"
app:iconTint="@color/primarytext_dark"
app:showAsAction="always">
<menu>

View File

@ -5,12 +5,11 @@
<item
android:id="@+id/charts_fetch_activity_data"
app:showAsAction="ifRoom"
android:icon="@android:drawable/stat_notify_sync_noanim"
android:icon="@drawable/ic_refresh"
android:title="@string/controlcenter_fetch_activity_data"/>
<item
android:id="@+id/prefs_charts_menu"
android:icon="@drawable/ic_settings"
android:title="@string/pref_header_charts"
app:iconTint="@color/primarytext_dark"
app:showAsAction="ifRoom" />
</menu>

View File

@ -4,11 +4,13 @@
<item>@string/pref_theme_system</item>
<item>@string/pref_theme_light</item>
<item>@string/pref_theme_dark</item>
<item>@string/pref_theme_dynamic</item>
</string-array>
<string-array name="pref_theme_values">
<item>@string/pref_theme_value_system</item>
<item>@string/pref_theme_value_light</item>
<item>@string/pref_theme_value_dark</item>
<item>@string/pref_theme_value_dynamic</item>
</string-array>
<string-array name="pref_language_options">

View File

@ -4,6 +4,8 @@
<attr name="textColorSecondary" format="color" />
<attr name="textColorTertiary" format="color" />
<attr name="drawer_header_color" format="color" />
<attr name="chart_deep_sleep" format="color" />
<attr name="chart_light_sleep" format="color" />
<attr name="chart_rem_sleep" format="color" />

View File

@ -214,6 +214,7 @@
<string name="pref_theme_light">Light</string>
<string name="pref_theme_dark">Dark</string>
<string name="pref_theme_system">System</string>
<string name="pref_theme_dynamic">Dynamic colors</string>
<string name="pref_theme_black_background">Use black background in Dark Theme</string>
<string name="pref_title_language">Language</string>
<string name="pref_title_minimize_priority">Hide the Gadgetbridge notification</string>
@ -2217,4 +2218,5 @@
<string name="withings_calibration_text_activity_target">Finally align the activity hand to 100%. Please be aware that this hand only moves clockwise.</string>
<string name="withings_bt_calibration_previous">Previous</string>
<string name="withings_bt_calibration_next">Next</string>
<string name="drag_handle">drag handle</string>
</resources>

View File

@ -1,17 +1,22 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="GadgetbridgeTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- light theme -->
<style name="GadgetbridgeTheme" parent="Theme.Material3.Light">
<item name="textColorPrimary">@color/primarytext_light</item>
<item name="textColorSecondary">@color/secondarytext</item>
<item name="textColorTertiary">@color/tertiarytext_light</item>
<item name="colorPrimary">@color/primary_light</item>
<item name="colorPrimary">@color/primarydark_light</item>
<item name="colorPrimaryDark">@color/primarydark_light</item>
<item name="colorAccent">@color/accent</item>
<item name="android:buttonStyle">@style/Widget.AppCompat.Button.Colored</item>
<item name="buttonStyle">@style/Widget.AppCompat.Button.Colored</item>
<item name="colorPrimaryContainer">@color/accent</item>
<item name="colorOnPrimaryContainer">@android:color/white</item>
<item name="actionBarStyle">@style/GadgetbridgeTheme.RedActionBar</item>
<item name="drawerArrowStyle">@style/GadgetbridgeTheme.DrawerButtonStyle</item>
<item name="toolbarNavigationButtonStyle">@style/GadgetbridgeTheme.NavigationButtonStyle</item>
<item name="drawer_header_color">?attr/colorPrimaryDark</item>
<item name="chart_deep_sleep">@color/chart_deep_sleep_light</item>
<item name="chart_light_sleep">@color/chart_light_sleep_light</item>
<item name="chart_rem_sleep">@color/chart_rem_sleep_light</item>
@ -21,24 +26,22 @@
<item name="sports_activity_summary_background">@color/chart_heartrate_fill</item>
</style>
<style name="GadgetbridgeTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<!-- dark theme -->
<style name="GadgetbridgeThemeDark" parent="Theme.AppCompat">
<style name="GadgetbridgeThemeDark" parent="Theme.Material3.Dark">
<item name="textColorPrimary">@color/primarytext_dark</item>
<item name="textColorSecondary">@color/secondarytext</item>
<item name="textColorTertiary">@color/tertiarytext_dark</item>
<item name="colorPrimary">@color/primary_dark</item>
<item name="colorPrimary">@color/primarydark_dark</item>
<item name="colorPrimaryDark">@color/primarydark_dark</item>
<item name="colorAccent">@color/accent</item>
<item name="android:buttonStyle">@style/ButtonDark</item>
<item name="buttonStyle">@style/ButtonDark</item>
<item name="colorOnPrimary">@android:color/white</item>
<item name="colorPrimaryContainer">@color/accent</item>
<item name="colorOnPrimaryContainer">@android:color/white</item>
<item name="actionBarStyle">@style/GadgetbridgeTheme.RedActionBar</item>
<item name="drawer_header_color">?attr/colorPrimaryDark</item>
<item name="chart_deep_sleep">@color/chart_deep_sleep_dark</item>
<item name="chart_light_sleep">@color/chart_light_sleep_dark</item>
<item name="chart_rem_sleep">@color/chart_rem_sleep_dark</item>
@ -50,52 +53,80 @@
</style>
<!-- black theme -->
<style name="GadgetbridgeThemeBlack" parent="Theme.AppCompat">
<item name="textColorPrimary">@color/primarytext_dark</item>
<item name="textColorSecondary">@color/secondarytext</item>
<item name="textColorTertiary">@color/tertiarytext_dark</item>
<style name="GadgetbridgeThemeBlack" parent="GadgetbridgeThemeDark">
<item name="android:windowBackground">@android:color/black</item>
<item name="colorPrimary">@color/primary_dark</item>
<item name="colorPrimaryDark">@color/primarydark_dark</item>
<item name="colorAccent">@color/accent</item>
<item name="android:buttonStyle">@style/ButtonDark</item>
<item name="buttonStyle">@style/ButtonDark</item>
<item name="chart_deep_sleep">@color/chart_deep_sleep_dark</item>
<item name="chart_light_sleep">@color/chart_light_sleep_dark</item>
<item name="chart_rem_sleep">@color/chart_rem_sleep_dark</item>
<item name="chart_activity">@color/chart_activity_dark</item>
<item name="chart_not_worn">@color/chart_not_worn_dark</item>
<item name="alternate_row_background">@color/alternate_row_background_dark</item>
<item name="sports_activity_summary_background">@color/alternate_row_background_dark</item>
</style>
<style name="ButtonDark" parent="Widget.AppCompat.Button.Colored">
<item name="android:textColor">@color/btn_dark</item>
<!-- Material 3 dynamic color (Material You) themes -->
<style name="GadgetbridgeThemeDynamicLight" parent="Theme.Material3.DynamicColors.Light">
<item name="actionBarStyle">@style/GadgetbridgeThemeDynamic.ActionBar</item>
<item name="android:statusBarColor">?attr/colorSurface</item>
<item name="android:windowLightStatusBar" tools:targetApi="23">true</item>
<item name="drawer_header_color">?attr/colorSurface</item>
<item name="alternate_row_background">?attr/colorSecondaryContainer</item>
</style>
<style name="GadgetbridgeThemeDynamicDark" parent="Theme.Material3.DynamicColors.Dark">
<item name="actionBarStyle">@style/GadgetbridgeThemeDynamic.ActionBar</item>
<item name="android:statusBarColor">?attr/colorSurface</item>
<item name="android:windowLightStatusBar" tools:targetApi="23">false</item>
<item name="drawer_header_color">?attr/colorSurface</item>
<item name="alternate_row_background">?attr/colorSecondaryContainer</item>
</style>
<style name="GadgetbridgeThemeDynamicDarkAmoled" parent="GadgetbridgeThemeDynamicDark">
<item name="android:windowBackground">@android:color/black</item>
</style>
<!-- theme variants without action bar -->
<style name="GadgetbridgeTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="GadgetbridgeThemeDark.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="GadgetbridgeThemeBlack.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="GadgetbridgeThemeDynamicLight.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="GadgetbridgeThemeDynamicDark.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="GadgetbridgeThemeDynamicDarkAmoled.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<!-- action bar styles -->
<style name="GadgetbridgeTheme.RedActionBar" parent="Widget.Material3.ActionBar.Solid">
<item name="titleTextStyle">@style/GadgetbridgeTheme.ActionBarTitleStyle</item>
<item name="background">@color/primarydark_dark</item>
</style>
<style name="GadgetbridgeThemeDynamic.ActionBar" parent="Widget.Material3.ActionBar.Solid">
<item name="background">?attr/colorSurface</item>
</style>
<style name="GadgetbridgeTheme.DrawerButtonStyle" parent="@style/Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">@android:color/white</item>
</style>
<style name="GadgetbridgeTheme.NavigationButtonStyle" parent="Widget.AppCompat.Toolbar.Button.Navigation">
<item name="tint">@android:color/white</item>
</style>
<style name="GadgetbridgeTheme.AppBarOverlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight" />
<style name="GadgetbridgeTheme.PopupOverlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight" />
<style name="GadgetbridgeTheme.ActionBarTitleStyle" parent="TextAppearance.Material3.ActionBar.Title">
<item name="android:textColor">@color/primarytext_dark</item>
</style>
<style name="GadgetbridgeTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="GadgetbridgeTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
<!-- splash screen -->
<style name="SplashTheme" parent="GadgetbridgeTheme.NoActionBar">
<item tools:targetApi="21" name="android:statusBarColor">@color/primarydark_dark</item>
<item tools:targetApi="21" name="android:navigationBarColor">@color/primarydark_dark</item>
<item name="android:statusBarColor">@color/primarydark_dark</item>
<item name="android:navigationBarColor">@color/primarydark_dark</item>
<item name="android:windowBackground">@drawable/splash</item>
</style>
</resources>

View File

@ -127,5 +127,6 @@
<item name="pref_theme_value_system" translatable="false" type="string">system</item>
<item name="pref_theme_value_light" translatable="false" type="string">light</item>
<item name="pref_theme_value_dark" translatable="false" type="string">dark</item>
<item name="pref_theme_value_dynamic" translatable="false" type="string">dynamic</item>
</resources>