카테고리 없음

UMC project 2주차(23/01/11~)

취업하고싶다! 2023. 1. 12. 20:07

<23/01/11>

앞에서 해결 못했던 문제들은 계속 찾아보고 있다.

우선, 이번주차에는 홈화면을 구현하기로 했다.

 

홈화면

사진을 보면 BottomNavigationView를 사용하고 각 화면들은 Fragment로 구현해야 한다.

BottomNavigationView 사용방법이 잘 기억나지 않아 찾아보았다.


BottomNavigationView 사용법

 

  1. res폴더 Resource type을 Menu로 선택하고 bottom_nav_menu.xml 파일 만들기
  2.  bottom_nav_menu.xml 파일에 실제로 표시될 항목들 정의
    • 하나의 아이템이 하나의 버튼 역할
      • android:id는 해당 버튼의 ID라고 생각하면 됨
      • android:icon 은 해당 버튼의 아이콘이라고 생각하면 됨
      • android:title 은 해당 버튼을 나타내는 Text 부분
  3. activity_main.xml 파일에 보여질 화면인 FrameLayout 작성하고 아래에 BottomNavigationView 작성
    • 아이템이 4개 이상이면 텍스트는 보이지 않고 이미지만 보임. 텍스트도 보여주려면 BottomNavigationView안에 app:labelVisibilityMode="labeled" 적어줘야 함
  4. 각 아이템들을 눌렀을 때 보여질 Fragment 파일들 생성
  5. MainActivity에서 코드 작성

bottom_nav_menu.xml

 

activity_main.xml

 

// MainActivity 코드

class MainActivity : AppCompatActivity() {

    private val fl: FrameLayout by lazy {
        findViewById(R.id.main_frm)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val main_bnv = findViewById<BottomNavigationView>(R.id.main_bnv)

        //supportFragmentManager.beginTransaction().add(R.id.fl_con, NaviHomeFragment()).commit()

        main_bnv.setOnItemSelectedListener { item ->
            changeFragment(
                when (item.itemId) {
                    R.id.navigation_home -> {
                        main_bnv.itemIconTintList = ContextCompat.getColorStateList(this, R.color.purple_200)
                        main_bnv.itemTextColor = ContextCompat.getColorStateList(this, R.color.purple_200)
                        NaviHomeFragment()
                        // Respond to navigation item 1 click
                    }
                    R.id.navigation_question -> {
                        main_bnv.itemIconTintList = ContextCompat.getColorStateList(this, R.color.purple_200)
                        main_bnv.itemTextColor = ContextCompat.getColorStateList(this, R.color.purple_200)
                        NaviQuestionFragment()
                        // Respond to navigation item 2 click
                    }
                    R.id.navigation_walk -> {
                        main_bnv.itemIconTintList = ContextCompat.getColorStateList(this, R.color.purple_200)
                        main_bnv.itemTextColor = ContextCompat.getColorStateList(this, R.color.purple_200)
                        NaviWalkFragment()
                        // Respond to navigation item 3 click
                    }
                    R.id.navigation_sale -> {
                        main_bnv.itemIconTintList = ContextCompat.getColorStateList(this, R.color.purple_200)
                        main_bnv.itemTextColor = ContextCompat.getColorStateList(this, R.color.purple_200)
                        NaviSaleFragment()
                        // Respond to navigation item 3 click
                    }
                    else -> {
                        main_bnv.itemIconTintList = ContextCompat.getColorStateList(this, R.color.purple_200)
                        main_bnv.itemTextColor = ContextCompat.getColorStateList(this, R.color.purple_200)
                        NaviMypageFragment()
                    }
                }
            )
            true
        }
        main_bnv.selectedItemId = R.id.navigation_home
    }

    private fun changeFragment(fragment: Fragment) {
        supportFragmentManager
            .beginTransaction()
            .replace(R.id.main_frm, fragment)
            .commit()
    }
}

 

<23/01/12>

 

이전 포스트에서 Edittext에 값이 있고 Spinner 3개가 모두 선택되었을 때 다음페이지로 넘어가는 버튼을 활성화하는 문제를 해결하지 못했었는데 오늘 해결하였다.

 

