Skip to content

List 일기 리스트, 필터

heewon edited this page Jan 15, 2021 · 3 revisions

List 일기 리스트, 필터


📱 구현 화면



리스트 뷰와 필터 모달이 함께 공유해서 사용하는 변수 선언

ListActivity.kt
companion object {

        var filter_year = 0
        var filter_month = 0
        var filter_emotion : Int? = null
        var filter_depth : Int? = null
        var filter_current_year = 0
        var filter_current_month = 0
        var selectCurrentDate = false
        lateinit var mContext : Context
    }



필터 모달창의 감정/깊이 checkbox 중 한 개의 버튼만 선택될 수 있도록 구현

FilterBottomSheetFragment.kt
    private fun initEmotionCheckBox() {
        binding.imgbtnFilterLove.selectEmotion()
        binding.imgbtnFilterHappy.selectEmotion()
        binding.imgbtnFilterConsole.selectEmotion()
        binding.imgbtnFilterAngry.selectEmotion()
        binding.imgbtnFilterSad.selectEmotion()
        binding.imgbtnFilterBored.selectEmotion()
        binding.imgbtnFilterMemory.selectEmotion()
        binding.imgbtnFilterDaily.selectEmotion()
    }

    private fun CheckBox.selectEmotion() {
        this.setOnClickListener {
            if (this.isChecked) {
                disableEmotionCheckBox()
                this.isChecked = true

                addEmotionId(this.id)
                activeApplyButton()
            }
            else if (!this.isChecked) {
                this.isChecked = false
                selectEmotion = null
            }
        }
    }



필터 모달에서 선택한 항목 리스트 뷰로 전달

FilterBottomSheetFragment.kt
private fun activeApplyButton() {
        binding.btnFilterApply.isEnabled = true
        binding.btnFilterApply.setOnClickListener {

            val pickDate = intArrayOf(selectYear, selectMonth)

            itemClick(selectDate, pickDate, isCurrentDate, selectEmotion, selectDepth)

            this.dismiss()
        }

    }



필터 모달창에서 받아온 항목을 기반으로 일기 필터링

ListActivity.kt
val frag = FilterBottomSheetFragment { date: String, pickDate : IntArray, isCurrentDate: Boolean, emotion: Int?, depth: Int? ->

                    filter_year = pickDate[0]
                    filter_month = pickDate[1]
                    filter_emotion = emotion
                    filter_depth = depth
                    selectCurrentDate = isCurrentDate

                    binding.collapsingtoolbarlayoutList.title = date

                    activeFilterButton()

                    setLabelData()

                    loadFilterLabelData()

                    loadFilteredData()

                }
                frag.show(supportFragmentManager, frag.tag)



필터 라벨 설정 및 필터링한 데이터 로드

ListActivity.kt
private fun loadFilterLabelData() {

        if (filter_emotion == null && filter_depth == null) {
            binding.rcvFilterLabel.visibility = View.GONE
        }
        else {
            binding.rcvFilterLabel.visibility = View.VISIBLE

            if (filter_emotion == null && filter_depth != null) {
                filterLabelAdapter.data = mutableListOf(FilterLabelData(selectDepth))
            }

            if (filter_emotion != null && filter_depth == null) {
                filterLabelAdapter.data = mutableListOf(FilterLabelData(selectEmotion))
            }

            if (filter_emotion != null && filter_depth != null) {
                filterLabelAdapter.data =
                    mutableListOf(FilterLabelData(selectEmotion), FilterLabelData(selectDepth))
            }
            filterLabelAdapter.notifyDataSetChanged()
        }
    }
