-
Notifications
You must be signed in to change notification settings - Fork 0
/
TagAdapter.kt
329 lines (289 loc) · 11.8 KB
/
TagAdapter.kt
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
package kr.ac.konkuk.koogle.Adapter
import android.content.Context
import android.text.Editable
import android.text.InputType
import android.text.TextUtils
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.*
import android.widget.LinearLayout
import androidx.core.view.children
import androidx.core.view.setMargins
import androidx.recyclerview.widget.RecyclerView
import kr.ac.konkuk.koogle.Model.TagModel
import kr.ac.konkuk.koogle.Model.TagType
import kr.ac.konkuk.koogle.R
import java.security.spec.EllipticCurve
/*
2021-05-27 주예진 작성
프로필에서 표시되는 태그 Recycler View 의 row adapter
대분류 태그(제목)와 소분류 태그를 표시
isSetting: 프로필에서 사용할 것인지 프로필 편집 창에서 사용할 것인지에 따라
태그를 누를 수 있는 지 여부가 결정됨
*/
class TagAdapter(val context: Context, val data: MutableList<TagModel>,
val isSetting: Boolean)
: RecyclerView.Adapter<RecyclerView.ViewHolder>(){
interface OnItemClickListener {
fun onItemClick(holder: DefaultViewHolder, view: EditText, data: TagModel, position: Int)
}
var itemClickListener: OnItemClickListener? = null
var subTagClickListener: OnItemClickListener? = null
// ProfileActivity 가 아닌 EditProfileActivity 에서만 사용해야 함
// AddNewTagActivity 에서 새롭게 받아온 것들 넣기
fun updateData(new_data: ArrayList<TagModel>){
for(tag in new_data){
var index = -1
for((i, d) in data.withIndex()){
// 이미 동일한 태그가 있을 때
if(tag.main_tag_name == d.main_tag_name){
index = i
break
}
}
// 중복 태그는 subTag 만 추가하기
if(index>-1){
for(s in tag.sub_tag_list){
// 서브태그도 중복 확인 후 추가하기
if(!data[index].sub_tag_list.contains(s))
data[index].sub_tag_list.add(s)
}
}
// 새로운 태그 추가하기
else{
data.add(TagModel(
tag.main_tag_name, tag.sub_tag_list, tag.value, tag.tag_type
))
}
}
notifyDataSetChanged()
}
fun moveItem(oldPos: Int, newPos: Int) {
val item = data[oldPos]
data.removeAt(oldPos)
data.add(newPos, item)
notifyItemMoved(oldPos, newPos)
}
fun removeItem(pos: Int) {
data.removeAt(pos)
notifyItemRemoved(pos)
}
inner class DefaultViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var mainTagText: TextView = itemView.findViewById(R.id.mainTagText)
var mainTag: String = ""
var subTagView: LinearLayout = itemView.findViewById(R.id.subTagView)
var nowIndex: Int = -1
var editNowSub: Int = -1
private fun editTagStart(subTagName: String): Boolean{
if(nowIndex==-1) return false
// 새로 추가된 태그의 경우
if(subTagName == " "){
editNowSub = data[nowIndex].sub_tag_list.size - 1
}
for((i, st) in data[nowIndex].sub_tag_list.withIndex()){
if(subTagName == st){
editNowSub = i
return true
}
}
for((j, t) in data.withIndex()){
}
return false
}
private fun editTag(subTagName: String){
if(subTagName.isNullOrBlank())
data[nowIndex].sub_tag_list.removeAt(editNowSub)
else
data[nowIndex].sub_tag_list[editNowSub] = subTagName
}
// SubTag 한 칸을 생성한다.
fun makeSubTagView(tagName: String): TextView {
var subTagText = EditText(context)
subTagText.isFocusable = isSetting
subTagText.setText(tagName)
// 모서리가 둥근 태그 스타일 적용(임시)
subTagText.setTextAppearance(R.style.TAG_STYLE)
subTagText.setBackgroundResource(R.drawable.layout_tag_background)
// 태그 간 간격 설정
val p = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
p.setMargins(5)
subTagText.layoutParams = p
// 편집 세팅
subTagText.addTextChangedListener(object: TextWatcher{
override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
if(!editTagStart(subTagText.text.toString()))
Log.d("jan", "editTagFail")
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
editTag(subTagText.text.toString())
if(s.isNullOrBlank()){
for (c in subTagView.children)
((c as ScrollView).getChildAt(0) as LinearLayout).removeView(subTagText)
}
}
})
// 클릭 이벤트 설정
subTagText.setOnClickListener {
subTagClickListener?.onItemClick(this, subTagText, data[adapterPosition], adapterPosition)
}
return subTagText
}
private fun getRow(index: Int): LinearLayout{
return (subTagView.getChildAt(index) as ScrollView).getChildAt(0) as LinearLayout
}
// 태그 추가 버튼
private fun makePlusBtn(): TextView {
var subTagText = TextView(context)
subTagText.text = "+"
// 태그 간 간격 설정
val p = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
p.setMargins(5)
subTagText.layoutParams = p
// 모서리가 둥근 태그 스타일 적용(임시)
subTagText.setTextAppearance(R.style.TAG_STYLE)
subTagText.setBackgroundResource(R.drawable.layout_tag_background)
subTagText.maxLines = 1
subTagText.ellipsize = TextUtils.TruncateAt.MARQUEE
subTagText.isSingleLine = true
subTagText.inputType = InputType.TYPE_CLASS_TEXT
// 새 태그 추가 기능
subTagText.setOnClickListener {
var lastRow: LinearLayout = getRow(subTagView.childCount - 1)
// 이미 빈 태그가 있으면 추가하지 않음
if((lastRow.getChildAt(lastRow.childCount - 1) as TextView).text.toString()
== " ") return@setOnClickListener
lastRow.addView(makeSubTagView(" "), lastRow.childCount-1)
}
return subTagText
}
// 소분류 태그 테이블 생성
fun bind(model: TagModel) {
var lastRow: LinearLayout
for (tag in model.sub_tag_list) {
// row 가 하나도 없으면 새로 만들기
if (subTagView.childCount == 0) {
addRow()
}
// 새로운 Table row 를 추가해야 하는지 길이 검사
lastRow = getRow(subTagView.childCount - 1)
var len = 0
val row_len = 26
val margin = 1
for (i in lastRow.children) {
i as TextView
len += i.text.length + margin
}
len += tag.length
if (len > row_len) {
addRow()
}
lastRow = getRow(subTagView.childCount - 1)
lastRow.addView(makeSubTagView(tag))
}
// 프로필 편집 액티비티의 경우 + 버튼 추가
if(isSetting){
lastRow = getRow(subTagView.childCount - 1)
lastRow.addView(makePlusBtn())
// 데이터에 추가
for(d in data){
if(d.main_tag_name == mainTag){
d.sub_tag_list.add(" ")
}
}
}
// 현재 Main Tag 의 View index 구함
// 리사이클러 뷰 내 위치 변경 시에도 업데이트 되어야 함
for ((i, t) in data.withIndex()){
if(t.main_tag_name == mainTag) nowIndex = i
}
}
// 태그 row 추가
private fun addRow() {
val row = LinearLayout(context)
val lp: LinearLayout.LayoutParams =
LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
row.orientation = LinearLayout.HORIZONTAL
row.layoutParams = lp
val newScrollView = ScrollView(context)
val layoutParams = LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
newScrollView.layoutParams = layoutParams
val linearParams = LinearLayout.LayoutParams(
800,
ViewGroup.LayoutParams.WRAP_CONTENT
)
row.orientation = LinearLayout.HORIZONTAL
row.layoutParams = linearParams
newScrollView.addView(row)
subTagView.addView(newScrollView)
}
}
// Tag 밑에 수치형 데이터 가 있는 형태의 row
inner class ValueViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val mainTagText: TextView = itemView.findViewById(R.id.mainTagText)
val valueText: TextView = itemView.findViewById(R.id.tagValueText)
var mainTag: String = ""
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view:View
return when(viewType){
TagType.TAG ->{
view = LayoutInflater.from(context).inflate(R.layout.row_user_tag, parent, false)
DefaultViewHolder(view)
}
TagType.VALUE->{
view = LayoutInflater.from(context).inflate(R.layout.row_user_value, parent, false)
ValueViewHolder(view)
}
else -> {
view = LayoutInflater.from(context).inflate(R.layout.row_user_tag, parent, false)
DefaultViewHolder(view)
}
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val tagName: String = data[position].main_tag_name
if(holder is DefaultViewHolder){
holder.mainTag = tagName
holder.mainTagText.text = tagName
// 바인드 할 때 마다 다시 생성
holder.subTagView.removeAllViews()
holder.bind(data[position])
}else if(holder is ValueViewHolder){
holder.mainTag = tagName
holder.mainTagText.text = tagName
holder.valueText.text = data[position].value.toString()
}else {
//(holder as SettingViewHolder)
}
}
override fun getItemCount(): Int {
return data.size
}
// 헤더의 경우 메뉴에 포함되지 않으므로 제외
override fun getItemViewType(position: Int): Int {
return data[position].tag_type
}
}