管灌系统巡查员智能手机App
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package com.example.expand_button
 
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.EditText
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
 
class CustomSearchBar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr) {
 
    private var isExpanded = false
    private var searchIcon: ImageView
    private var searchInput: EditText
    private var searchButton: TextView
    private var onSearchClickListener: ((String) -> Unit)? = null
    private var expandedWidth = 0
    private var animationDuration: Long = 300
    private var initialWidth = 0
 
    init {
        // 创建一个新的LayoutInflater,避免使用带背景的布局
        val inflater = LayoutInflater.from(context).cloneInContext(context)
        val root = inflater.inflate(R.layout.layout_search_bar, this, false)
        // 清除布局文件中的背景
        root.background = null
        // 添加布局
        addView(root)
 
        // 初始化视图
        searchIcon = findViewById(R.id.iv_search)
        searchInput = findViewById(R.id.et_search)
        searchButton = findViewById(R.id.tv_search)
 
        // 设置初始状态
        post {
            // 保存初始宽度
            initialWidth = width
            
            // 确保搜索图标居中显示
            (searchIcon.layoutParams as RelativeLayout.LayoutParams).apply {
                removeRule(ALIGN_PARENT_START)
                addRule(CENTER_IN_PARENT)
                setMargins(0, 0, 0, 0)
            }
            
            // 初始状态隐藏输入框和搜索按钮
            searchInput.visibility = View.GONE
            searchButton.visibility = View.GONE
        }
 
        // 设置点击监听
        searchIcon.setOnClickListener {
            if (!isExpanded) {
                expand()
            }
        }
 
        searchButton.setOnClickListener {
            onSearchClickListener?.invoke(searchInput.text.toString())
            collapse()
        }
 
        // 设置整个布局的点击监听
        setOnClickListener {
            if (!isExpanded) {
                expand()
            }
        }
    }
 
    private fun expand() {
        if (isExpanded) return
 
        // 计算展开后的宽度(屏幕宽度减去左右边距)
        if (expandedWidth == 0) {
            expandedWidth = context.resources.displayMetrics.widthPixels -
                    (32 * context.resources.displayMetrics.density).toInt()
        }
 
        // 创建宽度动画
        ValueAnimator.ofInt(initialWidth, expandedWidth).apply {
            duration = animationDuration
            addUpdateListener { animator ->
                layoutParams = layoutParams.apply {
                    width = animator.animatedValue as Int
                }
            }
            start()
        }
 
        // 重置搜索图标位置
        (searchIcon.layoutParams as RelativeLayout.LayoutParams).apply {
            removeRule(CENTER_VERTICAL)
            addRule(ALIGN_PARENT_START)
            setMargins(
                (8 * context.resources.displayMetrics.density).toInt(),
                0,
                0,
                0
            )
        }
 
        // 显示输入框和搜索按钮
        searchInput.visibility = View.VISIBLE
        searchButton.visibility = View.VISIBLE
        searchInput.requestFocus()
 
        isExpanded = true
    }
 
    private fun collapse() {
        if (!isExpanded) return
 
        // 创建宽度动画
        ValueAnimator.ofInt(expandedWidth, initialWidth).apply {
            duration = animationDuration
            addUpdateListener { animator ->
                layoutParams = layoutParams.apply {
                    width = animator.animatedValue as Int
                }
            }
            start()
        }
 
        // 重置搜索图标到中心位置
        (searchIcon.layoutParams as RelativeLayout.LayoutParams).apply {
            removeRule(ALIGN_PARENT_START)
            addRule(CENTER_IN_PARENT)
            setMargins(0, 0, 0, 0)
        }
 
        // 隐藏输入框和搜索按钮
        searchInput.visibility = View.GONE
        searchButton.visibility = View.GONE
        searchInput.setText("")
 
        isExpanded = false
    }
 
    /**
     * 设置搜索按钮点击监听器
     * @param listener 回调函数,参数为输入框中的文本内容
     */
    fun setOnSearchClickListener(listener: (String) -> Unit) {
        onSearchClickListener = listener
    }
 
    /**
     * 设置动画时长
     */
    fun setAnimationDuration(duration: Long) {
        animationDuration = duration
    }
 
    /**
     * 设置提示文字
     */
    fun setHint(hint: String) {
        searchInput.hint = hint
    }
 
    /**
     * 获取输入的文本
     */
    fun getText(): String {
        return searchInput.text.toString()
    }