mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
fix(flashbar): use material components in FlashbarView
This commit is contained in:
Generated
+3
@@ -73,6 +73,9 @@
|
||||
<TypeScriptCodeStyleSettings>
|
||||
<option name="INDENT_CHAINED_CALLS" value="false" />
|
||||
</TypeScriptCodeStyleSettings>
|
||||
<XML>
|
||||
<option name="XML_ALIGN_ATTRIBUTES" value="true" />
|
||||
</XML>
|
||||
<files>
|
||||
<extensions>
|
||||
<pair source="cc" header="h" fileNamingConvention="NONE" />
|
||||
|
||||
@@ -881,8 +881,8 @@ open class IDEEditor @JvmOverloads constructor(context: Context, attrs: Attribut
|
||||
|
||||
private fun configureFlashbar(builder: Flashbar.Builder, @StringRes message: Int,
|
||||
cancelChecker: ICancelChecker) {
|
||||
builder.message(message).negativeActionText(android.R.string.cancel)
|
||||
.negativeActionTapListener { bar: Flashbar ->
|
||||
builder.message(message).primaryActionText(android.R.string.cancel)
|
||||
.primaryActionTapListener { bar: Flashbar ->
|
||||
cancelChecker.cancel()
|
||||
bar.dismiss()
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.common.utilcode)
|
||||
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.androidx.annotation)
|
||||
implementation(libs.androidx.core.ktx)
|
||||
|
||||
@@ -75,9 +75,10 @@ class Flashbar private constructor(private var builder: Builder) {
|
||||
flashbarContainerView = FlashbarContainerView(builder.activity)
|
||||
flashbarContainerView.adjustOrientation(builder.activity)
|
||||
flashbarContainerView.addParent(this)
|
||||
flashbarContainerView.fitsSystemWindows = true
|
||||
|
||||
flashbarView = FlashbarView(builder.activity)
|
||||
flashbarView.init(builder.gravity, builder.castShadow, builder.shadowStrength)
|
||||
flashbarView.init(builder.gravity)
|
||||
flashbarView.adjustWitPositionAndOrientation(builder.activity, builder.gravity)
|
||||
flashbarView.addParent(flashbarContainerView)
|
||||
|
||||
@@ -181,7 +182,6 @@ class Flashbar private constructor(private var builder: Builder) {
|
||||
internal var overlay: Boolean = false
|
||||
internal var overlayColor: Int = ContextCompat.getColor(activity, R.color.modal)
|
||||
internal var overlayBlockable: Boolean = false
|
||||
internal var castShadow: Boolean = true
|
||||
internal var shadowStrength: Int = DEFAULT_SHADOW_STRENGTH
|
||||
internal var enableSwipeToDismiss: Boolean = false
|
||||
internal var vibrationTargets: List<Vibration> = emptyList()
|
||||
@@ -308,15 +308,6 @@ class Flashbar private constructor(private var builder: Builder) {
|
||||
/** Specifies if modal overlay is blockable and should comsume touch events */
|
||||
fun overlayBlockable() = apply { this.overlayBlockable = true }
|
||||
|
||||
/** Specifies if the flashbar should cast shadow and the strength of it */
|
||||
@JvmOverloads
|
||||
fun castShadow(shadow: Boolean = true, strength: Int = DEFAULT_SHADOW_STRENGTH) = apply {
|
||||
require(strength > 0) { "Shadow strength can not be negative or zero" }
|
||||
|
||||
this.castShadow = shadow
|
||||
this.shadowStrength = strength
|
||||
}
|
||||
|
||||
/** Specifies the enter animation of the flashbar */
|
||||
fun enterAnimation(builder: FlashAnimBarBuilder) = apply { this.enterAnimBuilder = builder }
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ package com.itsaky.androidide.flashbar
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.Typeface
|
||||
@@ -37,6 +38,13 @@ import android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM
|
||||
import android.widget.RelativeLayout.ALIGN_PARENT_TOP
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.core.view.marginBottom
|
||||
import androidx.core.view.marginLeft
|
||||
import androidx.core.view.marginRight
|
||||
import androidx.core.view.marginTop
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
import com.itsaky.androidide.flashbar.Flashbar.Gravity
|
||||
import com.itsaky.androidide.flashbar.Flashbar.Gravity.BOTTOM
|
||||
import com.itsaky.androidide.flashbar.Flashbar.Gravity.TOP
|
||||
@@ -48,11 +56,7 @@ import com.itsaky.androidide.flashbar.Flashbar.ProgressPosition.RIGHT
|
||||
import com.itsaky.androidide.flashbar.SwipeDismissTouchListener.DismissCallbacks
|
||||
import com.itsaky.androidide.flashbar.anim.FlashAnimIconBuilder
|
||||
import com.itsaky.androidide.flashbar.databinding.FlashBarViewBinding
|
||||
import com.itsaky.androidide.flashbar.util.convertDpToPx
|
||||
import com.itsaky.androidide.flashbar.util.getStatusBarHeightInPx
|
||||
import com.itsaky.androidide.flashbar.view.FbButton
|
||||
import com.itsaky.androidide.flashbar.view.FbProgress
|
||||
import com.itsaky.androidide.flashbar.view.ShadowView
|
||||
|
||||
/**
|
||||
* The actual Flashbar withView representation that can consist of the title, message, button, icon,
|
||||
@@ -84,22 +88,22 @@ class FlashbarView(context: Context) : LinearLayout(context) {
|
||||
private val fbIcon: ImageView
|
||||
get() = this.binding.fbIcon
|
||||
|
||||
private val fbLeftProgress: FbProgress
|
||||
private val fbLeftProgress: CircularProgressIndicator
|
||||
get() = this.binding.fbLeftProgress
|
||||
|
||||
private val fbRightProgress: FbProgress
|
||||
private val fbRightProgress: CircularProgressIndicator
|
||||
get() = this.binding.fbRightProgress
|
||||
|
||||
private val fbMessage: TextView
|
||||
get() = this.binding.fbMessage
|
||||
|
||||
private val fbPrimaryAction: FbButton
|
||||
private val fbPrimaryAction: MaterialButton
|
||||
get() = this.binding.fbPrimaryAction
|
||||
|
||||
private val fbPositiveAction: FbButton
|
||||
private val fbPositiveAction: MaterialButton
|
||||
get() = this.binding.fbPositiveAction
|
||||
|
||||
private val fbNegativeAction: FbButton
|
||||
private val fbNegativeAction: MaterialButton
|
||||
get() = this.binding.fbNegativeAction
|
||||
|
||||
private val fbSecondaryActionContainer: LinearLayout
|
||||
@@ -123,22 +127,27 @@ class FlashbarView(context: Context) : LinearLayout(context) {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun init(gravity: Gravity, castShadow: Boolean, shadowStrength: Int) {
|
||||
internal fun init(gravity: Gravity) {
|
||||
this.gravity = gravity
|
||||
this.orientation = VERTICAL
|
||||
|
||||
// If the bar appears with the bottom, then the shadow needs to added to the top of it,
|
||||
// Thus, before the inflation of the bar
|
||||
if (castShadow && gravity == BOTTOM) {
|
||||
castShadow(ShadowView.ShadowType.TOP, shadowStrength)
|
||||
}
|
||||
|
||||
this.binding = FlashBarViewBinding.inflate(LayoutInflater.from(context), this, true)
|
||||
|
||||
// If the bar appears with the top, then the shadow needs to added to the bottom of it,
|
||||
// Thus, after the inflation of the bar
|
||||
if (castShadow && gravity == TOP) {
|
||||
castShadow(ShadowView.ShadowType.BOTTOM, shadowStrength)
|
||||
this.binding.root.apply {
|
||||
// add margin to the card view so that the card elevation is visible
|
||||
val dp16 = context.resources.getDimensionPixelSize(R.dimen.fb_card_elevation)
|
||||
val (topIncr, bottomIncr) = when (gravity) {
|
||||
TOP -> 0 to dp16
|
||||
BOTTOM -> dp16 to 0
|
||||
}
|
||||
|
||||
updateLayoutParams<MarginLayoutParams> {
|
||||
setMargins(
|
||||
/* left = */ marginLeft,
|
||||
/* top = */ marginTop + topIncr,
|
||||
/* right = */ marginRight,
|
||||
/* bottom = */ marginBottom + bottomIncr
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,6 +162,7 @@ class FlashbarView(context: Context) : LinearLayout(context) {
|
||||
flashbarViewContentLp.topMargin = statusBarHeight.plus(compensationMarginTop / 2)
|
||||
flashbarViewLp.addRule(ALIGN_PARENT_TOP)
|
||||
}
|
||||
|
||||
BOTTOM -> {
|
||||
flashbarViewContentLp.bottomMargin = compensationMarginBottom
|
||||
flashbarViewLp.addRule(ALIGN_PARENT_BOTTOM)
|
||||
@@ -456,6 +466,7 @@ class FlashbarView(context: Context) : LinearLayout(context) {
|
||||
fbLeftProgress.visibility = VISIBLE
|
||||
fbRightProgress.visibility = GONE
|
||||
}
|
||||
|
||||
RIGHT -> {
|
||||
fbLeftProgress.visibility = GONE
|
||||
fbRightProgress.visibility = VISIBLE
|
||||
@@ -472,13 +483,6 @@ class FlashbarView(context: Context) : LinearLayout(context) {
|
||||
RIGHT -> fbRightProgress
|
||||
}
|
||||
|
||||
progressBar.setBarColor(progressTint)
|
||||
}
|
||||
|
||||
private fun castShadow(shadowType: ShadowView.ShadowType, strength: Int) {
|
||||
val params = RelativeLayout.LayoutParams(MATCH_PARENT, context.convertDpToPx(strength))
|
||||
val shadow = ShadowView(context)
|
||||
shadow.applyShadow(shadowType)
|
||||
addView(shadow, params)
|
||||
progressBar.progressTintList = ColorStateList.valueOf(progressTint)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.itsaky.androidide.flashbar.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import com.itsaky.androidide.flashbar.R
|
||||
|
||||
internal class FbButton : AppCompatTextView {
|
||||
constructor(context: Context) : this(context, null)
|
||||
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, R.style.FbButtonStyle)
|
||||
|
||||
constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet?,
|
||||
defStyleAttr: Int
|
||||
) : super(context, attrs, defStyleAttr)
|
||||
}
|
||||
@@ -1,581 +0,0 @@
|
||||
package com.itsaky.androidide.flashbar.view
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.TypedArray
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.RectF
|
||||
import android.os.Build
|
||||
import android.os.Build.VERSION
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import android.os.SystemClock
|
||||
import android.provider.Settings
|
||||
import android.util.AttributeSet
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import com.itsaky.androidide.flashbar.R
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/** Forked from Todd Davies' Progress Wheel https://github.com/Todd-Davies/ProgressWheel */
|
||||
class FbProgress : View {
|
||||
|
||||
private val barLength = 16
|
||||
private val barMaxLength = 270
|
||||
private val pauseGrowingTime: Long = 200
|
||||
|
||||
private var circleRadius = 28
|
||||
private var barWidth = 4
|
||||
private var rimWidth = 4
|
||||
private var fillRadius = false
|
||||
private var timeStartGrowing = 0.0
|
||||
private var barSpinCycleTime = 460.0
|
||||
private var barExtraLength = 0f
|
||||
private var barGrowingFromFront = true
|
||||
private var pausedTimeWithoutGrowing: Long = 0
|
||||
|
||||
private var barColor = -0x56000000
|
||||
private var rimColor = 0x00FFFFFF
|
||||
|
||||
private val barPaint = Paint()
|
||||
private val rimPaint = Paint()
|
||||
|
||||
private var circleBounds = RectF()
|
||||
|
||||
private var spinSpeed = 230.0f
|
||||
private var lastTimeAnimated: Long = 0
|
||||
private var linearProgress: Boolean = false
|
||||
|
||||
private var progress = 0.0f
|
||||
private var targetProgress = 0.0f
|
||||
private var isSpinning = false
|
||||
private var shouldAnimate: Boolean = false
|
||||
|
||||
private var callback: ProgressCallback? = null
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
parseAttributes(context.obtainStyledAttributes(attrs, R.styleable.FbProgress))
|
||||
setAnimationEnabled()
|
||||
}
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
setAnimationEnabled()
|
||||
}
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||
|
||||
val viewWidth = circleRadius + this.paddingLeft + this.paddingRight
|
||||
val viewHeight = circleRadius + this.paddingTop + this.paddingBottom
|
||||
|
||||
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
|
||||
val widthSize = MeasureSpec.getSize(widthMeasureSpec)
|
||||
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
|
||||
val heightSize = MeasureSpec.getSize(heightMeasureSpec)
|
||||
|
||||
val width: Int =
|
||||
when (widthMode) {
|
||||
MeasureSpec.EXACTLY -> widthSize
|
||||
MeasureSpec.AT_MOST -> viewWidth.coerceAtMost(widthSize)
|
||||
else -> viewWidth
|
||||
}
|
||||
|
||||
val height: Int =
|
||||
when {
|
||||
heightMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.EXACTLY -> heightSize
|
||||
heightMode == MeasureSpec.AT_MOST -> viewHeight.coerceAtMost(heightSize)
|
||||
else -> viewHeight
|
||||
}
|
||||
|
||||
setMeasuredDimension(width, height)
|
||||
}
|
||||
|
||||
override fun onSizeChanged(w: Int, h: Int, oldW: Int, oldH: Int) {
|
||||
super.onSizeChanged(w, h, oldW, oldH)
|
||||
|
||||
setupBounds(w, h)
|
||||
setupPaints()
|
||||
invalidate()
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
|
||||
canvas.drawArc(circleBounds, 360f, 360f, false, rimPaint)
|
||||
|
||||
var mustInvalidate = false
|
||||
|
||||
if (!shouldAnimate) {
|
||||
return
|
||||
}
|
||||
|
||||
if (isSpinning) {
|
||||
mustInvalidate = true
|
||||
|
||||
val deltaTime = SystemClock.uptimeMillis() - lastTimeAnimated
|
||||
val deltaNormalized = deltaTime * spinSpeed / 1000.0f
|
||||
|
||||
updateBarLength(deltaTime)
|
||||
|
||||
progress += deltaNormalized
|
||||
if (progress > 360) {
|
||||
progress -= 360f
|
||||
|
||||
runCallback(-1.0f)
|
||||
}
|
||||
lastTimeAnimated = SystemClock.uptimeMillis()
|
||||
|
||||
var from = progress - 90
|
||||
var length = barLength + barExtraLength
|
||||
|
||||
if (isInEditMode) {
|
||||
from = 0f
|
||||
length = 135f
|
||||
}
|
||||
canvas.drawArc(circleBounds, from, length, false, barPaint)
|
||||
} else {
|
||||
val oldProgress = progress
|
||||
|
||||
if (progress != targetProgress) {
|
||||
mustInvalidate = true
|
||||
|
||||
val deltaTime = (SystemClock.uptimeMillis() - lastTimeAnimated).toFloat() / 1000
|
||||
val deltaNormalized = deltaTime * spinSpeed
|
||||
|
||||
progress = (progress + deltaNormalized).coerceAtMost(targetProgress)
|
||||
lastTimeAnimated = SystemClock.uptimeMillis()
|
||||
}
|
||||
|
||||
if (oldProgress != progress) {
|
||||
runCallback()
|
||||
}
|
||||
|
||||
var offset = 0.0f
|
||||
var progress = this.progress
|
||||
if (!linearProgress) {
|
||||
val factor = 2.0f
|
||||
offset =
|
||||
(1.0f - (1.0f - this.progress / 360.0f).toDouble().pow((2.0f * factor).toDouble()))
|
||||
.toFloat() * 360.0f
|
||||
progress =
|
||||
(1.0f - (1.0f - this.progress / 360.0f).toDouble().pow(factor.toDouble())).toFloat() *
|
||||
360.0f
|
||||
}
|
||||
|
||||
if (isInEditMode) {
|
||||
progress = 360f
|
||||
}
|
||||
|
||||
canvas.drawArc(circleBounds, offset - 90, progress, false, barPaint)
|
||||
}
|
||||
|
||||
if (mustInvalidate) {
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onVisibilityChanged(changedView: View, visibility: Int) {
|
||||
super.onVisibilityChanged(changedView, visibility)
|
||||
|
||||
if (visibility == VISIBLE) {
|
||||
lastTimeAnimated = SystemClock.uptimeMillis()
|
||||
}
|
||||
}
|
||||
|
||||
public override fun onSaveInstanceState(): Parcelable {
|
||||
val superState = super.onSaveInstanceState()
|
||||
|
||||
val ss = WheelSavedState(superState)
|
||||
|
||||
ss.mProgress = this.progress
|
||||
ss.mTargetProgress = this.targetProgress
|
||||
ss.isSpinning = this.isSpinning
|
||||
ss.spinSpeed = this.spinSpeed
|
||||
ss.barWidth = this.barWidth
|
||||
ss.barColor = this.barColor
|
||||
ss.rimWidth = this.rimWidth
|
||||
ss.rimColor = this.rimColor
|
||||
ss.circleRadius = this.circleRadius
|
||||
ss.linearProgress = this.linearProgress
|
||||
ss.fillRadius = this.fillRadius
|
||||
|
||||
return ss
|
||||
}
|
||||
|
||||
public override fun onRestoreInstanceState(state: Parcelable) {
|
||||
if (state !is WheelSavedState) {
|
||||
super.onRestoreInstanceState(state)
|
||||
return
|
||||
}
|
||||
|
||||
super.onRestoreInstanceState(state.superState)
|
||||
|
||||
this.progress = state.mProgress
|
||||
this.targetProgress = state.mTargetProgress
|
||||
this.isSpinning = state.isSpinning
|
||||
this.spinSpeed = state.spinSpeed
|
||||
this.barWidth = state.barWidth
|
||||
this.barColor = state.barColor
|
||||
this.rimWidth = state.rimWidth
|
||||
this.rimColor = state.rimColor
|
||||
this.circleRadius = state.circleRadius
|
||||
this.linearProgress = state.linearProgress
|
||||
this.fillRadius = state.fillRadius
|
||||
|
||||
this.lastTimeAnimated = SystemClock.uptimeMillis()
|
||||
}
|
||||
|
||||
fun resetCount() {
|
||||
progress = 0.0f
|
||||
targetProgress = 0.0f
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun stopSpinning() {
|
||||
isSpinning = false
|
||||
progress = 0.0f
|
||||
targetProgress = 0.0f
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun spin() {
|
||||
lastTimeAnimated = SystemClock.uptimeMillis()
|
||||
isSpinning = true
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun setInstantProgress(update: Float) {
|
||||
var progressUpdate = update
|
||||
if (isSpinning) {
|
||||
progress = 0.0f
|
||||
isSpinning = false
|
||||
}
|
||||
|
||||
if (progressUpdate > 1.0f) {
|
||||
progressUpdate -= 1.0f
|
||||
} else if (progressUpdate < 0) {
|
||||
progressUpdate = 0f
|
||||
}
|
||||
|
||||
if (progressUpdate == targetProgress) {
|
||||
return
|
||||
}
|
||||
|
||||
targetProgress = (progressUpdate * 360.0f).coerceAtMost(360.0f)
|
||||
progress = targetProgress
|
||||
lastTimeAnimated = SystemClock.uptimeMillis()
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun getProgress(): Float {
|
||||
return if (isSpinning) -1f else progress / 360.0f
|
||||
}
|
||||
|
||||
fun setProgress(update: Float) {
|
||||
var progress = update
|
||||
if (isSpinning) {
|
||||
this.progress = 0.0f
|
||||
isSpinning = false
|
||||
|
||||
runCallback()
|
||||
}
|
||||
|
||||
if (progress > 1.0f) {
|
||||
progress -= 1.0f
|
||||
} else if (progress < 0) {
|
||||
progress = 0f
|
||||
}
|
||||
|
||||
if (progress == targetProgress) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.progress == targetProgress) {
|
||||
lastTimeAnimated = SystemClock.uptimeMillis()
|
||||
}
|
||||
|
||||
targetProgress = (progress * 360.0f).coerceAtMost(360.0f)
|
||||
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun setLinearProgress(isLinear: Boolean) {
|
||||
linearProgress = isLinear
|
||||
if (!isSpinning) {
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
fun getCircleRadius() = circleRadius
|
||||
|
||||
fun setCircleRadius(circleRadius: Int) {
|
||||
this.circleRadius = circleRadius
|
||||
if (!isSpinning) {
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
fun getBarWidth() = barWidth
|
||||
|
||||
fun setBarWidth(barWidth: Int) {
|
||||
this.barWidth = barWidth
|
||||
if (!isSpinning) {
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
fun getBarColor() = barColor
|
||||
|
||||
fun setBarColor(barColor: Int) {
|
||||
this.barColor = barColor
|
||||
setupPaints()
|
||||
if (!isSpinning) {
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
fun getRimColor(): Int {
|
||||
return rimColor
|
||||
}
|
||||
|
||||
fun setRimColor(rimColor: Int) {
|
||||
this.rimColor = rimColor
|
||||
setupPaints()
|
||||
if (!isSpinning) {
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
fun getSpinSpeed() = spinSpeed / 360.0f
|
||||
|
||||
fun setSpinSpeed(spinSpeed: Float) {
|
||||
this.spinSpeed = spinSpeed * 360.0f
|
||||
}
|
||||
|
||||
fun getRimWidth() = rimWidth
|
||||
|
||||
fun setRimWidth(rimWidth: Int) {
|
||||
this.rimWidth = rimWidth
|
||||
if (!isSpinning) {
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
fun setCallback(progressCallback: ProgressCallback) {
|
||||
callback = progressCallback
|
||||
|
||||
if (!isSpinning) {
|
||||
runCallback()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setAnimationEnabled() {
|
||||
val currentApiVersion = VERSION.SDK_INT
|
||||
|
||||
val animationValue =
|
||||
if (currentApiVersion >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
Settings.Global.getFloat(
|
||||
context.contentResolver,
|
||||
Settings.Global.ANIMATOR_DURATION_SCALE,
|
||||
1f
|
||||
)
|
||||
} else {
|
||||
Settings.System.getFloat(
|
||||
context.contentResolver,
|
||||
Settings.System.ANIMATOR_DURATION_SCALE,
|
||||
1f
|
||||
)
|
||||
}
|
||||
|
||||
shouldAnimate = animationValue != 0f
|
||||
}
|
||||
|
||||
private fun setupBounds(layoutWidth: Int, layoutHeight: Int) {
|
||||
val paddingTop = paddingTop
|
||||
val paddingBottom = paddingBottom
|
||||
val paddingLeft = paddingLeft
|
||||
val paddingRight = paddingRight
|
||||
|
||||
if (!fillRadius) {
|
||||
val minValue =
|
||||
(layoutWidth - paddingLeft - paddingRight).coerceAtMost(
|
||||
layoutHeight - paddingBottom - paddingTop
|
||||
)
|
||||
|
||||
val circleDiameter = minValue.coerceAtMost(circleRadius * 2 - barWidth * 2)
|
||||
|
||||
val xOffset = (layoutWidth - paddingLeft - paddingRight - circleDiameter) / 2 + paddingLeft
|
||||
val yOffset = (layoutHeight - paddingTop - paddingBottom - circleDiameter) / 2 + paddingTop
|
||||
|
||||
circleBounds =
|
||||
RectF(
|
||||
(xOffset + barWidth).toFloat(),
|
||||
(yOffset + barWidth).toFloat(),
|
||||
(xOffset + circleDiameter - barWidth).toFloat(),
|
||||
(yOffset + circleDiameter - barWidth).toFloat()
|
||||
)
|
||||
} else {
|
||||
circleBounds =
|
||||
RectF(
|
||||
(paddingLeft + barWidth).toFloat(),
|
||||
(paddingTop + barWidth).toFloat(),
|
||||
(layoutWidth - paddingRight - barWidth).toFloat(),
|
||||
(layoutHeight - paddingBottom - barWidth).toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseAttributes(a: TypedArray) {
|
||||
val metrics = context.resources.displayMetrics
|
||||
barWidth =
|
||||
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, barWidth.toFloat(), metrics).toInt()
|
||||
rimWidth =
|
||||
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rimWidth.toFloat(), metrics).toInt()
|
||||
circleRadius =
|
||||
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, circleRadius.toFloat(), metrics)
|
||||
.toInt()
|
||||
|
||||
circleRadius =
|
||||
a.getDimension(R.styleable.FbProgress_fbp_circleRadius, circleRadius.toFloat()).toInt()
|
||||
|
||||
fillRadius = a.getBoolean(R.styleable.FbProgress_fbp_fillRadius, false)
|
||||
|
||||
barWidth = a.getDimension(R.styleable.FbProgress_fbp_barWidth, barWidth.toFloat()).toInt()
|
||||
|
||||
rimWidth = a.getDimension(R.styleable.FbProgress_fbp_rimWidth, rimWidth.toFloat()).toInt()
|
||||
|
||||
val baseSpinSpeed = a.getFloat(R.styleable.FbProgress_fbp_spinSpeed, spinSpeed / 360.0f)
|
||||
spinSpeed = baseSpinSpeed * 360
|
||||
|
||||
barSpinCycleTime =
|
||||
a.getInt(R.styleable.FbProgress_fbp_barSpinCycleTime, barSpinCycleTime.toInt()).toDouble()
|
||||
|
||||
barColor = a.getColor(R.styleable.FbProgress_fbp_barColor, barColor)
|
||||
|
||||
rimColor = a.getColor(R.styleable.FbProgress_fbp_rimColor, rimColor)
|
||||
|
||||
linearProgress = a.getBoolean(R.styleable.FbProgress_fbp_linearProgress, false)
|
||||
|
||||
if (a.getBoolean(R.styleable.FbProgress_fbp_progressIndeterminate, false)) {
|
||||
spin()
|
||||
}
|
||||
|
||||
a.recycle()
|
||||
}
|
||||
|
||||
private fun setupPaints() {
|
||||
barPaint.color = barColor
|
||||
barPaint.isAntiAlias = true
|
||||
barPaint.style = Paint.Style.STROKE
|
||||
barPaint.strokeWidth = barWidth.toFloat()
|
||||
|
||||
rimPaint.color = rimColor
|
||||
rimPaint.isAntiAlias = true
|
||||
rimPaint.style = Paint.Style.STROKE
|
||||
rimPaint.strokeWidth = rimWidth.toFloat()
|
||||
}
|
||||
|
||||
private fun updateBarLength(deltaTimeInMilliSeconds: Long) {
|
||||
if (pausedTimeWithoutGrowing >= pauseGrowingTime) {
|
||||
timeStartGrowing += deltaTimeInMilliSeconds.toDouble()
|
||||
|
||||
if (timeStartGrowing > barSpinCycleTime) {
|
||||
timeStartGrowing -= barSpinCycleTime
|
||||
pausedTimeWithoutGrowing = 0
|
||||
barGrowingFromFront = !barGrowingFromFront
|
||||
}
|
||||
|
||||
val distance = cos((timeStartGrowing / barSpinCycleTime + 1) * Math.PI).toFloat() / 2 + 0.5f
|
||||
val destLength = (barMaxLength - barLength).toFloat()
|
||||
|
||||
if (barGrowingFromFront) {
|
||||
barExtraLength = distance * destLength
|
||||
} else {
|
||||
val newLength = destLength * (1 - distance)
|
||||
progress += barExtraLength - newLength
|
||||
barExtraLength = newLength
|
||||
}
|
||||
} else {
|
||||
pausedTimeWithoutGrowing += deltaTimeInMilliSeconds
|
||||
}
|
||||
}
|
||||
|
||||
private fun runCallback(value: Float) {
|
||||
if (callback != null) {
|
||||
callback!!.onProgressUpdate(value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun runCallback() {
|
||||
if (callback != null) {
|
||||
val normalizedProgress = (progress * 100 / 360.0f).roundToInt().toFloat() / 100
|
||||
callback!!.onProgressUpdate(normalizedProgress)
|
||||
}
|
||||
}
|
||||
|
||||
interface ProgressCallback {
|
||||
fun onProgressUpdate(progress: Float)
|
||||
}
|
||||
|
||||
internal class WheelSavedState : View.BaseSavedState {
|
||||
var mProgress: Float = 0.toFloat()
|
||||
var mTargetProgress: Float = 0.toFloat()
|
||||
var isSpinning: Boolean = false
|
||||
var spinSpeed: Float = 0.toFloat()
|
||||
var barWidth: Int = 0
|
||||
var barColor: Int = 0
|
||||
var rimWidth: Int = 0
|
||||
var rimColor: Int = 0
|
||||
var circleRadius: Int = 0
|
||||
var linearProgress: Boolean = false
|
||||
var fillRadius: Boolean = false
|
||||
|
||||
constructor(superState: Parcelable?) : super(superState)
|
||||
|
||||
private constructor(`in`: Parcel) : super(`in`) {
|
||||
this.mProgress = `in`.readFloat()
|
||||
this.mTargetProgress = `in`.readFloat()
|
||||
this.isSpinning = `in`.readByte().toInt() != 0
|
||||
this.spinSpeed = `in`.readFloat()
|
||||
this.barWidth = `in`.readInt()
|
||||
this.barColor = `in`.readInt()
|
||||
this.rimWidth = `in`.readInt()
|
||||
this.rimColor = `in`.readInt()
|
||||
this.circleRadius = `in`.readInt()
|
||||
this.linearProgress = `in`.readByte().toInt() != 0
|
||||
this.fillRadius = `in`.readByte().toInt() != 0
|
||||
}
|
||||
|
||||
override fun writeToParcel(out: Parcel, flags: Int) {
|
||||
super.writeToParcel(out, flags)
|
||||
out.writeFloat(this.mProgress)
|
||||
out.writeFloat(this.mTargetProgress)
|
||||
out.writeByte((if (isSpinning) 1 else 0).toByte())
|
||||
out.writeFloat(this.spinSpeed)
|
||||
out.writeInt(this.barWidth)
|
||||
out.writeInt(this.barColor)
|
||||
out.writeInt(this.rimWidth)
|
||||
out.writeInt(this.rimColor)
|
||||
out.writeInt(this.circleRadius)
|
||||
out.writeByte((if (linearProgress) 1 else 0).toByte())
|
||||
out.writeByte((if (fillRadius) 1 else 0).toByte())
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Suppress("unused")
|
||||
@JvmField
|
||||
val CREATOR: Parcelable.Creator<WheelSavedState> =
|
||||
object : Parcelable.Creator<WheelSavedState> {
|
||||
override fun createFromParcel(`in`: Parcel): WheelSavedState {
|
||||
return WheelSavedState(`in`)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<WheelSavedState> {
|
||||
return newArray(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.itsaky.androidide.flashbar.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.itsaky.androidide.flashbar.R
|
||||
import com.itsaky.androidide.flashbar.view.ShadowView.ShadowType.BOTTOM
|
||||
import com.itsaky.androidide.flashbar.view.ShadowView.ShadowType.TOP
|
||||
|
||||
internal class ShadowView
|
||||
@JvmOverloads
|
||||
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
|
||||
View(context, attrs, defStyleAttr) {
|
||||
|
||||
internal fun applyShadow(type: ShadowType) {
|
||||
when (type) {
|
||||
TOP -> setShadow(R.drawable.shadow_top)
|
||||
BOTTOM -> setShadow(R.drawable.shadow_bottom)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setShadow(@DrawableRes id: Int) {
|
||||
val shadow = ContextCompat.getDrawable(context, id)
|
||||
this.background = shadow
|
||||
}
|
||||
|
||||
enum class ShadowType {
|
||||
TOP,
|
||||
BOTTOM
|
||||
}
|
||||
}
|
||||
@@ -1,133 +1,142 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/fbRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/warm_grey"
|
||||
android:clickable="true"
|
||||
android:fitsSystemWindows="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/fb_content_padding_all">
|
||||
app:cardBackgroundColor="?colorPrimaryContainer"
|
||||
app:cardElevation="@dimen/fb_card_elevation"
|
||||
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Material3.Corner.Bottom">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/fbContent"
|
||||
<LinearLayout
|
||||
android:id="@+id/fbRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/fb_content_padding_all"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/fbContent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<com.itsaky.androidide.flashbar.view.FbProgress
|
||||
android:id="@+id/fbLeftProgress"
|
||||
style="@style/FbCircularIndeterminateProgressStyle"
|
||||
android:layout_width="@dimen/fb_progress_size"
|
||||
android:layout_height="@dimen/fb_progress_size"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="@dimen/fb_margin_progress"
|
||||
android:layout_marginRight="@dimen/fb_margin_progress"
|
||||
android:visibility="gone" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fbIcon"
|
||||
android:layout_width="@dimen/fb_icon_size"
|
||||
android:layout_height="@dimen/fb_icon_size"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="@dimen/fb_margin_right_icon"
|
||||
android:layout_marginRight="@dimen/fb_margin_right_icon"
|
||||
android:src="@drawable/ic_info"
|
||||
android:visibility="gone"
|
||||
app:tint="@color/white"
|
||||
tools:visibility="visible" />
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="8"
|
||||
android:orientation="vertical">
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fbTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/fb_title_message_margin"
|
||||
android:textAppearance="@style/FbTitleTextStyle"
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:id="@+id/fbLeftProgress"
|
||||
android:layout_width="@dimen/fb_progress_size"
|
||||
android:layout_height="@dimen/fb_progress_size"
|
||||
android:layout_marginEnd="@dimen/fb_margin_progress"
|
||||
android:layout_marginRight="@dimen/fb_margin_progress"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fbIcon"
|
||||
android:layout_width="@dimen/fb_icon_size"
|
||||
android:layout_height="@dimen/fb_icon_size"
|
||||
android:layout_marginEnd="@dimen/fb_margin_right_icon"
|
||||
android:layout_marginRight="@dimen/fb_margin_right_icon"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/ic_info"
|
||||
android:visibility="gone"
|
||||
tools:text="Title"
|
||||
app:tint="?colorOnPrimaryContainer"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fbMessage"
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="8"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fbTitle"
|
||||
android:textStyle="bold"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/fb_title_message_margin"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
|
||||
android:textColor="?colorOnPrimaryContainer"
|
||||
android:visibility="gone"
|
||||
tools:text="Title"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fbMessage"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/fb_title_message_margin"
|
||||
android:justificationMode="inter_word"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:visibility="gone"
|
||||
tools:text="A quick brown fox jumps of the lazy dog."
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/fbPrimaryAction"
|
||||
style="@style/Widget.Material3.Button.TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/fb_title_message_margin"
|
||||
android:justificationMode="inter_word"
|
||||
android:textAppearance="@style/FbMessageStyle"
|
||||
android:textAllCaps="false"
|
||||
android:visibility="gone"
|
||||
tools:text="A quick brown fox jumps of the lazy dog."
|
||||
tools:text="CLICK"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:id="@+id/fbRightProgress"
|
||||
android:layout_width="@dimen/fb_progress_size"
|
||||
android:layout_height="@dimen/fb_progress_size"
|
||||
android:layout_marginStart="@dimen/fb_margin_progress"
|
||||
android:layout_marginLeft="@dimen/fb_margin_progress"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.itsaky.androidide.flashbar.view.FbButton
|
||||
android:id="@+id/fbPrimaryAction"
|
||||
style="@style/FbButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:id="@+id/fbSecondaryActionContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/FbButtonTextStyle"
|
||||
android:visibility="gone"
|
||||
tools:text="CLICK"
|
||||
tools:visibility="visible" />
|
||||
android:layout_marginTop="@dimen/fb_margin_secondary_action_container"
|
||||
android:gravity="end"
|
||||
android:visibility="gone">
|
||||
|
||||
<com.itsaky.androidide.flashbar.view.FbProgress
|
||||
android:id="@+id/fbRightProgress"
|
||||
style="@style/FbCircularIndeterminateProgressStyle"
|
||||
android:layout_width="@dimen/fb_progress_size"
|
||||
android:layout_height="@dimen/fb_progress_size"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/fb_margin_progress"
|
||||
android:layout_marginLeft="@dimen/fb_margin_progress"
|
||||
android:visibility="gone" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/fbNegativeAction"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:text="CANCEL"
|
||||
tools:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/fbPositiveAction"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/fb_margin_secondary_action"
|
||||
android:layout_marginLeft="@dimen/fb_margin_secondary_action"
|
||||
android:visibility="gone"
|
||||
tools:text="OK"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/fbSecondaryActionContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/fb_margin_secondary_action_container"
|
||||
android:gravity="end"
|
||||
android:visibility="gone">
|
||||
|
||||
<com.itsaky.androidide.flashbar.view.FbButton
|
||||
android:id="@+id/fbPositiveAction"
|
||||
style="@style/FbButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/FbButtonTextStyle"
|
||||
android:visibility="gone"
|
||||
tools:text="OK"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<com.itsaky.androidide.flashbar.view.FbButton
|
||||
android:id="@+id/fbNegativeAction"
|
||||
style="@style/FbButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/fb_margin_secondary_action"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:textAppearance="@style/FbButtonTextStyle"
|
||||
android:visibility="gone"
|
||||
tools:text="CANCEL"
|
||||
tools:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
@@ -1,5 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="fb_card_elevation">8dp</dimen>
|
||||
|
||||
<dimen name="fb_content_padding_all">16dp</dimen>
|
||||
<dimen name="fb_title_text_size">16sp</dimen>
|
||||
<dimen name="fb_message_text_size">14sp</dimen>
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="FbTitleTextStyle" parent="TextAppearance.AppCompat">
|
||||
<item name="android:textColor">@color/white</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:textSize">@dimen/fb_title_text_size</item>
|
||||
</style>
|
||||
|
||||
<style name="FbMessageStyle" parent="TextAppearance.AppCompat">
|
||||
<item name="android:textColor">@color/white</item>
|
||||
<item name="android:textSize">@dimen/fb_message_text_size</item>
|
||||
</style>
|
||||
|
||||
<style name="FbButtonTextStyle" parent="TextAppearance.AppCompat">
|
||||
<item name="android:textColor">@color/white</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:textSize">@dimen/fb_button_text_size</item>
|
||||
</style>
|
||||
|
||||
<style name="FbButtonStyle">
|
||||
<item name="android:paddingLeft">8dp</item>
|
||||
<item name="android:paddingRight">8dp</item>
|
||||
<item name="android:paddingTop">4dp</item>
|
||||
<item name="android:paddingBottom">4dp</item>
|
||||
<item name="android:background">@drawable/fb_button_background_selector</item>
|
||||
<item name="android:clickable">true</item>
|
||||
<item name="android:focusable">true</item>
|
||||
</style>
|
||||
|
||||
<style name="FbCircularIndeterminateProgressStyle">
|
||||
<item name="fbp_barColor">@color/white</item>
|
||||
<item name="fbp_barWidth">2dp</item>
|
||||
<item name="fbp_progressIndeterminate">true</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
Reference in New Issue
Block a user