This commit is contained in:
Koitharu
2023-07-01 16:03:48 +03:00
parent 98b8aa3f2d
commit 39cd199044
5 changed files with 238 additions and 6 deletions

View File

@@ -0,0 +1,135 @@
package org.koitharu.kotatsu.core.ui.widgets
import android.content.Context
import android.graphics.Outline
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewOutlineProvider
import android.widget.LinearLayout
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import androidx.core.content.withStyledAttributes
import androidx.core.view.setPadding
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.shape.ShapeAppearanceModel
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.util.ext.drawableStart
import org.koitharu.kotatsu.core.util.ext.getDrawableCompat
import org.koitharu.kotatsu.core.util.ext.getThemeColorStateList
import org.koitharu.kotatsu.core.util.ext.setTextAndVisible
import org.koitharu.kotatsu.core.util.ext.textAndVisible
import org.koitharu.kotatsu.databinding.ViewTipBinding
import com.google.android.material.R as materialR
class TipView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = R.attr.tipViewStyle,
) : LinearLayout(context, attrs, defStyleAttr), View.OnClickListener {
private val binding = ViewTipBinding.inflate(LayoutInflater.from(context), this)
var title: CharSequence?
get() = binding.textViewTitle.text
set(value) {
binding.textViewTitle.text = value
}
var text: CharSequence?
get() = binding.textViewBody.text
set(value) {
binding.textViewBody.text = value
}
var icon: Drawable?
get() = binding.textViewTitle.drawableStart
set(value) {
binding.textViewTitle.drawableStart = value
}
var primaryButtonText: CharSequence?
get() = binding.buttonPrimary.textAndVisible
set(value) {
binding.buttonPrimary.textAndVisible = value
}
var secondaryButtonText: CharSequence?
get() = binding.buttonSecondary.textAndVisible
set(value) {
binding.buttonSecondary.textAndVisible = value
}
var onButtonClickListener: OnButtonClickListener? = null
init {
orientation = VERTICAL
setPadding(context.resources.getDimensionPixelOffset(R.dimen.margin_normal))
context.withStyledAttributes(attrs, R.styleable.TipView, defStyleAttr) {
title = getText(R.styleable.TipView_title)
text = getText(R.styleable.TipView_android_text)
icon = getDrawableCompat(context, R.styleable.TipView_icon)
primaryButtonText = getString(R.styleable.TipView_primaryButtonText)
secondaryButtonText = getString(R.styleable.TipView_secondaryButtonText)
val shapeAppearanceModel = ShapeAppearanceModel.builder(context, attrs, defStyleAttr, 0).build()
background = MaterialShapeDrawable(shapeAppearanceModel).also {
it.fillColor = getColorStateList(R.styleable.TipView_cardBackgroundColor)
?: context.getThemeColorStateList(materialR.attr.colorBackgroundFloating)
it.strokeWidth = getDimension(R.styleable.TipView_strokeWidth, 0f)
it.strokeColor = getColorStateList(R.styleable.TipView_strokeColor)
it.elevation = getDimension(R.styleable.TipView_elevation, 0f)
}
outlineProvider = OutlineProvider(shapeAppearanceModel)
}
}
override fun onClick(v: View) {
when (v.id) {
R.id.button_primary -> onButtonClickListener?.onPrimaryButtonClick(this)
R.id.button_secondary -> onButtonClickListener?.onSecondaryButtonClick(this)
}
}
fun setTitle(@StringRes resId: Int) {
binding.textViewTitle.setText(resId)
}
fun setText(@StringRes resId: Int) {
binding.textViewBody.setText(resId)
}
fun setPrimaryButtonText(@StringRes resId: Int) {
binding.buttonPrimary.setTextAndVisible(resId)
}
fun setSecondaryButtonText(@StringRes resId: Int) {
binding.buttonSecondary.setTextAndVisible(resId)
}
fun setIcon(@DrawableRes resId: Int) {
icon = ContextCompat.getDrawable(context, resId)
}
interface OnButtonClickListener {
fun onPrimaryButtonClick(tipView: TipView)
fun onSecondaryButtonClick(tipView: TipView)
}
private class OutlineProvider(
shapeAppearanceModel: ShapeAppearanceModel,
) : ViewOutlineProvider() {
private val shapeDrawable = MaterialShapeDrawable(shapeAppearanceModel)
override fun getOutline(view: View, outline: Outline) {
shapeDrawable.setBounds(0, 0, view.width, view.height)
shapeDrawable.getOutline(outline)
}
}
}