if(validEditText==true&&validSpinner1==true&&validSpinner2==true&&validSpinner3==true) {
    next_page_btn.isEnabled
    next_page_btn.isClickable
    next_page_btn.setBackgroundResource(R.drawable.start_button)
}

기존에는 변수 4개를 상단에 false로 선언하고 Edittext의 경우 텍스트가 입력되면 true로, Spinner의 경우 리스트의 아이템이 선택되었을 때 true로 설정해 위의 코드를 통해 버튼 활성화하고자하였으나 실패하였다.

로그 찍으면 값이 잘 나오는데 왜 안되는지는 모르겠다.

위의 코드를 onCreate() 하단에 작성하였었는데 이번에는 함수를 따로 밖에 적어주었다.

 

private fun checkValid(v1:Boolean, v2:Boolean, v3:Boolean, v4:Boolean){
    Log.d("Valid", (v1 && v2 && v3 && v4).toString())
    if(v1 && v2 && v3 && v4){
        next_page_btn.isEnabled = true
        next_page_btn.isClickable = true
        next_page_btn.setBackgroundResource(R.drawable.start_button)
    } else {
        next_page_btn.isEnabled = false
        next_page_btn.isClickable = false
        next_page_btn.setBackgroundResource(R.drawable.disabled_button)
    }

제일 하단에 다음과 같이 valid를 체크하는 checkValid 함수를 만들고 체크 항목이 4개이므로 v1~v4로 변수를 주었다.

변수 타입은 Boolean이고 v1~v4가 모두 true이면 버튼을 활성화&클릭 가능하게하고 버튼 색상을 바꿔주었다.

else문을 통해 하나라도 false이면 버튼을 비활성화&클릭 불가능하게하고 버튼 색상을 불가능한 버튼 색상으로 설정하였다.

 

그리고 위의 checkValid 함수를 각각의 함수 안에 다 선언해주었다.

editText의 경우 TextWatcher 내의 afterTextChanged 함수 안에 checkValid 함수를 작성하고 validEditText 값을 editText가 비어있지 않을 때 true로 설정해주었다.

 

스피너의 경우 onItemSelected 함수 안에 적어주었는데 position == 0인 아이템은 힌트 아이템이므로 position == 0 일 때는 validSpinner = false로, else 일 때 true로 설정해주고 checkValid 함수를 작성하였다. 

onNothingSelected는 아무것도 선택되지 않은 경우이므로 validSpinner = false로 두었다.

viewBinding.dogNameEdtText.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(editable: Editable) {
                validEditText = editable.isNotEmpty()
                checkValid(validEditText, validSpinner1, validSpinner2, validSpinner3)
            }
viewBinding.breedSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
        when(position) {
            0 -> {
                validSpinner1 = false
            }
            else -> {
                validSpinner1 = true
                Log.d("스피너1", "$validSpinner1")
            }
        }
        checkValid(validEditText, validSpinner1, validSpinner2, validSpinner3)

    }
    override fun onNothingSelected(p0: AdapterView<*>?) {
        validSpinner1 = false
    }
}
viewBinding.dogGenderSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
        when(position) {
            0 -> {
                validSpinner2 = false
            }
            else -> {
                validSpinner2 = true
                Log.d("스피너2", "$validSpinner2")

            }
        }
        checkValid(validEditText, validSpinner1, validSpinner2, validSpinner3)

    }

    override fun onNothingSelected(p0: AdapterView<*>?) {
        validSpinner2 = false
    }
}
viewBinding.dogAgeSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
        when (position) {
            0 -> {
                validSpinner3 = false
            }
            else -> {
                validSpinner3 = true
                Log.d("스피너3", "$validSpinner3")
            }
        }
        checkValid(validEditText, validSpinner1, validSpinner2, validSpinner3)
    }
    override fun onNothingSelected(p0: AdapterView<*>?) {
        validSpinner3 = false
    }
}

 

이렇게 함수를 정의하니까 원하던대로 모든 조건이 충족되었을 때 버튼이 활성화되었다.

기존이랑 뭐가 다른지는 아직 잘 모르겠어서 공부가 더 필요할 것 같다.