问题
I have simple app that have one Activity , RecyclerView adapter , RecyclerView fragment , and other fragment to display the data of that item i click in RecyclerView but my problem is I don't know how to pass the data of array row with the click fun to show after the new fragment displayed
MainActivity.kt
class MainActivity : AppCompatActivity(),ContentAdapter.ContentListener{
override fun onItemClicked(item: MainMarketTickClass) {
var ft1 : FragmentTransaction = supportFragmentManager.beginTransaction()
ft1.replace(R.id.MainFrame,AddCar.newInstanceaddcar())
ft1.commit()}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var bnv = findViewById(R.id.navigation) as BottomNavigationView
bnv.setOnNavigationItemSelectedListener (object : BottomNavigationView.OnNavigationItemSelectedListener{
override fun onNavigationItemSelected(item: MenuItem): Boolean {
var selectFragment : Fragment? = null
when (item.itemId) {
R.id.navigation_home -> {
selectFragment = MainMarket.newInstance()
}
R.id.navigation_dashboard -> {
selectFragment = AddCar.newInstanceaddcar()
}
R.id.navigation_notifications -> {
}
}
var ft : FragmentTransaction = supportFragmentManager.beginTransaction()
ft.replace(R.id.MainFrame,selectFragment)
ft.commit()
return true
}
})
var ft : FragmentTransaction = supportFragmentManager.beginTransaction()
ft.replace(R.id.MainFrame,MainMarket.newInstance())
ft.commit()
}
}
ContentAdapter.kt
class ContentAdapter constructor(private val activity: MainActivity, private var listOfData: ArrayList<MainMarketTickClass>, val listener: ContentListener) : RecyclerView.Adapter<ContentAdapter.ViewHolder>() {
override fun getItemCount(): Int = listOfData.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
var inf = ViewHolder(LayoutInflater.from(parent!!.context).inflate(R.layout.maintick, parent, false))
return inf
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(listOfData, listener)
}
class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView) {
fun bind(listOfData: ArrayList<MainMarketTickClass>, listener: ContentListener) {
val dataListin2 = listOfData[adapterPosition]
itemView.textView.text = dataListin2.title
interface method implemented in the Activity
itemView.setOnClickListener {
listener.onItemClicked(listOfData.get(adapterPosition))
}
}
}
public interface ContentListener {
fun onItemClicked(item: MainMarketTickClass)
}
MainMarket.kt
class MainMarket: Fragment(),ContentAdapter.ContentListener{
var ITEMSList = ArrayList<MainMarketTickClass>()
companion object {
fun newInstance():Fragment{
var fb : MainMarket = MainMarket()
return fb
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
var inf = inflater!!.inflate(R.layout.main_marker,container,false)
return inf
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
ITEMSList .add ( MainMarketTickClass("123"))
ITEMSList .add ( MainMarketTickClass(" 123"))
ITEMSList .add ( MainMarketTickClass("123"))
var adapter = ContentAdapter (MainActivity(),ITEMSList,this)
list.adapter = adapter
list.layoutManager = LinearLayoutManager(this.context,LinearLayoutManager.VERTICAL,false)
}
override fun onItemClicked(item: MainMarketTickClass) {
if(activity is MainActivity){
(activity as MainActivity).onItemClicked(item)
}
}
addcar.kt
class AddCar: Fragment(), ContentAdapter.ContentListener{
companion object {
fun newInstanceaddcar(): Fragment {
var fb : AddCar = AddCar()
val args = Bundle()
fb.arguments = args
return fb
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater!!.inflate(R.layout.add_car,container,false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val TextView= view!!.findViewById(R.id.textView) as TextView
var titlein = ""
}
override fun onItemClicked(item: MainMarketTickClass) {
}
回答1:
Instead of passing the listOfData from your ContentAdapter to your ViewHolder, you should pass a single data of specific position to your ViewHolder. Here I make a change from your ContentAdapter:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(listOfData[position], listener)
}
And than your ViewHolder should look like this:
class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView) {
fun bind(data: MainMarketTickClass, listener: ContentListener) {
itemView.setOnClickListener {
listener.onItemClicked(data)
}
}
}
For transfering your data between fragment you may want to read Communicating with Other Fragments. Your ContentListener should be in MainMarket:
class MainMarket: Fragment() {
private lateinit var mCallback: ContentListener
// Container Activity must implement this interface
interface ContentListener {
fun onItemClicked(item: String)
}
override fun onAttach(context: Context?) {
super.onAttach(context)
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = context as ContentListener
} catch (e: ClassCastException) {
throw ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener")
}
}
And implement the ContentListener in your Activity
class MainActivity : AppCompatActivity(), MainMarket.ContentListener {
override fun onItemClicked(item: MainMarketTickClass) {
val bundle = Bundle()
bundle.putParcelable("data", item)
val addCar = AddCar()
addCar.arguments = bundle
var ft : FragmentTransaction = supportFragmentManager.beginTransaction()
ft.replace(R.id.frameLayout,addCar)
ft.commit()
}
If you want to bring your object to another fragment, you should consider implementing your object with Parcelable. Here is some example for it Send object using parcelable.
Hope it will help you.
回答2:
Here is a good tutorial that worked for me. In this tutorial, we create a bundle in the first fragment, then we put the that in this bundle. Finally we send the data to the second bundle using its arguments.
Kotlin Tutorial: Transfer data between Fragments -Android Studio Tutorials
回答3:
The ways of passing data between fragments are:
- Bundle (prefered)
- SharedPreferences
- Database
So, in your newInstanceaddcar(): Fragment pass as argument data you need, set is using bundle.putType() (where type is Int, Boolean, Serializable etc), and in your fragment code get those data using bundle.getType().
This way you can pass any serializable type to other fragment.
来源:https://stackoverflow.com/questions/49837447/kotlin-how-to-pass-a-data-between-two-fragments