Improve widgets ui #457

This commit is contained in:
Koitharu
2023-08-26 18:35:49 +03:00
parent 2684a7384e
commit 74ca19a931
23 changed files with 440 additions and 82 deletions

View File

@@ -148,13 +148,21 @@
android:name="org.koitharu.kotatsu.favourites.ui.categories.FavouriteCategoriesActivity"
android:label="@string/manage_categories" />
<activity
android:name="org.koitharu.kotatsu.widget.shelf.ShelfConfigActivity"
android:name="org.koitharu.kotatsu.widget.shelf.ShelfWidgetConfigActivity"
android:exported="true"
android:label="@string/manga_shelf">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<activity
android:name="org.koitharu.kotatsu.widget.recent.RecentWidgetConfigActivity"
android:exported="true"
android:label="@string/recent_manga">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<activity
android:name="org.koitharu.kotatsu.search.ui.multi.MultiSearchActivity"
android:label="@string/search" />

View File

@@ -1,15 +1,38 @@
package org.koitharu.kotatsu.core.prefs
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.os.Build
import androidx.core.content.edit
private const val CATEGORY_ID = "cat_id"
private const val BACKGROUND = "bg"
class AppWidgetConfig(context: Context, val widgetId: Int) {
class AppWidgetConfig(
context: Context,
cls: Class<out AppWidgetProvider>,
val widgetId: Int,
) {
private val prefs = context.getSharedPreferences("appwidget_$widgetId", Context.MODE_PRIVATE)
private val prefs = context.getSharedPreferences("appwidget_${cls.simpleName}_$widgetId", Context.MODE_PRIVATE)
var categoryId: Long
get() = prefs.getLong(CATEGORY_ID, 0L)
set(value) = prefs.edit { putLong(CATEGORY_ID, value) }
var hasBackground: Boolean
get() = prefs.getBoolean(BACKGROUND, Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
set(value) = prefs.edit { putBoolean(BACKGROUND, value) }
fun clear() {
prefs.edit { clear() }
}
fun copyFrom(other: AppWidgetConfig) {
prefs.edit {
clear()
putLong(CATEGORY_ID, other.categoryId)
putBoolean(BACKGROUND, other.hasBackground)
}
}
}

View File

@@ -0,0 +1,51 @@
package org.koitharu.kotatsu.core.ui
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.widget.RemoteViews
import androidx.annotation.CallSuper
import org.koitharu.kotatsu.core.prefs.AppWidgetConfig
abstract class BaseAppWidgetProvider : AppWidgetProvider() {
@CallSuper
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
appWidgetIds.forEach { id ->
val config = AppWidgetConfig(context, javaClass, id)
val views = onUpdateWidget(context, config)
appWidgetManager.updateAppWidget(id, views)
}
}
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
super.onDeleted(context, appWidgetIds)
for (id in appWidgetIds) {
AppWidgetConfig(context, javaClass, id).clear()
}
}
override fun onRestored(context: Context, oldWidgetIds: IntArray, newWidgetIds: IntArray) {
super.onRestored(context, oldWidgetIds, newWidgetIds)
if (oldWidgetIds.size != newWidgetIds.size) {
return
}
for (i in oldWidgetIds.indices) {
val oldId = oldWidgetIds[i]
val newId = newWidgetIds[i]
val oldConfig = AppWidgetConfig(context, javaClass, oldId)
val newConfig = AppWidgetConfig(context, javaClass, newId)
newConfig.copyFrom(oldConfig)
oldConfig.clear()
}
}
protected abstract fun onUpdateWidget(
context: Context,
config: AppWidgetConfig,
): RemoteViews
}

View File

@@ -0,0 +1,43 @@
package org.koitharu.kotatsu.core.util
import androidx.collection.ArrayMap
import kotlinx.coroutines.sync.Mutex
class CompositeMutex2<T : Any> : Set<T> {
private val delegates = ArrayMap<T, Mutex>()
override val size: Int
get() = delegates.size
override fun contains(element: T): Boolean {
return delegates.containsKey(element)
}
override fun containsAll(elements: Collection<T>): Boolean {
return elements.all { x -> delegates.containsKey(x) }
}
override fun isEmpty(): Boolean {
return delegates.isEmpty
}
override fun iterator(): Iterator<T> {
return delegates.keys.iterator()
}
suspend fun lock(element: T) {
val mutex = synchronized(delegates) {
delegates.getOrPut(element) {
Mutex()
}
}
mutex.lock()
}
fun unlock(element: T) {
synchronized(delegates) {
delegates.remove(element)?.unlock()
}
}
}

