why my TabLayout inside Fragment only work in first time? - android-studio

I Have a problem when I use a TabLayout on fragment. it is only one time performing by showing another fragment but after I click on other application part and then back to the fragment which is containing TabLayout, then it doesn't show TabLayout content.
My TabLayout Problem Ilustrate
class FavoritesFragment : Fragment() {
private var tabLayout: TabLayout? = null
private var viewPager: ViewPager? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_favorites, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
tabLayout = view.findViewById(R.id.tabs) as TabLayout
viewPager = view.findViewById(R.id.viewpager) as ViewPager
super.onViewCreated(view, savedInstanceState)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
viewPager!!.setAdapter(MyAdapter(fragmentManager))
tabLayout!!.post(Runnable { tabLayout!!.setupWithViewPager(viewPager) })
super.onActivityCreated(savedInstanceState)
}
private inner class MyAdapter(fm: FragmentManager?) : FragmentPagerAdapter(fm!!, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
private val int_items = 2
override fun getItem(position: Int): Fragment {
var fragment: Fragment? = null
when (position) {
0 -> fragment = MoviesFavoritesFragment()
1 -> fragment = TvSeriesFavoritesFragment()
}
return fragment!!
}
override fun getCount(): Int {
return int_items
}
override fun getPageTitle(position: Int): CharSequence? {
when (position) {
0 -> return "Movie Favorites"
1 -> return "Tv Series Favorites"
}
return null
}
}
}
and here my 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">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/material_blue_grey_800"
app:tabGravity="fill"
app:tabIndicatorColor="#color/colorPrimary"
app:tabSelectedTextColor="#color/white"
app:tabTextColor="#color/colorPrimary"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/tabs"/>
</androidx.constraintlayout.widget.ConstraintLayout>

Most probably the bug is in here:
viewPager!!.setAdapter(MyAdapter(fragmentManager))
Try passing childFragmentManager there

Related

Saving RecyclerView state in a fragment when exiting it

I am trying to make a app that sends messages to a recyclerView from fragment to another using a navgraph, but whenever I go back to my previous fragment to add a new message I lose the data of my recyclerView, and does not pile up.
---This is the kotlin code for the first fragment:
package com.example.passingdata
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
import androidx.navigation.Navigation
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
class Fragment_A : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment__a, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val messageET = view.findViewById<EditText>(R.id.ETmessageTaker)
val enterBTN = view.findViewById<Button>(R.id.BTNenter)
enterBTN.setOnClickListener{
val action = Fragment_ADirections.actionFragmentAToFragmentB(messageET.text.toString())
Navigation.findNavController(view).navigate(action)
}
}
companion object {
fun newInstance(param1: String, param2: String) =
Fragment_A().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
---XML code for first fragment:
<?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=".Fragment_A">
<EditText
android:id="#+id/ETmessageTaker"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:ems="10"
android:hint="Message"
android:inputType="textPersonName"
android:minHeight="48dp"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/BTNenter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Enter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/ETmessageTaker" />
</androidx.constraintlayout.widget.ConstraintLayout>
---Kotlin code for second fragment :
package com.example.passingdata
import android.content.ContentValues.TAG
import android.os.Bundle
import android.os.Parcelable
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.passingdata.databinding.FragmentBBinding
import messageAdapter
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
var state: Parcelable? = null
class Fragment_B : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
private val args:Fragment_BArgs by navArgs()
private var _binding: FragmentBBinding? = null
private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentBBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val eachMessage = args.messageRecieved
//putting words in TV
binding.TVNewMessage.text = eachMessage
//putting words in RV
val messageList = mutableListOf(
message(eachMessage)
)
val adapter = messageAdapter(messageList)
binding.RVMessages.adapter = adapter
binding.RVMessages.layoutManager = LinearLayoutManager(context)
binding.BTNBack.setOnClickListener {
Navigation.findNavController(view).navigate(R.id.action_fragment_B_to_fragment_A)
}
}
companion object {
fun newInstance(param1: String, param2: String) =
Fragment_B().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
override fun onResume() {
super.onResume()
Log.d(TAG, "onResume Called")
state = binding.RVMessages.layoutManager?.onSaveInstanceState();
}
override fun onPause() {
super.onPause()
Log.d(TAG, "onPause Called")
state = binding.RVMessages.layoutManager?.onSaveInstanceState();
}
override fun onStop() {
super.onStop()
Log.d(TAG, "onStop Called")
state = binding.RVMessages.layoutManager?.onSaveInstanceState();
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy Called")
_binding = null
}
}
---XML code for second fragment:
<?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=".Fragment_B">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/RV_messages"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toTopOf="#+id/TV_newMessage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/TV_newMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="60dp"
android:text="TextView"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/BTN_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_marginRight="10dp"
android:text="Back"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="#+id/BTN_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:text="Save"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Someone suggested I override the 3 states and save them like this, but it did not work.
I even tried using SharedPrefrences but it gives me a error saying, "Unresolved reference: getSharedPrefrences".
override fun onResume() {
super.onResume()
Log.d(TAG, "onResume Called")
state = binding.RVMessages.layoutManager?.onSaveInstanceState();
}
override fun onPause() {
super.onPause()
Log.d(TAG, "onPause Called")
state = binding.RVMessages.layoutManager?.onSaveInstanceState();
}
override fun onStop() {
super.onStop()
Log.d(TAG, "onStop Called")
state = binding.RVMessages.layoutManager?.onSaveInstanceState();
}

