코틀린 개인 과제

뉴스 리더 앱

songyooho 2024. 7. 18. 20:02

1. 구현 기능

1)타이틀을 따로 프래그먼트에 리사이클러뷰가 들어간 형태로 구현

2)세로화면에선 타이틀 클릭시 화면이 디테일 프래그먼트로 변경

3)가로화면에서는 타이틀과 디테일 프래그먼트가 같이 존재하도록 설정

4)타이틀을 클릭하면 디테일 프래그먼트로 데이터 전송

 

2.구현

1)NewsItem

data class NewsItem(val title: String, val article: String)

-뉴스 제목과 기사내용을 담은 데이터 클래스

 

2)CustomAdapter

class CustomAdapter(val datas:Array<NewsItem>): RecyclerView.Adapter<CustomAdapter.Holder>() {

    interface ItemClick{
        fun onClick(str:String)
    }

    var itemClick:ItemClick? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
        Holder(ItemTitleBinding.inflate(LayoutInflater.from(parent.context),parent,false))

    override fun onBindViewHolder(holder: Holder, position: Int) {
        holder.binding.root.setOnClickListener{
            itemClick?.onClick(datas[position].article)
        }

        holder.title.text = datas[position].title
    }

    override fun getItemCount(): Int = datas.size


    inner class Holder(val binding: ItemTitleBinding): RecyclerView.ViewHolder(binding.root){
        var title = binding.textTitle
    }
}

-기본적인 형태의 리사이클러뷰로 아이템 클릭시 해당 포지션에 연결된 NewsItem에 담긴 기사를 인자로 넘겨주도록 한다.

 

3)TitleFragment

class TitleFragment : Fragment() {

    private var _binding : FragmentTitleBinding? = null
    private val binding get() = _binding!!

    private val adapter by lazy {
        CustomAdapter(arrayOf(
            NewsItem(getString(R.string.title1),getString(R.string.article1)),
            NewsItem(getString(R.string.title2),getString(R.string.article2)),
            NewsItem(getString(R.string.title3),getString(R.string.article3)),
            NewsItem(getString(R.string.title4),getString(R.string.article4)),
            NewsItem(getString(R.string.title5),getString(R.string.article5)),
            NewsItem(getString(R.string.title1),getString(R.string.article1)),
            NewsItem(getString(R.string.title2),getString(R.string.article2)),
            NewsItem(getString(R.string.title3),getString(R.string.article3)),
            NewsItem(getString(R.string.title4),getString(R.string.article4)),
            NewsItem(getString(R.string.title5),getString(R.string.article5)),
            NewsItem(getString(R.string.title1),getString(R.string.article1)),
            NewsItem(getString(R.string.title2),getString(R.string.article2)),
            NewsItem(getString(R.string.title3),getString(R.string.article3)),
            NewsItem(getString(R.string.title4),getString(R.string.article4)),
            NewsItem(getString(R.string.title5),getString(R.string.article5))
        ))
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentTitleBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()

    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    fun initView(){
        binding.titleRecyclerview.apply {
            this@TitleFragment.adapter.itemClick=object : CustomAdapter.ItemClick{
                override fun onClick(str: String) {
                    if(roations() == android.view.Surface.ROTATION_90){
                        val fragment = DetailFragment.newInstance(str)
                        parentFragmentManager.beginTransaction().
                                replace(R.id.article_container, fragment).commit()
                    }
                    else{
                        val fragment = DetailFragment.newInstance(str)
                        parentFragmentManager.beginTransaction().
                            replace(R.id.fragment_container, fragment).addToBackStack(null).commit()
                    }
                }
            }
            layoutManager = LinearLayoutManager(context,LinearLayoutManager.VERTICAL, false)
            adapter = this@TitleFragment.adapter
            addItemDecoration(DividerItemDecoration(context, LinearLayout.VERTICAL))

        }
    }

    fun roations() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        requireActivity().display!!.rotation
    } else {
        requireActivity().windowManager.defaultDisplay.rotation
    }

    companion object{
        fun newInstance() = TitleFragment()
    }
}

-여기서 기사 데이터를 설정하고 리사이클러뷰로 

-화면 회전여부를 감지하는 함수를 만들어서 세로방향일시엔 현재 프래그먼트가 붙어있는 화면에 replace를 통해 디테일 프래그먼트를 붙여주고, 가로방향일시에는 따로 할당된 컨테이너에 디테일 프래그먼트를 붙여준다.

-이때 클릭에서 넘겨받은 기사내용 문자열을 newInstance()로 argument에 넘겨준다.

 

4)DetailFragment

class DetailFragment : Fragment() {

    private var param1:String? = null

    private var _binding: FragmentDetailBinding? = null
    private val binding get() = _binding!!

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentDetailBinding.inflate(inflater,container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.article.text = param1
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    companion object{
        @JvmStatic
        fun newInstance(param1:String) = DetailFragment().apply {
            arguments = Bundle().apply {
                putString(ARG_PARAM1,param1)
            }
        }
    }

}

-arguments로 넘겨받은 기사를 화면에 띄워준다.