2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-29 13:17:43 +00:00

Add a dark theme

Summary:
BUG: 375376

This revision adds dark mode support to the app ( T7044 ). It does so by injecting
theme information into each activity, and making sure that all Views
define their colors by reference to theme attributes.

In order to make this work, all of the buttons with images (like the list
of available devices) now are tinted according to the theme.

While all versions of android support the theme, only devices running
Android ICS or higher will have a toggle button in the drawer.

Test Plan: Open all the screens, both with and without the dark theme on.

Reviewers: #kde_connect, mtijink, #vdg, nicolasfella

Reviewed By: #kde_connect, mtijink, nicolasfella

Subscribers: apol, ngraham, nicolasfella, mtijink

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D11694
This commit is contained in:
Philip Cohn-Cort 2018-04-23 18:31:44 +02:00 committed by Nicolas Fella
parent b228fb2377
commit a1f1693d0b
23 changed files with 258 additions and 32 deletions

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/primary" android:state_checked="true" />
<item android:drawable="@color/darkStatusBarBackground" android:state_checked="false" />
</selector>

View File

@ -0,0 +1,18 @@
<android.support.v7.widget.SwitchCompat
android:id="@+id/dark_theme"
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="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="16dp"
android:paddingEnd="48dp"
android:paddingLeft="16dp"
android:paddingRight="48dp"
android:paddingStart="16dp"
android:paddingTop="4dp"
android:text="Dark theme"
android:textColor="@android:color/white"
app:switchPadding="12dp"
tools:background="@drawable/drawer_header"
/>

View File

@ -1,5 +1,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
@ -67,29 +69,46 @@
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<TextView <LinearLayout
android:id="@+id/not_reachable_message" android:id="@+id/error_message_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_error_outline_black_48dp" android:orientation="horizontal"
android:drawablePadding="8dip" android:gravity="center"
android:drawableStart="@drawable/ic_error_outline_black_48dp" android:visibility="gone" >
android:gravity="center_vertical"
android:text="@string/unreachable_description" <android.support.v7.widget.AppCompatImageView
android:textAppearance="?android:attr/textAppearanceMedium" android:id="@+id/error_message_icon"
android:visibility="gone" /> android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:importantForAccessibility="no"
android:paddingEnd="8dip"
android:paddingLeft="0dip"
android:paddingRight="8dip"
android:paddingStart="0dip"
android:src="@drawable/ic_error_outline_black_48dp"
app:tint="?attr/colorHighContrast"
tools:ignore="UnusedAttribute"/>
<TextView
android:id="@+id/not_reachable_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="@string/unreachable_description"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
<TextView
android:id="@+id/on_data_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="@string/on_data_message"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
</LinearLayout>
<TextView
android:id="@+id/on_data_message"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_error_outline_black_48dp"
android:drawablePadding="8dip"
android:drawableStart="@drawable/ic_error_outline_black_48dp"
android:gravity="center_vertical"
android:text="@string/on_data_message"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
<ListView <ListView
android:id="@+id/buttons_list" android:id="@+id/buttons_list"

View File

@ -16,9 +16,7 @@
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="8dp" android:elevation="8dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" /> app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<FrameLayout <FrameLayout
@ -33,10 +31,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="start" android:layout_gravity="start"
android:background="@drawable/state_list_drawer_background"
app:headerLayout="@layout/nav_header" app:headerLayout="@layout/nav_header"
app:itemBackground="@drawable/state_list_drawer_background" style="?attr/mainNavigationViewStyle" />
app:itemIconTint="@color/state_list_drawer_text"
app:itemTextColor="@color/state_list_drawer_text" />
</android.support.v4.widget.DrawerLayout> </android.support.v4.widget.DrawerLayout>

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/abc_list_selector_holo_dark" android:background="@drawable/abc_list_selector_holo_dark"
@ -14,12 +16,13 @@
android:paddingRight="?android:attr/scrollbarSize" android:paddingRight="?android:attr/scrollbarSize"
android:paddingStart="12dip"> android:paddingStart="12dip">
<ImageView <android.support.v7.widget.AppCompatImageView
android:id="@+id/list_item_entry_icon" android:id="@+id/list_item_entry_icon"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:contentDescription="@string/device_icon_description" android:contentDescription="@string/device_icon_description"
app:tint="?attr/colorControlNormal"
android:src="@drawable/ic_device_laptop" /> android:src="@drawable/ic_device_laptop" />
<LinearLayout <LinearLayout