View File

@@ -55,6 +55,7 @@ class RecentListFactory(
.data(item.coverUrl)
.size(coverSize)
.tag(item.source)
.tag(item)
.transformations(transformation)
.build(),
).getDrawableOrThrow().toBitmap()

View File

@@ -0,0 +1,74 @@
package org.koitharu.kotatsu.widget.recent
import android.app.Activity
import android.appwidget.AppWidgetManager
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.core.graphics.Insets
import androidx.core.view.updatePadding
import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppWidgetConfig
import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.databinding.ActivityAppwidgetRecentBinding
import com.google.android.material.R as materialR
@AndroidEntryPoint
class RecentWidgetConfigActivity :
BaseActivity<ActivityAppwidgetRecentBinding>(),
View.OnClickListener {
private lateinit var config: AppWidgetConfig
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(ActivityAppwidgetRecentBinding.inflate(layoutInflater))
supportActionBar?.run {
setDisplayHomeAsUpEnabled(true)
setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material)
}
viewBinding.buttonDone.setOnClickListener(this)
val appWidgetId = intent?.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID,
) ?: AppWidgetManager.INVALID_APPWIDGET_ID
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finishAfterTransition()
return
}
config = AppWidgetConfig(this, RecentWidgetProvider::class.java, appWidgetId)
viewBinding.switchBackground.isChecked = config.hasBackground
}
override fun onClick(v: View) {
when (v.id) {
R.id.button_done -> {
config.hasBackground = viewBinding.switchBackground.isChecked
updateWidget()
setResult(
Activity.RESULT_OK,
Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, config.widgetId),
)
finish()
}
}
}
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.root.updatePadding(
left = insets.left,
right = insets.right,
bottom = insets.bottom,
top = insets.top,
)
}
private fun updateWidget() {
val intent = Intent(this, RecentWidgetProvider::class.java)
intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
val ids = intArrayOf(config.widgetId)
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
sendBroadcast(intent)
}
}

View File

@@ -2,43 +2,52 @@ package org.koitharu.kotatsu.widget.recent
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.widget.RemoteViews
import androidx.core.app.PendingIntentCompat
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppWidgetConfig
import org.koitharu.kotatsu.core.ui.BaseAppWidgetProvider
import org.koitharu.kotatsu.reader.ui.ReaderActivity
class RecentWidgetProvider : AppWidgetProvider() {
class RecentWidgetProvider : BaseAppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
appWidgetIds.forEach { id ->
val views = RemoteViews(context.packageName, R.layout.widget_recent)
val adapter = Intent(context, RecentWidgetService::class.java)
adapter.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id)
adapter.data = Uri.parse(adapter.toUri(Intent.URI_INTENT_SCHEME))
views.setRemoteAdapter(R.id.stackView, adapter)
val intent = Intent(context, ReaderActivity::class.java)
intent.action = ReaderActivity.ACTION_MANGA_READ
views.setPendingIntentTemplate(
R.id.stackView,
PendingIntentCompat.getActivity(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT,
true,
),
)
views.setEmptyView(R.id.stackView, R.id.textView_holder)
appWidgetManager.updateAppWidget(id, views)
}
super.onUpdate(context, appWidgetManager, appWidgetIds)
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.stackView)
}
override fun onUpdateWidget(context: Context, config: AppWidgetConfig): RemoteViews {
val views = RemoteViews(context.packageName, R.layout.widget_recent)
if (!config.hasBackground) {
views.setInt(R.id.widget_root, "setBackgroundColor", Color.TRANSPARENT)
} else {
views.setInt(R.id.widget_root, "setBackgroundResource", R.drawable.bg_appwidget_root)
}
val adapter = Intent(context, RecentWidgetService::class.java)
adapter.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, config.widgetId)
adapter.data = Uri.parse(adapter.toUri(Intent.URI_INTENT_SCHEME))
views.setRemoteAdapter(R.id.stackView, adapter)
val intent = Intent(context, ReaderActivity::class.java)
intent.action = ReaderActivity.ACTION_MANGA_READ
views.setPendingIntentTemplate(
R.id.stackView,
PendingIntentCompat.getActivity(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT,
true,
),
)
views.setEmptyView(R.id.stackView, R.id.textView_holder)
return views
}
}

