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,44 +1,51 @@
|
||||
<LinearLayout
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="@integer/activity_device_orientation"
|
||||
tools:context="org.kde.kdeconnect.UserInterface.DeviceFragment">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- Layout shown when device is reachable but not yet paired -->
|
||||
<include
|
||||
android:id="@+id/pair_request"
|
||||
layout="@layout/view_pair_request"
|
||||
tools:visibility="gone"/>
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true">
|
||||
|
||||
<!-- Layout shown when we can't pair with device or device is not reachable -->
|
||||
<include
|
||||
android:id="@+id/pair_error"
|
||||
layout="@layout/view_pair_error"
|
||||
tools:visibility="gone"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:context="org.kde.kdeconnect.UserInterface.DeviceFragment">
|
||||
|
||||
<!-- Layouts shown when device is paired and reachable -->
|
||||
<GridView
|
||||
android:id="@+id/plugins_list"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="@integer/plugins_list_weight"
|
||||
android:numColumns="@integer/plugins_columns"
|
||||
android:horizontalSpacing="8dp"
|
||||
android:verticalSpacing="8dp"
|
||||
android:layout_margin="@dimen/activity_vertical_margin"
|
||||
tools:listitem="@layout/list_plugin_entry"
|
||||
tools:layout_height="300dp" />
|
||||
<!-- Layout shown when device is reachable but not yet paired -->
|
||||
<include
|
||||
android:id="@+id/pair_request"
|
||||
layout="@layout/view_pair_request"
|
||||
tools:visibility="gone"/>
|
||||
|
||||
<ListView
|
||||
android:id="@+id/buttons_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="@integer/buttons_list_weight"
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
tools:context=".DeviceActivity"
|
||||
tools:listitem="@layout/list_item_with_icon_entry"
|
||||
tools:layout_height="300dp" />
|
||||
</LinearLayout>
|
||||
<!-- Layout shown when we can't pair with device or device is not reachable -->
|
||||
<include
|
||||
android:id="@+id/pair_error"
|
||||
layout="@layout/view_pair_error"
|
||||
tools:visibility="gone"/>
|
||||
|
||||
<!-- Layouts shown when device is paired and reachable -->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/plugins_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="12dp"
|
||||
android:nestedScrollingEnabled="false"
|
||||
tools:listitem="@layout/list_plugin_entry"
|
||||
tools:layout_height="300dp" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/permissions_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:nestedScrollingEnabled="false"
|
||||
tools:context=".DeviceActivity"
|
||||
tools:listitem="@layout/list_item_plugin_header"
|
||||
tools:layout_height="300dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</FrameLayout>
|
@ -1,32 +1,37 @@
|
||||
<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"> <!-- fitSystemWindows to make the drawer slide below the Lollipop transparent status bar -->
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/coordinatorLayout"
|
||||
android:layout_height="match_parent"
|
||||
<FrameLayout 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"
|
||||
tools:context="org.kde.kdeconnect.UserInterface.MainActivity">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
<androidx.drawerlayout.widget.DrawerLayout
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
|
||||
android:fitsSystemWindows="true"> <!-- fitSystemWindows to make the drawer slide below the Lollipop transparent status bar -->
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
<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">
|
||||
|
||||
<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" />
|
||||
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout"/>
|
||||
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
<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>
|
||||
|
||||
<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.drawerlayout.widget.DrawerLayout>
|
||||
</FrameLayout>
|
@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingTop="28dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="8dp" />
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
android:padding="@dimen/view_default_padding"
|
||||
tools:background="@android:color/darker_gray"
|
||||
tools:text="@tools:sample/lorem"/>
|
||||
|
@ -2,10 +2,11 @@
|
||||
<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:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
style="@style/KdeConnectCardStyle.Filled"
|
||||
app:contentPadding="12dp"
|
||||
app:contentPadding="@dimen/view_default_padding"
|
||||
tools:layout_width="240dp">
|
||||
|
||||
<LinearLayout
|
||||
@ -17,7 +18,7 @@
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
<ImageView
|
||||
android:id="@+id/list_item_entry_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -33,17 +33,14 @@
|
||||
android:drawablePadding="5dp"
|
||||
android:layout_marginBottom="8dip"
|
||||
android:visibility="gone"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
app:drawableStartCompat="@drawable/ic_key" />
|
||||
|
||||
<Button
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/pair_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/button_round"
|
||||
android:text="@string/request_pairing"
|
||||
android:textColor="@android:color/white" />
|
||||
android:text="@string/request_pairing" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
@ -51,27 +48,27 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
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:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dip"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/button_round"
|
||||
android:text="@string/pairing_accept"
|
||||
android:textColor="@android:color/white" />
|
||||
android:text="@string/pairing_accept" />
|
||||
|
||||
<Button
|
||||
<android.widget.Space
|
||||
android:layout_width="8dp"
|
||||
android:layout_height="8dp" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/reject_button"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dip"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/button_round"
|
||||
android:text="@string/pairing_reject"
|
||||
android:textColor="@android:color/white" />
|
||||
android:text="@string/pairing_reject" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -1,11 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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_album_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>
|
||||
|
||||
<!--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>
|
||||
|
||||
<!--used in mpris_now_playing-->
|
||||
|
@ -2,6 +2,7 @@
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_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="fab_margin">16dp</dimen>
|
||||
<dimen name="fab_elevation">6dp</dimen>
|
||||
|
@ -162,7 +162,7 @@ public class RemoteKeyboardService
|
||||
}
|
||||
} else { // != 1 instance of plugin -> show main activity view
|
||||
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);
|
||||
startActivity(intent);
|
||||
if (instances.size() < 1)
|
||||
|
@ -32,13 +32,11 @@ internal class SystemVolumeProvider private constructor(plugin: SystemVolumePlug
|
||||
|
||||
@JvmStatic
|
||||
fun fromPlugin(systemVolumePlugin: SystemVolumePlugin): SystemVolumeProvider {
|
||||
if (currentProvider == null) {
|
||||
currentProvider = SystemVolumeProvider(systemVolumePlugin)
|
||||
}
|
||||
val currentProvider = currentProvider ?: SystemVolumeProvider(systemVolumePlugin)
|
||||
|
||||
currentProvider!!.update(systemVolumePlugin)
|
||||
currentProvider.update(systemVolumePlugin)
|
||||
|
||||
return currentProvider!!
|
||||
return currentProvider
|
||||
}
|
||||
|
||||
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(donateURL)
|
||||
|
||||
if (authorsFooterText == null) {
|
||||
parcel.writeByte(0x00)
|
||||
} else {
|
||||
authorsFooterText?.let {
|
||||
parcel.writeByte(0x01)
|
||||
parcel.writeInt(authorsFooterText!!)
|
||||
}
|
||||
parcel.writeInt(it)
|
||||
} ?: parcel.writeByte(0x00)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int = 0
|
||||
|
@ -6,7 +6,6 @@
|
||||
package org.kde.kdeconnect.UserInterface
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
@ -14,10 +13,10 @@ import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.kde.kdeconnect.BackgroundService
|
||||
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.Plugins.BatteryPlugin.BatteryPlugin
|
||||
import org.kde.kdeconnect.Plugins.Plugin
|
||||
import org.kde.kdeconnect.UserInterface.List.FailedPluginListItem
|
||||
import org.kde.kdeconnect.UserInterface.List.ListAdapter
|
||||
import org.kde.kdeconnect.UserInterface.List.PluginAdapter
|
||||
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.databinding.ActivityDeviceBinding
|
||||
import org.kde.kdeconnect_tp.databinding.ViewPairErrorBinding
|
||||
@ -48,8 +45,8 @@ class DeviceFragment : Fragment() {
|
||||
private val mActivity: MainActivity? by lazy { activity as MainActivity? }
|
||||
|
||||
//TODO use LinkedHashMap and delete irrelevant records when plugins changed
|
||||
private val pluginListItems: ArrayList<ListAdapter.Item> = ArrayList()
|
||||
private val permissionListItems: ArrayList<ListAdapter.Item> = ArrayList()
|
||||
private val pluginListItems: ArrayList<PluginItem> = ArrayList()
|
||||
private val permissionListItems: ArrayList<PluginItem> = ArrayList()
|
||||
|
||||
/**
|
||||
* Top-level ViewBinding for this fragment.
|
||||
@ -106,11 +103,13 @@ class DeviceFragment : Fragment() {
|
||||
}
|
||||
|
||||
requireBinding().pairButton.setOnClickListener {
|
||||
requireBinding().pairButton.visibility = View.GONE
|
||||
requireBinding().pairMessage.text = null
|
||||
requireBinding().pairVerification.visibility = View.VISIBLE
|
||||
requireBinding().pairVerification.text = SslHelper.getVerificationKey(SslHelper.certificate, device?.certificate)
|
||||
requireBinding().pairProgress.visibility = View.VISIBLE
|
||||
with(requireBinding()) {
|
||||
pairButton.visibility = View.GONE
|
||||
pairMessage.text = null
|
||||
pairVerification.visibility = View.VISIBLE
|
||||
pairVerification.text = SslHelper.getVerificationKey(SslHelper.certificate, device?.certificate)
|
||||
pairProgress.visibility = View.VISIBLE
|
||||
}
|
||||
device?.requestPairing()
|
||||
}
|
||||
requireBinding().acceptButton.setOnClickListener {
|
||||
@ -141,6 +140,10 @@ class DeviceFragment : Fragment() {
|
||||
refreshUI()
|
||||
}
|
||||
|
||||
requireDeviceBinding().pluginsList.layoutManager =
|
||||
GridLayoutManager(requireContext(), resources.getInteger(R.integer.plugins_columns))
|
||||
requireDeviceBinding().permissionsList.layoutManager = LinearLayoutManager(requireContext())
|
||||
|
||||
return deviceBinding.root
|
||||
}
|
||||
|
||||
@ -165,12 +168,11 @@ class DeviceFragment : Fragment() {
|
||||
//Plugins button list
|
||||
val plugins: Collection<Plugin> = device.loadedPlugins.values
|
||||
for (p in plugins) {
|
||||
if (!p.displayInContextMenu()) {
|
||||
continue
|
||||
}
|
||||
menu.add(p.actionName).setOnMenuItemClickListener {
|
||||
p.startMainActivity(mActivity)
|
||||
true
|
||||
if (p.displayInContextMenu()) {
|
||||
menu.add(p.actionName).setOnMenuItemClickListener {
|
||||
p.startMainActivity(mActivity)
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
val intent = Intent(mActivity, PluginSettingsActivity::class.java)
|
||||
@ -256,45 +258,57 @@ class DeviceFragment : Fragment() {
|
||||
if (paired && !reachable) {
|
||||
requireErrorBinding().errorMessageContainer.visibility = View.VISIBLE
|
||||
requireErrorBinding().notReachableMessage.visibility = View.VISIBLE
|
||||
requireDeviceBinding().permissionsList.visibility = View.GONE
|
||||
requireDeviceBinding().pluginsList.visibility = View.GONE
|
||||
} else {
|
||||
requireErrorBinding().errorMessageContainer.visibility = View.GONE
|
||||
requireErrorBinding().notReachableMessage.visibility = View.GONE
|
||||
requireDeviceBinding().permissionsList.visibility = View.VISIBLE
|
||||
requireDeviceBinding().pluginsList.visibility = View.VISIBLE
|
||||
}
|
||||
try {
|
||||
if (paired && reachable) {
|
||||
//Plugins button list
|
||||
val plugins: Collection<Plugin> = device.loadedPlugins.values
|
||||
|
||||
//TODO look for LinkedHashMap mention above
|
||||
pluginListItems.clear()
|
||||
permissionListItems.clear()
|
||||
|
||||
//Fill enabled plugins ArrayList
|
||||
for (p in plugins) {
|
||||
if (!p.hasMainActivity(context) || p.displayInContextMenu()) continue
|
||||
pluginListItems.add(PluginItem(p) { p.startMainActivity(mActivity) })
|
||||
if (p.hasMainActivity(context) && !p.displayInContextMenu()) {
|
||||
pluginListItems.add(
|
||||
PluginItem(requireContext(), p, { p.startMainActivity(mActivity) })
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//Fill permissionListItems with permissions plugins
|
||||
createPermissionsList(
|
||||
device.pluginsWithoutPermissions,
|
||||
R.string.plugins_need_permission
|
||||
) { plugin: Plugin ->
|
||||
val dialog = plugin.permissionExplanationDialog
|
||||
dialog?.show(childFragmentManager, null)
|
||||
) { p: Plugin ->
|
||||
p.permissionExplanationDialog?.show(childFragmentManager, null)
|
||||
}
|
||||
createPermissionsList(
|
||||
device.pluginsWithoutOptionalPermissions,
|
||||
R.string.plugins_need_optional_permission
|
||||
) { plugin: Plugin ->
|
||||
val dialog: DialogFragment? = plugin.optionalPermissionExplanationDialog
|
||||
dialog?.show(childFragmentManager, null)
|
||||
) { p: Plugin ->
|
||||
p.optionalPermissionExplanationDialog?.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()
|
||||
}
|
||||
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()
|
||||
} catch (e: IllegalStateException) {
|
||||
//Ignore: The activity was closed while we were trying to update it
|
||||
@ -320,7 +334,7 @@ class DeviceFragment : Fragment() {
|
||||
mActivity?.runOnUiThread {
|
||||
with(requireBinding()) {
|
||||
pairMessage.text = error
|
||||
pairVerification.text = ""
|
||||
pairVerification.text = null
|
||||
pairVerification.visibility = View.GONE
|
||||
pairProgress.visibility = View.GONE
|
||||
pairButton.visibility = View.VISIBLE
|
||||
@ -346,17 +360,24 @@ class DeviceFragment : Fragment() {
|
||||
|
||||
private fun createPermissionsList(
|
||||
plugins: ConcurrentHashMap<String, Plugin>,
|
||||
headerText: Int,
|
||||
action: FailedPluginListItem.Action
|
||||
@StringRes headerText: Int,
|
||||
action: (Plugin) -> Unit,
|
||||
) {
|
||||
if (plugins.isEmpty()) 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) {
|
||||
if (!device.isPluginEnabled(plugin.pluginKey)) {
|
||||
continue
|
||||
if (device.isPluginEnabled(plugin.pluginKey)) {
|
||||
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) {
|
||||
|
||||
@StringRes
|
||||
val resId: Int = if (info.isCharging) {
|
||||
R.string.battery_status_charging_format
|
||||
} else if (BatteryPlugin.isLowBattery(info)) {
|
||||
R.string.battery_status_low_format
|
||||
} else {
|
||||
R.string.battery_status_format
|
||||
val resId = when {
|
||||
info.isCharging -> R.string.battery_status_charging_format
|
||||
BatteryPlugin.isLowBattery(info) -> R.string.battery_status_low_format
|
||||
else -> R.string.battery_status_format
|
||||
}
|
||||
|
||||
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 EXTRA_DEVICE_ID = "deviceId";
|
||||
public static final String FLAG_FORCE_OVERVIEW = "forceOverview";
|
||||
|
||||
private NavigationView mNavigationView;
|
||||
private DrawerLayout mDrawerLayout;
|
||||
@ -95,22 +96,24 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
|
||||
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
|
||||
mDrawerLayout, /* DrawerLayout object */
|
||||
R.string.open, /* "open drawer" description */
|
||||
R.string.close /* "close drawer" description */
|
||||
);
|
||||
if (mDrawerLayout != null) {
|
||||
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
|
||||
mDrawerLayout, /* DrawerLayout object */
|
||||
R.string.open, /* "open drawer" description */
|
||||
R.string.close /* "close drawer" description */
|
||||
);
|
||||
|
||||
mDrawerLayout.addDrawerListener(mDrawerToggle);
|
||||
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
|
||||
mDrawerLayout.addDrawerListener(mDrawerToggle);
|
||||
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
|
||||
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
mDrawerToggle.setDrawerIndicatorEnabled(true);
|
||||
mDrawerToggle.syncState();
|
||||
}
|
||||
|
||||
mDrawerToggle.setDrawerIndicatorEnabled(true);
|
||||
mDrawerToggle.syncState();
|
||||
|
||||
preferences = getSharedPreferences("stored_menu_selection", Context.MODE_PRIVATE);
|
||||
|
||||
// Note: The preference changed listener should be registered before getting the name, because getting
|
||||
@ -144,14 +147,16 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences
|
||||
break;
|
||||
}
|
||||
|
||||
mDrawerLayout.closeDrawer(mNavigationView);
|
||||
if (mDrawerLayout != null) {
|
||||
mDrawerLayout.closeDrawer(mNavigationView);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// Decide which menu entry should be selected at start
|
||||
String savedDevice;
|
||||
int savedMenuEntry;
|
||||
if (getIntent().hasExtra("forceOverview")) {
|
||||
if (getIntent().hasExtra(FLAG_FORCE_OVERVIEW)) {
|
||||
Log.i("MainActivity", "Requested to start main overview");
|
||||
savedDevice = null;
|
||||
savedMenuEntry = MENU_ENTRY_ADD_DEVICE;
|
||||
@ -248,7 +253,7 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mDrawerLayout.isDrawerOpen(mNavigationView)) {
|
||||
if (mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mNavigationView)) {
|
||||
mDrawerLayout.closeDrawer(mNavigationView);
|
||||
} else if (mCurrentMenuEntry == MENU_ENTRY_SETTINGS || mCurrentMenuEntry == MENU_ENTRY_ABOUT) {
|
||||
mCurrentMenuEntry = MENU_ENTRY_ADD_DEVICE;
|
||||
@ -261,7 +266,7 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
if (mDrawerLayout != null && item.getItemId() == android.R.id.home) {
|
||||
mDrawerLayout.openDrawer(mNavigationView);
|
||||
return true;
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user