private fun loadListData(data: List<ListData>) {
        if (data.isNotEmpty()) {
            binding.rcvList.visibility = View.VISIBLE
            binding.constraintlayoutListFilterdNone.visibility = View.GONE
            binding.constraintlayoutListNone.visibility = View.GONE

            listAdapter.data = mutableListOf()

            for (i in 0..data.size-1) {
                listAdapter.data.add(
                    com.example.momo_android.list.adapter.ListData(
                        baseContext?.getDrawable(getEmotionImg(data[i].emotionId)),
                        data[i].Emotion.name,
                        getFormedDate(data[i].wroteAt),
                        getFormedDay(data[i].wroteAt),
                        getDepthString(data[i].depth),
                        data[i].Sentence.contents,
                        data[i].Sentence.writer,
                        "<" + data[i].Sentence.bookName + ">",
                        "(" + data[i].Sentence.publisher + ")",
                        data[i].contents
                    )
                )
            }
        }
        listAdapter.notifyDataSetChanged()

        initItemClickListener(data)
    }



customUnderLineTextView로 textColor와 다른 색상의 밑줄 생성

UnderlineTextView.kt
init {
        val density = context.resources.displayMetrics.density

        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.UnderlineTextView, defStyleAttr, 0)
        lineColor = typedArray.getColor(R.styleable.UnderlineTextView_underlineColor, currentTextColor)
        lineTopOffset = typedArray.getDimension(R.styleable.UnderlineTextView_underlineOffset, 0f)
        lineHeight = typedArray.getDimension(R.styleable.UnderlineTextView_underlineHeight, density * 1)
        linePosition = typedArray.getInt(R.styleable.UnderlineTextView_underLinePosition, POSITION_BASELINE)
        typedArray.recycle()
    }
override fun onDraw(canvas: Canvas?) {
        canvas?.takeIf { !text.isNullOrEmpty() }?.let {
            val count = lineCount
            val layout = layout
            var xStart: Float
            var xStop: Float
            var yStart: Float
            var firstCharInLine: Int
            var lastCharInLine: Int
            var lastLine: Boolean
            var offset: Int
            val lineSpacing = lineSpacingExtra * lineSpacingMultiplier
            for (i in 0 until count) {
                val baseline = getLineBounds(i, rect)
                lastLine = i == count - 1
                offset = if (lastLine) 0 else 1
                firstCharInLine = layout.getLineStart(i)
                lastCharInLine = layout.getLineEnd(i)
                xStart = layout.getPrimaryHorizontal(firstCharInLine)
                xStop = layout.getPrimaryHorizontal(lastCharInLine - offset)
                yStart = when (linePosition) {
                    POSITION_BASELINE -> baseline + lineTopOffset
                    POSITION_BELOW -> (rect.bottom + lineTopOffset) - if (lastLine) 0F else lineSpacing
                    else -> throw NotImplementedError("")
                }
                if (lastLine) {
                    canvas.drawRect(xStart, yStart, xStop, yStart + lineHeight, linePaint)
                } else {
                    canvas.drawRect(xStart, yStart, xStop + 35, yStart + lineHeight, linePaint)
                }
            }

            // (텍스트가 여러 줄인 경우) 텍스트가 버튼을 가리지 않게 적절히 잘리도록 함
            if (this.width * 2 <= this.paint.measureText(this.text.toString()).toInt()) {
                var splitedText = this.text.substring(0, layout.getLineEnd(1) - 4)
                splitedText = "$splitedText"
                this.text = splitedText
            }
            // (텍스트가 한 줄인 경우) 텍스트가 버튼을 가리지 않고 바로 다음 줄로 넘어가도록 함
            else if ((this.width * 0.97 < this.paint.measureText(this.text.toString()).toInt()) &&
                    (this.width >= this.paint.measureText(this.text.toString()).toInt())) {
                val originText = StringBuffer(this.text)
                originText.insert(layout.getLineEnd(0) - 1, "\n")
                if (lineCount == 1) {
                    this.text = originText
                }
            }
        }
        super.onDraw(canvas)
    }
item_list.kt
<com.example.momo_android.util.ui.UnderlineTextView
            android:id="@+id/tv_list_diary"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fontFamily="@font/notosans"
            android:includeFontPadding="false"
            android:text="오늘 새벽엔 눈이 내렸다."
            android:textColor="@color/black_4"
            android:lineSpacingExtra="10dp"
            android:textFontWeight="400"
            android:maxLines="2"
            android:textSize="13dp"
            app:underlineColor="@color/line_light_gray"
            app:underlineHeight="1dp"
            app:underLinePosition="below"/>