View File

@ -137,7 +137,7 @@
android:layout_marginTop="8dip" android:layout_marginTop="8dip"
android:orientation="horizontal"> android:orientation="horizontal">
<ImageView <android.support.v7.widget.AppCompatImageView
android:id="@+id/imageView" android:id="@+id/imageView"
android:layout_width="30dip" android:layout_width="30dip"
android:layout_height="30dip" android:layout_height="30dip"
@ -146,6 +146,7 @@
android:layout_weight="0" android:layout_weight="0"
android:contentDescription="@string/mpris_volume" android:contentDescription="@string/mpris_volume"
android:maxWidth="30dip" android:maxWidth="30dip"
app:tint="?attr/colorHighContrast"
android:src="@drawable/ic_volume_black" /> android:src="@drawable/ic_volume_black" />

View File

@ -16,7 +16,9 @@
<!-- Layout for a Preference in a PreferenceActivity. The <!-- Layout for a Preference in a PreferenceActivity. The
Preference is able to place a specific widget for its particular Preference is able to place a specific widget for its particular
type in the "widget_frame" layout. --> type in the "widget_frame" layout. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
@ -68,13 +70,14 @@
</RelativeLayout> </RelativeLayout>
<ImageButton <android.support.v7.widget.AppCompatImageButton
android:id="@+id/settingsButton" android:id="@+id/settingsButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/abc_btn_borderless_material" android:background="@drawable/abc_btn_borderless_material"
android:contentDescription="@string/settings_icon_description" android:contentDescription="@string/settings_icon_description"
android:padding="8dip" android:padding="8dip"
app:tint="?attr/colorControlNormal"
android:src="@drawable/ic_action_settings_inverted" /> android:src="@drawable/ic_action_settings_inverted" />
</LinearLayout> </LinearLayout>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="KdeConnectTheme.Dark" parent="KdeConnectThemeBase.Dark">
<item name="android:colorEdgeEffect">@color/darkGrey</item>
</style>
<style name="KdeConnectTheme.Dark.NoActionBar" parent="KdeConnectThemeBase.Dark.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:colorEdgeEffect">@color/darkGrey</item>
</style>
</resources>

6
res/values/attrs.xml Normal file
View File

@ -0,0 +1,6 @@
<resources>
<!-- The style to use on the MainActivity's NavigationView -->
<attr name="mainNavigationViewStyle" format="reference" />
<!-- A high-contrast color for important visual elements (for less important elements, use colorControlNormal instead) -->
<attr name="colorHighContrast" format="color" />
</resources>

View File

@ -0,0 +1,40 @@
<resources>
<color name="darkGrey">#555555</color>
<color name="darkToolbarBackground">#222222</color>
<color name="darkStatusBarBackground">#333333</color>
<!-- KdeConnectThemeBase styles must only be defined in the main res/values/ folder -->
<style name="KdeConnectThemeBase.Dark" parent="Theme.AppCompat">
<item name="colorPrimary">@color/darkGrey</item>
<item name="colorPrimaryDark">@color/darkStatusBarBackground</item>
<item name="colorAccent">@color/accent</item>
<item name="android:windowBackground">@android:color/black</item>
<item name="toolbarStyle">@style/KdeConnectTheme.Toolbar.Dark</item>
<item name="popupTheme">@style/ThemeOverlay.AppCompat</item>
<item name="mainNavigationViewStyle">@style/MainNavigationView.Dark</item>
<item name="colorHighContrast">@android:color/white</item>
<item name="android:textColorPrimary">@android:color/white</item>
<item name="android:textColor">@android:color/white</item>
</style>
<style name="KdeConnectThemeBase.Dark.NoActionBar" parent="KdeConnectThemeBase.Dark">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<!-- KdeConnectTheme styles (without the 'Base' on the end) can be redefined in other 'values' folders. like res/values-v21/ -->
<style name="KdeConnectTheme.Toolbar.Dark">
<item name="android:background">@color/darkToolbarBackground</item>
</style>
<style name="KdeConnectTheme.Dark" parent="KdeConnectThemeBase.Dark" />
<style name="KdeConnectTheme.Dark.NoActionBar" parent="KdeConnectThemeBase.Dark.NoActionBar" />
<style name="MainNavigationView.Dark">
<item name="android:background">@drawable/state_list_drawer_background_dark</item>
<item name="itemBackground">@drawable/state_list_drawer_background_dark</item>
<item name="itemIconTint">@android:color/white</item>
<item name="itemTextColor">@android:color/white</item>
</style>
</resources>

