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
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
}`
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)
}
}
...
}
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.
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
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.