ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 안드로이드 앱 개발 연습 - 4 | Fragment
    Archive/캡스톤디자인 2022. 3. 25. 17:26

    Activity에 Fragment 추가

    frameLayout

    MainActivity.kt

    class MainActivity : AppCompatActivity() {
        val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(binding.root)
    
            setFragment()
        }
    
        fun setFragment() {
        	// Transaction: begin transaction => add fragment => commit transaction
            
            val listFragment: ListFragment = ListFragment()
            val transaction = supportFragmentManager.beginTransaction() // begin transaction
            transaction.add(R.id.frameLayout, listFragment) // add fragment
            transaction.commit() // commit transaction
        }
    }

     

    ListFragment.kt

    class ListFragment : Fragment() {
        lateinit var binding: FragmentListBinding
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            binding = FragmentListBinding.inflate(inflater, container, false)
            return binding.root
        }
    }

     

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <FrameLayout
            android:id="@+id/frameLayout"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="parent">
    
        </FrameLayout>
    
    </androidx.constraintlayout.widget.ConstraintLayout>

    fragmentContainerView

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <androidx.fragment.app.FragmentContainerView
            ...
            tools:layout="@layout/fragment_list" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>

    Fragment 화면 전환 (MainActivity에 Fragment 연결)

    MainActivity.kt

    class MainActivity : AppCompatActivity() {
        val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(binding.root)
    
            setFragment()
        }
    
        fun setFragment() {
        	// Transaction: begin transaction => add fragment => commit transaction
            
            val listFragment: ListFragment = ListFragment()
            val transaction = supportFragmentManager.beginTransaction() // begin transaction
            transaction.add(R.id.frameLayout, listFragment) // add fragment
            transaction.commit() // commit transaction
        }
        
        fun goDetail() {
            val detailFragment = DetailFragment()
            val transaction = supportFragmentManager.beginTransaction() // begin transaction
            transaction.add(R.id.frameLayout, detailFragment) // add fragment
            transaction.addToBackStack("detail") // for using android back button
            transaction.commit() // commit transaction
        }
    
        fun goBack() {
            onBackPressed() // Activity's Original Method
        }
    }

    ListFragment.kt

    class ListFragment : Fragment() {
        var mainActivity: MainActivity? = null
        lateinit var binding: FragmentListBinding
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            binding = FragmentListBinding.inflate(inflater, container, false)
            binding.nextBtn.setOnClickListener { mainActivity?.goDetail() }
            return binding.root
        }
    
        override fun onAttach(context: Context) {
            super.onAttach(context)
            if (context is MainActivity) mainActivity = context
        }
    }

    DetailFragment.kt

    class DetailFragment : Fragment() {
        lateinit var mainActivity: MainActivity
        lateinit var binding: FragmentDetailBinding
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            binding = FragmentDetailBinding.inflate(inflater, container, false)
            binding.backBtn.setOnClickListener { mainActivity.goBack() }
            return binding.root
        }
    
        override fun onAttach(context: Context) {
            super.onAttach(context)
            mainActivity = context as MainActivity
        }
    }

    Fragment 값 전달

    Fragment 생성 시 값 전달 (arguments)

    MainActivity.kt

    class MainActivity : AppCompatActivity() {
        val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
        lateinit var listFragment: ListFragment
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(binding.root)
    
            setFragment()
        }
    
        fun setFragment() {
            listFragment = ListFragment()
            val transaction = supportFragmentManager.beginTransaction() // begin transaction
            transaction.add(R.id.frameLayout, listFragment) // add fragment
            transaction.commit() // commit transaction
    
            // --------------------------------------------------
            var bundle = Bundle()
            bundle.putString("key1", "List Fragment")
            bundle.putInt("key2", 2022)
            listFragment.arguments = bundle
            // --------------------------------------------------
        }
    
        fun goDetail() {
            val detailFragment = DetailFragment()
            val transaction = supportFragmentManager.beginTransaction() // begin transaction
            transaction.add(R.id.frameLayout, detailFragment) // add fragment
            transaction.addToBackStack("detail")
            transaction.commit() // commit transaction
        }
    
        fun goBack() {
            onBackPressed() // Activity's Original Method
        }
    }

     

    ListFragment.kt

    class ListFragment : Fragment() {
        var mainActivity: MainActivity? = null
        lateinit var binding: FragmentListBinding
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            binding = FragmentListBinding.inflate(inflater, container, false)
            binding.nextBtn.setOnClickListener { mainActivity?.goDetail() }
            // ------------------------------------------------------------
            binding.textTitle.text = arguments?.getString("key1")
            binding.textValue.text = "${arguments?.getInt("key2")}"
            // ------------------------------------------------------------
            return binding.root
        }
    
        override fun onAttach(context: Context) {
            super.onAttach(context)
            if (context is MainActivity) mainActivity = context
        }
    }

    ​이미 생성된 Fragment에 값 전달

    MainActivity.kt

    class MainActivity : AppCompatActivity() {
        val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
        lateinit var listFragment: ListFragment
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(binding.root)
    
            setFragment()
    
            // --------------------------------------------------------------------------------
            var sendInput: String? = null
            binding.sendInput.addTextChangedListener { sendInput = it.toString() }
            binding.sendBtn.setOnClickListener { listFragment.setValue(sendInput?:"") }
            // --------------------------------------------------------------------------------
        }
    
        fun setFragment() {
            listFragment = ListFragment()
            val transaction = supportFragmentManager.beginTransaction() // begin transaction
            transaction.add(R.id.frameLayout, listFragment) // add fragment
            transaction.commit() // commit transaction
    
            var bundle = Bundle()
            bundle.putString("key1", "List Fragment")
            bundle.putInt("key2", 2022)
            listFragment.arguments = bundle
        }
    
        fun goDetail() {
            val detailFragment = DetailFragment()
            val transaction = supportFragmentManager.beginTransaction() // begin transaction
            transaction.add(R.id.frameLayout, detailFragment) // add fragment
            transaction.addToBackStack("detail")
            transaction.commit() // commit transaction
        }
    
        fun goBack() {
            onBackPressed() // Activity's Original Method
        }
    }

     

    ListFragment

    class ListFragment : Fragment() {
        var mainActivity: MainActivity? = null
        lateinit var binding: FragmentListBinding
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            binding = FragmentListBinding.inflate(inflater, container, false)
            binding.nextBtn.setOnClickListener { mainActivity?.goDetail() }
            binding.textTitle.text = arguments?.getString("key1")
            binding.textTitle.text = "${arguments?.getInt("key2")}"
            return binding.root
        }
    
        override fun onAttach(context: Context) {
            super.onAttach(context)
            if (context is MainActivity) mainActivity = context
        }
    
        // --------------------------------------------------
        fun setValue(value: String?) {
            binding.textFromActivity.text = value
        }
        // --------------------------------------------------
    }

    Fragment 간 값 전달

    build.gradle (:app)

    ...
    
    dependencies {
        def fragment_version = "1.3.0-beta02"
        implementation "androidx.fragment:fragment:$fragment_version"
        implementation "androidx.fragment:fragment-ktx:$fragment_version"
        ...
    }

     

    ListFragment.kt

    class ListFragment : Fragment() {
        var mainActivity: MainActivity? = null
        lateinit var binding: FragmentListBinding
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            binding = FragmentListBinding.inflate(inflater, container, false)
            binding.nextBtn.setOnClickListener { mainActivity?.goDetail() }
            binding.textTitle.text = arguments?.getString("key1")
            binding.textTitle.text = "${arguments?.getInt("key2")}"
            return binding.root
        }
    
        // --------------------------------------------------------------------------------
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            val bundle = Bundle()
            var toFragmentInput: String? = null
    
            binding.toFragmentInput.addTextChangedListener { toFragmentInput = it.toString() }
            binding.nextBtn.setOnClickListener {
                bundle.putString("valueKey", toFragmentInput?: "")
                setFragmentResult("request", bundle)
                mainActivity?.goDetail()
            }
        }
        // --------------------------------------------------------------------------------
        
        override fun onAttach(context: Context) {
            super.onAttach(context)
            if (context is MainActivity) mainActivity = context
        }
    
        fun setValue(value: String?) {
            binding.textFromActivity.text = value
        }
    }

     

    DetailFragment.kt

    class DetailFragment : Fragment() {
        lateinit var mainActivity: MainActivity
        lateinit var binding: FragmentDetailBinding
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            binding = FragmentDetailBinding.inflate(inflater, container, false)
            binding.backBtn.setOnClickListener { mainActivity.goBack() }
            return binding.root
        }
    
        // ----------------------------------------------------------------------
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            setFragmentResultListener("request") { requestKey, bundle ->
                bundle.getString("valueKey")?.let {
                    binding.fromFragmentText.text = it
                }
            }
        }
        // ----------------------------------------------------------------------
    
        override fun onAttach(context: Context) {
            super.onAttach(context)
            mainActivity = context as MainActivity
        }
    }

    댓글