一、自定义编辑框
效果图:
主要的代码为:
class EditLayout @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
private var editTitle: String
private var editContent: String
private var editType: Int
private var isMust: Boolean
private var tvLabelEdit: TextView
private var ivMustEdit: ImageView
private var etEdit: EditText
private var editable: Boolean
init {
LayoutInflater.from(context).inflate(R.layout.layout_edit, this)
tvLabelEdit = findViewById(R.id.tv_label_edit)
ivMustEdit = findViewById(R.id.iv_must_edit)
etEdit = findViewById(R.id.et_edit)
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.EditLayout)
editTitle = typedArray.getString(R.styleable.EditLayout_editTitle) ?: ""
editContent = typedArray.getString(R.styleable.EditLayout_editContent) ?: ""
editType = typedArray.getInt(R.styleable.EditLayout_editType, 1)
editable = typedArray.getBoolean(R.styleable.EditLayout_editable, true)
isMust = typedArray.getBoolean(R.styleable.EditLayout_isMust, false)
typedArray.recycle();
applyLabel()
applyIv()
applyEdit()
}
private fun applyLabel() {
tvLabelEdit.text = editTitle
etEdit.setText(editContent)
}
private fun applyIv() {
ivMustEdit.visibility = if (isMust) View.VISIBLE else View.GONE
}
private fun applyEdit() {
etEdit.inputType = when (editType) {
1 -> InputType.TYPE_CLASS_TEXT
2 -> InputType.TYPE_CLASS_NUMBER
else -> InputType.TYPE_CLASS_TEXT
}
etEdit.isEnabled = editable
}
fun getEditText(): EditText {
return etEdit
}
fun getInputText(): String {
return etEdit.text.toString()
}
fun setInputText(input: String) {
etEdit.setText(input)
}
}
使用3个原生控件组合而成,具体的代码可以到这里下载:
https://download.csdn.net/download/wy313622821/88467564
二、悬浮窗
主要的代码:
@SuppressLint("ClickableViewAccessibility")
class FloatWindow(private val mContext: Context) : LifecycleService() {
private var floatRootView: View? = null
private val mBinding: WindowFloatBinding by lazy {
DataBindingUtil.inflate(LayoutInflater.from(mContext), R.layout.window_float, null, false)
}
private val windowManager: WindowManager by lazy {
mContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
}
private val layoutParams: WindowManager.LayoutParams by lazy {
WindowManager.LayoutParams().apply {
width = WindowManager.LayoutParams.WRAP_CONTENT
height = WindowManager.LayoutParams.WRAP_CONTENT
flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
gravity = Gravity.END
type = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
WindowManager.LayoutParams.TYPE_PHONE
}
}
}
private var mAllDoorListen: () -> Unit = {}
init {
floatRootView = mBinding.root
floatRootView?.setOnTouchListener(ItemViewTouchListener(layoutParams, windowManager))
floatRootView?.setBackgroundColor(Color.TRANSPARENT)
val outMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(outMetrics)
layoutParams.format = PixelFormat.TRANSPARENT
mBinding.tvOpenDoorAll.setOnClickListener {
}
mBinding.clLeft.setOnClickListener {
Log.e("TAG", "缩小")
indenteOrExpand()
}
}
/** 缩进或者展开 **/
private fun indenteOrExpand() {
mBinding.llContentOperate.let {
if (it.visibility == View.GONE) {
it.visibility = View.VISIBLE
mBinding.ivIndenteExpand.setImageResource(R.mipmap.ic_indentation_float)
} else {
it.visibility = View.GONE
mBinding.ivIndenteExpand.setImageResource(R.mipmap.ic_expand_float)
}
}
}
inner class ItemViewTouchListener(
private val wl: WindowManager.LayoutParams,
private val windowManager: WindowManager
) : View.OnTouchListener {
// private var x = 0
private var y = 0
override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
Log.e("TAG", "位置改变")
when (motionEvent.action) {
MotionEvent.ACTION_DOWN -> {
// x = motionEvent.rawX.toInt()
y = motionEvent.rawY.toInt()
}
MotionEvent.ACTION_MOVE -> {
// val nowX = motionEvent.rawX.toInt()
val nowY = motionEvent.rawY.toInt()
// val movedX = nowX - x
val movedY = nowY - y
// x = nowX
y = nowY
wl.apply {
// x += movedX
y += movedY
}
//更新悬浮球控件位置
windowManager.updateViewLayout(view, wl)
}
else -> {
}
}
return false
}
}
/** 悬浮窗显示 */
fun show() {
windowManager.addView(floatRootView, layoutParams)
}
/** 悬浮窗移除 */
fun remove() {
floatRootView?.let {
windowManager.removeViewImmediate(it)
floatRootView = null
}
}
/** 设置全部开启按钮监听 */
fun setOpenAllListener(mListen: () -> Unit) {
mAllDoorListen = mListen
}
}
详细的代码请到这里下载:https://download.csdn.net/download/wy313622821/88468147