I need to output data from activity to a fragment - android

When the application starts, null is displayed.
I think that I am not correctly assigning a value to the TextView.
class MyFragment : Fragment() {
private lateinit var textView: TextView
companion object {
private val TEXT_FIELD = "text_field"
#JvmStatic
fun newInstance(text_field: Int) = MyFragment().apply {
arguments = Bundle().apply {
putInt(TEXT_FIELD, text_field)
}
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_my, container, false)
textView = view!!.findViewById(R.id.text_view)
textView.text = "${arguments?.getInt(TEXT_FIELD)}"
return view
}
}

You have putInt in assignment but you do getString when trying to retrieve the value.

Related

custome layout in HeadersSupportFragment whit leanback

I have just started working with leanback. I want to add my custom layout to this class.please help me...
`class CustomHeadersFragment: HeadersSupportFragment(),OnHeaderClickedListener {
lateinit var adapter: ArrayObjectAdapter
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
// customSetBackground(R.color.fastlane_background)
setOnHeaderClickedListener(this)
setHeaderAdapter()
presenterSelector
}
private fun setHeaderAdapter() {
adapter = ArrayObjectAdapter()
val fragments: LinkedHashMap<Int, CustomRowsFragment> =
(activity as MainActivity?)?.getFragments()!!
var id = 0
for (i in 0 until fragments.size) {
val header = HeaderItem(id.toLong(), "Category $i")
val innerAdapter = ArrayObjectAdapter()
innerAdapter.add(fragments[i])
adapter.add(id, ListRow(header, innerAdapter))
id++
}
setAdapter(adapter)
}`
this is my rows fragment
`class CustomRowsFragment : RowsSupportFragment() {
private var rowsAdapter: ArrayObjectAdapter? = null
private var cardPresenter: Presenter? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val v = super.onCreateView(inflater, container, savedInstanceState)
return v
}`

Getting NullPointerException when trying to display the data of passed object from one fragment to another

Here is my code on the sender fragment
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_list_card,container,false)
rcvAdapter = CardAdapter(cardList,this)
view.cardRecyclerView.layoutManager = LinearLayoutManager(container?.context,LinearLayoutManager.VERTICAL,false)
view.cardRecyclerView.adapter = rcvAdapter
return view
}
override fun onClick(card: Card) {
val cardBundle = Bundle()
cardBundle.putSerializable("Card",card)
val infoFrag = CardInfoFrag()
infoFrag.arguments = cardBundle
val transaction = activity?.supportFragmentManager?.beginTransaction()
transaction?.replace(R.id.fragmentContainer,infoFrag)
transaction?.commit()
}
Here is the code on the receiver
class CardInfoFrag : Fragment() {
private val card : Card? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val bundle = Bundle(arguments)
val card : Card = bundle.getSerializable("Card") as Card
Log.d("CARDINFO: ",card.name+" "+ card.cardDate+" "+card.cardNum)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
cardNameInfo.text = card?.name
cardExDateInfo.text = card?.cardDate
cardNumInfo.text = card?.cardNum
return inflater.inflate(R.layout.fragment_card_info,container,false)
}
}
The cardList is declared as ArrayList<Card>
The Card object
class Card (val cardNum : String, val cardDate : String, val name : String) :Serializable{
}
The logcat, when I attempt to create a new fragment with data from the passed object, says my cardNameInfo.text can't be null while the log command clearly says I received the object and its data. I can't work out what may cause the problem
Any tip is appreciated
As its name implies, onCreateView get called before the fragment view is created; So within the onCreateView, you need to explicitly use the view that will be returned by it to access any underlying views.
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_card_info,container,false)
cardNameInfo = view.findViewById<TextView>(R.id.foo1)
cardExDateInfo= view.findViewById<TextView>(R.id.foo2)
cardNumInfo= view.findViewById<TextView>(R.id.foo3)
cardNameInfo.text = card?.name
cardExDateInfo.text = card?.cardDate
cardNumInfo.text = card?.cardNum
return view
}
Change the foo Ids to the corresponding ids in the fragment layout
Try this once, when you are getting the Bundle, the arguments is already a Bundle object. Maybe if you do something like this it might work: ( My answer is based off this answer :) )
class CardInfoFrag : Fragment() {
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val bundle: Bundle? = arguments
bundle?.let{
val card : Card = it.getSerializable("Card") as Card
Log.d("CARDINFO: ",card.name+" "+ card.cardDate+" "+card.cardNum)
}
}
...
}

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.

Numberpicker send data to HomeFragment (Fragment to Fragment)

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

Fragments don't communicate via sharedViewModel and LiveData

I want first fragment to observe information via LiveData comming from second fragment. I tried doing the same but only in 1 Fragment and it worked, but as soon as I want to recieve the data in other fragment it stops working (textView has no text). How should I fix this problem?
SharedViewModel:
class SharedViewModel : ViewModel() {
private val selected : MutableLiveData<Person> = MutableLiveData<Person>()
fun select(person: Person){
selected.value = person
}
fun getSelected(): LiveData<Person>{
return selected
}
}
First fragment:
class FirstFragment : Fragment() {
private lateinit var sharedViewModel: SharedViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
sharedViewModel =
ViewModelProviders.of(this).get(SharedViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_home, container, false)
val textView: TextView = root.findViewById(R.id.text_home)
sharedViewModel.getSelected().observe(viewLifecycleOwner, Observer{
textView.text = it.name
})
return root
}
}
Second Fragment:
class SecondFragment : Fragment() {
private lateinit var sharedViewModel: SharedViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
sharedViewModel =
ViewModelProviders.of(this).get(SharedViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_dashboard, container, false)
val textView: TextView = root.findViewById(R.id.text_dashboard)
val person = Person("John")
val newPerson = Person("Anton")
val button2: Button = root.findViewById(R.id.button2)
val button: Button = root.findViewById(R.id.button)
button2.setOnClickListener {
sharedViewModel.select(person)
}
button.setOnClickListener {
sharedViewModel.select(newPerson)
}
return root
}
}
Class Person:
class Person (var name: String) {
}
I think you are using https://developer.android.com/reference/android/arch/lifecycle/ViewModelProviders#of(android.support.v4.app.Fragment) but instead you should be using https://developer.android.com/reference/android/arch/lifecycle/ViewModelProviders#of(android.support.v4.app.FragmentActivity). That's how sharing works.

Categories

Resources