Card inside cardView isn't showing

The cards are not showing when im running the simulator (the recyclerView is showing). I think the problem is in "onCreateView" at AdvertsFragement. My MainActivity activity is with binding inflated. The advertsfragement is embedded in the MainActivity thru a navigation bottom bar.
Card Layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_margin="5dp"
app:cardBackgroundColor="#color/oceanBlue"
app:cardCornerRadius="12dp"
app:cardElevation="3dp"
app:contentPadding="4dp"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/forestGreen"
android:id="#+id/relativeLayout"
android:padding="16dp"
>
<ImageView
android:id="#+id/item_image"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="#+id/item_title"
android:textColor="#color/black"
android:layout_width="236dp"
android:layout_height="39dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="#+id/item_image"
android:layout_marginStart="16dp"
android:textSize="30sp"/>
<TextView
android:id="#+id/item_detail"
android:textColor="#color/black"
android:layout_width="236dp"
android:layout_height="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/item_title"
app:layout_constraintLeft_toRightOf="#+id/item_image"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
Fragment
class AdvertsFragment : Fragment() {
private var layoutManager: RecyclerView.LayoutManager? = null
private var adapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
R.id.recycler_view.apply {
// set a LinearLayoutManager to handle Android
// RecyclerView behavior
layoutManager = LinearLayoutManager(activity)
// set the custom adapter to the RecyclerView
adapter = RecyclerAdapter()
}
return inflater.inflate(R.layout.fragment_adverts, container, false)
}
override fun onViewCreated(itemView: View, savedInstanceState: Bundle?) {
super.onViewCreated(itemView, savedInstanceState)
}
}
RecyclerAdapter and ViewHolder
class RecyclerAdapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
private var titles = arrayOf("Test1", "Test2", "Test3", "Test4", "Test5")
private var details = arrayOf("Detail1", "Detail2", "Detail3", "Detail4", "Detail5")
private var images = intArrayOf(R.drawable.ic_notifications_black_24dp, R.drawable.ic_notifications_black_24dp, R.drawable.ic_notifications_black_24dp, R.drawable.ic_notifications_black_24dp, R.drawable.ic_notifications_black_24dp)
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder{
val v = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.card_layout, viewGroup, false)
return ViewHolder(v)
}
override fun getItemCount(): Int {
return titles.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.itemTitle.text = titles[position]
holder.itemDetail.text = details[position]
holder.itemImage.setImageResource(images[position])
}
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var itemImage: ImageView
var itemTitle: TextView
var itemDetail: TextView
init {
itemImage = itemView.findViewById(R.id.item_image)
itemTitle = itemView.findViewById(R.id.item_title)
itemDetail = itemView.findViewById(R.id.item_detail)
itemView.setOnClickListener {
val position: Int = absoluteAdapterPosition
Toast.makeText(itemView.context, "you clicked on ${titles[position]}", Toast.LENGTH_LONG).show()
}
}
}
}
I just needed to use findViewById() in onViewCreated instead of "R.id.recycler_view.apply" in onCreateView:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_adverts, container, false)
}
override fun onViewCreated(itemView: View, savedInstanceState: Bundle?) {
super.onViewCreated(itemView, savedInstanceState)
itemView.findViewById<RecyclerView>(R.id.recycler_view).apply{
// set a LinearLayoutManager to handle Android
// RecyclerView behavior
layoutManager = LinearLayoutManager(activity)
// set the custom adapter to the RecyclerView
adapter = RecyclerAdapter()
}
}

How can i set sharedpreferences update value in dropdown menu