View File

@@ -14,6 +14,7 @@ import kotlinx.coroutines.runBlocking
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.parser.MangaIntent
import org.koitharu.kotatsu.core.prefs.AppWidgetConfig
import org.koitharu.kotatsu.core.ui.image.TrimTransformation
import org.koitharu.kotatsu.core.util.ext.getDrawableOrThrow
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
import org.koitharu.kotatsu.parsers.model.Manga
@@ -27,7 +28,7 @@ class ShelfListFactory(
) : RemoteViewsService.RemoteViewsFactory {
private val dataSet = ArrayList<Manga>()
private val config = AppWidgetConfig(context, widgetId)
private val config = AppWidgetConfig(context, ShelfWidgetProvider::class.java, widgetId)
private val transformation = RoundedCornersTransformation(
context.resources.getDimension(R.dimen.appwidget_corner_radius_inner),
)
@@ -66,7 +67,8 @@ class ShelfListFactory(
.data(item.coverUrl)
.size(coverSize)
.tag(item.source)
.transformations(transformation)
.tag(item)
.transformations(transformation, TrimTransformation())
.build(),
).getDrawableOrThrow().toBitmap()
}.onSuccess { cover ->

View File

@@ -8,7 +8,6 @@ import android.view.View
import android.view.ViewGroup
import androidx.activity.viewModels
import androidx.core.graphics.Insets
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import dagger.hilt.android.AndroidEntryPoint
@@ -19,14 +18,14 @@ import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.databinding.ActivityCategoriesBinding
import org.koitharu.kotatsu.databinding.ActivityAppwidgetShelfBinding
import org.koitharu.kotatsu.widget.shelf.adapter.CategorySelectAdapter
import org.koitharu.kotatsu.widget.shelf.model.CategoryItem
import com.google.android.material.R as materialR
@AndroidEntryPoint
class ShelfConfigActivity :
BaseActivity<ActivityCategoriesBinding>(),
class ShelfWidgetConfigActivity :
BaseActivity<ActivityAppwidgetShelfBinding>(),
OnListItemClickListener<CategoryItem>,
View.OnClickListener {
@@ -37,16 +36,14 @@ class ShelfConfigActivity :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(ActivityCategoriesBinding.inflate(layoutInflater))
setContentView(ActivityAppwidgetShelfBinding.inflate(layoutInflater))
supportActionBar?.run {
setDisplayHomeAsUpEnabled(true)
setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material)
}
adapter = CategorySelectAdapter(this)
viewBinding.recyclerView.adapter = adapter
viewBinding.buttonDone.isVisible = true
viewBinding.buttonDone.setOnClickListener(this)
viewBinding.fabAdd.hide()
val appWidgetId = intent?.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID,
@@ -55,8 +52,9 @@ class ShelfConfigActivity :
finishAfterTransition()
return
}
config = AppWidgetConfig(this, appWidgetId)
config = AppWidgetConfig(this, ShelfWidgetProvider::class.java, appWidgetId)
viewModel.checkedId = config.categoryId
viewBinding.switchBackground.isChecked = config.hasBackground
viewModel.content.observe(this, this::onContentChanged)
viewModel.onError.observeEvent(this, SnackbarErrorObserver(viewBinding.recyclerView, null))
@@ -66,6 +64,7 @@ class ShelfConfigActivity :
when (v.id) {
R.id.button_done -> {
config.categoryId = viewModel.checkedId
config.hasBackground = viewBinding.switchBackground.isChecked
updateWidget()
setResult(
Activity.RESULT_OK,
@@ -81,11 +80,6 @@ class ShelfConfigActivity :
}
override fun onWindowInsetsChanged(insets: Insets) {
viewBinding.fabAdd.updateLayoutParams<ViewGroup.MarginLayoutParams> {
rightMargin = topMargin + insets.right
leftMargin = topMargin + insets.left
bottomMargin = topMargin + insets.bottom
}
viewBinding.recyclerView.updatePadding(
left = insets.left,
right = insets.right,

View File

@@ -2,43 +2,52 @@ package org.koitharu.kotatsu.widget.shelf
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.widget.RemoteViews
import androidx.core.app.PendingIntentCompat
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.AppWidgetConfig
import org.koitharu.kotatsu.core.ui.BaseAppWidgetProvider
import org.koitharu.kotatsu.reader.ui.ReaderActivity
class ShelfWidgetProvider : AppWidgetProvider() {
class ShelfWidgetProvider : BaseAppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
appWidgetIds.forEach { id ->
val views = RemoteViews(context.packageName, R.layout.widget_shelf)
val adapter = Intent(context, ShelfWidgetService::class.java)
adapter.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id)
adapter.data = Uri.parse(adapter.toUri(Intent.URI_INTENT_SCHEME))
views.setRemoteAdapter(R.id.gridView, adapter)
val intent = Intent(context, ReaderActivity::class.java)
intent.action = ReaderActivity.ACTION_MANGA_READ
views.setPendingIntentTemplate(
R.id.gridView,
PendingIntentCompat.getActivity(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT,
true,
),
)
views.setEmptyView(R.id.gridView, R.id.textView_holder)
appWidgetManager.updateAppWidget(id, views)
}
super.onUpdate(context, appWidgetManager, appWidgetIds)
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.gridView)
}
override fun onUpdateWidget(context: Context, config: AppWidgetConfig): RemoteViews {
val views = RemoteViews(context.packageName, R.layout.widget_shelf)
if (!config.hasBackground) {
views.setInt(R.id.widget_root, "setBackgroundColor", Color.TRANSPARENT)
} else {
views.setInt(R.id.widget_root, "setBackgroundResource", R.drawable.bg_appwidget_root)
}
val adapter = Intent(context, ShelfWidgetService::class.java)
adapter.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, config.widgetId)
adapter.data = Uri.parse(adapter.toUri(Intent.URI_INTENT_SCHEME))
views.setRemoteAdapter(R.id.gridView, adapter)
val intent = Intent(context, ReaderActivity::class.java)
intent.action = ReaderActivity.ACTION_MANGA_READ
views.setPendingIntentTemplate(
R.id.gridView,
PendingIntentCompat.getActivity(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT,
true,
),
)
views.setEmptyView(R.id.gridView, R.id.textView_holder)
return views
}
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/appwidget_corner_radius_inner" />
<solid android:color="@android:color/system_accent2_100" />
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/appwidget_corner_radius_background" />
<solid android:color="@android:color/system_accent2_50" />
</shape>

View File

@@ -3,5 +3,5 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/appwidget_corner_radius_inner" />
<solid android:color="?android:panelColorBackground" />
</shape>
<solid android:color="@color/kotatsu_primaryContainer" />
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/appwidget_corner_radius_background" />
<solid android:color="@color/kotatsu_background" />
</shape>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical">
<com.google.android.material.appbar.MaterialToolbar
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
tools:title="@string/recent_manga">
<Button
android:id="@+id/button_done"
style="@style/Widget.Material3.Button.UnelevatedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginHorizontal="@dimen/toolbar_button_margin"
android:text="@string/done" />
</com.google.android.material.appbar.MaterialToolbar>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:paddingStart="?listPreferredItemPaddingStart"
android:paddingEnd="?listPreferredItemPaddingEnd"
android:text="@string/background"
android:textAppearance="?textAppearanceBodyMedium"
app:layout_scrollFlags="scroll" />
</LinearLayout>

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
tools:title="@string/manga_shelf">
<Button
android:id="@+id/button_done"
style="@style/Widget.Material3.Button.UnelevatedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginHorizontal="@dimen/toolbar_button_margin"
android:text="@string/done" />
</com.google.android.material.appbar.MaterialToolbar>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:checked="true"
android:paddingStart="?listPreferredItemPaddingStart"
android:paddingEnd="?listPreferredItemPaddingEnd"
android:text="@string/background"
android:textAppearance="?textAppearanceBodyMedium"
app:layout_scrollFlags="scroll" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|start"
android:paddingStart="?listPreferredItemPaddingStart"
android:paddingTop="6dp"
android:paddingEnd="?listPreferredItemPaddingEnd"
android:singleLine="true"
android:text="@string/favourites_categories"
android:textAppearance="@style/TextAppearance.Kotatsu.SectionHeader" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:orientation="vertical"
android:paddingVertical="@dimen/list_spacing_normal"
android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
tools:listitem="@layout/item_checkable_single" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -5,7 +5,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp"
android:theme="@style/Theme.Kotatsu.AppWidgetContainer">
android:theme="@style/Theme.Kotatsu.AppWidgetContainer"
tools:layout_width="116dp">
<LinearLayout
android:id="@+id/rootLayout"
@@ -13,14 +14,15 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@drawable/bg_appwidget_card"
android:clipToOutline="true"
android:foreground="?android:selectableItemBackground"
android:orientation="vertical"
android:padding="4dp"
android:outlineProvider="background"
tools:ignore="UnusedAttribute,UselessParent">
<ImageView
android:id="@+id/imageView_cover"
android:layout_width="@dimen/widget_cover_width"
android:layout_width="match_parent"
android:layout_height="@dimen/widget_cover_height"
android:scaleType="centerCrop"
tools:ignore="ContentDescription"
@@ -33,8 +35,11 @@
android:elegantTextHeight="false"
android:ellipsize="end"
android:lines="2"
android:padding="2dp"
android:paddingHorizontal="6dp"
android:paddingTop="2dp"
android:paddingBottom="4dp"
android:textColor="?android:attr/textColorPrimary"
android:textSize="12sp"
tools:text="@tools:sample/lorem" />
</LinearLayout>

View File

@@ -1,14 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<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:background="?android:attr/colorBackground"
android:clipToOutline="true"
android:outlineProvider="background"
android:padding="4dp"
android:theme="@style/Theme.Kotatsu.AppWidgetContainer">
android:theme="@style/Theme.Kotatsu.AppWidgetContainer"
tools:background="@drawable/bg_appwidget_root">
<StackView
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/stackView"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -23,4 +25,4 @@
android:text="@string/history_is_empty"
android:textColor="?android:textColorPrimary" />
</FrameLayout>
</FrameLayout>

View File

@@ -1,21 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/widget_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/colorBackground"
android:padding="4dp"
android:theme="@style/Theme.Kotatsu.AppWidgetContainer">
android:clipToOutline="true"
android:outlineProvider="background"
android:theme="@style/Theme.Kotatsu.AppWidgetContainer"
tools:background="?android:attr/colorBackground">
<GridView
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:columnWidth="92dp"
android:gravity="center_horizontal"
android:numColumns="auto_fit"
android:orientation="horizontal"
android:padding="4dp"
tools:listitem="@layout/item_shelf" />
<TextView
@@ -27,4 +31,4 @@
android:text="@string/you_have_not_favourites_yet"
android:textColor="?android:attr/textColorPrimary" />
</FrameLayout>
</FrameLayout>

View File

@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="appwidget_corner_radius_inner">@android:dimen/system_app_widget_inner_radius</dimen>
</resources>
<dimen name="appwidget_corner_radius_background">@android:dimen/system_app_widget_background_radius</dimen>
</resources>

View File

@@ -54,7 +54,8 @@
<dimen name="card_indicator_size_small">24dp</dimen>
<dimen name="card_indicator_offset">8dp</dimen>
<dimen name="appwidget_corner_radius_inner">8dp</dimen>
<dimen name="appwidget_corner_radius_inner">20dp</dimen>
<dimen name="appwidget_corner_radius_background">28dp</dimen>
<!-- FastScroller -->
<dimen name="fastscroll_bubble_radius">44dp</dimen>

View File

@@ -2,6 +2,7 @@
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:configure="org.koitharu.kotatsu.widget.recent.RecentWidgetConfigActivity"
android:description="@string/appwidget_recent_description"
android:initialLayout="@layout/widget_recent"
android:minWidth="120dp"

View File

@@ -2,7 +2,7 @@
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:configure="org.koitharu.kotatsu.widget.shelf.ShelfConfigActivity"
android:configure="org.koitharu.kotatsu.widget.shelf.ShelfWidgetConfigActivity"
android:description="@string/appwidget_shelf_description"
android:initialLayout="@layout/widget_shelf"
android:minWidth="160dp"