i only output integer but string dont outputing - android-studio

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.

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();
}

E/RecyclerView: No adapter attached; skipping layout. Recyclerlist can't be viewed. Output get crashed

Its saying adapter is not attached. I am new to kotlin. So I don't know where does it go wrong.
RestaurantModel.kt
package com.example.foodtogo.model
import android.os.Parcel
import android.os.Parcelable
import java.io.Serializable
class RestaurantModel(val name:String?, val address:String?, val delivery_charge: Int, val image: String?, val open: String?,
var menus: List<Menus?>?): Serializable {}
class Menus(val name:String?, val price: Float, val url:String?, var totalInCart: Int):Serializable {}
RestaurantMainActivity.kt
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.foodtogo.databinding.ActivityRestaurantMainBinding
import com.example.foodtogo.model.RestaurantModel
import com.example.foodtogo.view.RestaurantListAdapter
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.*
import com.google.firebase.database.ktx.database
import com.google.firebase.ktx.Firebase
import android.content.Intent as Intent
class RestaurantMainActivity : AppCompatActivity(),RestaurantListAdapter.ValueEventListener {
private lateinit var binding: ActivityRestaurantMainBinding
private lateinit var firebaseAuth: FirebaseAuth
private lateinit var database: FirebaseDatabase
private lateinit var reference: DatabaseReference
private lateinit var restaurantList: ArrayList<RestaurantModel>
//var adapter: RestaurantListAdapter?=null
//private lateinit var restaurantList: MutableList<RestaurantModel?>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityRestaurantMainBinding.inflate(layoutInflater)
setContentView(binding.root)
firebaseAuth = FirebaseAuth.getInstance()
database = FirebaseDatabase.getInstance()
reference = database.reference
Log.e("AKSA", "TEST1")
binding.recyclerViewRestaurant.layoutManager = LinearLayoutManager(this)
Log.e("AKSA", "TEST")
restaurantList = arrayListOf<RestaurantModel>()
getRestaurantData()
Log.e("AKSA", "TEST3")
}
override fun Context.onItemClick(restaurantModel: RestaurantModel) {
val intent = Intent(applicationContext,RestaurantMenuActivity::class.java)
intent.putExtra("RestaurantModel", restaurantModel)
startActivity(intent)
Log.d("AKSA", "MESSAGE")
}
private fun getRestaurantData(){
val db = Firebase.database.reference
val restaurantModelRef = db.child("RestaurantModel")
restaurantModelRef.get().addOnCompleteListener {
if (it.isSuccessful) {
val snapshot = it.result
for (restaurant in snapshot.children) {
Log.d("AKSA", "T4")
val restaurantModel = restaurant.child("RestaurantModel").getValue(RestaurantModel::class.java)
Log.d("AKSA", restaurantModel?.address.toString())
restaurantList.add(restaurantModel!!)
}
val adapter = RestaurantListAdapter(restaurantList, getApplicationContext())
binding.recyclerViewRestaurant.adapter = adapter
adapter.notifyDataSetChanged()
} } }
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menubar, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.home_menu -> {
val intent = Intent(this, ViewOrderActivity::class.java)
startActivity(intent)
}
R.id.signout_menu -> {
firebaseAuth.signOut()
val intent = Intent(this, LOGIN::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
finish()
}
}
return super.onOptionsItemSelected(item)
}
}
activity_restaurant_main.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"
android:background="#color/white"
tools:context=".RestaurantMainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewRestaurant"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="4dp"
android:clipToPadding="false"
android:paddingBottom="2dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
tools:listitem="#layout/recycler_restaurantlist"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
ResaturantListAdapter.kt
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.foodtogo.R
import com.example.foodtogo.RestaurantMenuActivity
import com.example.foodtogo.model.RestaurantModel
class RestaurantListAdapter(val restaurantList: ArrayList<RestaurantModel>, val clickListener: Context):
RecyclerView.Adapter<RestaurantListAdapter.MyViewHolder>() {
//private lateinit var database: FirebaseDatabase
//private lateinit var reference:DatabaseReference
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): RestaurantListAdapter.MyViewHolder {
val view: View = LayoutInflater.from(parent.context).inflate(R.layout.recycler_restaurantlist,parent,false)
return MyViewHolder(view)
}
override fun onBindViewHolder(holder: RestaurantListAdapter.MyViewHolder, position: Int) {
holder.bind(restaurantList.get(position))
holder.itemView.setOnClickListener{
clickListener.onItemClick(restaurantList.get(position))
}
}
override fun getItemCount(): Int {
return restaurantList.size
}
inner class MyViewHolder(view: View):RecyclerView.ViewHolder(view){
val thumbImage: ImageView =view.findViewById(R.id.thumbImage)
val restaurantName: TextView =view.findViewById(R.id.restaurantName)
val restaurantAddress:TextView=view.findViewById(R.id.restaurantAddress)
val restaurantHours:TextView=view.findViewById(R.id.restaurantHours)
fun bind(restaurantModel: RestaurantModel?){
restaurantName.text=restaurantModel?.name
restaurantAddress.text="Address: "+restaurantModel?.address
restaurantHours.text="Open: "+restaurantModel?.open
Glide.with(this.thumbImage).load(restaurantModel?.image).centerCrop().placeholder(R.drawable.ic_launcher_background).into(thumbImage)
}
}
interface ValueEventListener {
// fun onItemClick(restaurantModel: RestaurantModel)
fun Context.onItemClick(restaurantModel: RestaurantModel)
}
}
private fun Context.onItemClick(restaurantModel: RestaurantModel) {
val intent = Intent(applicationContext, RestaurantMenuActivity::class.java)
intent.putExtra("RestaurantModel", restaurantModel)
startActivity(intent)
}
recycler_restaurantlist.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="wrap_content">
<androidx.cardview.widget.CardView
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:paddingTop="5dp"
app:cardCornerRadius="7dp"
app:cardElevation="7dp"
app:cardUseCompatPadding="true"
app:contentPadding="5dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/thumbImage"
android:layout_width="110dp"
android:layout_height="110dp"
android:layout_gravity="start"
android:layout_margin="10dp"
tools:srcCompat="#drawable/ic_launcher_background" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="125dp"
android:orientation="vertical">
<TextView
android:id="#+id/restaurantName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:textColor="#color/yellow"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/restaurantAddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:textColor="#color/black"
android:textSize="14sp"
android:textStyle="normal" />
<TextView
android:id="#+id/restaurantHours"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:textColor="#color/black"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
While I was using json file it worked. But when I tried to retrieve data from realtime database firebase, it got stuck. I don't know, where does it go wrong. And also I can't retrieve the data from realtime database too.

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

why my TabLayout inside Fragment only work in first time?

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

Resources