效果图:
之前在这篇文章介绍了如何基于TextView实现带搜索框的Spinner
直到拿到项目中使用,才发现了各式各样的问题,想着解决这些问题太麻烦了,所以决定重写
现在看来,很庆幸当时决定重写,因为重写后很多地方的代码看起来不像之前那么绕,之前一个onClick方法写了一堆代码,现在的onClick方法也简化了很多
先初始化3个常用变量
val screenHeight = context.resources.displayMetrics.heightPixels
val statusBarHeight = getStatusBarHeight()
val elevationSize = 16f
private fun getStatusBarHeight():Int{
val resourceId = Resources.getSystem().getIdentifier("status_bar_height", "dimen", "android")
if (resourceId > 0) {
return Resources.getSystem().getDimensionPixelSize(resourceId)
}
return 0
}
这次的实现是基于LinearLayout,实现的思路和上次差不多,只是很多细节不一样
根View
1,设置LinearLayout的orientation为Horizontal
2,添加TextIView和ImageView分别用于显示文本和箭头
3,设置onClick
这里之所不使用TextView是因为要在TextView里面控制箭头旋转太麻烦了
private val textView : TextView
private val imageView : ImageView
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
textView = TextView(context)
textView.gravity = Gravity.CENTER_VERTICAL
//最大行数必须只能为1行
textView.maxLines = 1
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
textView.textColor = 0xff000000.toInt()
//设置结尾 ...
textView.ellipsize = TextUtils.TruncateAt.END
val param1 = generateDefaultLayoutParams() as LinearLayout.LayoutParams
param1.gravity = Gravity.CENTER_VERTICAL
//ImageView用剩下的都给TextView用
param1.weight = 1f
textView.layoutParams = param1
super.addView(textView)
imageView = ImageView(context)
imageView.setImageResource(R.drawable.search_down)
val param2 = LinearLayout.LayoutParams(dip(10), dip(10))
param2.gravity = Gravity.CENTER_VERTICAL
//设置左右margin
param2.marginStart = dip(2.5f)
param2.marginEnd = dip(2.5f)
imageView.layoutParams = param2
imageView.adjustViewBounds = true
super.addView(imageView)
setOnClickListener(this)
}
//旋转图片,true为重置,false为旋转
private fun animateArrow(isRelease: Boolean) {
if (isRelease) {
imageView.animate().rotation(0f).start()
} else {
imageView.animate().rotation(180f).start()
}
}
PopupWindow的根View依然是RelativeLayout,里面存放
1,EditText:用于搜素(下面使用popupEditText表示)
2,ListView:用于显示数据(下面用popupListView表示)
3,TextView:用于没有搜索结果的提示(下面用popupTextView表示)
private val popupWindow: PopupWindow
private val popupEditText : EditText
private val popupTextView : TextView
private val popupListView : ListView
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
popupWindow = PopupWindow(context)
popupWindow.isFocusable = true
popupWindow.isOutsideTouchable = true