In my app I have a feature, the feature is localise. first, I am using an exposed dropdown menu(using textinputlayout) and this dropdown shows the language list when the user selects the language the app shows the text based on the user's selected language and I save user value in sharedpreference and it's working fine but the problem is when the user closes the app and reopen user can show their selected language text but the dropdown can't change based on sharedpreference value.
MainActivity.kt
class MainActivity : AppCompatActivity() {
companion object {
const val TAG = "MainActivity"
}
lateinit var lanList: List<String>
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
PrefHelper.init(this)
lanList = arrayListOf("EN","AR")
var la = PrefHelper.getValue("localise","")
Log.i("la", "onCreate: $la")
val adapter = MyAdapter(this, android.R.layout.simple_spinner_dropdown_item, lanList)
binding?.typesFilter?.setAdapter(adapter)
binding?.typesFilter.onItemClickListener =
AdapterView.OnItemClickListener { parent, view, position, id ->
val selectedLang: String = parent?.getItemAtPosition(position).toString()
when (selectedLang) {
"EN" -> {
binding.typesFilter.dismissDropDown()
lifecycleScope.launchWhenCreated {
delay(100)
setLocalise("en")
recreate()
}
}
"AR" -> {
binding.typesFilter.dismissDropDown()
lifecycleScope.launchWhenCreated {
delay(100)
setLocalise("ar")
recreate()
}
}
}
}
binding.typesFilter.post {
binding.typesFilter.dismissDropDown()
}
binding?.typesFilter.setDropDownBackgroundDrawable(
ResourcesCompat.getDrawable(
resources,
R.drawable.filter_spinner_dropdown_bg,
null
)
)
}
override fun attachBaseContext(newBase: Context?) {
PrefHelper.init(newBase!!)
super.attachBaseContext(LanguageChangeHelper.setLanguage(newBase!!,PrefHelper.getValue("localise","")!!))
}
private fun setLocalise(lan: String) {
var p:String = PrefHelper.setValue("localise",lan).toString()!!
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/typesFilterContainer"
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginTop="32dp"
android:background="#drawable/filter_spinner_dropdown_bg"
app:boxBackgroundColor="#color/pastel_orange_light"
app:boxCornerRadiusBottomEnd="20dp"
app:boxCornerRadiusBottomStart="20dp"
app:boxCornerRadiusTopEnd="20dp"
app:boxCornerRadiusTopStart="20dp"
app:boxStrokeWidth="0dp"
app:boxStrokeWidthFocused="0dp"
app:endIconDrawable="#drawable/ic_baseline_keyboard_arrow_down_24"
app:endIconTint="#color/pastel_orange_txt_highlight"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<AutoCompleteTextView
android:id="#+id/typesFilter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#null"
android:dropDownSelector="#drawable/filter_spinner_dropdown_bg"
android:ellipsize="end"
android:inputType="none"
android:maxLines="1"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:singleLine="true"
android:text="EN"
android:textAlignment="center"
android:textColor="#color/pastel_orange_txt_highlight"
tools:ignore="LabelFor">
<requestFocus />
</AutoCompleteTextView>
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:text="#string/title_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/typesFilterContainer" />
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="#string/body_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:text="Button"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
MyAdapter.kt
class MyAdapter : ArrayAdapter<Any?> {
constructor(context: Context, resource: Int) : super(context, resource) {}
constructor(context: Context, resource: Int, textViewResourceId: Int) : super(
context,
resource,
textViewResourceId
) {
}
constructor(context: Context, resource: Int, objects: Array<Any?>) : super(
context,
resource,
objects
) {
}
constructor(
context: Context,
resource: Int,
textViewResourceId: Int,
objects: Array<Any?>
) : super(context, resource, textViewResourceId, objects) {
}
constructor(context: Context, resource: Int, objects: List<*>) : super(
context,
resource,
objects
) {
}
constructor(context: Context, resource: Int, textViewResourceId: Int, objects: List<*>) : super(
context,
resource,
textViewResourceId,
objects
) {
}
override fun getFilter(): Filter {
return object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults? {
return null
}
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {}
}
}
}
PrefHelper.kt
object PrefHelper {
private lateinit var prefs: SharedPreferences
private const val PREF_NAME = "PrefHelper"
fun init(context: Context){
prefs = context.getSharedPreferences(PREF_NAME,Context.MODE_PRIVATE)
}
//For String
fun getValue(key:String,value:String):String?{
return prefs.getString(key, value)
}
fun setValue(key:String,value:String){
val prefEditor: SharedPreferences.Editor = prefs.edit()
with(prefEditor){
putString(key,value)
commit()
}
}
}
LanguageChangeHelper.kt
object LanguageChangeHelper {
fun setLanguage(context: Context,lan:String): Context? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
updateResources(context,lan)
} else updateResourcesLegacy(context,lan)
}
#TargetApi(Build.VERSION_CODES.N)
private fun updateResources(context: Context, language: String): Context? {
val locale = Locale(language)
val configuration = context.resources.configuration
val localeList = LocaleList(locale)
LocaleList.setDefault(localeList)
configuration.setLocales(localeList)
return context.createConfigurationContext(configuration)
}
private fun updateResourcesLegacy(context: Context, language: String): Context? {
val locale = Locale(language)
Locale.setDefault(locale)
val resources = context.resources
val configuration = resources.configuration
configuration.locale = locale
resources.updateConfiguration(configuration, resources.displayMetrics)
return context
}
}
better understanding I also show my app
first time open the app
after change the language
when user reopen the app
how can i change user selected option based sharedpreferences?
Thank you

