mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-08-30 05:37:43 +00:00
Main activity responsive layout
This commit is contained in:
parent
e2dbc39e3a
commit
8aeefded7c
30
res/layout-w820dp/activity_main.xml
Normal file
30
res/layout-w820dp/activity_main.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<LinearLayout 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"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
|
<com.google.android.material.navigation.NavigationView
|
||||||
|
android:id="@+id/navigation_drawer"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="start"
|
||||||
|
app:headerLayout="@layout/nav_header" />
|
||||||
|
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
android:id="@+id/coordinatorLayout"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
tools:context="org.kde.kdeconnect.UserInterface.MainActivity">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
</LinearLayout>
|
@ -1,9 +1,18 @@
|
|||||||
<LinearLayout
|
<FrameLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="@integer/activity_device_orientation"
|
android:fillViewport="true">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
tools:context="org.kde.kdeconnect.UserInterface.DeviceFragment">
|
tools:context="org.kde.kdeconnect.UserInterface.DeviceFragment">
|
||||||
|
|
||||||
<!-- Layout shown when device is reachable but not yet paired -->
|
<!-- Layout shown when device is reachable but not yet paired -->
|
||||||
@ -19,26 +28,24 @@
|
|||||||
tools:visibility="gone"/>
|
tools:visibility="gone"/>
|
||||||
|
|
||||||
<!-- Layouts shown when device is paired and reachable -->
|
<!-- Layouts shown when device is paired and reachable -->
|
||||||
<GridView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/plugins_list"
|
android:id="@+id/plugins_list"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="@integer/plugins_list_weight"
|
android:layout_margin="12dp"
|
||||||
android:numColumns="@integer/plugins_columns"
|
android:nestedScrollingEnabled="false"
|
||||||
android:horizontalSpacing="8dp"
|
|
||||||
android:verticalSpacing="8dp"
|
|
||||||
android:layout_margin="@dimen/activity_vertical_margin"
|
|
||||||
tools:listitem="@layout/list_plugin_entry"
|
tools:listitem="@layout/list_plugin_entry"
|
||||||
tools:layout_height="300dp" />
|
tools:layout_height="300dp" />
|
||||||
|
|
||||||
<ListView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/buttons_list"
|
android:id="@+id/permissions_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="@integer/buttons_list_weight"
|
android:nestedScrollingEnabled="false"
|
||||||
android:divider="@null"
|
|
||||||
android:dividerHeight="0dp"
|
|
||||||
tools:context=".DeviceActivity"
|
tools:context=".DeviceActivity"
|
||||||
tools:listitem="@layout/list_item_with_icon_entry"
|
tools:listitem="@layout/list_item_plugin_header"
|
||||||
tools:layout_height="300dp" />
|
tools:layout_height="300dp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
</FrameLayout>
|
@ -1,6 +1,10 @@
|
|||||||
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.drawerlayout.widget.DrawerLayout
|
||||||
android:id="@+id/drawer_layout"
|
android:id="@+id/drawer_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@ -30,3 +34,4 @@
|
|||||||
app:headerLayout="@layout/nav_header"/>
|
app:headerLayout="@layout/nav_header"/>
|
||||||
|
|
||||||
</androidx.drawerlayout.widget.DrawerLayout>
|
</androidx.drawerlayout.widget.DrawerLayout>
|
||||||
|
</FrameLayout>
|
@ -1,9 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
android:paddingLeft="16dp"
|
android:padding="@dimen/view_default_padding"
|
||||||
android:paddingTop="28dp"
|
tools:background="@android:color/darker_gray"
|
||||||
android:paddingRight="16dp"
|
tools:text="@tools:sample/lorem"/>
|
||||||
android:paddingBottom="8dp" />
|
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="4dp"
|
||||||
style="@style/KdeConnectCardStyle.Filled"
|
style="@style/KdeConnectCardStyle.Filled"
|
||||||
app:contentPadding="12dp"
|
app:contentPadding="@dimen/view_default_padding"
|
||||||
tools:layout_width="240dp">
|
tools:layout_width="240dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -17,7 +18,7 @@
|
|||||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<ImageView
|
||||||
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"
|
||||||
|
@ -33,17 +33,14 @@
|
|||||||
android:drawablePadding="5dp"
|
android:drawablePadding="5dp"
|
||||||
android:layout_marginBottom="8dip"
|
android:layout_marginBottom="8dip"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:text=""
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
app:drawableStartCompat="@drawable/ic_key" />
|
app:drawableStartCompat="@drawable/ic_key" />
|
||||||
|
|
||||||
<Button
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/pair_button"
|
android:id="@+id/pair_button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/button_round"
|
android:text="@string/request_pairing" />
|
||||||
android:text="@string/request_pairing"
|
|
||||||
android:textColor="@android:color/white" />
|
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -51,27 +48,27 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:visibility="gone">
|
android:visibility="gone"
|
||||||
|
android:paddingVertical="4dp"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
<Button
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/accept_button"
|
android:id="@+id/accept_button"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="4dip"
|
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@drawable/button_round"
|
android:text="@string/pairing_accept" />
|
||||||
android:text="@string/pairing_accept"
|
|
||||||
android:textColor="@android:color/white" />
|
|
||||||
|
|
||||||
<Button
|
<android.widget.Space
|
||||||
|
android:layout_width="8dp"
|
||||||
|
android:layout_height="8dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/reject_button"
|
android:id="@+id/reject_button"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="4dip"
|
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@drawable/button_round"
|
android:text="@string/pairing_reject" />
|
||||||
android:text="@string/pairing_reject"
|
|
||||||
android:textColor="@android:color/white" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -1,11 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<integer name="activity_device_orientation">@integer/orientation_horizontal</integer>
|
|
||||||
|
|
||||||
<integer name="plugins_list_weight">4</integer>
|
|
||||||
<integer name="buttons_list_weight">6</integer>
|
|
||||||
|
|
||||||
<integer name="mpris_now_playing_orientation">@integer/orientation_horizontal</integer>
|
<integer name="mpris_now_playing_orientation">@integer/orientation_horizontal</integer>
|
||||||
<integer name="mpris_now_playing_album_weight">1</integer>
|
<integer name="mpris_now_playing_album_weight">1</integer>
|
||||||
<integer name="mpris_now_playing_controls_weight">1</integer>
|
<integer name="mpris_now_playing_controls_weight">1</integer>
|
||||||
|
@ -10,9 +10,6 @@
|
|||||||
<item name="layout_wrap_content" type="dimen">-2</item>
|
<item name="layout_wrap_content" type="dimen">-2</item>
|
||||||
|
|
||||||
<!--used in activity_device-->
|
<!--used in activity_device-->
|
||||||
<integer name="activity_device_orientation">@integer/orientation_vertical</integer>
|
|
||||||
<integer name="plugins_list_weight">@null</integer>
|
|
||||||
<integer name="buttons_list_weight">@null</integer>
|
|
||||||
<integer name="plugins_columns">2</integer>
|
<integer name="plugins_columns">2</integer>
|
||||||
|
|
||||||
<!--used in mpris_now_playing-->
|
<!--used in mpris_now_playing-->
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||||
|
<dimen name="view_default_padding">16dp</dimen>
|
||||||
<dimen name="key_height">48dip</dimen>
|
<dimen name="key_height">48dip</dimen>
|
||||||
<dimen name="fab_margin">16dp</dimen>
|
<dimen name="fab_margin">16dp</dimen>
|
||||||
<dimen name="fab_elevation">6dp</dimen>
|
<dimen name="fab_elevation">6dp</dimen>
|
||||||
|
@ -162,7 +162,7 @@ public class RemoteKeyboardService
|
|||||||
}
|
}
|
||||||
} else { // != 1 instance of plugin -> show main activity view
|
} else { // != 1 instance of plugin -> show main activity view
|
||||||
Intent intent = new Intent(this, MainActivity.class);
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
intent.putExtra("forceOverview", true);
|
intent.putExtra(MainActivity.FLAG_FORCE_OVERVIEW, true);
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
if (instances.size() < 1)
|
if (instances.size() < 1)
|
||||||
|
@ -32,13 +32,11 @@ internal class SystemVolumeProvider private constructor(plugin: SystemVolumePlug
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun fromPlugin(systemVolumePlugin: SystemVolumePlugin): SystemVolumeProvider {
|
fun fromPlugin(systemVolumePlugin: SystemVolumePlugin): SystemVolumeProvider {
|
||||||
if (currentProvider == null) {
|
val currentProvider = currentProvider ?: SystemVolumeProvider(systemVolumePlugin)
|
||||||
currentProvider = SystemVolumeProvider(systemVolumePlugin)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentProvider!!.update(systemVolumePlugin)
|
currentProvider.update(systemVolumePlugin)
|
||||||
|
|
||||||
return currentProvider!!
|
return currentProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scale(value: Int, maxValue: Int, maxScaled: Int): Int {
|
private fun scale(value: Int, maxValue: Int, maxScaled: Int): Int {
|
||||||
|
@ -37,12 +37,10 @@ class AboutData(var name: String, var icon: Int, var versionName: String, var bu
|
|||||||
parcel.writeString(sourceCodeURL)
|
parcel.writeString(sourceCodeURL)
|
||||||
parcel.writeString(donateURL)
|
parcel.writeString(donateURL)
|
||||||
|
|
||||||
if (authorsFooterText == null) {
|
authorsFooterText?.let {
|
||||||
parcel.writeByte(0x00)
|
|
||||||
} else {
|
|
||||||
parcel.writeByte(0x01)
|
parcel.writeByte(0x01)
|
||||||
parcel.writeInt(authorsFooterText!!)
|
parcel.writeInt(it)
|
||||||
}
|
} ?: parcel.writeByte(0x00)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun describeContents(): Int = 0
|
override fun describeContents(): Int = 0
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
package org.kde.kdeconnect.UserInterface
|
package org.kde.kdeconnect.UserInterface
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
@ -14,10 +13,10 @@ import android.view.LayoutInflater
|
|||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.LinearLayout
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.fragment.app.DialogFragment
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import org.kde.kdeconnect.BackgroundService
|
import org.kde.kdeconnect.BackgroundService
|
||||||
import org.kde.kdeconnect.Device
|
import org.kde.kdeconnect.Device
|
||||||
@ -26,10 +25,8 @@ import org.kde.kdeconnect.Device.PluginsChangedListener
|
|||||||
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper
|
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper
|
||||||
import org.kde.kdeconnect.Plugins.BatteryPlugin.BatteryPlugin
|
import org.kde.kdeconnect.Plugins.BatteryPlugin.BatteryPlugin
|
||||||
import org.kde.kdeconnect.Plugins.Plugin
|
import org.kde.kdeconnect.Plugins.Plugin
|
||||||
import org.kde.kdeconnect.UserInterface.List.FailedPluginListItem
|
import org.kde.kdeconnect.UserInterface.List.PluginAdapter
|
||||||
import org.kde.kdeconnect.UserInterface.List.ListAdapter
|
|
||||||
import org.kde.kdeconnect.UserInterface.List.PluginItem
|
import org.kde.kdeconnect.UserInterface.List.PluginItem
|
||||||
import org.kde.kdeconnect.UserInterface.List.PluginListHeaderItem
|
|
||||||
import org.kde.kdeconnect_tp.R
|
import org.kde.kdeconnect_tp.R
|
||||||
import org.kde.kdeconnect_tp.databinding.ActivityDeviceBinding
|
import org.kde.kdeconnect_tp.databinding.ActivityDeviceBinding
|
||||||
import org.kde.kdeconnect_tp.databinding.ViewPairErrorBinding
|
import org.kde.kdeconnect_tp.databinding.ViewPairErrorBinding
|
||||||
@ -48,8 +45,8 @@ class DeviceFragment : Fragment() {
|
|||||||
private val mActivity: MainActivity? by lazy { activity as MainActivity? }
|
private val mActivity: MainActivity? by lazy { activity as MainActivity? }
|
||||||
|
|
||||||
//TODO use LinkedHashMap and delete irrelevant records when plugins changed
|
//TODO use LinkedHashMap and delete irrelevant records when plugins changed
|
||||||
private val pluginListItems: ArrayList<ListAdapter.Item> = ArrayList()
|
private val pluginListItems: ArrayList<PluginItem> = ArrayList()
|
||||||
private val permissionListItems: ArrayList<ListAdapter.Item> = ArrayList()
|
private val permissionListItems: ArrayList<PluginItem> = ArrayList()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top-level ViewBinding for this fragment.
|
* Top-level ViewBinding for this fragment.
|
||||||
@ -106,11 +103,13 @@ class DeviceFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
requireBinding().pairButton.setOnClickListener {
|
requireBinding().pairButton.setOnClickListener {
|
||||||
requireBinding().pairButton.visibility = View.GONE
|
with(requireBinding()) {
|
||||||
requireBinding().pairMessage.text = null
|
pairButton.visibility = View.GONE
|
||||||
requireBinding().pairVerification.visibility = View.VISIBLE
|
pairMessage.text = null
|
||||||
requireBinding().pairVerification.text = SslHelper.getVerificationKey(SslHelper.certificate, device?.certificate)
|
pairVerification.visibility = View.VISIBLE
|
||||||
requireBinding().pairProgress.visibility = View.VISIBLE
|
pairVerification.text = SslHelper.getVerificationKey(SslHelper.certificate, device?.certificate)
|
||||||
|
pairProgress.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
device?.requestPairing()
|
device?.requestPairing()
|
||||||
}
|
}
|
||||||
requireBinding().acceptButton.setOnClickListener {
|
requireBinding().acceptButton.setOnClickListener {
|
||||||
@ -141,6 +140,10 @@ class DeviceFragment : Fragment() {
|
|||||||
refreshUI()
|
refreshUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requireDeviceBinding().pluginsList.layoutManager =
|
||||||
|
GridLayoutManager(requireContext(), resources.getInteger(R.integer.plugins_columns))
|
||||||
|
requireDeviceBinding().permissionsList.layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
|
||||||
return deviceBinding.root
|
return deviceBinding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,14 +168,13 @@ class DeviceFragment : Fragment() {
|
|||||||
//Plugins button list
|
//Plugins button list
|
||||||
val plugins: Collection<Plugin> = device.loadedPlugins.values
|
val plugins: Collection<Plugin> = device.loadedPlugins.values
|
||||||
for (p in plugins) {
|
for (p in plugins) {
|
||||||
if (!p.displayInContextMenu()) {
|
if (p.displayInContextMenu()) {
|
||||||
continue
|
|
||||||
}
|
|
||||||
menu.add(p.actionName).setOnMenuItemClickListener {
|
menu.add(p.actionName).setOnMenuItemClickListener {
|
||||||
p.startMainActivity(mActivity)
|
p.startMainActivity(mActivity)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
val intent = Intent(mActivity, PluginSettingsActivity::class.java)
|
val intent = Intent(mActivity, PluginSettingsActivity::class.java)
|
||||||
intent.putExtra("deviceId", deviceId)
|
intent.putExtra("deviceId", deviceId)
|
||||||
menu.add(R.string.device_menu_plugins).setOnMenuItemClickListener {
|
menu.add(R.string.device_menu_plugins).setOnMenuItemClickListener {
|
||||||
@ -256,45 +258,57 @@ class DeviceFragment : Fragment() {
|
|||||||
if (paired && !reachable) {
|
if (paired && !reachable) {
|
||||||
requireErrorBinding().errorMessageContainer.visibility = View.VISIBLE
|
requireErrorBinding().errorMessageContainer.visibility = View.VISIBLE
|
||||||
requireErrorBinding().notReachableMessage.visibility = View.VISIBLE
|
requireErrorBinding().notReachableMessage.visibility = View.VISIBLE
|
||||||
|
requireDeviceBinding().permissionsList.visibility = View.GONE
|
||||||
|
requireDeviceBinding().pluginsList.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
requireErrorBinding().errorMessageContainer.visibility = View.GONE
|
requireErrorBinding().errorMessageContainer.visibility = View.GONE
|
||||||
requireErrorBinding().notReachableMessage.visibility = View.GONE
|
requireErrorBinding().notReachableMessage.visibility = View.GONE
|
||||||
|
requireDeviceBinding().permissionsList.visibility = View.VISIBLE
|
||||||
|
requireDeviceBinding().pluginsList.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (paired && reachable) {
|
if (paired && reachable) {
|
||||||
//Plugins button list
|
//Plugins button list
|
||||||
val plugins: Collection<Plugin> = device.loadedPlugins.values
|
val plugins: Collection<Plugin> = device.loadedPlugins.values
|
||||||
|
|
||||||
|
//TODO look for LinkedHashMap mention above
|
||||||
pluginListItems.clear()
|
pluginListItems.clear()
|
||||||
permissionListItems.clear()
|
permissionListItems.clear()
|
||||||
|
|
||||||
|
//Fill enabled plugins ArrayList
|
||||||
for (p in plugins) {
|
for (p in plugins) {
|
||||||
if (!p.hasMainActivity(context) || p.displayInContextMenu()) continue
|
if (p.hasMainActivity(context) && !p.displayInContextMenu()) {
|
||||||
pluginListItems.add(PluginItem(p) { p.startMainActivity(mActivity) })
|
pluginListItems.add(
|
||||||
|
PluginItem(requireContext(), p, { p.startMainActivity(mActivity) })
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fill permissionListItems with permissions plugins
|
||||||
createPermissionsList(
|
createPermissionsList(
|
||||||
device.pluginsWithoutPermissions,
|
device.pluginsWithoutPermissions,
|
||||||
R.string.plugins_need_permission
|
R.string.plugins_need_permission
|
||||||
) { plugin: Plugin ->
|
) { p: Plugin ->
|
||||||
val dialog = plugin.permissionExplanationDialog
|
p.permissionExplanationDialog?.show(childFragmentManager, null)
|
||||||
dialog?.show(childFragmentManager, null)
|
|
||||||
}
|
}
|
||||||
createPermissionsList(
|
createPermissionsList(
|
||||||
device.pluginsWithoutOptionalPermissions,
|
device.pluginsWithoutOptionalPermissions,
|
||||||
R.string.plugins_need_optional_permission
|
R.string.plugins_need_optional_permission
|
||||||
) { plugin: Plugin ->
|
) { p: Plugin ->
|
||||||
val dialog: DialogFragment? = plugin.optionalPermissionExplanationDialog
|
p.optionalPermissionExplanationDialog?.show(childFragmentManager, null)
|
||||||
dialog?.show(childFragmentManager, null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requireDeviceBinding().permissionsList.adapter =
|
||||||
|
PluginAdapter(permissionListItems, R.layout.list_item_plugin_header)
|
||||||
|
requireDeviceBinding().pluginsList.adapter =
|
||||||
|
PluginAdapter(pluginListItems, R.layout.list_plugin_entry)
|
||||||
|
|
||||||
|
requireDeviceBinding().permissionsList.adapter?.notifyDataSetChanged()
|
||||||
|
requireDeviceBinding().pluginsList.adapter?.notifyDataSetChanged()
|
||||||
|
|
||||||
displayBatteryInfoIfPossible()
|
displayBatteryInfoIfPossible()
|
||||||
}
|
}
|
||||||
requireDeviceBinding().pluginsList.adapter = ListAdapter(mActivity, pluginListItems)
|
|
||||||
//don't do unnecessary work when all permissions granted and remove view for landscape orientation
|
|
||||||
if (permissionListItems.isEmpty()) {
|
|
||||||
requireDeviceBinding().buttonsList.visibility = View.GONE
|
|
||||||
} else {
|
|
||||||
requireDeviceBinding().buttonsList.adapter = ListAdapter(mActivity, permissionListItems)
|
|
||||||
requireDeviceBinding().buttonsList.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
mActivity?.invalidateOptionsMenu()
|
mActivity?.invalidateOptionsMenu()
|
||||||
} catch (e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
//Ignore: The activity was closed while we were trying to update it
|
//Ignore: The activity was closed while we were trying to update it
|
||||||
@ -320,7 +334,7 @@ class DeviceFragment : Fragment() {
|
|||||||
mActivity?.runOnUiThread {
|
mActivity?.runOnUiThread {
|
||||||
with(requireBinding()) {
|
with(requireBinding()) {
|
||||||
pairMessage.text = error
|
pairMessage.text = error
|
||||||
pairVerification.text = ""
|
pairVerification.text = null
|
||||||
pairVerification.visibility = View.GONE
|
pairVerification.visibility = View.GONE
|
||||||
pairProgress.visibility = View.GONE
|
pairProgress.visibility = View.GONE
|
||||||
pairButton.visibility = View.VISIBLE
|
pairButton.visibility = View.VISIBLE
|
||||||
@ -346,17 +360,24 @@ class DeviceFragment : Fragment() {
|
|||||||
|
|
||||||
private fun createPermissionsList(
|
private fun createPermissionsList(
|
||||||
plugins: ConcurrentHashMap<String, Plugin>,
|
plugins: ConcurrentHashMap<String, Plugin>,
|
||||||
headerText: Int,
|
@StringRes headerText: Int,
|
||||||
action: FailedPluginListItem.Action
|
action: (Plugin) -> Unit,
|
||||||
) {
|
) {
|
||||||
if (plugins.isEmpty()) return
|
if (plugins.isEmpty()) return
|
||||||
val device = device ?: return
|
val device = device ?: return
|
||||||
permissionListItems.add(PluginListHeaderItem(headerText))
|
permissionListItems.add(
|
||||||
|
PluginItem(
|
||||||
|
context = requireContext(),
|
||||||
|
header = requireContext().getString(headerText),
|
||||||
|
textStyleRes = R.style.TextAppearance_Material3_BodyMedium,
|
||||||
|
)
|
||||||
|
)
|
||||||
for (plugin in plugins.values) {
|
for (plugin in plugins.values) {
|
||||||
if (!device.isPluginEnabled(plugin.pluginKey)) {
|
if (device.isPluginEnabled(plugin.pluginKey)) {
|
||||||
continue
|
permissionListItems.add(
|
||||||
|
PluginItem(requireContext(), plugin, action, R.style.TextAppearance_Material3_LabelLarge)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
permissionListItems.add(FailedPluginListItem(plugin, action))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,12 +396,10 @@ class DeviceFragment : Fragment() {
|
|||||||
if (info != null) {
|
if (info != null) {
|
||||||
|
|
||||||
@StringRes
|
@StringRes
|
||||||
val resId: Int = if (info.isCharging) {
|
val resId = when {
|
||||||
R.string.battery_status_charging_format
|
info.isCharging -> R.string.battery_status_charging_format
|
||||||
} else if (BatteryPlugin.isLowBattery(info)) {
|
BatteryPlugin.isLowBattery(info) -> R.string.battery_status_low_format
|
||||||
R.string.battery_status_low_format
|
else -> R.string.battery_status_format
|
||||||
} else {
|
|
||||||
R.string.battery_status_format
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mActivity?.supportActionBar?.subtitle = mActivity?.getString(resId, info.currentCharge)
|
mActivity?.supportActionBar?.subtitle = mActivity?.getString(resId, info.currentCharge)
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2018 Nicolas Fella <nicolas.fella@gmx.de>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
package org.kde.kdeconnect.UserInterface.List;
|
|
||||||
|
|
||||||
import org.kde.kdeconnect.Plugins.Plugin;
|
|
||||||
|
|
||||||
public class FailedPluginListItem extends SmallEntryItem {
|
|
||||||
|
|
||||||
public interface Action {
|
|
||||||
void action(Plugin plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
public FailedPluginListItem(Plugin plugin, Action action) {
|
|
||||||
super(plugin.getDisplayName(), (view) -> action.action(plugin));
|
|
||||||
}
|
|
||||||
}
|
|
47
src/org/kde/kdeconnect/UserInterface/List/PluginAdapter.kt
Normal file
47
src/org/kde/kdeconnect/UserInterface/List/PluginAdapter.kt
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package org.kde.kdeconnect.UserInterface.List
|
||||||
|
|
||||||
|
import android.annotation.TargetApi
|
||||||
|
import android.os.Build
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import org.kde.kdeconnect_tp.R
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapter for showing enabled plugins and permission requests
|
||||||
|
* can be used with following layouts:
|
||||||
|
* list_plugin_entry - card view with text and icon
|
||||||
|
* list_item_plugin_header - plain TextView
|
||||||
|
* Any other TextView layout
|
||||||
|
*/
|
||||||
|
class PluginAdapter(
|
||||||
|
private val pluginList: ArrayList<PluginItem>,
|
||||||
|
private val layoutRes: Int,
|
||||||
|
) : RecyclerView.Adapter<PluginAdapter.PluginViewHolder>() {
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(viewGroup: ViewGroup, type: Int) =
|
||||||
|
PluginViewHolder(LayoutInflater.from(viewGroup.context).inflate(layoutRes, viewGroup, false))
|
||||||
|
|
||||||
|
override fun getItemCount() = pluginList.size
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.M)
|
||||||
|
override fun onBindViewHolder(holder: PluginViewHolder, position: Int) {
|
||||||
|
pluginList[position].let { plugin ->
|
||||||
|
holder.pluginTitle.text = plugin.header
|
||||||
|
holder.pluginIcon?.setImageDrawable(plugin.icon)
|
||||||
|
|
||||||
|
plugin.textStyleRes?.let { holder.pluginTitle.setTextAppearance(it) }
|
||||||
|
|
||||||
|
plugin.action?.let { action -> holder.itemView.setOnClickListener { action.invoke() } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PluginViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
val pluginTitle: TextView = view.findViewById(R.id.list_item_entry_title) ?: view as TextView
|
||||||
|
val pluginIcon: ImageView? = view.findViewById(R.id.list_item_entry_icon)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Albert Vaca Cintora <albertvaka@gmail.com>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.kde.kdeconnect.UserInterface.List;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.kde.kdeconnect.Plugins.Plugin;
|
|
||||||
|
|
||||||
public class PluginItem extends EntryItemWithIcon {
|
|
||||||
private final View.OnClickListener clickListener;
|
|
||||||
|
|
||||||
public PluginItem(Plugin p, View.OnClickListener clickListener) {
|
|
||||||
super(p.getActionName(), p.getIcon());
|
|
||||||
this.clickListener = clickListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public View inflateView(@NonNull LayoutInflater layoutInflater) {
|
|
||||||
final View root = super.inflateView(layoutInflater);
|
|
||||||
root.setOnClickListener(clickListener);
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
}
|
|
29
src/org/kde/kdeconnect/UserInterface/List/PluginItem.kt
Normal file
29
src/org/kde/kdeconnect/UserInterface/List/PluginItem.kt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package org.kde.kdeconnect.UserInterface.List
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import org.kde.kdeconnect.Plugins.Plugin
|
||||||
|
|
||||||
|
class PluginItem(
|
||||||
|
val context: Context,
|
||||||
|
val header: String,
|
||||||
|
val textStyleRes: Int? = null,
|
||||||
|
) {
|
||||||
|
|
||||||
|
var action: (() -> Unit)? = null
|
||||||
|
var icon: Drawable? = null
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
context: Context,
|
||||||
|
plugin: Plugin,
|
||||||
|
action: (Plugin) -> Unit,
|
||||||
|
textStyleRes: Int? = null,
|
||||||
|
) : this(
|
||||||
|
context = context,
|
||||||
|
header = plugin.displayName,
|
||||||
|
textStyleRes = textStyleRes,
|
||||||
|
) {
|
||||||
|
this.action = { action(plugin) }
|
||||||
|
this.icon = plugin.icon
|
||||||
|
}
|
||||||
|
}
|
@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Albert Vaca Cintora <albertvaka@gmail.com>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.kde.kdeconnect.UserInterface.List;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.kde.kdeconnect_tp.databinding.ListItemPluginHeaderBinding;
|
|
||||||
|
|
||||||
public class PluginListHeaderItem implements ListAdapter.Item {
|
|
||||||
private final int text;
|
|
||||||
|
|
||||||
public PluginListHeaderItem(int text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public View inflateView(@NonNull LayoutInflater layoutInflater) {
|
|
||||||
TextView textView = ListItemPluginHeaderBinding.inflate(layoutInflater).getRoot();
|
|
||||||
textView.setText(text);
|
|
||||||
textView.setOnClickListener(null);
|
|
||||||
textView.setOnLongClickListener(null);
|
|
||||||
return textView;
|
|
||||||
}
|
|
||||||
}
|
|
@ -63,6 +63,7 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences
|
|||||||
public static final String PAIRING_PENDING = "pending";
|
public static final String PAIRING_PENDING = "pending";
|
||||||
|
|
||||||
public static final String EXTRA_DEVICE_ID = "deviceId";
|
public static final String EXTRA_DEVICE_ID = "deviceId";
|
||||||
|
public static final String FLAG_FORCE_OVERVIEW = "forceOverview";
|
||||||
|
|
||||||
private NavigationView mNavigationView;
|
private NavigationView mNavigationView;
|
||||||
private DrawerLayout mDrawerLayout;
|
private DrawerLayout mDrawerLayout;
|
||||||
@ -95,6 +96,7 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences
|
|||||||
|
|
||||||
ActionBar actionBar = getSupportActionBar();
|
ActionBar actionBar = getSupportActionBar();
|
||||||
|
|
||||||
|
if (mDrawerLayout != null) {
|
||||||
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
|
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
|
||||||
mDrawerLayout, /* DrawerLayout object */
|
mDrawerLayout, /* DrawerLayout object */
|
||||||
R.string.open, /* "open drawer" description */
|
R.string.open, /* "open drawer" description */
|
||||||
@ -110,6 +112,7 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences
|
|||||||
|
|
||||||
mDrawerToggle.setDrawerIndicatorEnabled(true);
|
mDrawerToggle.setDrawerIndicatorEnabled(true);
|
||||||
mDrawerToggle.syncState();
|
mDrawerToggle.syncState();
|
||||||
|
}
|
||||||
|
|
||||||
preferences = getSharedPreferences("stored_menu_selection", Context.MODE_PRIVATE);
|
preferences = getSharedPreferences("stored_menu_selection", Context.MODE_PRIVATE);
|
||||||
|
|
||||||
@ -144,14 +147,16 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mDrawerLayout != null) {
|
||||||
mDrawerLayout.closeDrawer(mNavigationView);
|
mDrawerLayout.closeDrawer(mNavigationView);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Decide which menu entry should be selected at start
|
// Decide which menu entry should be selected at start
|
||||||
String savedDevice;
|
String savedDevice;
|
||||||
int savedMenuEntry;
|
int savedMenuEntry;
|
||||||
if (getIntent().hasExtra("forceOverview")) {
|
if (getIntent().hasExtra(FLAG_FORCE_OVERVIEW)) {
|
||||||
Log.i("MainActivity", "Requested to start main overview");
|
Log.i("MainActivity", "Requested to start main overview");
|
||||||
savedDevice = null;
|
savedDevice = null;
|
||||||
savedMenuEntry = MENU_ENTRY_ADD_DEVICE;
|
savedMenuEntry = MENU_ENTRY_ADD_DEVICE;
|
||||||
@ -248,7 +253,7 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (mDrawerLayout.isDrawerOpen(mNavigationView)) {
|
if (mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mNavigationView)) {
|
||||||
mDrawerLayout.closeDrawer(mNavigationView);
|
mDrawerLayout.closeDrawer(mNavigationView);
|
||||||
} else if (mCurrentMenuEntry == MENU_ENTRY_SETTINGS || mCurrentMenuEntry == MENU_ENTRY_ABOUT) {
|
} else if (mCurrentMenuEntry == MENU_ENTRY_SETTINGS || mCurrentMenuEntry == MENU_ENTRY_ABOUT) {
|
||||||
mCurrentMenuEntry = MENU_ENTRY_ADD_DEVICE;
|
mCurrentMenuEntry = MENU_ENTRY_ADD_DEVICE;
|
||||||
@ -261,7 +266,7 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
if (item.getItemId() == android.R.id.home) {
|
if (mDrawerLayout != null && item.getItemId() == android.R.id.home) {
|
||||||
mDrawerLayout.openDrawer(mNavigationView);
|
mDrawerLayout.openDrawer(mNavigationView);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user