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.