Numberpicker send data to HomeFragment (Fragment to Fragment) - android

I have app who have viewpagers and in inside is numberpicker. I try to send this data to my HomeFragment but crash my app. This is my source code. What i do wrong?
Create Interface for communication
interface Communicator {
fun passData(numberpicker: NumberPicker) {
}
This is my fragment with numberpicker
lateinit var comm: Communicator
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_period_length, container, false)
view.number_picker_period?.minValue = 21
view.number_picker_period?.maxValue = 35
view.number_picker_period?.wrapSelectorWheel = true
val viewPager = activity?.findViewById<ViewPager2>(R.id.viewPager)
view.next_txt_period.setOnClickListener {
viewPager?.currentItem = 1
comm.passData(view.number_picker_period)
}
return view
}
This is MainActivity
val fragment1 = DaysLength()
supportFragmentManager.beginTransaction().replace(R.id.content_id, fragment1).commit()
}
override fun passData(numberpicker: NumberPicker) {
val bundle = Bundle()
bundle.putString("input_txt", number_picker_period.toString())
val transaction = this.supportFragmentManager.beginTransaction()
val fragment2 = HomeFragment()
fragment2.arguments = bundle
}
My HomeFragment
var inputtext: String? = ""
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_home, container, false)
inputtext = arguments?.getString("input_txt")
view.output_numberpicker.text = inputtext
return view
What i do wrong?
Error
Unable to start activity ComponentInfo{com.example.oapp/com.example.oapp.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f080067 (com.example.oapp:id/content_id) for fragment DaysLength{aa77410}

your main activity is crashing on this line as it doesn't know what the view "number_picker_period" is
bundle.putString("input_txt", number_picker_period.toString())
try accessing the number picker through the parameter in the function called "numberPicker", Or alternatively, change your passData interface function to return the string value instead of the entire numberPicker

Related

How can I pass a mutable list of type custom object between fragments?

I am trying to pass a mutable list of custom object type SavedRecipes from one fragment to be displayed in a recyclerview on another fragment, however I am struggling to work out how to pass this list.
I have the code below:
RecipePage.kt
class RecipePage : Fragment() {
var allSavedRecipes = mutableListOf<SavedRecipes>()
lateinit var savedRecipe: SavedRecipes
lateinit var id: String
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_recipe_page, container, false)
val args = this.arguments
id = args?.get("id").toString()
view.addToCollection.setOnClickListener {
saveRecipe()
val bundle = Bundle()
bundle.putStringArrayList("allsaved", allSavedRecipes)
val savedRecipePage = SavedRecipesFragment()
savedRecipePage.arguments = bundle
}
return view
}
The line
bundle.putStringArrayList("allsaved", allSavedRecipes)
is where I want to be passing the list of allSavedRecipes to the second fragment.
How can I accomplish this?

Kotlin interface, sending data between two fragments

I am looking to send a string from FragmentA to FragmentDialog by means of an interface Communicator through my Main Activity (which automatically opens FragmentDialog). Some code to illustrate what I have:
class FragmentA: Fragment() {
private lateinit var communicator: Communicator
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_A, container, false)
val title = "My Title"
button.setOnClickListener { communicator.passData(title) }
return view
}
}
class FragmentDialog : DialogFragment() {
var title: String? = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.dialog, container, false)
view.button_close.setOnClickListener { dismiss() }
title = arguments?.getString("title")
view.dialog_title.text = title
return view
}
}
interface Communicator {
fun passData (titleInput: String)
}
and in my Main Activity, which extends the interface:
private val fragmentDialog = FragmentDialog()
override fun passData(titleInput: String) {
val bundle = Bundle()
bundle.putString("title", titleInput)
fullScreenDialog.arguments = bundle
val transaction = supportFragmentManager.beginTransaction().add(android.R.id.content, fragmentDialog).addToBackStack(null).commit()
}
When I click the button in FragmentA, I want to send the string title to Communicator, set the XML element with id dialog_title in FragmentDialog and automatically open the fragment. In fact, this works fine. The issue is that my "back button" in FragmentDialog, i.e. view.button_close.setOnClickListener { dismiss() } only works exactly once. If I click button in FragmentA again, FragmentDialog opens fine with the correct title still but button_close no longer dismisses the dialog. What could be causing this? I am not getting any consol errors.

Error during passing data between fragment