i only output integer but string dont outputing

Hello guys i am doing wizard but last activity there is not printing name (String) whats the problem can someone solve it this is xml code of last activity
<?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="wrap_content"
tools:context=".thirdActivity3">
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="50dp"
android:textColor="#color/black"
android:text="lala"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:textColor="#color/black"
android:text="lala"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
class thirdActivity3 : AppCompatActivity() {
private lateinit var textView: TextView
private lateinit var textView2: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_third3)
textView = findViewById(R.id.textView)
textView2 = findViewById(R.id.textView2)
val extras = intent.extras
if(extras != null){
textView.text = extras.getString("NAME","") //getString("NAME","")
textView2.text = extras.getInt("AGE",0).toString() //getInt("AGE",0).toString()
}
}
}
and this is activityy codee when i am running age is printing but somehow name string not printing
this is mainActivity where i am transfering name data to second activity with startactivity(intent)
class MainActivity : AppCompatActivity() {
private lateinit var editTextName:EditText
private lateinit var nextButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
editTextName=findViewById(R.id.editTextName)
nextButton=findViewById(R.id.nextButton)
nextButton.setOnClickListener {
val name = editTextName.text.toString()
val intent = Intent(this,secondActivity2::class.java)
intent.putExtra("PERONS_NAME",name)
startActivity(intent)
}
}
}
class secondActivity2 : AppCompatActivity() {
private lateinit var inputTextAge:EditText
private lateinit var finishButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second2)
inputTextAge=findViewById(R.id.inputTextAge)
finishButton=findViewById(R.id.finishButton)
val extras = intent.extras
var name = ""
if (extras != null){
name=extras.getString("PERSON_NAME","")
}
finishButton.setOnClickListener {
val age = inputTextAge.text.toString().toInt()
val intent = Intent(this,thirdActivity3::class.java)
intent.putExtra("NAME",name)
intent.putExtra("AGE",age)
startActivity(intent)
}
}
}
and this last one is second activity where i am outputing name and transfering to last page thirdactivity. first page code is third activity and problem is that i can read age in activity but name not ouputing
In MainActivity, the KeyName in intent is PERONS_NAME whereas in
SecondActivity2, the KeyName is PERSONS_NAME.
Clearly there is a mismatch of KeyNames.
In order to solve the issue, make sure the KeyName in MainActivity and SecondActivity2 are same.

Adding fragment to Android Developer Studio's Tabbed Activity Template

Beginner here. Creating an app using the Android Developer Studios Tabbed Activity Template. I have two xml, the generated fragment_main.xml that comes with the template and secondtab.xml for what I want to be the second tab.
This is the code generated by the template:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sectionsPagerAdapter = SectionsPagerAdapter(this, supportFragmentManager)
val viewPager: ViewPager = findViewById(R.id.view_pager)
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = findViewById(R.id.tabs)
tabs.setupWithViewPager(viewPager)
val fab: FloatingActionButton = findViewById(R.id.fab)
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
I've been reading through the ViewPager documentation and a lot of what I can find is making this all from scratch and I'm having trouble understanding. I feel like I'm missing something obvious. How do I add my secondtab.xml to this pregenerated template so it shows up when the user clicks on the second tab?
Yours SectionsPagerAdapter getItem function should looks like this:
class SectionsPagerAdapter(
private val context: Context,
fm: FragmentManager
) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItem(position: Int) = when (position) {
0 -> FirstTabFragment()
1 -> SecondTabFragment()
else -> error("Unknown")
}
override fun getPageTitle(position: Int) = context.resources.getString(TAB_TITLES[position])
override fun getCount() = 2
}
Because by default in this template SectionsPagerAdapter always creates PlaceholderFragment:
override fun getItem(position: Int): Fragment {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
return PlaceholderFragment.newInstance(position + 1)
}
But in yours case you need use two different fragments with two different xml-layouts like this:
class FirstTabFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val root = inflater.inflate(R.layout.fragment_main, container, false)
val textView: TextView = root.findViewById(R.id.section_label)
return root
}
}
class SecondTabFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val root = inflater.inflate(R.layout.secondtab, container, false)
val textView: TextView = root.findViewById(R.id.section_label)
return root
}
}
Also make sure to add:
<TextView
android:id="#+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:layout_marginTop="#dimen/activity_vertical_margin"
android:layout_marginEnd="#dimen/activity_horizontal_margin"
android:layout_marginBottom="#dimen/activity_vertical_margin"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="#+id/constraintLayout"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintTop_creator="1" />
to the fragment xml

Resources