= arrayListOf()
47 |
48 | inner class Send {
49 | fun send(any: Any) {
50 | for (recv in data) {
51 | recv.recv(any)
52 | }
53 | }
54 | }
55 |
56 | fun add(recv: Recv) {
57 | data.add(recv)
58 | }
59 |
60 | fun getSend(): Send {
61 | return Send()
62 | }
63 |
64 | /**
65 | * Get data reception / 获取数据接收
66 | */
67 | fun getRecv(flags: Int): Recv {
68 | return Recv(flags, defValue).also { add(it) }
69 | }
70 |
71 | /**
72 | * Please do not use it directly. / 请不要直接使用.
73 | *
74 | * Please use {@link cn.fkj233.ui.activity.data.DataBinding.Binding#getRecv(int)}
75 | */
76 | inner class Recv(private val flags: Int, private val defValue: () -> Any) {
77 | private lateinit var mView: View
78 |
79 | fun setView(view: View) {
80 | mView = view
81 | recv(defValue())
82 | }
83 |
84 | fun recv(any: Any) {
85 | recvCallbacks(mView, flags, any)
86 | }
87 | }
88 | }
89 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/SeekBarV.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 | import android.content.Context
26 | import android.os.Build
27 | import android.view.View
28 | import android.view.ViewGroup
29 | import android.widget.LinearLayout
30 | import android.widget.SeekBar
31 | import android.widget.TextView
32 | import cn.fkj233.ui.R
33 | import cn.fkj233.ui.activity.MIUIActivity
34 | import cn.fkj233.ui.activity.data.DataBinding
35 | import cn.fkj233.ui.activity.dp2px
36 | import cn.fkj233.ui.activity.fragment.MIUIFragment
37 |
38 | class SeekBarV(
39 | val key: String = "",
40 | private val min: Int,
41 | val max: Int,
42 | private val defaultProgress: Int,
43 | private val dataSend: DataBinding.Binding.Send? = null,
44 | private val dataBindingRecv: DataBinding.Binding.Recv? = null,
45 | val callBacks: ((Int, TextView) -> Unit)? = null
46 | ) : BaseView {
47 |
48 | override fun getType(): BaseView = this
49 |
50 | override fun create(context: Context, callBacks: (() -> Unit)?): View {
51 | return SeekBar(context).also { view ->
52 | view.thumb = null
53 | view.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
54 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
55 | view.maxHeight = dp2px(context, 35f)
56 | view.minHeight = dp2px(context, 35f)
57 | }
58 | view.isIndeterminate = false
59 | view.progressDrawable = context.getDrawable(R.drawable.seekbar_progress_drawable)
60 | view.indeterminateDrawable = context.getDrawable(R.color.colorAccent)
61 | view.min = min
62 | view.max = max
63 | if (MIUIActivity.safeSP.containsKey(key)) {
64 | MIUIActivity.safeSP.getInt(key, defaultProgress).let {
65 | view.progress = it
66 | }
67 | } else {
68 | view.progress = defaultProgress
69 | MIUIActivity.safeSP.putAny(key, defaultProgress)
70 | }
71 | view.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
72 | override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
73 | callBacks?.let { it() }
74 | dataSend?.send(p1)
75 | MIUIActivity.safeSP.putAny(key, p1)
76 | }
77 |
78 | override fun onStartTrackingTouch(p0: SeekBar?) {}
79 | override fun onStopTrackingTouch(p0: SeekBar?) {}
80 | })
81 | dataBindingRecv?.setView(view)
82 | }
83 | }
84 |
85 | override fun onDraw(thiz: MIUIFragment, group: LinearLayout, view: View) {
86 | thiz.apply {
87 | group.apply {
88 | addView(LinearLayout(context).apply {
89 | setPadding(dp2px(context, 12f), 0, dp2px(context, 12f), 0)
90 | addView(view, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT))
91 | })
92 | }
93 | }
94 | }
95 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/TextWithSpinnerV.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 | import android.annotation.SuppressLint
26 | import android.content.Context
27 | import android.view.Gravity
28 | import android.view.MotionEvent
29 | import android.view.View
30 | import android.widget.LinearLayout
31 | import cn.fkj233.ui.activity.data.DataBinding
32 | import cn.fkj233.ui.activity.data.LayoutPair
33 | import cn.fkj233.ui.activity.dp2px
34 | import cn.fkj233.ui.activity.fragment.MIUIFragment
35 |
36 | class TextWithSpinnerV(private val textV: TextV, private val spinnerV: SpinnerV, private val dataBindingRecv: DataBinding.Binding.Recv? = null): BaseView {
37 |
38 | override fun getType(): BaseView = this
39 |
40 | override fun create(context: Context, callBacks: (() -> Unit)?): View {
41 | return LinearContainerV(
42 | LinearContainerV.HORIZONTAL,
43 | arrayOf(
44 | LayoutPair(textV.create(context, callBacks), LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)),
45 | LayoutPair(spinnerV.create(context, callBacks), LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).also { it.gravity = Gravity.CENTER_VERTICAL })
46 | ),
47 | descendantFocusability = LinearContainerV.FOCUS_BLOCK_DESCENDANTS,
48 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
49 | ).create(context, callBacks).also {
50 | dataBindingRecv?.setView(it)
51 | }
52 | }
53 |
54 | @SuppressLint("ClickableViewAccessibility")
55 | override fun onDraw(thiz: MIUIFragment, group: LinearLayout, view: View) {
56 | thiz.apply {
57 | group.apply {
58 | addView(view)
59 | setOnClickListener {}
60 | setOnTouchListener { view, motionEvent ->
61 | if (motionEvent.action == MotionEvent.ACTION_UP) {
62 | val popup = MIUIPopup(context, view, spinnerV.currentValue, spinnerV.dropDownWidth, {
63 | spinnerV.select.text = it
64 | spinnerV.currentValue = it
65 | callBacks?.let { it1 -> it1() }
66 | spinnerV.dataBindingSend?.send(it)
67 | }, SpinnerV.SpinnerData().apply(spinnerV.data).arrayList)
68 | if (view.width / 2 >= motionEvent.x) {
69 | popup.apply {
70 | horizontalOffset = dp2px(context, 24F)
71 | setDropDownGravity(Gravity.LEFT)
72 | }
73 | } else {
74 | popup.apply {
75 | horizontalOffset = - dp2px(context, 24F)
76 | setDropDownGravity(Gravity.RIGHT)
77 | }
78 | }
79 | popup.show()
80 | }
81 | false
82 | }
83 | }
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/RadioViewV.kt:
--------------------------------------------------------------------------------
1 | package cn.fkj233.ui.activity.view
2 |
3 | import android.content.Context
4 | import android.graphics.Typeface
5 | import android.os.Build
6 | import android.util.TypedValue
7 | import android.view.View
8 | import android.widget.LinearLayout
9 | import android.widget.RadioButton
10 | import android.widget.RadioGroup
11 | import cn.fkj233.ui.R
12 | import cn.fkj233.ui.activity.MIUIActivity
13 | import cn.fkj233.ui.activity.data.DataBinding
14 | import cn.fkj233.ui.activity.dp2px
15 | import cn.fkj233.ui.activity.fragment.MIUIFragment
16 | import cn.fkj233.ui.activity.isRtl
17 |
18 | class RadioViewV(private val key: String, val dataBindingRecv: DataBinding.Binding.Recv? = null, val data: RadioData.() -> Unit) : BaseView {
19 | data class RadioDataValue(val value: String, val name: String, val dataBindingRecv: DataBinding.Binding.Recv?, val dataBindingSend: DataBinding.Binding.Send?, val callBacks: ((View, Any) -> Unit)?)
20 |
21 | class RadioData {
22 | val data: ArrayList = arrayListOf()
23 |
24 | fun add(value: String, name: String, dataBindingRecv: DataBinding.Binding.Recv? = null, dataBindingSend: DataBinding.Binding.Send? = null, callBacks: ((View, Any) -> Unit)? = null) {
25 | data.add(RadioDataValue(value, name, dataBindingRecv, dataBindingSend, callBacks))
26 | }
27 | }
28 |
29 | override fun getType(): BaseView = this
30 |
31 | override fun create(context: Context, callBacks: (() -> Unit)?): View {
32 | val data = RadioData().apply(data)
33 | val viewId: HashMap = hashMapOf()
34 | return RadioGroup(context).apply {
35 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
36 | orientation = LinearLayout.VERTICAL
37 | for (radioData in data.data) {
38 | addView(RadioButton(context).apply {
39 | id = View.generateViewId()
40 | viewId[radioData.value] = id
41 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
42 | text = radioData.name
43 | setTextColor(context.getColor(R.color.whiteText))
44 | setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
45 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
46 | paint.typeface = Typeface.create(null, 500, false)
47 | } else {
48 | paint.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
49 | }
50 | if (isRtl(context))
51 | setPadding(dp2px(context, 35f), dp2px(context, 20f), dp2px(context, 30f), dp2px(context, 20f))
52 | else
53 | setPadding(dp2px(context, 30f), dp2px(context, 20f), dp2px(context, 35f), dp2px(context, 20f))
54 | buttonDrawable = null
55 | background = context.getDrawable(R.drawable.ic_click_check)
56 | val drawable = context.getDrawable(android.R.drawable.btn_radio).also { it?.setBounds(0,0,60,60) }
57 | if (isRtl(context))
58 | setCompoundDrawables(drawable, null, null, null)
59 | else
60 | setCompoundDrawables(null, null, drawable, null)
61 | setOnClickListener { view ->
62 | radioData.callBacks?.let { it(view, radioData.value) }
63 | radioData.dataBindingSend?.send(radioData.value)
64 | MIUIActivity.safeSP.putAny(key, radioData.value)
65 | }
66 | radioData.dataBindingRecv?.setView(this)
67 | })
68 | }
69 | viewId[MIUIActivity.safeSP.getString(key, "")]?.let { check(it) }
70 | dataBindingRecv?.setView(this)
71 | }
72 | }
73 |
74 | override fun onDraw(thiz: MIUIFragment, group: LinearLayout, view: View) {
75 | thiz.apply {
76 | group.apply {
77 | setPadding(0, 0, 0, 0)
78 | addView(view)
79 | }
80 | }
81 | }
82 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/TextSummaryWithSwitchV.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 | import android.annotation.SuppressLint
26 | import android.content.Context
27 | import android.view.Gravity
28 | import android.view.MotionEvent
29 | import android.view.View
30 | import android.widget.LinearLayout
31 | import cn.fkj233.ui.R
32 | import cn.fkj233.ui.activity.data.DataBinding
33 | import cn.fkj233.ui.activity.data.LayoutPair
34 | import cn.fkj233.ui.activity.dp2px
35 | import cn.fkj233.ui.activity.fragment.MIUIFragment
36 |
37 | class TextSummaryWithSwitchV(private val textSummaryV: TextSummaryV, private val switchV: SwitchV, private val dataBindingRecv: DataBinding.Binding.Recv? = null): BaseView {
38 |
39 | override fun getType(): BaseView = this
40 |
41 | override fun create(context: Context, callBacks: (() -> Unit)?): View {
42 | textSummaryV.notShowMargins(true)
43 | return LinearContainerV(
44 | LinearContainerV.HORIZONTAL,
45 | arrayOf(
46 | LayoutPair(textSummaryV.create(context, callBacks), LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)),
47 | LayoutPair(switchV.create(context, callBacks), LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).also { it.gravity = Gravity.CENTER_VERTICAL })
48 | ),
49 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT).also {
50 | it.setMargins(0, dp2px(context, 17.75f),0, dp2px(context, 17.75f))
51 | }
52 | ).create(context, callBacks).also {
53 | dataBindingRecv?.setView(it)
54 | }
55 | }
56 |
57 | @SuppressLint("ClickableViewAccessibility")
58 | override fun onDraw(thiz: MIUIFragment, group: LinearLayout, view: View) {
59 | thiz.apply {
60 | group.apply {
61 | addView(view) // 带文本的开关
62 | setOnTouchListener { _, motionEvent ->
63 | when (motionEvent.action) {
64 | MotionEvent.ACTION_DOWN -> if (switchV.switch.isEnabled) background = context.getDrawable(R.drawable.ic_main_down_bg)
65 | MotionEvent.ACTION_UP -> {
66 | val touchX: Float = motionEvent.x
67 | val touchY: Float = motionEvent.y
68 | val maxX = width.toFloat()
69 | val maxY = height.toFloat()
70 | if (touchX < 0 || touchX > maxX || touchY < 0 || touchY > maxY) {
71 | isPressed = false
72 | return@setOnTouchListener false
73 | }
74 | if (switchV.switch.isEnabled) {
75 | switchV.click()
76 | callBacks?.let { it1 -> it1() }
77 | background = context.getDrawable(R.drawable.ic_main_bg)
78 | }
79 | }
80 | else -> background = context.getDrawable(R.drawable.ic_main_bg)
81 | }
82 | true
83 | }
84 | }
85 | }
86 | }
87 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/TextSummaryWithSpinnerV.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 | import android.annotation.SuppressLint
26 | import android.content.Context
27 | import android.view.Gravity
28 | import android.view.MotionEvent
29 | import android.view.View
30 | import android.widget.LinearLayout
31 | import cn.fkj233.ui.activity.data.DataBinding
32 | import cn.fkj233.ui.activity.data.LayoutPair
33 | import cn.fkj233.ui.activity.dp2px
34 | import cn.fkj233.ui.activity.fragment.MIUIFragment
35 |
36 | class TextSummaryWithSpinnerV(private val textSummaryV: TextSummaryV, private val spinnerV: SpinnerV, private val dataBindingRecv: DataBinding.Binding.Recv? = null): BaseView {
37 |
38 | override fun getType(): BaseView = this
39 |
40 | override fun create(context: Context, callBacks: (() -> Unit)?): View {
41 | return LinearContainerV(
42 | LinearContainerV.HORIZONTAL,
43 | arrayOf(
44 | LayoutPair(textSummaryV.create(context, callBacks), LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)),
45 | LayoutPair(spinnerV.create(context, callBacks), LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).also { it.gravity = Gravity.CENTER_VERTICAL })
46 | ),
47 | descendantFocusability = LinearContainerV.FOCUS_BLOCK_DESCENDANTS,
48 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT).also {
49 | it.setMargins(0, dp2px(context, 17.75f),0, dp2px(context, 17.75f))
50 | }
51 | ).create(context, callBacks).also {
52 | dataBindingRecv?.setView(it)
53 | }
54 | }
55 |
56 | @SuppressLint("ClickableViewAccessibility")
57 | override fun onDraw(thiz: MIUIFragment, group: LinearLayout, view: View) {
58 | thiz.apply {
59 | group.apply {
60 | addView(view)
61 | setOnClickListener {}
62 | setOnTouchListener { view, motionEvent ->
63 | if (motionEvent.action == MotionEvent.ACTION_UP) {
64 | val popup = MIUIPopup(context, view, spinnerV.currentValue, spinnerV.dropDownWidth, {
65 | spinnerV.select.text = it
66 | spinnerV.currentValue = it
67 | callBacks?.let { it1 -> it1() }
68 | spinnerV.dataBindingSend?.send(it)
69 | }, SpinnerV.SpinnerData().apply(spinnerV.data).arrayList)
70 | if (view.width / 2 >= motionEvent.x) {
71 | popup.apply {
72 | horizontalOffset = dp2px(context, 24F)
73 | setDropDownGravity(Gravity.LEFT)
74 | }
75 | } else {
76 | popup.apply {
77 | horizontalOffset = -dp2px(context, 24F)
78 | setDropDownGravity(Gravity.RIGHT)
79 | }
80 | }
81 | popup.show()
82 | }
83 | false
84 | }
85 | }
86 | }
87 | }
88 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/TextWithSwitchV.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 | import android.annotation.SuppressLint
26 | import android.content.Context
27 | import android.view.Gravity
28 | import android.view.MotionEvent
29 | import android.view.View
30 | import android.widget.LinearLayout
31 | import cn.fkj233.ui.R
32 | import cn.fkj233.ui.activity.data.DataBinding
33 | import cn.fkj233.ui.activity.data.LayoutPair
34 | import cn.fkj233.ui.activity.dp2px
35 | import cn.fkj233.ui.activity.fragment.MIUIFragment
36 |
37 | class TextWithSwitchV(private val textV: TextV, private val switchV: SwitchV, private val dataBindingRecv: DataBinding.Binding.Recv? = null) : BaseView {
38 |
39 | override fun getType(): BaseView = this
40 |
41 | override fun create(context: Context, callBacks: (() -> Unit)?): View {
42 | textV.notShowMargins(true)
43 | return LinearContainerV(
44 | LinearContainerV.HORIZONTAL,
45 | arrayOf(
46 | LayoutPair(
47 | textV.create(context, callBacks),
48 | LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
49 | .also { it.gravity = Gravity.CENTER_VERTICAL }
50 | ),
51 | LayoutPair(
52 | switchV.create(context, callBacks),
53 | LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
54 | .also { it.gravity = Gravity.CENTER_VERTICAL })
55 | ), layoutParams = LinearLayout.LayoutParams(
56 | LinearLayout.LayoutParams.MATCH_PARENT,
57 | LinearLayout.LayoutParams.WRAP_CONTENT
58 | ).also {
59 | it.setMargins(0, dp2px(context, 15.75f), 0, dp2px(context, 15.75f))
60 | })
61 | .create(context, callBacks).also {
62 | dataBindingRecv?.setView(it)
63 | }
64 | }
65 |
66 | @SuppressLint("ClickableViewAccessibility")
67 | override fun onDraw(thiz: MIUIFragment, group: LinearLayout, view: View) {
68 | thiz.apply {
69 | group.apply {
70 | addView(view) // 带文本的开关
71 | setOnTouchListener { _, motionEvent ->
72 | when (motionEvent.action) {
73 | MotionEvent.ACTION_DOWN -> if (switchV.switch.isEnabled) background = context.getDrawable(R.drawable.ic_main_down_bg)
74 | MotionEvent.ACTION_UP -> {
75 | val touchX: Float = motionEvent.x
76 | val touchY: Float = motionEvent.y
77 | val maxX = width.toFloat()
78 | val maxY = height.toFloat()
79 | if (touchX < 0 || touchX > maxX || touchY < 0 || touchY > maxY) {
80 | isPressed = false
81 | return@setOnTouchListener false
82 | }
83 | if (switchV.switch.isEnabled) {
84 | switchV.click()
85 | callBacks?.let { it1 -> it1() }
86 | background = context.getDrawable(R.drawable.ic_main_bg)
87 | }
88 | }
89 |
90 | else -> background = context.getDrawable(R.drawable.ic_main_bg)
91 | }
92 | true
93 | }
94 | }
95 | }
96 | }
97 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/RoundCornerImageView.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 | import android.annotation.SuppressLint
26 | import android.content.Context
27 | import android.graphics.*
28 | import android.widget.ImageView
29 |
30 | @SuppressLint("ViewConstructor")
31 | class RoundCornerImageView(context: Context, private val roundWidth: Int = 5, private val roundHeight: Int = 5) : ImageView(context) {
32 | private var paint: Paint? = null
33 | private var paint2: Paint? = null
34 |
35 | init {
36 | paint = Paint()
37 | paint!!.color = Color.WHITE
38 | paint!!.isAntiAlias = true
39 | paint!!.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OUT)
40 | paint2 = Paint()
41 | paint2!!.xfermode = null
42 | }
43 |
44 | override fun draw(canvas: Canvas) {
45 | val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
46 | val canvas2 = Canvas(bitmap)
47 | super.draw(canvas2)
48 | drawLiftUp(canvas2)
49 | drawRightUp(canvas2)
50 | drawLiftDown(canvas2)
51 | drawRightDown(canvas2)
52 | canvas.drawBitmap(bitmap, 0f, 0f, paint2)
53 | bitmap.recycle()
54 | }
55 |
56 | private fun drawLiftUp(canvas: Canvas) {
57 | canvas.drawPath(Path().apply {
58 | moveTo(0f, roundHeight.toFloat())
59 | lineTo(0f, 0f)
60 | lineTo(roundWidth.toFloat(), 0f)
61 | arcTo(
62 | RectF(
63 | 0f,
64 | 0f,
65 | (roundWidth * 2).toFloat(),
66 | (roundHeight * 2).toFloat()
67 | ), -90f, -90f
68 | )
69 | close()
70 | }, paint!!)
71 | }
72 |
73 | private fun drawLiftDown(canvas: Canvas) {
74 | canvas.drawPath(Path().apply {
75 | moveTo(0f, (height - roundHeight).toFloat())
76 | lineTo(0f, height.toFloat())
77 | lineTo(roundWidth.toFloat(), height.toFloat())
78 | arcTo(
79 | RectF(
80 | 0f,
81 | (height - roundHeight * 2).toFloat(),
82 | (0 + roundWidth * 2).toFloat(),
83 | height.toFloat()
84 | ), 90f, 90f
85 | )
86 | close()
87 | }, paint!!)
88 | }
89 |
90 | private fun drawRightDown(canvas: Canvas) {
91 | canvas.drawPath(Path().apply {
92 | moveTo((width - roundWidth).toFloat(), height.toFloat())
93 | lineTo(width.toFloat(), height.toFloat())
94 | lineTo(width.toFloat(), (height - roundHeight).toFloat())
95 | arcTo(
96 | RectF(
97 | (width - roundWidth * 2).toFloat(),
98 | (height - roundHeight * 2).toFloat(),
99 | width.toFloat(),
100 | height.toFloat()
101 | ), 0f, 90f
102 | )
103 | close()
104 | }, paint!!)
105 | }
106 |
107 | private fun drawRightUp(canvas: Canvas) {
108 | canvas.drawPath(Path().apply {
109 | moveTo(width.toFloat(), roundHeight.toFloat())
110 | lineTo(width.toFloat(), 0f)
111 | lineTo((width - roundWidth).toFloat(), 0f)
112 | arcTo(
113 | RectF(
114 | (width - roundWidth * 2).toFloat(),
115 | 0f,
116 | width.toFloat(),
117 | (0 + roundHeight * 2).toFloat()
118 | ), -90f, 90f
119 | )
120 | close()
121 | }, paint!!)
122 | }
123 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/PageV.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 | import android.content.Context
26 | import android.graphics.Typeface
27 | import android.graphics.drawable.Drawable
28 | import android.os.Build
29 | import android.util.TypedValue
30 | import android.view.Gravity
31 | import android.view.View
32 | import android.widget.ImageView
33 | import android.widget.LinearLayout
34 | import android.widget.TextView
35 | import cn.fkj233.ui.R
36 | import cn.fkj233.ui.activity.data.DataBinding
37 | import cn.fkj233.ui.activity.data.LayoutPair
38 | import cn.fkj233.ui.activity.dp2px
39 | import cn.fkj233.ui.activity.fragment.MIUIFragment
40 | import cn.fkj233.ui.activity.isRtl
41 |
42 | class PageV(
43 | private val pageHead: Drawable,
44 | private val pageName: String?,
45 | private val pageNameId: Int?,
46 | private val round: Float = 0f,
47 | private val onClick: (() -> Unit)? = null,
48 | private val dataBindingRecv: DataBinding.Binding.Recv? = null
49 | ) : BaseView {
50 |
51 | override fun getType(): BaseView {
52 | return this
53 | }
54 |
55 | override fun create(context: Context, callBacks: (() -> Unit)?): View {
56 | return LinearContainerV(LinearContainerV.HORIZONTAL, arrayOf(
57 | LayoutPair(
58 | RoundCornerImageView(context, dp2px(context, round), dp2px(context, round)).also {
59 | it.background = pageHead
60 | },
61 | LinearLayout.LayoutParams(
62 | dp2px(context, 30f),
63 | dp2px(context, 30f)
64 | )
65 | ),
66 | LayoutPair(
67 | TextView(context).also {
68 | if (isRtl(context))
69 | it.setPadding(0, 0, dp2px(context, 16f), 0)
70 | else
71 | it.setPadding(dp2px(context, 16f), 0, 0, 0)
72 | it.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
73 | it.setTextColor(context.getColor(R.color.whiteText))
74 | pageName?.let { it1 -> it.text = it1 }
75 | pageNameId?.let { it1 -> it.setText(it1) }
76 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
77 | it.paint.typeface = Typeface.create(null, 500, false)
78 | } else {
79 | it.paint.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
80 | }
81 | },
82 | LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f).also { it.gravity = Gravity.CENTER_VERTICAL }
83 | ),
84 | LayoutPair(
85 | ImageView(context).also { it.background = context.getDrawable(R.drawable.ic_right_arrow) },
86 | LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).also { it.gravity = Gravity.CENTER_VERTICAL })
87 | ), layoutParams = LinearLayout.LayoutParams(
88 | LinearLayout.LayoutParams.MATCH_PARENT,
89 | LinearLayout.LayoutParams.WRAP_CONTENT
90 | ).also {
91 | it.setMargins(0, dp2px(context, 14.8f), 0, dp2px(context, 14.8f))
92 | }).create(context, callBacks).also {
93 | dataBindingRecv?.setView(it)
94 | }
95 | }
96 |
97 | override fun onDraw(thiz: MIUIFragment, group: LinearLayout, view: View) {
98 | thiz.apply {
99 | group.apply {
100 | addView(view)
101 | onClick?.let { unit ->
102 | setOnClickListener {
103 | unit()
104 | callBacks?.let { it1 -> it1() }
105 | }
106 | }
107 | }
108 | }
109 | }
110 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/TextV.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 |
26 | import android.content.Context
27 | import android.graphics.Typeface
28 | import android.os.Build
29 | import android.util.TypedValue
30 | import android.view.Gravity
31 | import android.view.View
32 | import android.widget.LinearLayout
33 | import android.widget.TextView
34 | import cn.fkj233.ui.R
35 | import cn.fkj233.ui.activity.data.DataBinding
36 | import cn.fkj233.ui.activity.data.Padding
37 | import cn.fkj233.ui.activity.dp2px
38 | import cn.fkj233.ui.activity.fragment.MIUIFragment
39 | import cn.fkj233.ui.activity.isRtl
40 |
41 | class TextV(val text: String? = null, private val textId: Int? = null, val textSize: Float? = null, private val colorInt: Int? = null, private val colorId: Int? = null, private val padding: Padding? = null, private val dataBindingRecv: DataBinding.Binding.Recv? = null, private val typeface: Typeface? = null, val onClickListener: (() -> Unit)? = null): BaseView {
42 |
43 | private var notShowMargins = false
44 |
45 | override fun getType(): BaseView = this
46 |
47 | fun notShowMargins(boolean: Boolean) {
48 | notShowMargins = boolean
49 | }
50 |
51 | override fun create(context: Context, callBacks: (() -> Unit)?): View {
52 | return TextView(context).also { view ->
53 | view.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
54 | text?.let { view.text = it }
55 | view.gravity = if (isRtl(context)) Gravity.RIGHT else Gravity.LEFT
56 | textId?.let { view.setText(it) }
57 | if (textSize == null)
58 | view.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
59 | else
60 | view.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize)
61 | colorInt?.let { view.setTextColor(colorInt) }
62 | colorId?.let { view.setTextColor(context.getColor(colorId)) }
63 | if (colorId == null && colorInt == null) {
64 | view.setTextColor(context.getColor(R.color.whiteText))
65 | }
66 | if (typeface == null) {
67 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
68 | view.paint.typeface = Typeface.create(null, 500, false)
69 | } else {
70 | view.paint.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
71 | }
72 | } else {
73 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
74 | view.paint.typeface = typeface
75 | } else {
76 | view.paint.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
77 | }
78 | }
79 | if (!notShowMargins) {
80 | if (isRtl(context)) view.setPadding(dp2px(context, 5f), dp2px(context, 20f), 0, dp2px(context, 20f))
81 | else view.setPadding(0, dp2px(context, 20f), dp2px(context, 5f), dp2px(context, 20f))
82 | }
83 | padding?.let {
84 | if (isRtl(context))
85 | view.setPadding(it.right, it.top, it.left, it.bottom)
86 | else
87 | view.setPadding(it.left, it.top, it.right, it.bottom)
88 | }
89 | dataBindingRecv?.setView(view)
90 | }
91 | }
92 |
93 | override fun onDraw(thiz: MIUIFragment, group: LinearLayout, view: View) {
94 | thiz.apply {
95 | group.apply {
96 | addView(view)
97 | onClickListener?.let { unit ->
98 | setOnClickListener {
99 | unit()
100 | callBacks?.let { it1 -> it1() }
101 | }
102 | }
103 | }
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/SpinnerV.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 | import android.content.Context
26 | import android.graphics.Typeface
27 | import android.os.Build
28 | import android.util.TypedValue
29 | import android.view.Gravity
30 | import android.view.View
31 | import android.view.ViewGroup
32 | import android.widget.ImageView
33 | import android.widget.LinearLayout
34 | import android.widget.TextView
35 | import cn.fkj233.ui.R
36 | import cn.fkj233.ui.activity.data.DataBinding
37 | import cn.fkj233.ui.activity.data.LayoutPair
38 | import cn.fkj233.ui.activity.data.MIUIPopupData
39 | import cn.fkj233.ui.activity.dp2px
40 | import cn.fkj233.ui.activity.isRtl
41 |
42 | /**
43 | * Spinner / 下拉框
44 | * @param currentValue current select value / 当前选中的值 (name)
45 | * @param dropDownWidth Spinner width / 下拉框宽度
46 | * @param dataBindingSend Data binding send / 数据绑定发送 (name)
47 | * @param dataBindingRecv Data binding recv / 数据绑定接收
48 | * @param data Spinner data / 下拉框数据
49 | */
50 | class SpinnerV(var currentValue: String, val dropDownWidth: Float = 150F, val dataBindingSend: DataBinding.Binding.Send? = null, private val dataBindingRecv: DataBinding.Binding.Recv? = null, val data: SpinnerData.() -> Unit): BaseView {
51 |
52 | class SpinnerData {
53 | val arrayList: ArrayList = arrayListOf()
54 |
55 | fun add(name: String, dataBindingSend: DataBinding.Binding.Send? = null, callBacks: () -> Unit) {
56 | arrayList.add(MIUIPopupData(name, dataBindingSend, callBacks))
57 | }
58 | }
59 |
60 | private lateinit var context: Context
61 |
62 | lateinit var select: TextView
63 |
64 | override fun getType(): BaseView = this
65 |
66 | override fun create(context: Context, callBacks: (() -> Unit)?): View {
67 | this.context = context
68 | return LinearContainerV(
69 | LinearContainerV.HORIZONTAL,
70 | arrayOf(
71 | LayoutPair(
72 | TextView(context).also {
73 | it.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12f)
74 | it.gravity = if (isRtl(context)) Gravity.LEFT else Gravity.RIGHT
75 | it.text = currentValue
76 | it.setTextColor(context.getColor(R.color.spinner))
77 | select = it
78 | it.width = dp2px(context, dropDownWidth)
79 | if (isRtl(context))
80 | it.setPadding(dp2px(context, 5f), 0, dp2px(context, 30f), 0)
81 | else
82 | it.setPadding(dp2px(context, 30f), 0, dp2px(context, 5f), 0)
83 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
84 | it.paint.typeface = Typeface.create(null, 400, false)
85 | } else {
86 | it.paint.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
87 | }
88 | it.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15f)
89 | },
90 | LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
91 | ),
92 | LayoutPair(
93 | ImageView(context).also {
94 | it.background = context.getDrawable(R.drawable.ic_up_down)
95 | },
96 | LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).also { it.gravity = Gravity.CENTER_VERTICAL }
97 | )
98 | ),
99 | descendantFocusability = ViewGroup.FOCUS_BLOCK_DESCENDANTS,
100 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f).also { it.gravity = Gravity.CENTER_VERTICAL }
101 | ).create(context, callBacks).also {
102 | dataBindingRecv?.setView(it)
103 | }
104 | }
105 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/TextSummaryV.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 | import android.content.Context
26 | import android.graphics.Typeface
27 | import android.os.Build
28 | import android.util.TypedValue
29 | import android.view.Gravity
30 | import android.view.View
31 | import android.widget.LinearLayout
32 | import android.widget.TextView
33 | import cn.fkj233.ui.R
34 | import cn.fkj233.ui.activity.data.DataBinding
35 | import cn.fkj233.ui.activity.data.LayoutPair
36 | import cn.fkj233.ui.activity.dp2px
37 | import cn.fkj233.ui.activity.fragment.MIUIFragment
38 | import cn.fkj233.ui.activity.isRtl
39 |
40 | class TextSummaryV(private val text: String? = null, private val textId: Int? = null, private val tips: String? = null, private val colorInt: Int? = null, private val colorId: Int? = null, private val tipsId: Int? = null, private val dataBindingRecv: DataBinding.Binding.Recv? = null, val onClickListener: (() -> Unit)? = null): BaseView {
41 |
42 | private var notShowMargins = false
43 |
44 | override fun getType(): BaseView {
45 | return this
46 | }
47 |
48 | fun notShowMargins(boolean: Boolean) {
49 | notShowMargins = boolean
50 | }
51 |
52 | override fun create(context: Context, callBacks: (() -> Unit)?): View {
53 | return LinearContainerV(LinearContainerV.VERTICAL, arrayOf(
54 | LayoutPair(
55 | TextView(context).also { view ->
56 | view.setTextSize(TypedValue.COMPLEX_UNIT_SP, if (text == null && textId == null) 15f else 18.25f)
57 | view.gravity = if (isRtl(context)) Gravity.RIGHT else Gravity.LEFT
58 | colorInt?.let { view.setTextColor(colorInt) }
59 | colorId?.let { view.setTextColor(context.getColor(colorId)) }
60 | if (colorId == null && colorInt == null) {
61 | view.setTextColor(context.getColor(R.color.whiteText))
62 | }
63 | text?.let { it1 -> view.text = it1 }
64 | textId?.let { it1 -> view.setText(it1) }
65 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
66 | view.paint.typeface = Typeface.create(null, 500,false)
67 | } else {
68 | view.paint.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
69 | }
70 | },
71 | LinearLayout.LayoutParams(
72 | LinearLayout.LayoutParams.MATCH_PARENT,
73 | LinearLayout.LayoutParams.MATCH_PARENT
74 | )
75 | ),
76 | LayoutPair(
77 | TextView(context).also {
78 | it.gravity = if (isRtl(context)) Gravity.RIGHT else Gravity.LEFT
79 | it.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13.75f)
80 | it.setTextColor(context.getColor(R.color.author_tips))
81 | if (tips == null && tipsId == null) {
82 | it.visibility = View.GONE
83 | } else {
84 | tips?.let { it1 -> it.text = it1 }
85 | tipsId?.let { it1 -> it.setText(it1) }
86 | }
87 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
88 | it.paint.typeface = Typeface.create(null, 350,false)
89 | } else {
90 | it.paint.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
91 | }
92 | },
93 | LinearLayout.LayoutParams(
94 | LinearLayout.LayoutParams.MATCH_PARENT,
95 | LinearLayout.LayoutParams.MATCH_PARENT
96 | )
97 | )
98 | ), layoutParams = LinearLayout.LayoutParams(
99 | LinearLayout.LayoutParams.MATCH_PARENT,
100 | LinearLayout.LayoutParams.WRAP_CONTENT
101 | ).also {
102 | if (!notShowMargins) it.setMargins(0, dp2px(context, 15f),0, dp2px(context, 15f))
103 | }).create(context, callBacks).also {
104 | dataBindingRecv?.setView(it)
105 | }
106 | }
107 |
108 | override fun onDraw(thiz: MIUIFragment, group: LinearLayout, view: View) {
109 | thiz.apply {
110 | group.apply {
111 | addView(view)
112 | onClickListener?.let { unit ->
113 | setOnClickListener {
114 | unit()
115 | callBacks?.let { it1 -> it1() }
116 | }
117 | }
118 | }
119 | }
120 | }
121 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/SeekBarWithTextV.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 | import android.annotation.TargetApi
26 | import android.content.Context
27 | import android.graphics.Typeface
28 | import android.os.Build
29 | import android.view.View
30 | import android.view.ViewGroup
31 | import android.widget.LinearLayout
32 | import android.widget.SeekBar
33 | import android.widget.TextView
34 | import cn.fkj233.ui.R
35 | import cn.fkj233.ui.activity.MIUIActivity
36 | import cn.fkj233.ui.activity.data.DataBinding
37 | import cn.fkj233.ui.activity.data.LayoutPair
38 | import cn.fkj233.ui.activity.dp2px
39 | import cn.fkj233.ui.activity.fragment.MIUIFragment
40 |
41 | class SeekBarWithTextV(val key: String = "", private val min: Int, private val max: Int, private val defaultProgress: Int = 0, private val dataBindingRecv: DataBinding.Binding.Recv? = null, private val dataBindingSend: DataBinding.Binding.Send? = null, val callBacks: ((Int, TextView) -> Unit)? = null) : BaseView {
42 |
43 | override fun getType(): BaseView = this
44 |
45 | @TargetApi(Build.VERSION_CODES.P)
46 | override fun create(context: Context, callBack: (() -> Unit)?): View {
47 | val minText = TextV(min.toString(), textSize = 13f, colorId = R.color.author_tips, typeface = Typeface.create(null, 400, false)).create(context, null)
48 | val maxText = TextV(max.toString(), textSize = 13f, colorId = R.color.author_tips, typeface = Typeface.create(null, 400, false)).create(context, null)
49 | val mutableText = TextV("", textSize = 13f, colorId = R.color.author_tips, typeface = Typeface.create(null, 400, false)).create(context, null)
50 | val seekBar = SeekBar(context).also { view ->
51 | view.thumb = null
52 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
53 | view.maxHeight = dp2px(context, 31f)
54 | view.minHeight = dp2px(context, 31f)
55 | }
56 | view.isIndeterminate = false
57 | view.progressDrawable = context.getDrawable(R.drawable.seekbar_progress_drawable)
58 | view.indeterminateDrawable = context.getDrawable(R.color.colorAccent)
59 | view.min = min
60 | view.max = max
61 | view.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
62 | if (MIUIActivity.safeSP.containsKey(key)) {
63 | MIUIActivity.safeSP.getInt(key, defaultProgress).let {
64 | view.progress = it
65 | (mutableText as TextView).text = it.toString()
66 | }
67 | } else {
68 | view.progress = defaultProgress
69 | (mutableText as TextView).text = defaultProgress.toString()
70 | MIUIActivity.safeSP.putAny(key, defaultProgress)
71 | }
72 | view.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
73 | override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
74 | dataBindingSend?.send(p1)
75 | (mutableText as TextView).text = p1.toString()
76 | MIUIActivity.safeSP.putAny(key, p1)
77 | callBacks?.let { it(p1, mutableText) }
78 | }
79 |
80 | override fun onStartTrackingTouch(p0: SeekBar?) {}
81 | override fun onStopTrackingTouch(p0: SeekBar?) {}
82 | })
83 | }
84 | return LinearContainerV(LinearContainerV.VERTICAL, arrayOf(LayoutPair(seekBar.also { it.setPadding(0, 0, 0, 0) }, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)), LayoutPair(LinearContainerV(LinearContainerV.HORIZONTAL, arrayOf(LayoutPair(minText.also { it.setPadding(0, dp2px(context, 5f), 0, dp2px(context, 17.75f)) }, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)), LayoutPair(mutableText.also { it.textAlignment = TextView.TEXT_ALIGNMENT_CENTER; it.setPadding(0, dp2px(context, 5f), 0, dp2px(context, 17.75f)) }, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)), LayoutPair(maxText.also { it.textAlignment = TextView.TEXT_ALIGNMENT_VIEW_END; it.setPadding(0, dp2px(context, 5f), 0, dp2px(context, 17.75f)) }, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)))).create(context, callBack).also { it.setPadding(0, 0, 0, 0) }, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)))).create(context, null).also {
85 | dataBindingRecv?.setView(it)
86 | }
87 | }
88 |
89 | override fun onDraw(thiz: MIUIFragment, group: LinearLayout, view: View) {
90 | thiz.apply {
91 | group.apply {
92 | addView(view, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT))
93 | }
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/data/InitView.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("FunctionName")
2 |
3 | package cn.fkj233.ui.activity.data
4 |
5 | import android.graphics.Typeface
6 | import android.graphics.drawable.Drawable
7 | import android.view.View
8 | import android.widget.TextView
9 | import cn.fkj233.ui.activity.view.*
10 |
11 | @Deprecated("Use BMMainPage/BMMenuPage/BMPage instead")
12 | class InitView(private val datalist: HashMap) {
13 | var isMenu = false
14 | var mainShowBack = false
15 |
16 | inner class ItemData(val title: String, val hideMenu: Boolean) {
17 | val itemList: ArrayList = arrayListOf()
18 | var bindingData = arrayListOf()
19 | var async: AsyncInit? = null
20 |
21 | fun GetDataBinding(defValue: () -> Any, recvCallbacks: (View, Int, Any) -> Unit): DataBinding.BindingData {
22 | return DataBinding.get(bindingData, defValue, recvCallbacks)
23 | }
24 |
25 | fun Author(authorHead: Drawable, authorName: String, authorTips: String? = null, round: Float = 30f, onClickListener: (() -> Unit)? = null, dataBindingRecv: DataBinding.Binding.Recv? = null) {
26 | itemList.add(ImageTextV(authorHead, authorName, authorTips, round, onClickListener, dataBindingRecv))
27 | }
28 |
29 | fun Page(pageHead: Drawable, pageName: String?, pageNameId: Int?, round: Float = 0f, onClickListener: (() -> Unit)? = null, dataBindingRecv: DataBinding.Binding.Recv? = null) {
30 | itemList.add(PageV(pageHead, pageName, pageNameId, round, onClickListener, dataBindingRecv))
31 | }
32 |
33 | fun Line() {
34 | itemList.add(LineV())
35 | }
36 |
37 | fun SeekBar(key: String, min: Int, max: Int, defaultProgress: Int, dataSend: DataBinding.Binding.Send? = null, dataBindingRecv: DataBinding.Binding.Recv? = null, callBacks: ((Int, TextView) -> Unit)? = null) {
38 | itemList.add(SeekBarV(key, min, max, defaultProgress, dataSend, dataBindingRecv, callBacks))
39 | }
40 |
41 | fun TextSummaryWithSpinner(textV: TextSummaryV, spinnerV: SpinnerV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
42 | itemList.add(TextSummaryWithSpinnerV(textV, spinnerV, dataBindingRecv))
43 | }
44 |
45 | fun Text(text: String? = null, textId: Int? = null, textSize: Float? = null, colorInt: Int? = null, colorId: Int? = null, padding: Padding? = null, dataBindingRecv: DataBinding.Binding.Recv? = null, typeface: Typeface? = null, onClickListener: (() -> Unit)? = null) {
46 | itemList.add(TextV(text, textId, textSize, colorInt, colorId, padding, dataBindingRecv, typeface, onClickListener))
47 | }
48 |
49 | fun SeekBarWithText(key: String = "", min: Int, max: Int, defaultProgress: Int = 0, dataBindingRecv: DataBinding.Binding.Recv? = null, dataBindingSend: DataBinding.Binding.Send? = null, callBacks: ((Int, TextView) -> Unit)? = null) {
50 | itemList.add(SeekBarWithTextV(key, min, max, defaultProgress, dataBindingRecv, dataBindingSend, callBacks))
51 | }
52 |
53 | fun TextSummaryArrow(textSummaryV: TextSummaryV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
54 | itemList.add(TextSummaryWithArrowV(textSummaryV, dataBindingRecv))
55 | }
56 |
57 | fun TextA(text: String? = null, textId: Int? = null, onClickListener: (() -> Unit)? = null, dataBindingRecv: DataBinding.Binding.Recv? = null) {
58 | itemList.add(TextSummaryWithArrowV(TextSummaryV(text, textId, onClickListener = onClickListener), dataBindingRecv))
59 | }
60 |
61 | fun TextSummaryWithSwitch(textSummaryV: TextSummaryV, switchV: SwitchV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
62 | itemList.add(TextSummaryWithSwitchV(textSummaryV, switchV, dataBindingRecv))
63 | }
64 |
65 | fun TitleText(text: String? = null, textId: Int? = null,colorInt: Int? = null, colorId: Int? = null, dataBindingRecv: DataBinding.Binding.Recv? = null, onClickListener: (() -> Unit)? = null) {
66 | itemList.add(TitleTextV(text, textId,colorInt, colorId,dataBindingRecv, onClickListener))
67 | }
68 |
69 | fun TextWithSwitch(textV: TextV, switchV: SwitchV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
70 | itemList.add(TextWithSwitchV(textV, switchV, dataBindingRecv))
71 | }
72 |
73 | fun TextS(text: String? = null, textId: Int? = null, key: String, defValue: Boolean=false, onClickListener: ((Boolean) -> Unit)? = null, dataBindingRecv: DataBinding.Binding.Recv? = null) {
74 | itemList.add(TextWithSwitchV(TextV(text, textId), SwitchV(key, defValue, onClickListener = onClickListener), dataBindingRecv))
75 | }
76 |
77 | fun TextWithSpinner(textV: TextV, spinnerV: SpinnerV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
78 | itemList.add(TextWithSpinnerV(textV, spinnerV, dataBindingRecv))
79 | }
80 |
81 | fun CustomView(view: View, dataBindingRecv: DataBinding.Binding.Recv? = null) {
82 | itemList.add(CustomViewV(view, dataBindingRecv))
83 | }
84 |
85 | fun RadioView(key: String, dataBindingRecv: DataBinding.Binding.Recv? = null, data: RadioViewV.RadioData.() -> Unit) {
86 | itemList.add(RadioViewV(key, dataBindingRecv, data))
87 | }
88 |
89 | fun TextSummary(text: String? = null, textId: Int? = null, tips: String? = null, colorInt: Int? = null, colorId: Int? = null, tipsId: Int? = null, dataBindingRecv: DataBinding.Binding.Recv? = null, onClickListener: (() -> Unit)? = null) {
90 | itemList.add(TextSummaryV(text, textId, tips, colorInt, colorId, tipsId, dataBindingRecv, onClickListener))
91 | }
92 | }
93 |
94 | fun registerMain(title: String, showBack: Boolean, itemData: ItemData.() -> Unit) {
95 | datalist["Main"] = ItemData(title, false).apply(itemData)
96 | mainShowBack = showBack
97 | }
98 |
99 | fun registerMenu(title: String, itemData: ItemData.() -> Unit) {
100 | datalist["Menu"] = ItemData(title, true).apply(itemData)
101 | isMenu = true
102 | }
103 |
104 | fun register(key: String, title: String, hideMenu: Boolean, itemData: ItemData.() -> Unit) {
105 | if (key in arrayOf("Main", "Menu")) throw Throwable("[$key] This is reserved and cannot be used!")
106 | datalist[key] = ItemData(title, hideMenu).apply(itemData)
107 | }
108 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/fragment/MIUIFragment.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | @file:Suppress("DEPRECATION", "DuplicatedCode")
24 |
25 | package cn.fkj233.ui.activity.fragment
26 |
27 | import android.annotation.SuppressLint
28 | import android.app.Dialog
29 | import android.app.Fragment
30 | import android.os.Bundle
31 | import android.os.Handler
32 | import android.os.Looper
33 | import android.view.LayoutInflater
34 | import android.view.View
35 | import android.view.ViewGroup
36 | import android.view.animation.AnimationSet
37 | import android.view.animation.LinearInterpolator
38 | import android.view.animation.RotateAnimation
39 | import android.widget.ImageView
40 | import android.widget.LinearLayout
41 | import android.widget.RelativeLayout
42 | import android.widget.ScrollView
43 | import androidx.annotation.Keep
44 | import cn.fkj233.ui.R
45 | import cn.fkj233.ui.activity.MIUIActivity
46 | import cn.fkj233.ui.activity.data.AsyncInit
47 | import cn.fkj233.ui.activity.dp2px
48 | import cn.fkj233.ui.activity.view.BaseView
49 |
50 | @Suppress("MemberVisibilityCanBePrivate")
51 | @SuppressLint("ValidFragment")
52 | @Keep
53 | class MIUIFragment() : Fragment() {
54 | private var key = ""
55 | private lateinit var scrollView: ScrollView
56 | private lateinit var itemView: LinearLayout
57 | val callBacks: (() -> Unit)? by lazy { MIUIActivity.activity.getAllCallBacks() }
58 | private val async: AsyncInit? by lazy { MIUIActivity.activity.getThisAsync(key.ifEmpty { MIUIActivity.activity.getTopPage() }) }
59 | private var dialog: Dialog? = null
60 | val handler: Handler by lazy { Handler(Looper.getMainLooper()) }
61 |
62 | constructor(keys: String) : this() {
63 | key = keys
64 | }
65 |
66 | @Deprecated("Deprecated in Java")
67 | override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View {
68 | scrollView = ScrollView(context).apply {
69 | isVerticalScrollBarEnabled = false
70 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
71 | isFillViewport = true
72 | addView(LinearLayout(context).apply { // 总布局
73 | layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
74 | orientation = LinearLayout.VERTICAL
75 | background = context.getDrawable(R.color.foreground)
76 | itemView = this
77 | if (async?.skipLoadItem != true) initData()
78 | })
79 | }
80 | async?.let { Thread { it.onInit(this) }.start() }
81 | return scrollView
82 | }
83 |
84 | /**
85 | * 如果 skipLoadItem 为 true 则需要手动调用 / If skipLoadItem is true, it needs to be called manually
86 | */
87 | @Suppress("MemberVisibilityCanBePrivate")
88 | fun initData() {
89 | for (item: BaseView in MIUIActivity.activity.getThisItems(key.ifEmpty { MIUIActivity.activity.getTopPage() })) {
90 | addItem(item)
91 | }
92 | }
93 |
94 | /**
95 | * Show loading dialog / 显示加载 Dialog
96 | */
97 | fun showLoading() {
98 | handler.post {
99 | dialog = Dialog(MIUIActivity.context, R.style.Translucent_NoTitle).apply {
100 | setCancelable(false)
101 | setContentView(LinearLayout(context).apply {
102 | layoutParams = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)
103 | addView(ImageView(context).apply {
104 | layoutParams = LinearLayout.LayoutParams(dp2px(context, 60f), dp2px(context, 60f))
105 | .also { it.setMargins(dp2px(context, 20f), dp2px(context, 20f), dp2px(context, 20f), dp2px(context, 20f)) }
106 | background = context.getDrawable(R.drawable.ic_loading)
107 | startAnimation(AnimationSet(true).apply {
108 | interpolator = LinearInterpolator()
109 | addAnimation(RotateAnimation(0f, +359f, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f).apply {
110 | repeatCount = -1
111 | startOffset = 0
112 | duration = 1000
113 | })
114 | })
115 | })
116 | })
117 | }
118 | dialog?.show()
119 | }
120 | }
121 |
122 | /**
123 | * Close loading dialog / 关闭加载 Dialog
124 | */
125 | fun closeLoading() {
126 | handler.post { dialog?.dismiss() }
127 | }
128 |
129 | /**
130 | * Add view / 添加控件
131 | */
132 | @SuppressLint("ClickableViewAccessibility")
133 | fun addItem(item: BaseView) {
134 | handler.post {
135 | itemView.addView(LinearLayout(MIUIActivity.context).apply { // 控件布局
136 | layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
137 | background = context.getDrawable(R.drawable.ic_click_check)
138 | setPadding(dp2px(context, 30f), 0, dp2px(context, 30f), 0)
139 | item.onDraw(this@MIUIFragment, this, item.create(context, callBacks))
140 | })
141 | }
142 | }
143 |
144 | /**
145 | * Clear all view / 清除所有控件
146 | */
147 | fun clearAll() {
148 | handler.post {
149 | itemView.removeAllViews()
150 | }
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/ImageTextV.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 | import android.content.Context
26 | import android.graphics.Typeface
27 | import android.graphics.drawable.Drawable
28 | import android.os.Build
29 | import android.util.TypedValue
30 | import android.view.Gravity
31 | import android.view.View
32 | import android.widget.ImageView
33 | import android.widget.LinearLayout
34 | import android.widget.TextView
35 | import cn.fkj233.ui.R
36 | import cn.fkj233.ui.activity.data.DataBinding
37 | import cn.fkj233.ui.activity.data.LayoutPair
38 | import cn.fkj233.ui.activity.dp2px
39 | import cn.fkj233.ui.activity.fragment.MIUIFragment
40 | import cn.fkj233.ui.activity.isRtl
41 |
42 | class ImageTextV(private val authorHead: Drawable, private val authorName: String, private val authorTips: String? = null, private val round: Float = 30f, private val onClick: (() -> Unit)? = null, private val dataBindingRecv: DataBinding.Binding.Recv? = null): BaseView {
43 |
44 | override fun getType(): BaseView {
45 | return this
46 | }
47 |
48 | override fun create(context: Context, callBacks: (() -> Unit)?): View {
49 | return LinearContainerV(LinearContainerV.HORIZONTAL, arrayOf(
50 | LayoutPair(
51 | RoundCornerImageView(context, dp2px(context, round), dp2px(context, round)).also {
52 | it.setPadding(0, dp2px(context, 10f), 0, dp2px(context, 10f))
53 | it.background = authorHead
54 | },
55 | LinearLayout.LayoutParams(
56 | dp2px(context, 60f),
57 | dp2px(context, 60f)
58 | )
59 | ),
60 | LayoutPair(
61 | LinearContainerV(
62 | LinearContainerV.VERTICAL, arrayOf(
63 | LayoutPair(
64 | TextView(context).also {
65 | if (isRtl(context))
66 | it.setPadding(0, dp2px(context, if (authorTips == null) 17f else 5f), dp2px(context, 15f), 0)
67 | else
68 | it.setPadding(dp2px(context, 15f), dp2px(context, if (authorTips == null) 17f else 5f), 0, 0)
69 | it.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
70 | it.setTextColor(context.getColor(R.color.whiteText))
71 | it.text = authorName
72 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
73 | it.paint.typeface = Typeface.create(null, 500,false)
74 | } else {
75 | it.paint.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
76 | }
77 | },
78 | LinearLayout.LayoutParams(
79 | LinearLayout.LayoutParams.MATCH_PARENT,
80 | LinearLayout.LayoutParams.MATCH_PARENT
81 | )
82 | ),
83 | LayoutPair(
84 | TextView(context).also {
85 | if (isRtl(context))
86 | it.setPadding(0, 0, dp2px(context, 16f), 0)
87 | else
88 | it.setPadding(dp2px(context, 16f), 0, 0, 0)
89 | it.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13f)
90 | it.setTextColor(context.getColor(R.color.author_tips))
91 | if (authorTips == null) {
92 | it.visibility = View.GONE
93 | } else {
94 | it.text = authorTips
95 | }
96 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
97 | it.paint.typeface = Typeface.create(null, 400,false)
98 | } else {
99 | it.paint.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
100 | }
101 | },
102 | LinearLayout.LayoutParams(
103 | LinearLayout.LayoutParams.MATCH_PARENT,
104 | LinearLayout.LayoutParams.MATCH_PARENT
105 | )
106 | )
107 | )).create(context, callBacks),
108 | LinearLayout.LayoutParams(
109 | 0,
110 | LinearLayout.LayoutParams.WRAP_CONTENT,
111 | 1f
112 | )
113 | ),
114 | LayoutPair(
115 | ImageView(context).also {
116 | it.background = context.getDrawable(R.drawable.ic_right_arrow)
117 | },
118 | LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
119 | it.gravity = Gravity.CENTER_VERTICAL
120 | if (isRtl(context)) it.setMargins(0, 0, dp2px(context, 5f), 0)
121 | }
122 | )
123 | ), layoutParams = LinearLayout.LayoutParams(
124 | LinearLayout.LayoutParams.MATCH_PARENT,
125 | LinearLayout.LayoutParams.WRAP_CONTENT
126 | ).also {
127 | it.setMargins(0, dp2px(context, 10f), 0, dp2px(context, 10f))
128 | }).create(context, callBacks).also {
129 | dataBindingRecv?.setView(it)
130 | }
131 | }
132 |
133 | override fun onDraw(thiz: MIUIFragment, group: LinearLayout, view: View) {
134 | thiz.apply {
135 | group.apply {
136 | addView(view)
137 | onClick?.let { unit ->
138 | setOnClickListener {
139 | unit()
140 | callBacks?.let { it1 -> it1() }
141 | }
142 | }
143 | }
144 | }
145 | }
146 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/view/MIUIPopup.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.activity.view
24 |
25 | import android.content.Context
26 | import android.graphics.Typeface
27 | import android.graphics.drawable.GradientDrawable
28 | import android.graphics.drawable.StateListDrawable
29 | import android.text.TextUtils
30 | import android.util.TypedValue
31 | import android.view.Gravity
32 | import android.view.View
33 | import android.view.ViewGroup
34 | import android.widget.*
35 | import cn.fkj233.ui.R
36 | import cn.fkj233.ui.activity.data.MIUIPopupData
37 | import cn.fkj233.ui.activity.dp2px
38 | import cn.fkj233.ui.activity.isRtl
39 |
40 |
41 | class MIUIPopup(private val context: Context, view: View, private val currentValue: String, private val dropDownWidth: Float, private val dataBacks: (String) -> Unit, private val arrayList: ArrayList): ListPopupWindow(context) {
42 |
43 | /**
44 | * 创建背景颜色
45 | *
46 | * @param color 填充色
47 | * @param strokeColor 线条颜色
48 | * @param strokeWidth 线条宽度 单位px
49 | * @param radius 角度 px,长度为4,分别表示左上,右上,右下,左下的角度
50 | */
51 | fun createRectangleDrawable(color: Int, strokeColor: Int = 0, strokeWidth: Int, radius: FloatArray?): GradientDrawable {
52 | return try {
53 | GradientDrawable().apply {
54 | shape = GradientDrawable.RECTANGLE
55 | setColor(color)
56 | if (strokeColor != 0) setStroke(strokeWidth, strokeColor)
57 | if (radius != null && radius.size == 4) {
58 | cornerRadii = floatArrayOf(
59 | radius[0], radius[0], radius[1],
60 | radius[1], radius[2], radius[2],
61 | radius[3], radius[3]
62 | )
63 | }
64 | }
65 | } catch (e: Exception) {
66 | GradientDrawable()
67 | }
68 | }
69 |
70 | /**
71 | * 创建点击颜色
72 | *
73 | * @param pressedDrawable 点击颜色
74 | * @param normalDrawable 正常颜色
75 | */
76 | fun createStateListDrawable(pressedDrawable: GradientDrawable, normalDrawable: GradientDrawable): StateListDrawable {
77 | return StateListDrawable().apply {
78 | addState(intArrayOf(android.R.attr.state_focused), pressedDrawable)
79 | addState(intArrayOf(android.R.attr.state_pressed), pressedDrawable)
80 | addState(intArrayOf(-android.R.attr.state_focused), normalDrawable)
81 | }
82 | }
83 |
84 |
85 | init {
86 | setBackgroundDrawable(context.getDrawable(R.drawable.miui_rounded_corners_pop))
87 | width = dp2px(context, dropDownWidth)
88 | height = ViewGroup.LayoutParams.WRAP_CONTENT
89 | isModal = true
90 | anchorView = view
91 |
92 | setAdapter(object: BaseAdapter() {
93 | override fun getCount(): Int = arrayList.size
94 |
95 | override fun getItem(p0: Int): Any = arrayList[p0]
96 |
97 | override fun getItemId(p0: Int): Long = p0.toLong()
98 |
99 | override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
100 | val thisText = arrayList[p0].getName()
101 | val dataBinding = arrayList[p0].getDataBindingSend()
102 | return (p1 as? LinearLayout ?: LinearLayout(context)).apply {
103 | var radius = floatArrayOf(0f, 0f, 0f, 0f)
104 | val radiusFloat = dp2px(context, 20f).toFloat()
105 | if (arrayList.size == 1)
106 | radius = floatArrayOf(radiusFloat, radiusFloat, radiusFloat, radiusFloat)
107 | else when (p0) {
108 | 0 -> {
109 | radius = floatArrayOf(radiusFloat, radiusFloat, 0f, 0f)
110 | }
111 | arrayList.size - 1 -> {
112 | radius = floatArrayOf(0f, 0f, radiusFloat, radiusFloat)
113 | }
114 | }
115 | val pressedDrawable = createRectangleDrawable(context.getColor(if (currentValue == thisText) R.color.popup_select_click else R.color.popup_background_click), 0, 0, radius)
116 | val normalDrawable = createRectangleDrawable(context.getColor(if (currentValue == thisText) R.color.popup_select else R.color.popup_background), 0, 0, radius)
117 | background = createStateListDrawable(pressedDrawable, normalDrawable)
118 | removeAllViews()
119 | addView((object : TextView(context) {
120 | init {
121 | isFocusable = true
122 | }
123 |
124 | override fun isFocused(): Boolean {
125 | return true
126 | }
127 |
128 | }).apply {
129 | layoutParams = LinearLayout.LayoutParams(dp2px(context, dropDownWidth - 35), LinearLayout.LayoutParams.WRAP_CONTENT)
130 | descendantFocusability = LinearContainerV.FOCUS_BLOCK_DESCENDANTS
131 | setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
132 | if (isRtl(context))
133 | setPadding(dp2px(context, 10f), dp2px(context, 25f), dp2px(context, 25f), dp2px(context, 25f))
134 | else
135 | setPadding(dp2px(context, 25f), dp2px(context, 25f), dp2px(context, 10f), dp2px(context, 25f))
136 | width = dp2px(context, 105f)
137 | isSingleLine = true
138 | text = thisText
139 | ellipsize = TextUtils.TruncateAt.MARQUEE
140 | paint.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
141 | if (currentValue == thisText) setTextColor(context.getColor(R.color.popup_select_text)) else setTextColor(context.getColor(R.color.whiteText))
142 | })
143 | addView(ImageView(context).apply {
144 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
145 | it.gravity = Gravity.CENTER_VERTICAL
146 | if (isRtl(context))
147 | it.setMargins(dp2px(context, 20f), 0, 0, 0)
148 | else
149 | it.setMargins(0, 0, dp2px(context, 20f), 0)
150 | }
151 | background = context.getDrawable(R.drawable.ic_popup_select)
152 | if (currentValue != thisText) visibility = View.GONE
153 | })
154 | setOnClickListener {
155 | (it as ViewGroup).apply {
156 | for (i in 0 until childCount) {
157 | val mView = getChildAt(i)
158 | if (mView is TextView) {
159 | dataBacks(mView.text.toString())
160 | dataBinding?.send(mView.text.toString())
161 | break
162 | }
163 | }
164 | }
165 | arrayList[p0].getCallBacks()()
166 | dismiss()
167 | }
168 | }
169 | }
170 | })
171 | }
172 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/data/BasePage.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("FunctionName")
2 |
3 | package cn.fkj233.ui.activity.data
4 |
5 | import android.graphics.Typeface
6 | import android.graphics.drawable.Drawable
7 | import android.view.View
8 | import android.widget.TextView
9 | import cn.fkj233.ui.activity.MIUIActivity
10 | import cn.fkj233.ui.activity.fragment.MIUIFragment
11 | import cn.fkj233.ui.activity.view.*
12 |
13 | abstract class BasePage {
14 | val itemList: ArrayList = arrayListOf()
15 | var bindingData = arrayListOf()
16 | var skipLoadItem: Boolean = false
17 | lateinit var activity: MIUIActivity
18 |
19 | abstract fun onCreate()
20 |
21 | open fun asyncInit(fragment: MIUIFragment) {}
22 |
23 | fun showPage(page: Class) {
24 | activity.showFragment(page.simpleName)
25 | }
26 |
27 | fun setTitle(title: String) {
28 | activity.title = title
29 | }
30 |
31 | open fun getTitle(): String = ""
32 |
33 | fun getString(id: Int): String = activity.getString(id)
34 | fun getDrawable(id: Int): Drawable = activity.getDrawable(id)!!
35 | fun getColor(id: Int): Int = activity.getColor(id)
36 |
37 |
38 | fun GetDataBinding(defValue: () -> Any, recvCallbacks: (View, Int, Any) -> Unit): DataBinding.BindingData {
39 | return DataBinding.get(bindingData, defValue, recvCallbacks)
40 | }
41 |
42 | fun ImageWithText(head: Drawable, name: String, tips: String? = null, round: Float = 30f, onClickListener: (() -> Unit)? = null, dataBindingRecv: DataBinding.Binding.Recv? = null) {
43 | itemList.add(ImageTextV(head, name, tips, round, onClickListener, dataBindingRecv))
44 | }
45 |
46 | fun Page(pageHead: Drawable, pageName: String? = null, pageNameId: Int? = null, round: Float = 0f, onClickListener: (() -> Unit)? = null, dataBindingRecv: DataBinding.Binding.Recv? = null) {
47 | itemList.add(PageV(pageHead, pageName, pageNameId, round, onClickListener, dataBindingRecv))
48 | }
49 |
50 | fun Line(dataBindingRecv: DataBinding.Binding.Recv? = null,) {
51 | itemList.add(LineV(dataBindingRecv))
52 | }
53 |
54 | fun SeekBar(key: String, min: Int, max: Int, defaultProgress: Int, dataSend: DataBinding.Binding.Send? = null, dataBindingRecv: DataBinding.Binding.Recv? = null, callBacks: ((Int, TextView) -> Unit)? = null) {
55 | itemList.add(SeekBarV(key, min, max, defaultProgress, dataSend, dataBindingRecv, callBacks))
56 | }
57 |
58 | fun SeekBarWithText(key: String = "", min: Int, max: Int, defaultProgress: Int = 0, dataBindingRecv: DataBinding.Binding.Recv? = null, dataBindingSend: DataBinding.Binding.Send? = null, callBacks: ((Int, TextView) -> Unit)? = null) {
59 | itemList.add(SeekBarWithTextV(key, min, max, defaultProgress, dataBindingRecv, dataBindingSend, callBacks))
60 | }
61 |
62 | fun Text(text: String? = null, textId: Int? = null, textSize: Float? = null, colorInt: Int? = null, colorId: Int? = null, padding: Padding? = null, dataBindingRecv: DataBinding.Binding.Recv? = null, typeface: Typeface? = null, onClickListener: (() -> Unit)? = null) {
63 | itemList.add(TextV(text, textId, textSize, colorInt, colorId, padding, dataBindingRecv, typeface, onClickListener))
64 | }
65 |
66 | fun TextWithSwitch(textV: TextV, switchV: SwitchV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
67 | itemList.add(TextWithSwitchV(textV, switchV, dataBindingRecv))
68 | }
69 |
70 | fun TextSw(text: String? = null, textId: Int? = null, key: String, defValue: Boolean = false, onClickListener: ((Boolean) -> Unit)? = null, dataBindingRecv: DataBinding.Binding.Recv? = null) {
71 | itemList.add(TextWithSwitchV(TextV(text, textId), SwitchV(key, defValue, onClickListener = onClickListener), dataBindingRecv))
72 | }
73 |
74 | fun TextWithSpinner(textV: TextV, spinnerV: SpinnerV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
75 | itemList.add(TextWithSpinnerV(textV, spinnerV, dataBindingRecv))
76 | }
77 |
78 | fun TextSp(text: String? = null, textId: Int? = null, currentValue: String, data: SpinnerV.SpinnerData.() -> Unit, dataBindingRecv: DataBinding.Binding.Recv? = null) {
79 | itemList.add(TextWithSpinnerV(TextV(text, textId), SpinnerV(currentValue, data = data), dataBindingRecv))
80 | }
81 |
82 | fun TextWithArrow(textV: TextV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
83 | itemList.add(TextWithArrowV(textV, dataBindingRecv))
84 | }
85 |
86 | fun TextA(text: String? = null, textId: Int? = null, onClickListener: (() -> Unit)? = null, dataBindingRecv: DataBinding.Binding.Recv? = null) {
87 | itemList.add(TextWithArrowV(TextV(text, textId, onClickListener = onClickListener), dataBindingRecv))
88 | }
89 |
90 | fun TextWithSeekBar(textV: TextV, seekBarWithTextV: SeekBarWithTextV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
91 | itemList.add(TextWithSeekBarV(textV, seekBarWithTextV, dataBindingRecv))
92 | }
93 |
94 | fun TextSummary(text: String? = null, textId: Int? = null, tips: String? = null, colorInt: Int? = null, colorId: Int? = null, tipsId: Int? = null, dataBindingRecv: DataBinding.Binding.Recv? = null, onClickListener: (() -> Unit)? = null) {
95 | itemList.add(TextSummaryV(text, textId, tips, colorInt, colorId, tipsId, dataBindingRecv, onClickListener))
96 | }
97 |
98 | fun TextS(text: String? = null, textId: Int? = null, tips: String? = null, colorInt: Int? = null, colorId: Int? = null, tipsId: Int? = null, dataBindingRecv: DataBinding.Binding.Recv? = null, onClickListener: (() -> Unit)? = null) {
99 | itemList.add(TextSummaryV(text, textId, tips, colorInt, colorId, tipsId, dataBindingRecv, onClickListener))
100 | }
101 |
102 | fun TextSummaryWithSwitch(textSummaryV: TextSummaryV, switchV: SwitchV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
103 | itemList.add(TextSummaryWithSwitchV(textSummaryV, switchV, dataBindingRecv))
104 | }
105 |
106 | fun TextSSw(text: String? = null, textId: Int? = null, tips: String? = null, tipsId: Int? = null, key: String, defValue: Boolean = false, onClickListener: ((Boolean) -> Unit)? = null, dataBindingRecv: DataBinding.Binding.Recv? = null) {
107 | itemList.add(TextSummaryWithSwitchV(TextSummaryV(text, textId, tips, tipsId = tipsId), SwitchV(key, defValue, onClickListener = onClickListener), dataBindingRecv))
108 | }
109 |
110 | fun TextSummaryWithSpinner(textSummaryV: TextSummaryV, spinnerV: SpinnerV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
111 | itemList.add(TextSummaryWithSpinnerV(textSummaryV, spinnerV, dataBindingRecv))
112 | }
113 |
114 | fun TextSSp(text: String? = null, textId: Int? = null, tips: String? = null, tipsId: Int? = null, currentValue: String, data: SpinnerV.SpinnerData.() -> Unit, dataBindingRecv: DataBinding.Binding.Recv? = null) {
115 | itemList.add(TextSummaryWithSpinnerV(TextSummaryV(text, textId, tips, tipsId), SpinnerV(currentValue, data = data), dataBindingRecv))
116 | }
117 |
118 | fun TextSummaryWithArrow(textSummaryV: TextSummaryV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
119 | itemList.add(TextSummaryWithArrowV(textSummaryV, dataBindingRecv))
120 | }
121 |
122 | fun TextSA(text: String? = null, textId: Int? = null, tips: String? = null, tipsId: Int? = null, onClickListener: (() -> Unit)? = null, dataBindingRecv: DataBinding.Binding.Recv? = null) {
123 | itemList.add(TextSummaryWithArrowV(TextSummaryV(text = text, textId = textId, tips = tips, tipsId = tipsId, onClickListener = onClickListener), dataBindingRecv))
124 | }
125 |
126 | fun TextSummaryWithSeekBar(textSummaryV: TextSummaryV, seekBarWithTextV: SeekBarWithTextV, dataBindingRecv: DataBinding.Binding.Recv? = null) {
127 | itemList.add(TextSummaryWithSeekBarV(textSummaryV, seekBarWithTextV, dataBindingRecv))
128 | }
129 |
130 | fun TitleText(text: String? = null, textId: Int? = null, colorInt: Int? = null, colorId: Int? = null, dataBindingRecv: DataBinding.Binding.Recv? = null, onClickListener: (() -> Unit)? = null) {
131 | itemList.add(TitleTextV(text, textId, colorInt, colorId, dataBindingRecv, onClickListener))
132 | }
133 |
134 | fun CustomView(view: View, dataBindingRecv: DataBinding.Binding.Recv? = null) {
135 | itemList.add(CustomViewV(view, dataBindingRecv))
136 | }
137 |
138 | fun RadioView(key: String, dataBindingRecv: DataBinding.Binding.Recv? = null, data: RadioViewV.RadioData.() -> Unit) {
139 | itemList.add(RadioViewV(key, dataBindingRecv, data))
140 | }
141 |
142 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/dialog/NewDialog.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | @file:Suppress("FunctionName")
24 |
25 | package cn.fkj233.ui.dialog
26 |
27 | import android.app.Dialog
28 | import android.content.Context
29 | import android.graphics.Typeface
30 | import android.graphics.drawable.GradientDrawable
31 | import android.os.Build
32 | import android.text.Editable
33 | import android.text.TextWatcher
34 | import android.util.DisplayMetrics
35 | import android.util.TypedValue
36 | import android.view.Gravity
37 | import android.view.View
38 | import android.view.WindowManager
39 | import android.widget.Button
40 | import android.widget.LinearLayout
41 | import android.widget.RelativeLayout
42 | import android.widget.TextView
43 | import cn.fkj233.ui.R
44 | import cn.fkj233.ui.activity.dp2px
45 | import cn.fkj233.ui.activity.view.MIUIEditText
46 | import kotlin.math.roundToInt
47 |
48 | class NewDialog(context: Context, private val newStyle: Boolean = true, val build: NewDialog.() -> Unit) : Dialog(context, R.style.CustomDialog) {
49 |
50 | private var finallyCallBacks: ((View) -> Unit)? = null
51 |
52 | private val title by lazy {
53 | TextView(context).also { textView ->
54 | textView.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
55 | it.setMargins(0, dp2px(context, 20f), 0, dp2px(context, 20f))
56 | }
57 | textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 19f)
58 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
59 | textView.paint.typeface = Typeface.create(null, 500, false)
60 | }
61 | textView.setTextColor(context.getColor(R.color.whiteText))
62 | textView.gravity = Gravity.CENTER
63 | textView.setPadding(0, dp2px(context, 10f), 0, 0)
64 | }
65 | }
66 |
67 | private val message by lazy {
68 | TextView(context).also { textView ->
69 | textView.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
70 | it.setMargins(dp2px(context, 20f), 0, dp2px(context, 20f), dp2px(context, 5f))
71 | }
72 | textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17f)
73 | textView.setTextColor(context.getColor(R.color.whiteText))
74 | textView.gravity = Gravity.CENTER
75 | textView.visibility = View.GONE
76 | textView.setPadding(dp2px(context, 10f), 0, dp2px(context, 10f), 0)
77 | }
78 | }
79 |
80 | private val editText by lazy { MIUIEditText(context) }
81 |
82 |
83 | private val view by lazy {
84 | LinearLayout(context).also { linearLayout ->
85 | linearLayout.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
86 | linearLayout.orientation = LinearLayout.VERTICAL
87 | linearLayout.addView(message)
88 | linearLayout.addView(editText)
89 | }
90 | }
91 |
92 | private var bView: LinearLayout
93 |
94 | private val root = RelativeLayout(context).also { viewRoot ->
95 | viewRoot.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
96 | viewRoot.addView(LinearLayout(context).also { viewLinearLayout ->
97 | viewLinearLayout.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
98 | viewLinearLayout.orientation = LinearLayout.VERTICAL
99 | viewLinearLayout.addView(title)
100 | viewLinearLayout.addView(view)
101 | viewLinearLayout.addView(LinearLayout(context).also { linearLayout ->
102 | linearLayout.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
103 | it.gravity = Gravity.CENTER_HORIZONTAL
104 | }
105 | linearLayout.orientation = LinearLayout.VERTICAL
106 | linearLayout.setPadding(0, 0, 0, dp2px(context, 35f))
107 | bView = linearLayout
108 | })
109 | })
110 | }
111 |
112 | fun Button(text: CharSequence?, enable: Boolean = true, cancelStyle: Boolean = false) {
113 | Button(text, enable, cancelStyle, null)
114 | }
115 |
116 | fun Button(text: CharSequence?, enable: Boolean = true, cancelStyle: Boolean = false, callBacks: ((View) -> Unit)?) {
117 | bView.addView(Button(context).also { buttonView ->
118 | buttonView.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, dp2px(context, 48f), 1f).also {
119 | it.setMargins(dp2px(context, 30f), dp2px(context, 10f), dp2px(context, 30f), 0)
120 | it.gravity = Gravity.CENTER
121 | }
122 | buttonView.setPadding(0, 0, 0, 0)
123 | buttonView.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
124 | buttonView.setTextColor(context.getColor(if (cancelStyle) R.color.LButtonText else R.color.RButtonText))
125 | if (!enable) {
126 | buttonView.setTextColor(context.getColor(R.color.disable_button_text))
127 | }
128 | buttonView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17.5f)
129 | buttonView.text = text
130 | buttonView.isEnabled = enable
131 | buttonView.stateListAnimator = null
132 | buttonView.background = context.getDrawable(if (cancelStyle) R.drawable.l_button_background else R.drawable.r_button_background)
133 | buttonView.setOnClickListener {
134 | callBacks?.invoke(it)
135 | finallyCallBacks?.invoke(it)
136 | }
137 | })
138 | }
139 |
140 | init {
141 | window?.setGravity(Gravity.BOTTOM)
142 | setContentView(root)
143 | window?.setBackgroundDrawable(GradientDrawable().apply {
144 | if (newStyle) {
145 | cornerRadius = dp2px(context, 30f).toFloat()
146 | } else {
147 | val dp30 = dp2px(context, 30f).toFloat()
148 | cornerRadii = floatArrayOf(dp30, dp30, dp30, dp30, 0f, 0f, 0f, 0f)
149 | }
150 | setColor(context.getColor(R.color.dialog_background))
151 | })
152 | }
153 |
154 | fun addView(mView: View) {
155 | view.addView(mView)
156 | }
157 |
158 | override fun setTitle(title: CharSequence?) {
159 | this.title.text = title
160 | }
161 |
162 | override fun setTitle(titleId: Int) {
163 | this.title.setText(titleId)
164 | }
165 |
166 | override fun show() {
167 | build()
168 | window!!.setWindowAnimations(R.style.DialogAnim)
169 | super.show()
170 | val layoutParams = window!!.attributes
171 | layoutParams.dimAmount = 0.5F
172 | if (newStyle) {
173 | val resources = context.resources
174 | val dm: DisplayMetrics = resources.displayMetrics
175 | val width = dm.widthPixels
176 | layoutParams.width = (width * 0.92f).roundToInt()
177 | layoutParams.y = (width * 0.045f).roundToInt()
178 | } else {
179 | layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT
180 | }
181 | layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT
182 | window!!.attributes = layoutParams
183 | }
184 |
185 | fun setMessage(textId: Int) {
186 | message.apply {
187 | setText(textId)
188 | visibility = View.VISIBLE
189 | }
190 | }
191 |
192 | fun setMessage(text: CharSequence?, isCenter: Boolean = true) {
193 | if (isCenter) {
194 | message.gravity = Gravity.CENTER
195 | } else {
196 | message.gravity = Gravity.START
197 | }
198 | message.apply {
199 | this.text = text
200 | visibility = View.VISIBLE
201 | }
202 | }
203 |
204 | fun setEditText(text: String, hint: String, isSingleLine: Boolean = true, editCallBacks: ((String) -> Unit)? = null) {
205 | editText.apply {
206 | setText(text.toCharArray(), 0, text.length)
207 | this.hint = hint
208 | this.isSingleLine = isSingleLine
209 | this.maxLines = 5
210 | visibility = View.VISIBLE
211 | editCallBacks?.let {
212 | addTextChangedListener(object : TextWatcher {
213 | override fun afterTextChanged(var1: Editable?) {
214 | it(var1.toString())
215 | }
216 |
217 | override fun beforeTextChanged(var1: CharSequence?, var2: Int, var3: Int, var4: Int) {}
218 | override fun onTextChanged(var1: CharSequence?, var2: Int, var3: Int, var4: Int) {}
219 | })
220 | }
221 | }
222 | }
223 |
224 | fun Finally(callBacks: (View) -> Unit) {
225 | finallyCallBacks = callBacks
226 | }
227 |
228 | fun getEditText(): String = editText.text.toString()
229 | }
230 |
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/dialog/MIUIDialog.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | package cn.fkj233.ui.dialog
24 |
25 | import android.annotation.SuppressLint
26 | import android.app.Dialog
27 | import android.content.Context
28 | import android.graphics.Typeface
29 | import android.graphics.drawable.GradientDrawable
30 | import android.os.Build
31 | import android.text.Editable
32 | import android.text.TextWatcher
33 | import android.util.DisplayMetrics
34 | import android.util.TypedValue
35 | import android.view.Gravity
36 | import android.view.View
37 | import android.view.WindowManager
38 | import android.widget.Button
39 | import android.widget.EditText
40 | import android.widget.LinearLayout
41 | import android.widget.RelativeLayout
42 | import android.widget.TextView
43 | import cn.fkj233.ui.R
44 | import cn.fkj233.ui.activity.dp2px
45 | import cn.fkj233.ui.activity.isRtl
46 | import cn.fkj233.ui.activity.view.MIUIEditText
47 | import kotlin.math.roundToInt
48 |
49 | @SuppressLint("ClickableViewAccessibility")
50 | class MIUIDialog(context: Context, private val newStyle: Boolean = true, val build: MIUIDialog.() -> Unit) : Dialog(context, R.style.CustomDialog) {
51 |
52 | private var finallyCallBacks: ((View) -> Unit)? = null
53 |
54 | private val title by lazy {
55 | TextView(context).also { textView ->
56 | textView.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
57 | it.setMargins(0, dp2px(context, 20f), 0, dp2px(context, 20f))
58 | }
59 | textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 19f)
60 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
61 | textView.paint.typeface = Typeface.create(null, 500, false)
62 | }
63 | textView.setTextColor(context.getColor(R.color.whiteText))
64 | textView.gravity = Gravity.CENTER
65 | textView.setPadding(0, dp2px(context, 10f), 0, 0)
66 | }
67 | }
68 |
69 | private val message by lazy {
70 | TextView(context).also { textView ->
71 | textView.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
72 | it.setMargins(dp2px(context, 20f), 0, dp2px(context, 20f), dp2px(context, 5f))
73 | }
74 | textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17f)
75 | textView.setTextColor(context.getColor(R.color.whiteText))
76 | textView.gravity = Gravity.CENTER
77 | textView.visibility = View.GONE
78 | textView.setPadding(dp2px(context, 10f), 0, dp2px(context, 10f), 0)
79 | }
80 | }
81 |
82 | private val editText by lazy { MIUIEditText(context) }
83 |
84 | private val rButton by lazy {
85 | Button(context).also { buttonView ->
86 | buttonView.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, dp2px(context, 48f), 1f).also {
87 | it.setMargins(dp2px(context, 25f), 0, dp2px(context, 25f), 0)
88 | it.gravity = Gravity.CENTER
89 | }
90 | buttonView.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
91 | buttonView.setTextColor(context.getColor(R.color.RButtonText))
92 | buttonView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17.5f)
93 | buttonView.stateListAnimator = null
94 | buttonView.background = context.getDrawable(R.drawable.r_button_background)
95 | buttonView.visibility = View.GONE
96 | }
97 | }
98 |
99 | private val lButton by lazy {
100 | Button(context).also { buttonView ->
101 | buttonView.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, dp2px(context, 48f), 1f).also {
102 | it.setMargins(dp2px(context, 25f), 0, dp2px(context, 25f), 0)
103 | it.gravity = Gravity.CENTER
104 | }
105 | buttonView.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
106 | buttonView.setTextColor(context.getColor(R.color.LButtonText))
107 | buttonView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17.5f)
108 | buttonView.stateListAnimator = null
109 | buttonView.visibility = View.GONE
110 | buttonView.background = context.getDrawable(R.drawable.l_button_background)
111 | }
112 | }
113 |
114 | private val view by lazy {
115 | LinearLayout(context).also { linearLayout ->
116 | linearLayout.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
117 | linearLayout.orientation = LinearLayout.VERTICAL
118 | linearLayout.addView(message)
119 | linearLayout.addView(editText)
120 | }
121 | }
122 |
123 | private val root = RelativeLayout(context).also { viewRoot ->
124 | viewRoot.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
125 | viewRoot.addView(LinearLayout(context).also { viewLinearLayout ->
126 | viewLinearLayout.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
127 | viewLinearLayout.orientation = LinearLayout.VERTICAL
128 | viewLinearLayout.addView(title)
129 | viewLinearLayout.addView(view)
130 | viewLinearLayout.addView(LinearLayout(context).also { linearLayout ->
131 | linearLayout.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
132 | it.gravity = Gravity.CENTER_HORIZONTAL
133 | }
134 | linearLayout.setPadding(0, dp2px(context, 16f), 0, dp2px(context, 24f))
135 | linearLayout.addView(lButton)
136 | linearLayout.addView(rButton)
137 | })
138 | })
139 | }
140 |
141 | init {
142 | window?.setGravity(Gravity.BOTTOM)
143 | setContentView(root)
144 | window?.setBackgroundDrawable(GradientDrawable().apply {
145 | if (newStyle) {
146 | cornerRadius = dp2px(context, 32f).toFloat()
147 | } else {
148 | val dp32 = dp2px(context, 32f).toFloat()
149 | cornerRadii = floatArrayOf(dp32, dp32, dp32, dp32, 0f, 0f, 0f, 0f)
150 | }
151 | setColor(context.getColor(R.color.dialog_background))
152 | })
153 | }
154 |
155 | fun addView(mView: View) {
156 | view.addView(mView)
157 | }
158 |
159 | override fun setTitle(title: CharSequence?) {
160 | this.title.text = title
161 | }
162 |
163 | override fun setTitle(titleId: Int) {
164 | this.title.setText(titleId)
165 | }
166 |
167 | fun setLButton(text: CharSequence?, enable: Boolean = true) {
168 | setLButton(text, enable, null)
169 | }
170 |
171 | fun setLButton(text: CharSequence?, enable: Boolean = true, callBacks: ((View) -> Unit)?) {
172 | lButton.apply {
173 | this.isEnabled = enable
174 | visibility = View.VISIBLE
175 | setText(text)
176 | setOnClickListener {
177 | callBacks?.invoke(it)
178 | finallyCallBacks?.invoke(it)
179 | }
180 | }
181 | }
182 |
183 | fun setLButton(textId: Int, enable: Boolean = true) {
184 | setLButton(textId, enable, null)
185 | }
186 |
187 | fun setLButton(textId: Int, enable: Boolean = true, callBacks: ((View) -> Unit)?) {
188 | lButton.apply {
189 | this.isEnabled = enable
190 | visibility = View.VISIBLE
191 | setText(textId)
192 | setOnClickListener {
193 | callBacks?.invoke(it)
194 | finallyCallBacks?.invoke(it)
195 | }
196 | }
197 | }
198 |
199 | fun setRButton(text: CharSequence?, enable: Boolean = true) {
200 | setRButton(text, enable, null)
201 | }
202 |
203 | fun setRButton(text: CharSequence?, enable: Boolean = true, callBacks: ((View) -> Unit)?) {
204 | rButton.apply {
205 | setText(text)
206 | this.isEnabled = enable
207 | setOnClickListener {
208 | callBacks?.invoke(it)
209 | finallyCallBacks?.invoke(it)
210 | }
211 | visibility = View.VISIBLE
212 | }
213 | }
214 |
215 | fun setRButton(textId: Int, enable: Boolean = true) {
216 | setRButton(textId, enable, null)
217 | }
218 |
219 | fun setRButton(textId: Int, enable: Boolean = true, callBacks: ((View) -> Unit)?) {
220 | rButton.apply {
221 | setText(textId)
222 | this.isEnabled = enable
223 | setOnClickListener {
224 | callBacks?.invoke(it)
225 | finallyCallBacks?.invoke(it)
226 | }
227 | visibility = View.VISIBLE
228 | }
229 | }
230 |
231 | fun getRButton(): TextView = rButton
232 |
233 | fun getLButton(): TextView = lButton
234 |
235 | override fun show() {
236 | build()
237 | window!!.setWindowAnimations(R.style.DialogAnim)
238 | if (rButton.visibility == View.VISIBLE && lButton.visibility == View.VISIBLE) {
239 | if (isRtl(context)) {
240 | (rButton.layoutParams as LinearLayout.LayoutParams).setMargins(dp2px(context, 24f), 0, dp2px(context, 5f), 0)
241 | (lButton.layoutParams as LinearLayout.LayoutParams).setMargins(dp2px(context, 5f), 0, dp2px(context, 24f), 0)
242 | } else {
243 | (rButton.layoutParams as LinearLayout.LayoutParams).setMargins(dp2px(context, 5f), 0, dp2px(context, 24f), 0)
244 | (lButton.layoutParams as LinearLayout.LayoutParams).setMargins(dp2px(context, 24f), 0, dp2px(context, 5f), 0)
245 | }
246 | }
247 | super.show()
248 | val layoutParams = window!!.attributes
249 | layoutParams.dimAmount = 0.3F
250 | if (newStyle) {
251 | val resources = context.resources
252 | val dm: DisplayMetrics = resources.displayMetrics
253 | val width = dm.widthPixels
254 | layoutParams.width = (width * 0.94f).roundToInt()
255 | layoutParams.y = (width * 0.03f).roundToInt()
256 | } else {
257 | layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT
258 | }
259 | layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT
260 | window!!.attributes = layoutParams
261 | }
262 |
263 | fun setMessage(textId: Int, isCenter: Boolean = true) {
264 | if (isCenter) {
265 | message.gravity = Gravity.CENTER
266 | } else {
267 | message.gravity = Gravity.START
268 | }
269 | message.apply {
270 | setText(textId)
271 | visibility = View.VISIBLE
272 | }
273 | }
274 |
275 | fun setMessage(text: CharSequence, isCenter: Boolean = true) {
276 | if (isCenter) {
277 | message.gravity = Gravity.CENTER
278 | } else {
279 | message.gravity = Gravity.START
280 | }
281 | message.apply {
282 | this.text = text
283 | visibility = View.VISIBLE
284 | }
285 | }
286 |
287 | fun setEditText(text: String, hint: String, isSingleLine: Boolean = true, config: ((EditText) -> Unit)? = null, editCallBacks: ((String) -> Unit)? = null) {
288 | editText.apply {
289 | setText(text.toCharArray(), 0, text.length)
290 | this.hint = hint
291 | this.isSingleLine = isSingleLine
292 | this.maxLines = 5
293 | visibility = View.VISIBLE
294 | editCallBacks?.let {
295 | addTextChangedListener(object : TextWatcher {
296 | override fun afterTextChanged(var1: Editable?) {
297 | it(var1.toString())
298 | }
299 |
300 | override fun beforeTextChanged(var1: CharSequence?, var2: Int, var3: Int, var4: Int) {}
301 | override fun onTextChanged(var1: CharSequence?, var2: Int, var3: Int, var4: Int) {}
302 | })
303 | }
304 | config?.invoke(this)
305 | }
306 | }
307 |
308 | fun finally(callBacks: (View) -> Unit) {
309 | finallyCallBacks = callBacks
310 | }
311 |
312 | fun getEditText(): String = editText.text.toString()
313 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/fkj233/ui/activity/MIUIActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * BlockMIUI
3 | * Copyright (C) 2022 fkj@fkj233.cn
4 | * https://github.com/577fkj/BlockMIUI
5 | *
6 | * This software is free opensource software: you can redistribute it
7 | * and/or modify it under the terms of the GNU Lesser General Public License v2.1
8 | * as published by the Free Software Foundation; either
9 | * version 3 of the License, or any later version and our eula as published
10 | * by 577fkj.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * GNU Lesser General Public License v2.1 for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License v2.1
18 | * and eula along with this software. If not, see
19 | *
20 | * .
21 | */
22 |
23 | @file:Suppress("DEPRECATION")
24 |
25 | package cn.fkj233.ui.activity
26 |
27 | import android.annotation.SuppressLint
28 | import android.app.Activity
29 | import android.app.FragmentManager
30 | import android.content.Context
31 | import android.content.SharedPreferences
32 | import android.graphics.Typeface
33 | import android.os.Bundle
34 | import android.util.TypedValue
35 | import android.view.Gravity
36 | import android.view.View
37 | import android.widget.FrameLayout
38 | import android.widget.ImageView
39 | import android.widget.LinearLayout
40 | import android.widget.TextView
41 | import androidx.annotation.Keep
42 | import cn.fkj233.ui.R
43 | import cn.fkj233.ui.activity.annotation.BMMainPage
44 | import cn.fkj233.ui.activity.annotation.BMMenuPage
45 | import cn.fkj233.ui.activity.annotation.BMPage
46 | import cn.fkj233.ui.activity.data.AsyncInit
47 | import cn.fkj233.ui.activity.data.BasePage
48 | import cn.fkj233.ui.activity.data.InitView
49 | import cn.fkj233.ui.activity.data.SafeSharedPreferences
50 | import cn.fkj233.ui.activity.fragment.MIUIFragment
51 | import cn.fkj233.ui.activity.view.BaseView
52 |
53 | /**
54 | * @version: V1.0
55 | * @author: 577fkj
56 | * @className: MIUIActivity
57 | * @packageName: MIUIActivity
58 | * @description: BaseActivity / 基本Activity
59 | * @data: 2022-02-05 18:30
60 | **/
61 | @Keep
62 | open class MIUIActivity : Activity() {
63 | private var callbacks: (() -> Unit)? = null
64 |
65 | private var thisName: ArrayList = arrayListOf()
66 |
67 | private lateinit var viewData: InitView
68 |
69 | private val dataList: HashMap = hashMapOf()
70 |
71 | private lateinit var initViewData: InitView.() -> Unit
72 |
73 | companion object {
74 | var safeSP: SafeSharedPreferences = SafeSharedPreferences()
75 |
76 | @SuppressLint("StaticFieldLeak")
77 | lateinit var context: Context
78 |
79 | @SuppressLint("StaticFieldLeak")
80 | lateinit var activity: MIUIActivity
81 | }
82 |
83 | private val backButton by lazy {
84 | ImageView(activity).apply {
85 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).also {
86 | it.gravity = Gravity.CENTER_VERTICAL
87 | if (isRtl(context)) it.setMargins(dp2px(activity, 5f), 0, 0, 0)
88 | else it.setMargins(0, 0, dp2px(activity, 5f), 0)
89 | }
90 | background = getDrawable(R.drawable.abc_ic_ab_back_material)
91 | visibility = View.GONE
92 | setOnClickListener {
93 | this@MIUIActivity.onBackPressed()
94 | }
95 | }
96 | }
97 |
98 | private val menuButton by lazy {
99 | ImageView(activity).apply {
100 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
101 | .also { it.gravity = Gravity.CENTER_VERTICAL }
102 | background = getDrawable(R.drawable.abc_ic_menu_overflow_material)
103 | visibility = View.GONE
104 | if (isRtl(context)) setPadding(dp2px(activity, 25f), 0, 0, 0)
105 | else setPadding(0, 0, dp2px(activity, 25f), 0)
106 | setOnClickListener {
107 | showFragment(if (this@MIUIActivity::initViewData.isInitialized) "Menu" else "__menu__")
108 | }
109 | }
110 | }
111 |
112 | private val titleView by lazy {
113 | TextView(activity).apply {
114 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f).also {
115 | it.gravity = Gravity.CENTER_VERTICAL
116 | }
117 | gravity = if (isRtl(context)) Gravity.RIGHT else Gravity.LEFT
118 | setTextColor(getColor(R.color.whiteText))
119 | setTextSize(TypedValue.COMPLEX_UNIT_SP, 25f)
120 | paint.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
121 | }
122 | }
123 |
124 | private var frameLayoutId: Int = -1
125 | private val frameLayout by lazy {
126 | val mFrameLayout = FrameLayout(activity).apply {
127 | layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
128 | }
129 | frameLayoutId = View.generateViewId()
130 | mFrameLayout.id = frameLayoutId
131 | mFrameLayout
132 | }
133 |
134 | /**
135 | * 是否继续加载 / Continue loading
136 | */
137 | @Suppress("MemberVisibilityCanBePrivate")
138 | var isLoad = true
139 |
140 | /**
141 | * 退出时是否保留后台 / Retaining the background
142 | */
143 | @Suppress("MemberVisibilityCanBePrivate")
144 | var isExit = false
145 |
146 | override fun onCreate(savedInstanceState: Bundle?) {
147 | super.onCreate(savedInstanceState)
148 | context = this
149 | activity = this
150 | register()
151 | actionBar?.hide()
152 | setContentView(LinearLayout(activity).apply {
153 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
154 | background = getDrawable(R.color.foreground)
155 | orientation = LinearLayout.VERTICAL
156 | addView(LinearLayout(activity).apply {
157 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
158 | setPadding(dp2px(activity, 25f), dp2px(activity, 20f), dp2px(activity, 25f), dp2px(activity, 15f))
159 | orientation = LinearLayout.HORIZONTAL
160 | addView(backButton)
161 | addView(titleView)
162 | addView(menuButton)
163 | })
164 | addView(frameLayout)
165 | })
166 | if (savedInstanceState != null) {
167 | if (this::initViewData.isInitialized) {
168 | viewData = InitView(dataList).apply(initViewData)
169 | setMenuShow(viewData.isMenu)
170 | val list = savedInstanceState.getStringArrayList("this")!!
171 | fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
172 | for (name: String in list) {
173 | showFragment(name)
174 | }
175 | if (list.size == 1) {
176 | setBackupShow(viewData.mainShowBack)
177 | }
178 | return
179 | }
180 | val list = savedInstanceState.getStringArrayList("this")!!
181 | fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
182 | initAllPage()
183 | if (pageInfo.containsKey("__menu__")) setMenuShow(list.size == 1)
184 | for (name: String in list) {
185 | showFragment(name)
186 | }
187 | } else {
188 | if (isLoad) {
189 | if (this::initViewData.isInitialized) {
190 | viewData = InitView(dataList).apply(initViewData)
191 | setBackupShow(!viewData.mainShowBack)
192 | setMenuShow(viewData.isMenu)
193 | showFragment("Main")
194 | return
195 | }
196 | initAllPage()
197 | showFragment("__main__")
198 | }
199 | }
200 | val showFragmentName = intent.getStringExtra("showFragment").toString()
201 | if (showFragmentName != "null" && showFragmentName.isNotEmpty()) {
202 | if (pageInfo.containsKey(showFragmentName)) {
203 | showFragment(showFragmentName)
204 | return
205 | }
206 | }
207 | }
208 |
209 | private val pageInfo: HashMap = hashMapOf()
210 | private val pageList: HashMap, String> = HashMap()
211 |
212 | fun registerPage(basePage: Class, title: String? = null) {
213 | if (title == null) {
214 | pageList[basePage] = basePage.simpleName
215 | } else {
216 | pageList[basePage] = title
217 | }
218 | }
219 |
220 | open fun register() {}
221 |
222 | fun initAllPage() {
223 | pageList.forEach { (basePage, _) ->
224 | val mainPage = basePage.newInstance()
225 | mainPage.activity = this
226 | if (basePage.getAnnotation(BMMainPage::class.java) != null) {
227 | pageInfo["__main__"] = mainPage
228 | } else if (basePage.getAnnotation(BMMenuPage::class.java) != null) {
229 | menuButton.visibility = View.VISIBLE
230 | pageInfo["__menu__"] = mainPage
231 | } else if (basePage.getAnnotation(BMPage::class.java) != null) {
232 | pageInfo[basePage.simpleName] = mainPage
233 | } else {
234 | throw Exception("Page must be annotated with BMMainPage or BMMenuPage or BMPage")
235 | }
236 | }
237 | }
238 |
239 | fun initView(iView: InitView.() -> Unit) {
240 | initViewData = iView
241 | }
242 |
243 | override fun setTitle(title: CharSequence?) {
244 | titleView.text = title
245 | }
246 |
247 | /**
248 | * 设置 SharedPreferences / Set SharedPreferences
249 | * @param: SharedPreferences
250 | */
251 | fun setSP(sharedPreferences: SharedPreferences) {
252 | safeSP.mSP = sharedPreferences
253 | }
254 |
255 | /**
256 | * 获取 SharedPreferences / Get SharedPreferences
257 | * @return: SharedPreferences
258 | */
259 | fun getSP(): SharedPreferences? {
260 | return safeSP.mSP
261 | }
262 |
263 | /**
264 | * 显示 Fragment / Show fragment
265 | * @param: key 注册的key / Register key
266 | */
267 | fun showFragment(key: String) {
268 | if (this::initViewData.isInitialized) {
269 | title = dataList[key]?.title
270 | thisName.add(key)
271 | val frame = MIUIFragment(key)
272 | if (key != "Main" && fragmentManager.backStackEntryCount != 0) {
273 | fragmentManager.beginTransaction().let {
274 | if (key != "Menu") {
275 | if (isRtl(activity)) it.setCustomAnimations(
276 | R.animator.slide_left_in,
277 | R.animator.slide_right_out,
278 | R.animator.slide_right_in,
279 | R.animator.slide_left_out
280 | )
281 | else it.setCustomAnimations(R.animator.slide_right_in, R.animator.slide_left_out, R.animator.slide_left_in, R.animator.slide_right_out)
282 | } else {
283 | if (isRtl(activity)) it.setCustomAnimations(
284 | R.animator.slide_right_in,
285 | R.animator.slide_left_out,
286 | R.animator.slide_left_in,
287 | R.animator.slide_right_out
288 | )
289 | else it.setCustomAnimations(R.animator.slide_left_in, R.animator.slide_right_out, R.animator.slide_right_in, R.animator.slide_left_out)
290 | }
291 | }.replace(frameLayoutId, frame).addToBackStack(key).commit()
292 | backButton.visibility = View.VISIBLE
293 | setMenuShow(dataList[key]?.hideMenu == false)
294 | } else {
295 | setBackupShow(viewData.mainShowBack)
296 | fragmentManager.beginTransaction().replace(frameLayoutId, frame).addToBackStack(key).commit()
297 | }
298 | return
299 | }
300 | if (!pageInfo.containsKey(key)) {
301 | throw Exception("No page found")
302 | }
303 | val thisPage = pageInfo[key]!!
304 | title = getPageTitle(thisPage::class.java)
305 | thisName.add(key)
306 | val frame = MIUIFragment(key)
307 | if (key != "__main__" && fragmentManager.backStackEntryCount != 0) {
308 | fragmentManager.beginTransaction().let {
309 | if (key != "__menu__") {
310 | if (isRtl(activity)) it.setCustomAnimations(
311 | R.animator.slide_left_in,
312 | R.animator.slide_right_out,
313 | R.animator.slide_right_in,
314 | R.animator.slide_left_out
315 | )
316 | else it.setCustomAnimations(R.animator.slide_right_in, R.animator.slide_left_out, R.animator.slide_left_in, R.animator.slide_right_out)
317 | } else {
318 | if (isRtl(activity)) it.setCustomAnimations(
319 | R.animator.slide_right_in,
320 | R.animator.slide_left_out,
321 | R.animator.slide_left_in,
322 | R.animator.slide_right_out
323 | )
324 | else it.setCustomAnimations(R.animator.slide_left_in, R.animator.slide_right_out, R.animator.slide_right_in, R.animator.slide_left_out)
325 | }
326 | }.replace(frameLayoutId, frame).addToBackStack(key).commit()
327 | setBackupShow(true)
328 | if (key !in arrayOf("__main__", "__menu__")) setMenuShow(!getPageHideMenu(thisPage))
329 | if (key == "__menu__") setMenuShow(false)
330 | } else {
331 | setMenuShow(pageInfo.containsKey("__menu__"))
332 | setBackupShow(pageInfo["__main__"]!!.javaClass.getAnnotation(BMMainPage::class.java)!!.showBack)
333 | fragmentManager.beginTransaction().replace(frameLayoutId, frame).addToBackStack(key).commit()
334 | }
335 | }
336 |
337 | fun setMenuShow(show: Boolean) {
338 | if (this::initViewData.isInitialized) {
339 | if (!dataList.containsKey("Menu")) return
340 | if (show) menuButton.visibility = View.VISIBLE
341 | else menuButton.visibility = View.GONE
342 | return
343 | }
344 | if (pageInfo.containsKey("__menu__")) {
345 | if (show) {
346 | menuButton.visibility = View.VISIBLE
347 | } else {
348 | menuButton.visibility = View.GONE
349 | }
350 | }
351 | }
352 |
353 | fun setBackupShow(show: Boolean) {
354 | if (show) backButton.visibility = View.VISIBLE else backButton.visibility = View.GONE
355 | }
356 |
357 | private fun getPageHideMenu(basePage: BasePage): Boolean {
358 | return basePage.javaClass.getAnnotation(BMPage::class.java)?.hideMenu == true
359 | }
360 |
361 | private fun getPageTitle(basePage: Class): String {
362 | return pageList[basePage].toString()
363 | }
364 |
365 | fun getTopPage(): String {
366 | return thisName[thisName.lastSize()]
367 | }
368 |
369 | fun getThisItems(key: String): List {
370 | if (this::initViewData.isInitialized) {
371 | return dataList[key]?.itemList ?: arrayListOf()
372 | }
373 | val currentPage = pageInfo[key]!!
374 | if (currentPage.itemList.size == 0) {
375 | currentPage.onCreate()
376 | }
377 | return currentPage.itemList
378 | }
379 |
380 | fun getThisAsync(key: String): AsyncInit? {
381 | if (this::initViewData.isInitialized) {
382 | return dataList[key]?.async
383 | }
384 | val currentPage = pageInfo[key]!!
385 | if (currentPage.itemList.size == 0) {
386 | currentPage.onCreate()
387 | }
388 | return object : AsyncInit {
389 | override val skipLoadItem: Boolean
390 | get() = currentPage.skipLoadItem
391 |
392 | override fun onInit(fragment: MIUIFragment) {
393 | currentPage.asyncInit(fragment)
394 | }
395 | }
396 | }
397 |
398 | fun getAllCallBacks(): (() -> Unit)? {
399 | return callbacks
400 | }
401 |
402 | /**
403 | * 设置全局返回调用 / Set global return call methods
404 | * @param: Unit
405 | */
406 | fun setAllCallBacks(callbacks: () -> Unit) {
407 | this.callbacks = callbacks
408 | }
409 |
410 | @Deprecated("Deprecated in Java")
411 | override fun onBackPressed() {
412 | if (fragmentManager.backStackEntryCount <= 1) {
413 | if (isExit) {
414 | finishAndRemoveTask()
415 | } else {
416 | finish()
417 | }
418 | } else {
419 | thisName.removeAt(thisName.lastSize())
420 | val name = fragmentManager.getBackStackEntryAt(fragmentManager.backStackEntryCount - 2).name
421 | when (name) {
422 | "Main" -> {
423 | if (!viewData.mainShowBack) backButton.visibility = View.GONE
424 | if (viewData.isMenu) menuButton.visibility = View.VISIBLE
425 | }
426 |
427 | "__main__" -> {
428 | if (!pageInfo[name]!!.javaClass.getAnnotation(BMMainPage::class.java)!!.showBack) backButton.visibility = View.GONE
429 | setMenuShow(pageInfo.containsKey("__menu__"))
430 | }
431 |
432 | else -> {
433 | if (this::initViewData.isInitialized) {
434 | setMenuShow(dataList[name]?.hideMenu == false)
435 | } else {
436 | setMenuShow(!getPageHideMenu(pageInfo[name]!!))
437 | }
438 | }
439 | }
440 | title = if (this::initViewData.isInitialized) {
441 | dataList[name]?.title
442 | } else {
443 | getPageTitle(pageInfo[name]!!::class.java)
444 | }
445 | fragmentManager.popBackStack()
446 | }
447 | }
448 |
449 | private fun ArrayList<*>.lastSize(): Int = this.size - 1
450 |
451 | override fun onSaveInstanceState(outState: Bundle) {
452 | super.onSaveInstanceState(outState)
453 | outState.putStringArrayList("this", thisName)
454 | }
455 |
456 | }
--------------------------------------------------------------------------------