View File

@ -10,6 +10,10 @@
<item name="colorPrimary">@color/primary</item> <item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primaryDark</item> <item name="colorPrimaryDark">@color/primaryDark</item>
<item name="colorAccent">@color/accent</item> <item name="colorAccent">@color/accent</item>
<item name="toolbarStyle">@style/KdeConnectTheme.Toolbar</item>
<item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="mainNavigationViewStyle">@style/MainNavigationView</item>
<item name="colorHighContrast">@android:color/black</item>
<item name="android:textColorPrimary">@android:color/black</item> <item name="android:textColorPrimary">@android:color/black</item>
<item name="android:textColor">@android:color/black</item> <item name="android:textColor">@android:color/black</item>
</style> </style>
@ -21,8 +25,18 @@
<style name="KdeConnectTheme" parent="KdeConnectThemeBase" /> <style name="KdeConnectTheme" parent="KdeConnectThemeBase" />
<style name="KdeConnectTheme.Toolbar" parent="Widget.AppCompat.Toolbar">
<item name="android:background">?attr/colorPrimary</item>
</style>
<style name="KdeConnectTheme.NoActionBar" parent="KdeConnectThemeBase.NoActionBar" /> <style name="KdeConnectTheme.NoActionBar" parent="KdeConnectThemeBase.NoActionBar" />
<style name="MainNavigationView">
<item name="android:background">@drawable/state_list_drawer_background</item>
<item name="itemBackground">@drawable/state_list_drawer_background</item>
<item name="itemIconTint">@color/state_list_drawer_text</item>
<item name="itemTextColor">@color/state_list_drawer_text</item>
</style>
<style name="DisableableButton" parent="ThemeOverlay.AppCompat"> <style name="DisableableButton" parent="ThemeOverlay.AppCompat">
<item name="colorButtonNormal">@drawable/disableable_button</item> <item name="colorButtonNormal">@drawable/disableable_button</item>
</style> </style>

View File

