我有一个自定义视图 ProgessContainer,它可以处于三种状态(加载、错误、成功)。根据这些状态,显示不同的信息。但是,出于某种原因,layoutNotice 状态没有显示。加载和成功状态显示没有问题。我无法理解原因,这种状态根本就没有显示在屏幕上。有猜测可能是布局某处出错了
我试图在没有随机功能的情况下强制通知状态。它没有帮助
ProgressContainer.kt
private const val MAX_CHILD_COUNT = 3
class ProgressContainer @JvmOverloads constructor(
context : Context,
attrs: AttributeSet? = null,
defStyleAttr : Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
private val layoutLoading : ViewGroup
private val layoutNotice : ViewGroup
init {
val root = LayoutInflater.from(context).inflate(R.layout.view_progress_container, this, true)
layoutLoading = root.findViewById(R.id.layoutLoading)
layoutNotice = root.findViewById(R.id.layoutNotice)
}
override fun onViewAdded(child: View?) {
super.onViewAdded(child)
if(childCount > MAX_CHILD_COUNT) {
throw IllegalStateException("Progress container can host only one direct child")
}
}
private fun findContextView() : View? = children.firstOrNull {
it.id != R.id.layoutLoading && it.id != R.id.layoutNotice
}
var state : State by Delegates.observable(State.Loading) { _, _, state ->
when(state) {
is State.Loading -> {
layoutLoading.isVisible = true
layoutNotice.isVisible = false
findContextView()?.isVisible = false
}
is State.Notice -> {
layoutLoading.isVisible = false
layoutNotice.isVisible = true
findContextView()?.isVisible = false
val textViewError = layoutNotice.findViewById<TextView>(R.id.textViewError)
textViewError.text = context.getString(state.errorResId)
val textViewMessage = layoutNotice.findViewById<TextView>(R.id.textViewMessage)
textViewMessage.text = context.getString(state.messageResId)
val button = layoutNotice.findViewById<Button>(R.id.buttonRefresh)
if (state.buttonHandler != null) {
button.isVisible = true
button.setOnClickListener(state.buttonHandler)
} else {
button.isVisible = false
}
}
is State.Success -> {
layoutLoading.isVisible = false
layoutNotice.isVisible = false
findContextView()?.isVisible = true
}
}
}
sealed class State {
object Loading : State()
data class Notice(
val errorResId: Int,
val messageResId : Int,
val buttonHandler: OnClickListener? = null
) : State()
object Success : State()
}
}
view_progress_container.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--LOADING-->
<FrameLayout
android:id="@+id/layoutLoading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
*here are some elements*
</FrameLayout>
<!--LOADING-->
<!-- NOTICE-->
<FrameLayout
android:id="@+id/layoutNotice"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
*here are some elements*
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
<!-- NOTICE-->
</FrameLayout>
在片段中使用(只是随机生成状态)
class CatalogFragment : Fragment() {
private lateinit var binding : FragmentCatalogBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentCatalogBinding.inflate(inflater,container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
refreshAll()
}
private fun refreshAll() {
when((0..100).random()) {
in 0..33 -> binding.progressContainer.state = ProgressContainer.State.Loading
in 34..66 -> binding.progressContainer.state = ProgressContainer.State.Notice(
R.string.catalog_notice_error,
R.string.catalog_notice_error_message) {
refreshAll()
}
in 67..100 -> binding.progressContainer.state = ProgressContainer.State.Success
}
}
}