-
Notifications
You must be signed in to change notification settings - Fork 5
5.4. 키워드 선택
JiHwan edited this page Jan 15, 2021
·
8 revisions
- 입력할 때 다양한 효과를 보여주기 위해 TextInputLayout과 TextInputEditText를 사용
- 입력된 텍스트에 공백이 존재하거나, 최대 글자수를 초과하거나, 이미 있는 단어 입력을 했을 때 경고 문구 & 입력 버튼 비활성화를 위해
addTextChangedListener
를 사용
- 화면 전환을 위해 viewpager를 사용하였고 TabLayout custom
- 키워드 추가 및 선택, 취소 효과를 내기 위해 chip 사용
- chip이 추가되었을 때 추가 버튼이 맨 마지막으로 가게끔 하기 위해
binding.cgMyWord.addView(createChip("추가된 샘플"),binding.cgMyWord.childCount-1)
- chip을 눌렀을 때 색상이 바뀌게하는 스타일 및 기타 속성 지정을 위해
createChip
함수 작성
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/et_keyword_input_layout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginTop="41dp"
android:layout_marginRight="16dp"
android:hint="@string/input_value"
android:textColorHint="@color/alto"
app:boxCornerRadiusBottomEnd="15dp"
app:boxCornerRadiusBottomStart="15dp"
app:boxCornerRadiusTopEnd="15dp"
app:boxCornerRadiusTopStart="15dp"
app:boxStrokeColor="@color/selector_edittext"
app:boxStrokeErrorColor="@color/persimmon"
app:errorIconDrawable="@null"
app:hintTextColor="@color/persimmon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_keyword_guide">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_keyword_input"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="text"
android:maxLength="5"
android:maxLines="1"
android:privateImeOptions='"defaultInputmode=korean"'
android:textCursorDrawable="@drawable/edittext_cursor_cod_gray" />
private fun keywordInput() {
var sameKeyword: String
binding.etKeywordInput.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (binding.etKeywordInput.text.toString().isEmpty()) {
binding.btnAdd.isEnabled = false
binding.tvErrortext.visibility = View.INVISIBLE
binding.btnErrorIcon.visibility = View.INVISIBLE
} else if (binding.etKeywordInput.length() > 5) {
binding.btnAdd.isEnabled = false
binding.tvErrortext.visibility = View.VISIBLE
binding.btnErrorIcon.visibility = View.VISIBLE
binding.tvErrortext.setText(R.string.maximum_five_word)
} else if (binding.etKeywordInput.text.toString().contains(" ")) {
binding.btnAdd.isEnabled = false
binding.tvErrortext.visibility = View.VISIBLE
binding.btnErrorIcon.visibility = View.VISIBLE
binding.tvErrortext.setText(R.string.there_is_space)
} else if (keywordListForDuplicated.contains(binding.etKeywordInput.text.toString())) {
binding.btnAdd.isEnabled = false
sameKeyword =
"'" + binding.etKeywordInput.text.toString() + "' 은(는) " + getString(R.string.already_exist)
binding.tvErrortext.visibility = View.VISIBLE
binding.btnErrorIcon.visibility = View.VISIBLE
binding.tvErrortext.text = sameKeyword
} else if (addedMyWord.contains(binding.etKeywordInput.text.toString())) {
binding.btnAdd.isEnabled = false
sameKeyword =
"'" + binding.etKeywordInput.text.toString() + "' 은(는) " + getString(R.string.already_exist)
binding.tvErrortext.visibility = View.VISIBLE
binding.btnErrorIcon.visibility = View.VISIBLE
binding.tvErrortext.text = sameKeyword
} else if (isKoreanInWord(binding.etKeywordInput.text.toString())) {
binding.btnAdd.isEnabled = false
binding.tvErrortext.visibility = View.VISIBLE
binding.btnErrorIcon.visibility = View.VISIBLE
binding.tvErrortext.text = "특수문자, 숫자, 영어를 제외하고 입력해주세요."
} else {
binding.btnAdd.isEnabled = true
binding.tvErrortext.visibility = View.GONE
binding.btnErrorIcon.visibility = View.GONE
}
}
override fun afterTextChanged(s: Editable?) {}
})
}
<com.google.android.material.tabs.TabLayout
android:id="@+id/tl_keyword_popup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:tabBackground="@drawable/selector_tab_indicator"
app:tabGravity="center"
app:tabIndicator="@null"
app:tabPaddingEnd="9dp"
app:tabPaddingStart="9dp"
android:layout_marginTop="72dp">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/vp_keyword_popup"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/tv_popup_skip"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tl_keyword_popup" />
private fun viewPagerChange() {
binding.vpKeywordPopup.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(
position: Int,
positionOffset: Float,
positionOffsetPixels: Int
) {
btnOnOff()
}
override fun onPageSelected(position: Int) {
btnOnOff()
}
override fun onPageScrollStateChanged(state: Int) {
}
})
}
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<shape
android:shape="ring"
android:innerRadius="0dp"
android:thickness="3dp"
android:useLevel="false">
<solid android:color="#EA644B"/>
</shape>
</item>
<item>
<shape
android:shape="ring"
android:innerRadius="1dp"
android:thickness="2dp"
android:useLevel="false">
<solid android:color="@color/silver"/>
</shape>
</item>
</selector>
private fun createChip(str: String): Chip {
val chipDrawable = ChipDrawable.createFromAttributes(
this,
null,
0,
R.style.Widget_MaterialComponents_Chip_Choice
)
return Chip(this).apply {
text = str
setChipDrawable(chipDrawable)
setChipBackgroundColorResource(R.color.selector_chip)
setTextAppearance(R.style.MyDailyChipTextStyleAppearance)
setRippleColorResource(android.R.color.transparent)
setOnClickListener {
it as Chip
if (isChecked) { //주황색일 때
clickedChipCount++
if (clickedChipCount >= 9) {
binding.btnSelectFinish.isEnabled = true
it.isChecked = false
clickedChipCount--
floatingDialog()
} else if (clickedChipCount == 8) {
addKeywordList(it.text as String)
binding.btnSelectFinish.isEnabled = true
} else {
addKeywordList(it.text as String)
binding.btnSelectFinish.isEnabled = false
}
} else {
clickedChipCount--
if (clickedChipCount < 8) {
binding.btnSelectFinish.isEnabled = false
}
removeKeywordList(it.text as String)
}
}
}
}
<com.google.android.material.chip.ChipGroup
android:id="@+id/cg_my_word"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@id/tv_my_word"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<com.google.android.material.chip.Chip
android:id="@+id/chip_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIcon="@drawable/ic_add"
app:chipIconSize="32dp"
app:rippleColor="@android:color/transparent"
android:stateListAnimator="@null"
app:chipBackgroundColor="@android:color/transparent"/>
</com.google.android.material.chip.ChipGroup>
KeywordAddView | KeywordPopupView | KeywordListView |
---|---|---|