自定义复合View中Button可见,但TextView/ImageView不可见求助
问题原因分析
你重写的addView(child: View?)只是FrameLayout众多addView重载方法中的一个。当系统添加TextView或ImageView时,会调用其他重载版本(比如addView(View, LayoutParams)、addView(View, int)等),这些方法没被重写,导致子View被直接添加到外层FrameLayout中,而非目标的holder CardView。外层FrameLayout上的标题CardView会遮挡这些子View,或者因布局层级问题导致它们无法正常显示。
Button能正常显示是偶然情况——系统对Button的布局处理刚好调用了你重写的那个addView方法。
解决方案
重写所有FrameLayout的addView重载方法,确保所有子View都被添加到holder CardView中:
import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import android.widget.TextView import androidx.cardview.widget.CardView class CompoundCardView : FrameLayout{ private var childView:CardView? = null private var heading:String? = null set(value) { field = value invalidate() requestLayout() } get() = field constructor(context: Context) : super(context) { init(context, null) } constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { init(context, attrs) } constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) { init(context, attrs) } private fun init(context: Context, attrs: AttributeSet?) { context.theme.obtainStyledAttributes(attrs,R.styleable.CompoundCardView,0,0).apply { try { heading = getString(R.styleable.CompoundCardView_heading) }finally { recycle() } } val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater inflater.inflate(R.layout.compaund_card_view,this,true) childView = findViewById(R.id.holder) val header:TextView = findViewById(R.id.header) header.text = heading } // 重写所有addView重载方法,统一将子View添加到holder中 override fun addView(child: View?) { childView?.addView(child) requestLayout() invalidate() } override fun addView(child: View?, index: Int) { childView?.addView(child, index) requestLayout() invalidate() } override fun addView(child: View?, params: ViewGroup.LayoutParams?) { childView?.addView(child, params) requestLayout() invalidate() } override fun addView(child: View?, width: Int, height: Int) { childView?.addView(child, width, height) requestLayout() invalidate() } override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) { childView?.addView(child, index, params) requestLayout() invalidate() } }
额外优化建议
- 给
holderCardView添加app:contentPadding属性,避免子View紧贴边框,提升视觉体验; - 初始化
childView后增加非空判断,避免空指针异常。
内容的提问来源于stack exchange,提问作者Samaresh Sautia
相关产品推荐
相关产品推荐

