Ejercicio: Fragments con Recyclerview
Uso de fragments en Kotlin
Ejercicio: Fragments con Recyclerview
Crear el proyecto FragmentRecyclerView
Añadir dependencias en build.gradle (del módulo)
dependencias antiguas:
implementation("androidx.navigation:navigation-fragment:2.7.5") implementation("androidx.navigation:navigation-ui:2.7.5") implementation("androidx.recyclerview:recyclerview:1.3.2")
dependencias actuales
implementation(libs.androidx.navigation.fragment) implementation(libs.androidx.navigation.ui) implementation(libs.androidx.recyclerview)
colors.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="black">#FF000000</color> <color name="white">#FFFFFFFF</color> </resources>
dimens.xml
<resources> <dimen name="fab_margin">16dp</dimen> <dimen name="text_margin">16dp</dimen> </resources>
strings.xml
<resources> <string name="app_name">Cars</string> <!-- TODO: Remove or change this placeholder text --> <string name="hello_blank_fragment">Hello blank fragment</string> <string name="title_activity_main2">MainActivity</string> <!-- Strings used for fragments for navigation --> <string name="first_fragment_label">First Fragment</string> <string name="second_fragment_label">Second Fragment</string> <string name="next">Next</string> <string name="previous">Previous</string> <string name="hello_first_fragment">Hello first fragment</string> <string name="hello_second_fragment">Hello second fragment. Arg: %1$s</string> </resources>
data class DataModel.kt
data class DataModel ( var title : String )
interface ItemClickListener
interface ItemClickListener { fun onItemClick(dataModel: DataModel) }
recycler_row.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto"> <TextView android:id="@+id/titleTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_margin="20dp" android:textSize="30sp" android:textStyle="bold" android:textColor="#000000" /> </androidx.constraintlayout.widget.ConstraintLayout>
RecyclerViewAdapter.kt
class RecyclerViewAdapter( private val list: List<DataModel>, private val clickListener: ItemClickListener ) : RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.recycler_row, parent, false) return MyViewHolder(view) } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.titleTextView.text = list.get(position).title holder.itemView.setOnClickListener(View.OnClickListener { clickListener.onItemClick( list[position] ) }) } override fun getItemCount(): Int { return list.size } inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) { var titleTextView: TextView init { titleTextView = view.findViewById(R.id.titleTextView) } } // interface ItemClickListener { // fun onItemClick(dataModel: DataModel) // } }
fragment_main.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainFragment"> <!-- TODO: Update blank fragment layout --> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </FrameLayout>
MainFragment.kt
/** * A simple [Fragment] subclass. * Use the [MainFragment.newInstance] factory method to * create an instance of this fragment. */ class MainFragment : Fragment(), ItemClickListener { private lateinit var adapter : RecyclerViewAdapter private val list = ArrayList<DataModel>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment val view = inflater.inflate(R.layout.fragment_main, container, false) buildListData() initRecyclerView(view) return view } private fun initRecyclerView(view: View) { val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerView) val layoutManager = LinearLayoutManager(activity) recyclerView.layoutManager = layoutManager adapter = RecyclerViewAdapter(list, this) recyclerView.adapter = adapter //right swipe on recyclerview val itemSwipe = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) { override fun onMove( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean { //TODO("Not yet implemented") return false } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { showDialog(viewHolder) } } val swap = ItemTouchHelper(itemSwipe) swap.attachToRecyclerView(recyclerView) } private fun showDialog(viewHolder: RecyclerView.ViewHolder) { val builder = AlertDialog.Builder(activity) builder.setTitle("Delete Item") builder.setMessage("Are you sure to delete the item?") builder.setPositiveButton("Confirm") {dialog, which -> val position = viewHolder.adapterPosition list.removeAt(position) // adapter.notifyItemRemoved(position) adapter.notifyDataSetChanged() } builder.setNegativeButton("Cancel") {dialog, which -> val position = viewHolder.adapterPosition adapter.notifyItemChanged(position) } builder.show() } private fun buildListData() { list.add(DataModel("BMW")) list.add(DataModel("Audi")) list.add(DataModel("Chevrolet")) list.add(DataModel("Ford")) list.add(DataModel("Honda")) list.add(DataModel("Ferrari")) } override fun onItemClick(dataModel: DataModel) { val fragment: Fragment = DetailFragment.newInstance(dataModel.title) val transaction = activity?.supportFragmentManager!!.beginTransaction() // transaction.replace(R.id.frame_container, fragment, "detail_fragment"); transaction.hide(activity?.supportFragmentManager?.findFragmentByTag("main_fragment")!!) transaction.add(R.id.frame_container, fragment) transaction.addToBackStack(null) transaction.commit() } companion object { /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @return A new instance of fragment MainFragment. */ // TODO: Rename and change types and number of parameters fun newInstance(): MainFragment { return MainFragment() } } }
fragment_detail.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context=".DetailFragment"> <!-- TODO: Update blank fragment layout --> <TextView android:id="@+id/titleTV" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="parent" android:textStyle="bold" android:textSize="45sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:text="@string/hello_blank_fragment" /> </androidx.constraintlayout.widget.ConstraintLayout>
DetailFragment.kt
class DetailFragment : Fragment() { // TODO: Rename and change types of parameters private var mParam1: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (arguments != null) { mParam1 = arguments?.getString(ARG_PARAM1) } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment val view = inflater.inflate(R.layout.fragment_detail, container, false) val titleTV = view.findViewById<TextView>(R.id.titleTV) titleTV.text = mParam1 return view } companion object { // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER private const val ARG_PARAM1 = "param1" /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @param param1 Parameter 1. * @return A new instance of fragment DetailFragment. */ // TODO: Rename and change types and number of parameters fun newInstance(param1: String?): DetailFragment { val fragment = DetailFragment() val args = Bundle() args.putString(ARG_PARAM1, param1) fragment.arguments = args return fragment } } }
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"> <LinearLayout android:id="@+id/frame_container" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:orientation="vertical" /> </androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val fragment: Fragment = MainFragment.newInstance() val transaction = supportFragmentManager.beginTransaction() transaction.replace(R.id.frame_container, fragment, "main_fragment") transaction.commit() } }
Deja una respuesta
Lo siento, debes estar conectado para publicar un comentario.