View File

@@ -1,11 +1,16 @@
package org.koitharu.kotatsu.core.util.ext
import android.content.Context
import android.content.res.TypedArray
import android.graphics.Color
import android.graphics.drawable.Drawable
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.annotation.FloatRange
import androidx.annotation.Px
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.core.content.res.TypedArrayUtils
import androidx.core.content.res.use
import androidx.core.graphics.ColorUtils
@@ -60,3 +65,8 @@ fun Context.getThemeColorStateList(
) = obtainStyledAttributes(intArrayOf(resId)).use {
it.getColorStateList(0)
}
fun TypedArray.getDrawableCompat(context: Context, index: Int): Drawable? {
val resId = getResourceId(index, 0)
return if (resId != 0) ContextCompat.getDrawable(context, resId) else null
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<org.koitharu.kotatsu.core.ui.widgets.TipView
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="wrap_content"
app:cardBackgroundColor="@color/background_mamimi"
app:shapeAppearance="?shapeAppearanceCornerExtraLarge"
tools:icon="@drawable/ic_notification"
tools:primaryButtonText="@string/settings"
tools:secondaryButtonText="@string/close"
tools:text="Включите их, чтобы ничего не пропускать. Откройте настройки системы и разрешите их отправку."
tools:title="Уведомления отключены" />

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<merge
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:padding="@dimen/margin_normal"
tools:background="@drawable/bg_appwidget_card"
tools:backgroundTint="?colorBackgroundFloating"
tools:layout_height="wrap_content"
tools:layout_margin="16dp"
tools:layout_width="match_parent"
tools:orientation="vertical"
tools:parentTag="android.widget.LinearLayout">
<TextView
android:id="@+id/textView_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawablePadding="10dp"
android:gravity="center_vertical"
android:textAppearance="?textAppearanceTitleMedium"
tools:drawableStartCompat="@drawable/ic_app_update"
tools:text="Уведомления отключены" />
<TextView
android:id="@+id/textView_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textAppearance="?textAppearanceBodyMedium"
tools:text="Включите их, чтобы ничего не пропускать. Откройте настройки системы и разрешите их отправку." />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_weight="2"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/button_primary"
style="@style/Widget.Material3.Button.UnelevatedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_weight="1"
android:paddingHorizontal="8dp"
android:singleLine="true"
tools:text="Открыть настройки" />
<Button
android:id="@+id/button_secondary"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_weight="1"
android:paddingHorizontal="8dp"
android:singleLine="true"
tools:text="Отмена" />
</LinearLayout>
</merge>

View File

@@ -7,12 +7,7 @@
<attr name="themeChooserPreferenceStyle" />
<attr name="listItemTextViewStyle" />
<attr name="fastScrollerStyle" />
<declare-styleable name="Theme">
<attr name="navigationBarDividerColor" format="color" />
<attr name="colorControlLight" format="color" />
<attr name="colorSurfaceSecondary" format="color" />
</declare-styleable>
<attr name="tipViewStyle" />
<!--CoverImageView attrs-->
<declare-styleable name="CoverImageView">
@@ -112,4 +107,18 @@
<attr name="android:entries" />
</declare-styleable>
<declare-styleable name="TipView">
<attr name="icon" />
<attr name="title" />
<attr name="android:text" />
<attr name="primaryButtonText" format="string" />
<attr name="secondaryButtonText" format="string" />
<attr name="shapeAppearance" />
<attr name="shapeAppearanceOverlay" />
<attr name="cardBackgroundColor" />
<attr name="strokeWidth"/>
<attr name="strokeColor" />
<attr name="elevation" />
</declare-styleable>
</resources>