I need to refresh the list view with new data. This code below is used to obtain data in OnCreateView that is in FragmentActivity at the first time.
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val url = "something"
val request_queue = Volley.newRequestQueue(this.context)
val stringRequest = StringRequest(Request.Method.GET, url,
Response.Listener<String> { response ->
val pending_job = Gson().fromJson<ArrayList<HashMap<String, String>>>(
response.toString(),
object : TypeToken<ArrayList<HashMap<String, String>>>() {}.type
)
this#PlaceholderFragment.showList(rootView, R.id.pending_job_list, pending_job)
pending_job_list_layout.setOnRefreshListener(this)
request_queue.stop()
}, Response.ErrorListener { error ->
if (error.networkResponse != null) {
Toast.makeText(this.context, error.networkResponse.statusCode.toString(), Toast.LENGTH_SHORT).show()
}
request_queue.stop()
})
request_queue.add(stringRequest)
}
showList is the function to set CustomAdapter, which is
fun showList(rootView: View, tab_id: Int, job_list: ArrayList<HashMap<String, String>>) {
// custom display ListView
val adapter: CustomAdapter = CustomAdapter(
this.context,
job_list
)
this_adapter = adapter
val listView = rootView.findViewById(tab_id) as ListView
listView.adapter = adapter
}
, and this CustomAdapter class,
class CustomAdapter(internal var mContext: Context,
internal var job_list: ArrayList<HashMap<String, String>>
) : BaseAdapter() {
override fun getCount(): Int {
return job_list.size
}
override fun getItem(position: Int): Any? {
return null
}
override fun getItemId(position: Int): Long {
return 0
}
override fun getView(position: Int, view: View?, parent: ViewGroup): View {
val mInflater = mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val item_view = mInflater.inflate(R.layout.activity_job_item, parent, false)
val job_name: MutableList<String> = arrayListOf()
job_list.mapTo(job_name) { it["BaseSiteName"] as String }
val nameView: TextView = item_view.findViewById(R.id.name) as TextView
nameView.text = job_name[position]
val job_date: MutableList<String> = arrayListOf()
job_list.mapTo(job_date) { it["PlanDt"] as String}
val dateView: TextView = item_view.findViewById(R.id.date) as TextView
dateView.text = job_date[position]
item_view.setOnClickListener{
val intent: Intent = Intent(mContext, JobDetailActivity::class.java)
intent.putExtra("job", job_list[position])
mContext.startActivity(intent)
}
return item_view
}
}
However, I want to make the list refresh-able. I've written the following code to refresh the list.
override fun onRefresh() {
Toast.makeText(this.context, "Refresh", Toast.LENGTH_SHORT).show()
val rootView = this_inflater!!.inflate(R.layout.fragment_pending_job, this_container, false)
val url = "something"
val request_queue = Volley.newRequestQueue(this.context)
val stringRequest = StringRequest(Request.Method.GET, url,
Response.Listener<String> { response ->
val pending_job = Gson().fromJson<ArrayList<HashMap<String, String>>>(
response.toString(),
object : TypeToken<ArrayList<HashMap<String, String>>>() {}.type
)
val adapter: CustomAdapter = CustomAdapter(
this.context,
pending_job
)
val listView = rootView.findViewById(R.id.pending_job_list) as ListView
listView.adapter = adapter
pending_job_list_layout.isRefreshing = false
pending_job_list_layout.setOnRefreshListener(this)
request_queue.stop()
}, Response.ErrorListener { error ->
if (error.networkResponse != null) {
Toast.makeText(this.context, error.networkResponse.statusCode.toString(), Toast.LENGTH_SHORT).show()
}
request_queue.stop()
})
request_queue.add(stringRequest)
}
That is just instantiating the CustomAdapter again and take it to the listview again.
When I refresh, nothing in the list is changed.
Define a method UpdateData in CustomAdapter class which will receive new data and replaces old data
fun UpdateData(new_job_list: ArrayList<HashMap<String, String>>){
job_list.clear()
job_list.addAll(new_job_list)
notifyDataSetChanged()
}
Now when you get new data from volly, instead of setting adapter again for listview just use
adapter.UpdateData(pending_job)
1.Way:
You can make background listener with Asynctask .You can listen to your server in a loop continuous.When data changed than you can refresh the listview.This way is easy but not good for performance.
2.Way:
You can use firebase database.Because it is working realtime.
3.Way:
If you don't want change your database.You can use Google Cloud Messaging.You must implement this, both server and your application.When data changed on server listen and send message with cloud messaging to android app.And refresh list view automatically.
Related
I am trying to "dynamically" create CardView and then fill TextView with data from an API call. The thing is, to me it seems like the request is not getting called.
I created an adapter class based on Create dynamically lists with RecyclerView which is working fine and I am adding as many windows as needed. And then in the MainActivity, I am trying to do an API request with Volley. Before I created manually TextView and fed the results manually into it - which worked fine. But now with this dynamically created CardView nothing is happening. Could anyone try to guide me please?
MainActivity:
class MainActivity : AppCompatActivity() {
// private var message: TextView = findViewById<TextView>(R.id.jsonParse)
lateinit var weatherRV: RecyclerView
lateinit var weatherModelArray: ArrayList<WeatherViewModel>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportActionBar?.hide()
weatherRV = findViewById(R.id.mainView)
weatherModelArray = ArrayList()
val model1 = WeatherViewModel("Open weather", "")
val model2 = WeatherViewModel("Yr.no", "")
weatherModelArray.add(model1)
weatherModelArray.add(model2)
val weatherAdapter = WeatherAdapter(this, weatherModelArray)
val linearLayoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
weatherRV.layoutManager = linearLayoutManager
weatherRV.adapter = weatherAdapter
apICall(this#MainActivity, model1)
}
}
apiCall:
#RequiresApi(Build.VERSION_CODES.O)
internal fun apICall(context: Context, jsonView: WeatherViewModel) {
var lat: Double? = null
var lon: Double? = null
var url: String? = null
val apiKey: String = "XXXX"
lat = YYY.Y
lon = YYY.Y
url = "https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&appid=${apiKey}&units=metric&exclude=minutely,hourly"
// Instantiate the RequestQueue.
val queue = Volley.newRequestQueue(context)
val gsonPretty = GsonBuilder().setPrettyPrinting().create()
// Request a string response from the provided URL.
val stringRequest = StringRequest(
Request.Method.GET, url,
{response ->
val gson = Gson()
val openJSON = gson.fromJson(response.toString(), OpenWeatherJSON::class.java)
val prettyJsonString = gsonPretty.toJson(openJSON)
try {
val dt = openJSON.daily[0].dt
val sdf = SimpleDateFormat("dd-MM-yyyy")
val date = Date(dt * 1000) // snackbar.dismiss()
sdf.format(date) // jsonView.apiResult = sdf.format(date) // jsonView.apiResult.append("\n")
jsonView.apiResult = openJSON.daily[0].temp.toString()
}
catch (e: Exception) {
jsonView.apiResult = e.toString()
}
},
{
jsonView.apiResult = "Error"
})
// Add the request to the RequestQueue.
queue.add(stringRequest) }
Now in the image below you can see, that Result1 is not getting changed into the request response. I can change it with jsonView.text = "something" outside the stringRequest
Update1:
class WeatherAdapter(context: Context, weatherModelArray: ArrayList<WeatherViewModel>):
RecyclerView.Adapter<WeatherAdapter.ViewHolder>() {
private val weatherModelArray: ArrayList<WeatherViewModel>
// Constructor
init {
this.weatherModelArray = weatherModelArray
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WeatherAdapter.ViewHolder {
val view: View = LayoutInflater.from(parent.context).inflate(R.layout.card_layout, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: WeatherAdapter.ViewHolder, position: Int) {
val model = weatherModelArray[position]
holder.apiName.text = model.apiName
holder.apiResult.text = model.apiResult
}
override fun getItemCount(): Int {
return weatherModelArray.size
}
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val apiName: TextView
val apiResult: TextView
init {
apiName = itemView.findViewById(R.id.idApiName)
apiResult = itemView.findViewById(R.id.idApiResult)
}
}
}
You need to notify the RecyclerView adapter that the data has changed after you change the data. This means calling notifyDataSetChanged from within the callback. That would look something like this:
internal fun apICall(context: Context, jsonView: WeatherViewModel, adapter: WeatherAdapter) {
//...
val stringRequest = StringRequest(
Request.Method.GET, url,
{response ->
//...
jsonView.apiResult = openJSON.daily[0].temp.toString()
adapter.notifyDataSetChanged()
},
{
jsonView.apiResult = "Error"
adapter.notifyDataSetChanged()
})
// Add the request to the RequestQueue.
queue.add(stringRequest)
}
When I try to fill a ListView using a custom adapter, I get an empty list, I can't figure out what the error is? Why is everything loaded and displayed when using the default adapter?
HeroesAdapter.kt
class HeroesAdapter(context: Context, heroes: List<TestHero>): BaseAdapter() {
private val context = context
private val heroes = heroes
override fun getCount(): Int {
return heroes.count()
}
override fun getItem(position: Int): Any {
return heroes[position]
}
override fun getItemId(position: Int): Long {
return 0
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
// categoryView = LayoutInflater.from(context).inflate(R.layout.activity_heroes, null)
val categoryView = LayoutInflater.from(context).inflate(R.layout.activity_heroes, parent, false)
// val categoryImage: ImageView = categoryView.findViewById(R.id.heroesImageView)
val categoryText: TextView = categoryView.findViewById(R.id.textHeroView)
val category = heroes[position]
categoryText.text = category.global.name
return categoryView
}
}
HeroesActivity
class HeroesActivity : AppCompatActivity() {
lateinit var adapter : ArrayAdapter<TestHero>
lateinit var adapt: ArrayAdapter<String>
lateinit var heroesAdapt : HeroesAdapter
var listHero = ArrayList<TestHero>()
private val TAG = "HeroesActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_heroes)
// val adapterr = ArrayAdapter(this, android.R.layout.simple_list_item_1,)
adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1,
LinkedList<TestHero>())
// heroesListView.adapter = adapter
adapt = ArrayAdapter(this, android.R.layout.simple_list_item_1,
LinkedList<String>())
//heroesListView.adapter = adapt
getCurrentData()
heroesAdapt = HeroesAdapter(this, listHero)
heroesListView.adapter = heroesAdapt
}
private fun getCurrentData() {
val api = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiRequest::class.java)
GlobalScope.launch(Dispatchers.IO) {
val response = api.herList().awaitResponse()
if (response.isSuccessful) {
val data = response.body()!!
Log.d(TAG, data.toString())
withContext(Dispatchers.Main){
// adapter.add(data.global.name)
adapt.add(data.global.platform)
listHero.add(data)
}
}
}
}
}
Looks like you add data to the backing list of the adapter (listHero.add(data)), but you never inform the adapter that its backing data has changed (heroesAdapt.notifyDataSetChanged()).
As an aside, there are some issues with your coroutine. You should not use GlobalScope. Use lifecycleScope instead to avoid leaking network calls and copies of your Activity. Really, you should fetch data in a ViewModel using the ViewModel's scope and expose it via LiveData or SharedFlow so the network call doesn't have to restart if the phone rotates.
I am having an issue with reloading data in RecyclerView after the data is updated with a separate URL call. The FristFragment calls LoadDataFromUrl and displays the data in the Recycler View. Each Recycler's view item has a button with OnSetClickListener that calls another URL to update item's name data. After the user updates the item's name and a successful response is received, then the original myResponse data is updated with the new item's name. When the data is updated, I need to reload data in the Recycer View` but I can not figure it out. I spent two days trying to fix it but I can't get it running. Any help would be greatly appreciated!
Data Model:
DataModel.kt
class MyResponse (var Status: String = "", val items: List<Items> = emptyList())
class Items(var ItemId: String = "", var ItemName: String = "")
Code for Recycler View:
Adapter.kt
var recyclerView: RecyclerView? = null
class MainAdapter(val myResponse: MyResponse): RecyclerView.Adapter<CustomViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val layoutInflater = LayoutInflater.from(parent?.context)
val cellForRow = layoutInflater.inflate(R.layout.my_custom_cell, parent,false)
return CustomViewHolder(cellForRow)
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val item = myResponse.items.get(position)
//there is a button for each item in the list that will call a function ButtonPressed from Frist Fragment
holder.view.button.setOnClickListener {
val firstFragment = FirstFragment()
firstFragment.ButtonPressed(item.ItemId,item.ItemName, position)
}
holder.view.textView_ItemID = item.itemId
holder.view.textView_Item_Name = item.itemName
}
class CustomViewHolder(val view: View, var Items: Item? = null): RecyclerView.ViewHolder(view){
}
}
Then I have a fragment Fragment.kt
FirstFragment.kt
class FirstFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val rootView = inflater.inflate(R.layout.first_fragment, container, false)
return rootView
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
LoadDataFromUrl()
recyclerView.layoutManager = LinearLayoutManager(this.context,
LinearLayoutManager.HORIZONTAL, false)
}
//this function loads data on create view
fun LoadDataFromUrl(){
val url = "some_url"
val payload = "some_data_to_send"
val requestBody = payload.toRequestBody()
val request = Request.Builder()
.method("POST",requestBody)
.url(url)
.build()
val client = OkHttpClient()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
println("error")
}
override fun onResponse(call: Call, response: Response) {
val body = response?.body?.string()
val gson = GsonBuilder().create()
myResponse = gson.fromJson(body, MyResponse::class.java)
activity?.runOnUiThread {
if (myResponse.Status== "200"){
recyclerView.adapter = MainAdapter(myResponse)
}
}
}
})
}
fun ButtonPressed(itemId: String, itemName: String, position: Int){
val url = "some_another_url"
val payload = "some_another_data_to_send"
val requestBody = payload.toRequestBody()
val request = Request.Builder()
.method("POST",requestBody)
.url(url)
.build()
val client = OkHttpClient()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
println("error")
}
override fun onResponse(call: Call, response: Response) {
val body = response?.body?.string()
val gson = GsonBuilder().create()
val buttomPressedResponse = gson.fromJson(body, ButtonPressedResponse::class.java)
if (buttonPressedResponse.Status== "200") {
myResponse.response[position].Status = buttomPressedResponse.Status //will update existing object myResponse with a new item's name
//this is where I have a problem
recyclerView.adapter.notifyDataSetChanged()
}
}
}
}
I tried the following changes but I still get an error.
//I get this error: Fatal Exception: OkHttp Dispatcher Process. recyclerView must not be null. Then the app crashes and the view reloads. If I clcik the Button again I get an error saying: RecyclerView: No adapter atatched. Skipping layout.
activity?.runOnUiThread {
myResponse.response[position].Status = checkInOutResponse.Status //will update existing object myResponse with updated data
recyclerView.adapter?.notifyDataSetChanged()
}
I also tried to run on it runOnUiTHread but nothing happens with this code
activity?.runOnUiThread {
myResponse.response[position].Status = checkInOutResponse.Status //will update existing object myResponse with updated data
recyclerView.adapter?.notifyDataSetChanged()
}
Create var myResponse: MyResponse variable in Adapter
Adapter.kt
var recyclerView: RecyclerView? = null
class MainAdapter(val myResponseInit: MyResponse): RecyclerView.Adapter<CustomViewHolder>(){
var myResponse: MyResponse
myResponse = myResponseInit
fun submitMyResponse(data: MyResponse) {
myResponse = data
}
//Rest of the code onCreateViewHolder etc.
}
Call submitMyResponse() function and notifyDataSetChanged() on adapter everytime you receive response.
I'm trying to make my Android App (I'm only experienced in iOS).
I created a RecyclerView that gets the data from a web. I tried everything to implement endless scrolling to load more items, but when I call the function to get the items, the entire RecyclerView loads again and no attach the new results on the bottom.
This is my code:
ConversationUser.kt
data class ConversationUser(
val message_nickname: String,
val message_image_thumb: String,
val message_large_thumb: String,
val message_modified: String,
val message_status: String,
val message_unread: Int,
val conv_id: String,
val message_dest: String) {
}
ConversacionesActivity.kt
class ConversacionesActivity : AppCompatActivity() {
// MARK: Variables
var user_token = ""
var user_id = ""
override fun onCreate(savedInstanceState: Bundle?) {
// User Defaults
val sharedPreferences = getSharedPreferences("Preferences", Context.MODE_PRIVATE)
user_token = sharedPreferences.getString("user_token", "")!!
user_id = sharedPreferences.getString("user_id", "")!!
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_conversaciones)
recyclerConv.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))
getConversationsData()
recyclerConv.setLoadingListener(object : LoadingListener {
override fun onRefresh() {
//refresh data here
}
override fun onLoadMore() {
// load more data here
getConversationsData()
}
})
}
fun getConversationsData() {
val httpAsync = "https://mywebsite.com/conversations/${user_token}"
.httpPost()
.responseString { request, response, result ->
when (result) {
is Result.Failure -> {
val ex = result.getException()
println(ex)
}
is Result.Success -> {
val data = result.get()
runOnUiThread {
val conversaciones = processJson(data)
show(conversaciones)
return#runOnUiThread
}
}
}
}
httpAsync.join()
}
fun processJson(json: String): List<ConversationUser> {
val gson: Gson = GsonBuilder().create()
val conversaciones: List<ConversationUser> = gson.fromJson(
json,
Array<ConversationUser>::class.java
).toList()
return conversaciones
}
fun show(conversaciones: List<ConversationUser>) {
recyclerConv.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
recyclerConv.adapter = AdaptadorConv(conversaciones, this, user_token, user_id)
}
AdaptadorConv.kt
class AdaptadorConv(
val conversaciones: List<ConversationUser> = ArrayList(),
val context: Context,
val user_token: String,
val user_id: String) : RecyclerView.Adapter<AdaptadorConv.ConvViewHolder>() {
override fun onBindViewHolder(holder: ConvViewHolder, position: Int) {
holder.convName.text = conversaciones[position].message_nickname
holder.convTime.text = conversaciones[position].message_modified
}
override fun getItemCount(): Int {
return conversaciones.size - 1
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ConvViewHolder {
val view: View = LayoutInflater.from(parent.context).inflate(
R.layout.conversaciones,
parent,
false
)
return ConvViewHolder(view)
}
class ConvViewHolder(vista: View): RecyclerView.ViewHolder(vista) {
val convImg: ImageView = itemView.findViewById(R.id.convImg)
val convStatus: ImageView = itemView.findViewById(R.id.convStatus)
val convName: TextView = itemView.findViewById(R.id.convName)
val convUnread: TextView = itemView.findViewById(R.id.convUnread)
val convTime: TextView = itemView.findViewById(R.id.convTime)
}
Thanks for any help or hint.
Please check your show () method, you are creating new Adapter every time with the new dataset. You have to append the new items to the adapter's list and adapter should be set to list once. Helpful tutorial can be found at here.
I have recyclerview with checkbox and I want to checklist all the data using button. I have trying this tutorial, but when i click the button, the log is call the isSelectedAll function but can't make the checkbox checked. what wrong with my code?
this is my adapter code
var isSelectedAll = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListApproveDeatilViewHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.activity_list_approve_row, parent, false)
return ListApproveDeatilViewHolder(itemView)
}
private lateinit var mSelectedItemsIds: SparseBooleanArray
fun selectAll() {
Log.e("onClickSelectAll", "yes")
isSelectedAll = true
notifyDataSetChanged()
}
override fun onBindViewHolder(holder: ListApproveDeatilViewHolder, position: Int) {
val approve = dataSet!![position]
holder.soal.text = approve.title
holder.kategori.text = approve.kategori
if (!isSelectedAll){
holder.checkBox.setChecked(false)
} else {
holder.checkBox.setChecked(true)
}
}
and this is my activity code
override fun onCreate(savedInstanceState: Bundle?) {
private var adapter: ListApproveDetailAdapter? = null
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_list_approve)
ButterKnife.bind(this)
getData()
// this is my button onclick code
select.setOnClickListener(){
if (select.getText().toString().equals("Select all")){
Toast.makeText(this, "" + select.getText().toString(), Toast.LENGTH_SHORT).show()
adapter?.selectAll()
select.setText("Deselect all")
} else {
Toast.makeText(this, "" + select.getText().toString(), Toast.LENGTH_SHORT).show()
select.setText("Select all")
}
}
}
//this is for get my data for the recyclerview
fun getData() {
val created_by = intent.getStringExtra(ID_SA)
val tgl_supervisi = intent.getStringExtra(TGL_SURVEY)
val no_dlr = intent.getStringExtra(NO_DLR)
API.getListApproveDetail(created_by, tgl_supervisi, no_dlr).enqueue(object : Callback<ArrayList<ListApprove>> {
override fun onResponse(call: Call<ArrayList<ListApprove>>, response: Response<ArrayList<ListApprove>>) {
if (response.code() == 200) {
tempDatas = response.body()
Log.i("Data Index History", "" + tempDatas)
recyclerviewApprove?.setHasFixedSize(true)
recyclerviewApprove?.layoutManager = LinearLayoutManager(this#ListApproveActivity)
recyclerviewApprove?.adapter = ListApproveDetailAdapter(tempDatas)
adapter?.notifyDataSetChanged()
} else {
Toast.makeText(this#ListApproveActivity, "Error", Toast.LENGTH_LONG).show()
}
swipeRefreshLayout.isRefreshing = false
}
override fun onFailure(call: Call<ArrayList<ListApprove>>, t: Throwable) {
Toast.makeText(this#ListApproveActivity, "Error", Toast.LENGTH_SHORT).show()
swipeRefreshLayout.isRefreshing = false
}
})
}
thankyou for any help :)
I am posting the answer with implementation of demo project. I haven't modified your code but as per your requirement i have done this.
MainActivity class:
class MainActivity : AppCompatActivity() {
var selectAll: Boolean = false;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView) as RecyclerView
val btnSelectAll = findViewById<Button>(R.id.btnSelectAll) as Button
//adding a layoutmanager
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)
//crating an arraylist to store users using the data class user
val users = ArrayList<User>()
//adding some dummy data to the list
users.add(User("Piyush", "Ranchi"))
users.add(User("Mehul", "Chennai"))
users.add(User("Karan", "TamilNadu"))
users.add(User("Bela", "Kolkata"))
//creating our adapter
val adapter = CustomAdapter(users, selectAll)
//now adding the adapter to recyclerview
recyclerView.adapter = adapter
btnSelectAll.setOnClickListener {
if (!selectAll) {
selectAll = true
} else {
selectAll = false
}
adapter?.selectAllCheckBoxes(selectAll)
}
}
}
User class:
data class User(val name: String, val address: String)
Adapter class:
class CustomAdapter(val userList: ArrayList<User>, val selectAll: Boolean) :
RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
var selectAllA = selectAll;
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomAdapter.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.list_layout, parent, false)
return ViewHolder(v)
}
override fun onBindViewHolder(holder: CustomAdapter.ViewHolder, position: Int) {
holder.textViewName.text = userList[position].name;
if (!selectAllA){
holder.checkBox.setChecked(false)
} else {
holder.checkBox.setChecked(true)
}
}
//this method is giving the size of the list
override fun getItemCount(): Int {
return userList.size
}
//the class is hodling the list view
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textViewName = itemView.findViewById(R.id.textViewUsername) as TextView
val checkBox = itemView.findViewById(R.id.checkbox) as CheckBox
}
fun selectAllCheckBoxes(selectAll: Boolean) {
selectAllA = selectAll
notifyDataSetChanged()
}
}
As i already mentioned in comments you are using two different adapter instance .
Now i see you have declared adapter globally .
Just modify your code as follows and make sure response.body() have data int it :
if (response.code() == 200) {
tempDatas = response.body()
Log.i("Data Index History", "" + tempDatas)
recyclerviewApprove?.setHasFixedSize(true)
recyclerviewApprove?.layoutManager = LinearLayoutManager(this#ListApproveActivity)
adapter = ListApproveDetailAdapter(tempDatas)
recyclerviewApprove?.adapter=adapter
} else {
Toast.makeText(this#ListApproveActivity, "Error", Toast.LENGTH_LONG).show()
}
Add one variable in model class.
like var isSelect : Boolean
In your selectAll() method update adpter list and notify adapter.
Edit:
in the adapter class.
if (approve.isSelect){
holder.checkBox.setChecked(true)
} else {
holder.checkBox.setChecked(false)
}
Hope this may help you.
OR
If you are using AndroidX then use should use one recyclerview features.
androidx.recyclerview.selection
A RecyclerView addon library providing support for item selection. The
library provides support for both touch and mouse driven selection.
Developers retain control over the visual representation, and the
policies controlling selection behavior (like which items are eligible
for selection, and how many items can be selected.)
Reference from here