@ -34,6 +34,7 @@ import android.view.View;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
import org.kde.kdeconnect.UserInterface.ThemeUtil;
import org.kde.kdeconnect_tp.R; import org.kde.kdeconnect_tp.R;
public class FindMyPhoneActivity extends Activity { public class FindMyPhoneActivity extends Activity {
@ -56,6 +57,7 @@ public class FindMyPhoneActivity extends Activity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
setContentView(R.layout.activity_find_my_phone); setContentView(R.layout.activity_find_my_phone);
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

View File

@ -37,6 +37,7 @@ import android.view.inputmethod.InputMethodManager;
import org.kde.kdeconnect.BackgroundService; import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device; import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.UserInterface.ThemeUtil;
import org.kde.kdeconnect_tp.R; import org.kde.kdeconnect_tp.R;
public class MousePadActivity extends AppCompatActivity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, MousePadGestureDetector.OnGestureListener { public class MousePadActivity extends AppCompatActivity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, MousePadGestureDetector.OnGestureListener {
@ -80,6 +81,7 @@ public class MousePadActivity extends AppCompatActivity implements GestureDetect
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
setContentView(R.layout.activity_mousepad); setContentView(R.layout.activity_mousepad);

View File

@ -46,6 +46,7 @@ import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.BackgroundService; import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device; import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPacket; import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.UserInterface.ThemeUtil;
import org.kde.kdeconnect_tp.R; import org.kde.kdeconnect_tp.R;
import java.util.List; import java.util.List;
@ -314,6 +315,7 @@ public class MprisActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
setContentView(R.layout.activity_mpris); setContentView(R.layout.activity_mpris);
final String targetPlayerName = getIntent().getStringExtra("player"); final String targetPlayerName = getIntent().getStringExtra("player");

View File

@ -39,6 +39,7 @@ import android.widget.ListView;
import org.kde.kdeconnect.BackgroundService; import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Helpers.StringsHelper; import org.kde.kdeconnect.Helpers.StringsHelper;
import org.kde.kdeconnect.UserInterface.ThemeUtil;
import org.kde.kdeconnect_tp.R; import org.kde.kdeconnect_tp.R;
import java.util.Arrays; import java.util.Arrays;
@ -93,6 +94,7 @@ public class NotificationFilterActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
setContentView(R.layout.activity_notification_filter); setContentView(R.layout.activity_notification_filter);
appDatabase = new AppDatabase(NotificationFilterActivity.this, false); appDatabase = new AppDatabase(NotificationFilterActivity.this, false);

View File

@ -35,6 +35,7 @@ import org.json.JSONObject;
import org.kde.kdeconnect.BackgroundService; import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device; import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.UserInterface.List.ListAdapter; import org.kde.kdeconnect.UserInterface.List.ListAdapter;
import org.kde.kdeconnect.UserInterface.ThemeUtil;
import org.kde.kdeconnect_tp.R; import org.kde.kdeconnect_tp.R;
import java.util.ArrayList; import java.util.ArrayList;
@ -115,6 +116,7 @@ public class RunCommandActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
setContentView(R.layout.activity_runcommand); setContentView(R.layout.activity_runcommand);
deviceId = getIntent().getStringExtra("deviceId"); deviceId = getIntent().getStringExtra("deviceId");

View File

@ -32,6 +32,7 @@ import android.widget.Toast;
import org.kde.kdeconnect.BackgroundService; import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device; import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.UserInterface.ThemeUtil;
import org.kde.kdeconnect_tp.R; import org.kde.kdeconnect_tp.R;
import java.util.ArrayList; import java.util.ArrayList;
@ -44,6 +45,7 @@ public class SendFileActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
mDeviceId = getIntent().getStringExtra("deviceId"); mDeviceId = getIntent().getStringExtra("deviceId");

View File

@ -38,6 +38,7 @@ import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.UserInterface.List.EntryItem; import org.kde.kdeconnect.UserInterface.List.EntryItem;
import org.kde.kdeconnect.UserInterface.List.ListAdapter; import org.kde.kdeconnect.UserInterface.List.ListAdapter;
import org.kde.kdeconnect.UserInterface.List.SectionItem; import org.kde.kdeconnect.UserInterface.List.SectionItem;
import org.kde.kdeconnect.UserInterface.ThemeUtil;
import org.kde.kdeconnect_tp.R; import org.kde.kdeconnect_tp.R;
import java.util.ArrayList; import java.util.ArrayList;
@ -145,8 +146,11 @@ public class ShareActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ThemeUtil.setUserPreferredTheme(this);
setContentView(R.layout.devices_list); setContentView(R.layout.devices_list);
ActionBar actionBar = getSupportActionBar(); ActionBar actionBar = getSupportActionBar();
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.refresh_list_layout); mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.refresh_list_layout);
mSwipeRefreshLayout.setOnRefreshListener( mSwipeRefreshLayout.setOnRefreshListener(

View File

@ -45,6 +45,8 @@ public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
getDelegate().installViewFactory(); getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState); getDelegate().onCreate(savedInstanceState);
// The superclass's onCreate() method calls setContentView, so this ThemeUtil call must be before that
ThemeUtil.setUserPreferredTheme(this);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
} }

View File

@ -57,6 +57,7 @@ public class CustomDevicesActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
initializeDeviceList(this); initializeDeviceList(this);
ThemeUtil.setUserPreferredTheme(this);
setContentView(R.layout.custom_ip_list); setContentView(R.layout.custom_ip_list);
list = (ListView) findViewById(android.R.id.list); list = (ListView) findViewById(android.R.id.list);

View File

@ -334,6 +334,7 @@ public class DeviceFragment extends Fragment {
boolean onData = NetworkHelper.isOnMobileNetwork(getContext()); boolean onData = NetworkHelper.isOnMobileNetwork(getContext());
rootView.findViewById(R.id.pairing_buttons).setVisibility(paired ? View.GONE : View.VISIBLE); rootView.findViewById(R.id.pairing_buttons).setVisibility(paired ? View.GONE : View.VISIBLE);
rootView.findViewById(R.id.error_message_container).setVisibility((paired && !reachable) ? View.VISIBLE : View.GONE);
rootView.findViewById(R.id.not_reachable_message).setVisibility((paired && !reachable && !onData) ? View.VISIBLE : View.GONE); rootView.findViewById(R.id.not_reachable_message).setVisibility((paired && !reachable && !onData) ? View.VISIBLE : View.GONE);
rootView.findViewById(R.id.on_data_message).setVisibility((paired && !reachable && onData) ? View.VISIBLE : View.GONE); rootView.findViewById(R.id.on_data_message).setVisibility((paired && !reachable && onData) ? View.VISIBLE : View.GONE);

View File

@ -7,8 +7,11 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.design.widget.NavigationView; import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.view.GravityCompat; import android.support.v4.view.GravityCompat;
@ -16,12 +19,15 @@ import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SwitchCompat;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
@ -55,6 +61,10 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// We need to set this theme before the call to 'setContentView' below
ThemeUtil.setUserPreferredTheme(this);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mNavigationView = (NavigationView) findViewById(R.id.navigation_drawer); mNavigationView = (NavigationView) findViewById(R.id.navigation_drawer);
@ -91,6 +101,10 @@ public class MainActivity extends AppCompatActivity {
mDrawerHeader.findViewById(R.id.kdeconnect_label).setOnClickListener(renameListener); mDrawerHeader.findViewById(R.id.kdeconnect_label).setOnClickListener(renameListener);
mDrawerHeader.findViewById(R.id.device_name).setOnClickListener(renameListener); mDrawerHeader.findViewById(R.id.device_name).setOnClickListener(renameListener);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
addDarkModeSwitch((ViewGroup) mDrawerHeader);
}
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override @Override
public boolean onNavigationItemSelected(MenuItem menuItem) { public boolean onNavigationItemSelected(MenuItem menuItem) {
@ -132,6 +146,36 @@ public class MainActivity extends AppCompatActivity {
onDeviceSelected(savedDevice); onDeviceSelected(savedDevice);
} }
/**
* Adds a {@link SwitchCompat} to the bottom of the navigation header for
* toggling dark mode on and off. Call from {@link #onCreate(Bundle)}.
* <p>
* Only supports android ICS and higher because {@link SwitchCompat}
* requires that.
* </p>
*
* @param drawerHeader the layout which should contain the switch
*/
@RequiresApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private void addDarkModeSwitch(ViewGroup drawerHeader) {
getLayoutInflater().inflate(R.layout.nav_dark_mode_switch, drawerHeader);
SwitchCompat darkThemeSwitch = (SwitchCompat) drawerHeader.findViewById(R.id.dark_theme);
darkThemeSwitch.setChecked(ThemeUtil.shouldUseDarkTheme(this));
darkThemeSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@RequiresApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onCheckedChanged(CompoundButton darkThemeSwitch, boolean isChecked) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
boolean isDarkAlready = prefs.getBoolean("darkTheme", false);
if (isDarkAlready != isChecked) {
prefs.edit().putBoolean("darkTheme", isChecked).apply();
MainActivity.this.recreate();
}
}
});
}
//like onNewDeviceSelected but assumes that the new device is simply requesting to be paired //like onNewDeviceSelected but assumes that the new device is simply requesting to be paired
//and can't be null //and can't be null
private void onNewDeviceSelected(String deviceId, String pairStatus) { private void onNewDeviceSelected(String deviceId, String pairStatus) {

View File

@ -0,0 +1,46 @@
package org.kde.kdeconnect.UserInterface;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import org.kde.kdeconnect_tp.R;
/**
* Utilities for working with android {@link android.content.res.Resources.Theme Themes}.
*/
public class ThemeUtil {
/**
* This method should be called from the {@code activity}'s onCreate method, before
* any calls to {@link Activity#setContentView} or
* {@link android.preference.PreferenceActivity#setPreferenceScreen}.
*
* @param activity any Activity on screen
*/
public static void setUserPreferredTheme(Activity activity) {
boolean useDarkTheme = shouldUseDarkTheme(activity);
// Only MainActivity sets its own Toolbar as the ActionBar.
boolean usesOwnActionBar = activity instanceof MainActivity;
if (useDarkTheme) {
activity.setTheme(usesOwnActionBar ? R.style.KdeConnectTheme_Dark_NoActionBar : R.style.KdeConnectTheme_Dark);
} else {
activity.setTheme(usesOwnActionBar ? R.style.KdeConnectTheme_NoActionBar : R.style.KdeConnectTheme);
}
}
/**
* Checks {@link SharedPreferences} to figure out whether we should use the light
* theme or the dark theme. The app defaults to light theme.
*
* @param context any active context (Activity, Service, Application, etc.)
* @return true if the dark theme should be active, false otherwise
*/
public static boolean shouldUseDarkTheme(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean("darkTheme", false);
}
}