Im trying to pass data between two fragments but i have an error with arguments in execution when i launch fullFragment
i updated my code
Can you help me ?
architecture :
ListeFragment (sender) :
class ListeFragment : Fragment() {
companion object {
fun newInstance(s: String) = ListeFragment()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val layout = inflater.inflate(R.layout.liste_fragment, container, false)
val photo1 = layout.findViewById<ImageView>(R.id.imageButton1)
val model = ViewModelProviders.of(this).get(ListeViewModel::class.java)
imageButton1.setOnClickListener {
val newFragment = FullFragment()
val args = Bundle()
args.putString("key1", "data")
newFragment.arguments = args
Navigation.findNavController(imageButton1).navigate(R.id.versFullFragment);
}
FullFragment (receiver):
class FullFragment : Fragment() {
companion object {
fun newInstance() = FullFragment()
}
private lateinit var viewModel: FullViewModel
override fun onCreate( savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var value1 = getArguments()?.getString("key1")
Log.v("value" , value1.toString())
Toast.makeText(context, value1.toString(), Toast.LENGTH_SHORT).show()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val layout = inflater.inflate(R.layout.full_fragment, container, false)
return layout
}
I don't know what "newFragment.arguments = args" do because in FullFragment class I don't see any variable with that name, however you have to use "Fragment.setArguments(Bundle)" to set Fragment Arguments from the first one. Then in the Full you will have a correct result from "FullFragment.getArguments()" method.
PS: don't forget that the Context could be NULL in Fragment class and it should be handled in proper way.

Kotlin Android Navigate to a Fragment with OnItemClickListener of a listview

So I Have this one Fragment:
class OrderListFragment : Fragment() {
val language = arrayOf<String>(//Some String Content)
val description = arrayOf<String>( //Some String Content )
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Binding object for this fragment and the layout
val binding: FragmentOrderListBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_order_list, container, false)
val myListAdapter = OrderListAdapter((activity as AppCompatActivity),language,description)
binding.listView.adapter = myListAdapter
binding.listView.setOnItemClickListener(){adapterView, view, position, id ->
val itemAtPos = adapterView.getItemAtPosition(position)
val itemIdAtPos = adapterView.getItemIdAtPosition(position)
Navigation.createNavigateOnClickListener(R.id.action_orderListFragment_to_orderDetailFragment)
Toast.makeText((activity as AppCompatActivity), "Click on item at $itemAtPos its item id $itemIdAtPos", Toast.LENGTH_LONG).show()
}
//Return.... i don't know.
return binding.root
}
}
What i want is that when i click one of the listview items, it'll navigate to other fragments using this line.
Navigation.createNavigateOnClickListener(R.id.action_orderListFragment_to_orderDetailFragment)
But it does not do anything. Am i missing something ?

How do I correctly use Kotlin to call a blank fragment from the Home fragment?

class HomeFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
val v = inflater.inflate(R.layout.fragment_home, container, false)
val fab = v.findViewById(R.id.fab) as FloatingActionButton
fab.setOnClickListener {
val blankFragment = BlankFragment()
val manager = childFragmentManager
manager.beginTransaction().replace(R.id.frame_container, blankFragment, blankFragment.tag).commit()
// System.out.println("You have reached the floating action button")
}
return v
}
}
Getting a no view found error. I may have issues with the R.id.frame_content but Kotlin doesn't immediately identify all id values...
This may not be the best way and I apologize for the horrible formatting I does this while answer out on my phone and it's hard to get it perfect. Anyways In the activity that holds your fragments, such as MainActivity.kt add...
supportFragmentManager.beginTransaction.add(R.id.fragment_home, HomeFragment.newInstance, "HomeFragment").commit()
In your HomeFragment.kt change the following.
class HomeFragment: Fragment(){
companion object {
fun newInstance(): HomeFragment{
return HomeFragment() }
fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view: View = inflater!!.inflate(R.layout.fragment_home, container, false)
val activity = activity
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val clickListener = View.OnClickListener { view ->
when (view.getId()) {
R.id.fab -> NextFragment()
}
}
fab.setOnClickListener(clickListener)
}
NextFragment(){
val fragManager = activity?.supportFragmentManager
fragManager?.beginTransaction()?.replace(R.id.frame_container, BlankFragment.newInstance(), "blankFragment")?.commit()
}
Make sure you make the same changes to BlankFragment.kt
class BlankFragment: Fragment(){
companion object {
fun newInstance(): BlankFragment{
return BlankFragment() }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view: View = inflater!!.inflate(R.layout.fragment_blank, container, false)
val activity = activity
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//Do some stuff with your views in BlankFragment here
}
}

Categories

Resources