i was making app with 2 buttons where are 2 different lists (i used recycler view) & duration debugging i found Error while refreshing device settings: network time: 263, HTTP status code: 404, exception com.android.volley.ClientError. Retrying. network time: 263, HTTP status code: 404, exception com.android.volley.ClientError
This is my code in adapter.
class CardAdapter(val context: Context, private val layout: Int):
RecyclerView.Adapter<CardAdapterViewHolder>() {
private val datasetDishes = com.example.favthings.data.Data.dishes
private val datasetAct = com.example.favthings.data.Data.activity
class CardAdapterViewHolder(view: View?): RecyclerView.ViewHolder(view!!) {
val dish_name: TextView = view?.findViewById(R.id.dish_name)!!
val dish_description: TextView = view?.findViewById(R.id.dish_description)!!
val dish_img: ImageView = view?.findViewById(R.id.dish_img)!!
val act_title: TextView = view?.findViewById(R.id.act_title)!!
val act_description:TextView = view?.findViewById(R.id.act_description)!!
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardAdapterViewHolder {
val adapter = LayoutInflater.from(parent.context)
val inflatedAdapter = if(layout == 1 )
{
adapter.inflate(R.layout.activity_list_item , parent, false)
}else{
adapter.inflate(R.layout.activity_dishes_item , parent, false)
}
return CardAdapterViewHolder(inflatedAdapter)
}
override fun getItemCount(): Int{
return datasetDishes.size
return datasetAct.size
}
override fun onBindViewHolder(holder: CardAdapterViewHolder, position: Int) {
val item_dish = datasetDishes[position]
val item_act = datasetAct[position]
holder.act_title.text = item_act.strResource_activity.toString()
holder.act_description.text = item_act.strResource_description.toString()
holder.dish_name.text = item_dish.strResourse_dish.toString()
holder.dish_img.setImageResource(item_dish.imgResourse)
holder.dish_description.text = item_dish.strResourse_dishDescr.toString()
}
}
this my code in one of the activities
class Dish : AppCompatActivity() {
private lateinit var binding: ActivityDishesBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDishesBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.dishRecyclerView.adapter = CardAdapter(
applicationContext,
Layout.DISH
)
// Specify fixed size to improve performance
binding.dishRecyclerView.setHasFixedSize(true)
// Enable up button for backward navigation
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
}
and finally my main activity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val buttonActivity: Button = findViewById(R.id.buttonActivity)
buttonActivity.setOnClickListener {
val intent = Intent(this, FavActivities::class.java).apply {
startActivity(this)
}
}
val buttonPlaces: Button = findViewById(R.id.buttonPlaces)
buttonPlaces.setOnClickListener {
val intent1 = Intent(this, Dish::class.java).apply {
startActivity(this)
}
}
val buttonMusic: Button = findViewById(R.id.buttonMusic)
buttonMusic.setOnClickListener {
val intent2 = Intent(this, Music::class.java).apply {
startActivity(this)
}
}
}
i found some solution. where i should put it? what to write where are commentes "exception" and "do stuff with body"?
fun onErrorResponse(error: VolleyError?) {
if (error == null || error.networkResponse == null) {
return
}
val body: String
//get status code here
val statusCode: String = java.lang.String.valueOf(error.networkResponse.statusCode)
//get response body and parse with appropriate encoding
try {
val UTF_8: Charset = Charset.forName("UTF-8")
body = String(error.networkResponse.data, UTF_8)
} catch (e: UnsupportedEncodingException) {
// exception
}
//do stuff with the body
}
i will be soo grateful for any explanitions.
Related
Here RecyclerView loads only one item however the loops works prefect but with RecyclerView loads only one item and not load all items
.........................................................................................................................................................................................................................................
GetJson.kt
class GetJson : AppCompatActivity() {
lateinit var recyclerView: RecyclerView
var arrayList = ArrayList<JsonModel>()
private var requestQueue : RequestQueue? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_get_json)
recyclerView = findViewById(R.id.recyclerView2)
recyclerView.layoutManager = LinearLayoutManager(this)
val getButton : Button = findViewById(R.id.ShowButtonJson)
requestQueue = Volley.newRequestQueue(this)
getButton.setOnClickListener {
getFromServer()
}
}
fun getFromServer(){
val url = "http://..../testapp/getjson.php"
val request = JsonObjectRequest(Request.Method.GET,url,null, {
response -> try {
val jsonArray = response.getJSONArray("names")
for (i in 0 until jsonArray.length()){
val name = jsonArray.getJSONObject(i)
val firstname = name.getString("firstname")
val middlename = name.getString("middlename")
val lastname = name.getString("lastname")
arrayList.add(JsonModel(firstname,middlename,lastname))
}
val namesAdapter = jsonAdapter(arrayList)
recyclerView.adapter = namesAdapter
namesAdapter.notifyDataSetChanged()
} catch (e: JSONException){
e.printStackTrace()
}
}, { response -> response.printStackTrace()
})
requestQueue?.add(request)
}
}
jsonAdapter.kt
class jsonAdapter(val data : List<JsonModel>) : RecyclerView.Adapter<jsonAdapter.ViewHolder>() {
class ViewHolder(view : View) : RecyclerView.ViewHolder(view) {
val firstnameText : TextView = view.findViewById(R.id.firstnameView)
val middlenameText : TextView = view.findViewById(R.id.middleNameView)
val lastnameText : TextView = view.findViewById(R.id.lastNameView)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): jsonAdapter.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.jsonlist,parent,false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: jsonAdapter.ViewHolder, position: Int) {
val namesModel = data[position]
holder.firstnameText.text = namesModel.firstname
holder.middlenameText.text = namesModel.middlename
holder.lastnameText.text = namesModel.lastname
}
override fun getItemCount(): Int {
return data.size
}
}
If you see the read messages function in my activity class below, i wanted to update the isSeen field in firestore, but for some reason it does not work at all. My guess it requires a specific document value but that would not be possible as this a messaging app so there will be a lot of documents created.
Activity Class
class MessageActivity : AppCompatActivity() {
private lateinit var binding: ActivityMessageBinding
private lateinit var chat: ArrayList<Message>
private lateinit var messageAdapter: MessageAdapter
private lateinit var roomID: String
private lateinit var userID: String
private lateinit var recID: String
private var c: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMessageBinding.inflate(layoutInflater)
setContentView(binding.root)
userID = FirebaseAuth.getInstance().uid.toString()
recID = intent.getStringExtra("userID").toString()
val recName:String = intent.getStringExtra("userName").toString()
binding.userName.text = recName
chat = arrayListOf()
messageAdapter = MessageAdapter(chat)
binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.layoutManager = LinearLayoutManager(this)
when {
userID < recID ->
{
roomID = userID + recID
}
userID.compareTo(recID) == 0 ->
{
Toast.makeText(this, "Error you are chatting with yourself!!!", Toast.LENGTH_SHORT).show()
}
else -> {
roomID = recID + userID
}
}
readMessages(userID,recID)
binding.btnSend.setOnClickListener {
val message: String = binding.textSend.text.toString()
if(message.isNotEmpty()){
sendMessage(userID,recID,message)
binding.textSend.text.clear()
}
else{
Toast.makeText(this,"You can't send empty message", Toast.LENGTH_SHORT).show()
}
}
binding.gps.setOnClickListener {
val uri = "http://maps.google.com/maps?daddr="
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(uri))
intent.setPackage("com.google.android.apps.maps")
startActivity(intent)
}
}
private fun sendMessage(sender: String, rec: String, message: String){
val db = Firebase.firestore
val time: FieldValue = FieldValue.serverTimestamp()
val msg = hashMapOf(
"userID" to sender,
"recID" to rec,
"message" to message,
"time" to time,
"roomID" to roomID,
"isSeen" to false
)
db.collection("chats").document(roomID).collection("messages").document().set(msg,SetOptions.merge())
}
private fun readMessages(userId: String, recId: String){
val rootRef = Firebase.firestore
rootRef.collection("chats").document(roomID).collection("messages").orderBy("time", Query.Direction.ASCENDING).addSnapshotListener(object : EventListener<QuerySnapshot?>
{
override fun onEvent(#Nullable documentSnapshots: QuerySnapshot?, #Nullable e: FirebaseFirestoreException?)
{
if (e != null)
{
Log.e(TAG, "onEvent: Listen failed.", e)
return
}
chat.clear()
if (documentSnapshots != null)
{
for (queryDocumentSnapshots in documentSnapshots)
{
val msg = queryDocumentSnapshots.toObject(Message::class.java)
if (msg.recID == recId && msg.userID == userId || msg.recID == userId && msg.userID == recId)
{
chat.add(msg)
}
if(msg.recID.equals(userID).and(msg.userID.equals(recID))){
rootRef.collection("chats").document(roomID).collection("messages").document().update("isSeen",true)
}
messageAdapter = MessageAdapter(chat)
binding.recyclerView.adapter = messageAdapter
}
}
}
})
}
}
Adapter Class
class MessageAdapter(private val MessageList:ArrayList<Message>):RecyclerView.Adapter<MessageAdapter.MessageViewHolder>() {
private val left = 0
private val right = 1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessageViewHolder {
return if(viewType==right){
val view1 = LayoutInflater.from(parent.context).inflate(R.layout.chat_sender_item,parent,false)
MessageViewHolder(view1)
}else{
val view2 = LayoutInflater.from(parent.context).inflate(R.layout.chat_receiver_item,parent,false)
MessageViewHolder(view2)
}
}
override fun onBindViewHolder(holder: MessageViewHolder, position: Int) {
val message:Message = MessageList[position]
holder.showMessage.text = message.message
if(position==MessageList.size-1){
if(message.isSeen)
{
holder.textSeen.text = "Seen"
}else{
holder.textSeen.text = "Delivered"
}
}else{
holder.textSeen.visibility = View.GONE
}
}
override fun getItemCount(): Int {
return MessageList.size
}
class MessageViewHolder(itemView:View) : RecyclerView.ViewHolder(itemView){
val showMessage: TextView = itemView.findViewById(R.id.showMessage)
val textSeen: TextView = itemView.findViewById(R.id.textSeen)
}
override fun getItemViewType(position: Int): Int {
val userID = FirebaseAuth.getInstance().currentUser!!.uid
return if(MessageList[position].userID==userID)
{
right
}else
{
left
}
}
}
Model Class
package com.aarondcosta99.foodreuseapp.model
data class Message(var userID:String? = "",var message:String? = "",var recID:String? = "",var isSeen:Boolean=false)
Firestore
This won't work:
rootRef.collection("chats").document(roomID).collection("messages").document().update("isSeen",true)
The document() call without any arguments creates a reference to a new non-existing document, which you then try to update. But update() only works when a document already exists, you can't use update() to create a document, so this code ends up doing nothing.
To update a document, you need to specify the complete path to that document. The fact that you need to update a lot of documents makes no difference to that fact, it just means you'll need to paths to a lot of documents.
As far as I can tell, you are trying to update the document that you read in documentSnapshots, which means you already have the DocumentReference handy and can update it with:
queryDocumentSnapshots.reference.update("isSeen",true)
Somehow I see in the app messages I sent, but can't see those which should be received from others. Also when I'm sending a message it's sent to all users. Here I'm sending two classes, adapter and main chat activity. I tried using inner classes, different types of getItemViewType functions but nothing works.
MessageAdapter
class MessageAdapter(val context: Context, val messageList: ArrayList<Message>):
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
val ITEM_RECIEVE = 1
val ITEM_SENT = 2
class SentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
{
val sentMessage = itemView.findViewById<TextView>(R.id.txt_sent_message)
}
class RecieveViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
{
val recieveMessage = itemView.findViewById<TextView>(R.id.txt_recieve_message)
}
override fun getItemViewType(position: Int): Int {
val currentMessage = messageList[position]
if (FirebaseAuth.getInstance().currentUser?.uid.equals(currentMessage.senderId)) {
return ITEM_SENT
}
else {
return ITEM_RECIEVE
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
if (viewType == 1)
{
val view = LayoutInflater.from(context).inflate(R.layout.recieve, parent, false)
Log.d("tag2", "testrecieveviewholderview11")
return RecieveViewHolder(view)
}
else
{
val view = LayoutInflater.from(context).inflate(R.layout.sent, parent, false)
Log.d("tag", "testsentviewholderview22")
return SentViewHolder(view)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val currentMessage = messageList[position]
if(holder.javaClass == SentViewHolder::class.java)
{
val viewHolder = holder as SentViewHolder
holder.sentMessage.text = currentMessage.message
}
else
{
val viewHolder = holder as RecieveViewHolder
holder.recieveMessage.text = currentMessage.message
}
}
override fun getItemCount(): Int {
return messageList.size
}
}
And ChatActivity
var firebaseUser: FirebaseUser? = null
private lateinit var messageRecyclerView: RecyclerView
private lateinit var messageBox: EditText
private lateinit var sendButton: ImageButton
private lateinit var messageAdapter: MessageAdapter
private lateinit var messageList: ArrayList<Message>
private lateinit var mRef: DatabaseReference
var recieverRoom: String? = null
var senderRoom: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
val intent = Intent()
val name = intent.getStringExtra("name")
val recieverUid = intent.getStringExtra("uid")
val senderUid = FirebaseAuth.getInstance().currentUser?.uid
mRef = FirebaseDatabase.getInstance().reference
senderRoom = recieverUid + senderUid
recieverRoom = senderUid + recieverUid
messageRecyclerView = findViewById(R.id.RecyclerViewChat)
messageBox = findViewById(R.id.messageBox)
sendButton = findViewById(R.id.sendButton)
messageList = ArrayList()
messageAdapter = MessageAdapter(this, messageList)
messageRecyclerView.layoutManager = LinearLayoutManager(this)
messageRecyclerView.scrollToPosition(messageAdapter.itemCount-1)
messageRecyclerView.adapter = messageAdapter
mRef.child("chats").child(senderRoom!!).child("messages")
.addValueEventListener(object : ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
messageList.clear()
for (postSnapshot in snapshot.children)
{
val message = postSnapshot.getValue(Message::class.java)
messageList.add(message!!)
}
messageAdapter.notifyDataSetChanged()
}
override fun onCancelled(error: DatabaseError) {
}
})
sendButton.setOnClickListener {
if (messageBox.text.toString().isEmpty() || messageBox.text.toString().isBlank())
{
messageBox.setText("")
}
else {
val message = messageBox.text.toString()
val messageObject = Message(message, senderUid)
mRef.child("chats").child(senderRoom!!).child("messages").push()
.setValue(messageObject).addOnSuccessListener {
mRef.child("chats").child(recieverRoom!!).child("messages").push()
.setValue(messageObject)
}
messageBox.setText("")
}
}
}
}
The error coming in this code is "Unresolved reference: message" and "Unresolved reference: senderId" in MessageAdapter. MessageAdapter is not able to take variables that are declared in Message class(message and senderId).
From the Android app, I wrote for I want to add, add a button in the toolbar that acts as a toggle. When the toggle is disabled (the default state) all posts should be shown, when it is enabled (after a tap) the list should only show the posts having user_id set to 1 and sorted by descending published_at. Tapping on the button again will return it to its default state.
Note that publishedAt returning date and publishedAt and user_id coming from postList from the server I want to know how can I implement above requirement what kind of steps should I have to follow
below my logic implementation in MainActivity.kt
class MainActivity : AppCompatActivity() {
#Inject
lateinit var restInterface: RestInterface
private fun initializeDagger() = App.appComponent.inject(this)
var context: Context? = null
private var filteredList: List<Post>? = null
private var recyclerView: RecyclerView? = null
private var switch1: Switch? = null
private var restAdapter: RestAdapter? = null
private var postList: List<Post>? = null
private var restList: RestList? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initializeDagger()
recyclerView = findViewById(R.id.recycler_view)
switch1 = findViewById(R.id.switch1)
fetchPosts()
switch1.setOnclickListener {
postList.forEach { postItem: Post ->
if (postItem.userId == 1)
filteredList.add(postItem)
}
recyclerView.post = filteredList
recyclerView.notifyDatasetChanged()
}
// Collections.sort( filteredList.get(4).publishedAt, Collections.reverseOrder());
}
private fun fetchPosts() {
val progress = ProgressDialog(this)
progress.setMessage("Loading... ")
progress.isIndeterminate = true
progress.show()
restInterface?.getPosts?.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : DisposableSingleObserver<Response<RestList>>() {
override fun onSuccess(response: Response<RestList>) {
restList = response.body()
val layoutManager = LinearLayoutManager(applicationContext)
recyclerView?.layoutManager = layoutManager
// initialize postList with posts
postList = restList?.posts
restAdapter = postList?.let { RestAdapter(it, restList) }
recyclerView?.adapter = restAdapter
}
override fun onError(e: Throwable) {
progress.dismiss()
Toast.makeText(context, "" + e.message, Toast.LENGTH_SHORT).show()
}
})
}
}
below my RestAdapter.kt
class RestAdapter(val post: List<Post>,val restList: RestList?) : RecyclerView.Adapter<RestAdapter.PostHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.post_list, null)
return PostHolder(itemView)
}
override fun getItemCount(): Int {
return post.size
}
override fun onBindViewHolder(holder: PostHolder, position: Int) {
val posts = post[position]
Picasso
.get() // give it the context
.load(posts.image) // load the image
.into(holder.postImage)
holder.userId.text = posts.userId.toString()
holder.postTitle.text = posts.title
holder.postTime.text = posts.publishedAt
holder.postDescription.text = posts.description
}
class PostHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val postImage: ImageView = itemView.findViewById(R.id.postImage)
val userId: TextView = itemView.findViewById(R.id.userId)
val postTitle: TextView = itemView.findViewById(R.id.postTitle)
val postTime: TextView = itemView.findViewById(R.id.postTime)
val postDescription: TextView = itemView.findViewById(R.id.postDescription)
}
}
You can use method .sortedByDescending or .sortedBy on list :)
[Edit]
I give you a simple solution for that, maybe not the best but should work
1. Change RestAdapter constructor to (var post: List,val restList: RestList?)
Add method to updateData in apadapter:
fun filterData(isChecked: Boolean) {
if (isChecked) {
val filteredList = arrayListOf<Post>()
filteredList.addAll(restList?posts.filter { it.user_id == 1 }.sortedByDescending { it.published_at })
post = filteredList
} else {
post = restList?.posts
}
notifyDatasetChanged()
}
And in your class use this:
switch1.setOnclickListener {
restAdapter?.filterData(switch1.isChecked()//state of your switch i.e isChecked() which return true or false)
}
I'm tying to parse JSON in recyclerview. App compiles fine but it's outputting empty/blank screen
BlogAdapter.kt
class BlogAdapter(private val blogList: List<Blog>) : RecyclerView.Adapter<BlogAdapter.ViewHolder>() {
override fun getItemCount()= blogList.size
private var mContext: Context? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
this.mContext=parent.context;
return ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.character_item,
parent,
false
)
)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val mBlog = this.blogList[position]
if (mBlog.img != null) {
Glide.with(mContext!!)
.load(mBlog.img)
.into(holder.ivThumbnail)
}
if (mBlog.name != null) {
holder.tvTitle.text = mBlog.name
println("Log: Kabe "+mBlog.name)
}
}
class ViewHolder(itemView:View):RecyclerView.ViewHolder(itemView){
val ivThumbnail:ImageView = itemView.findViewById(R.id.ivThumbnail);
val tvTitle:TextView = itemView.findViewById(R.id.tvTitle);
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
var mainViewModel: MainViewModel? = null
var mBlogAdapter: BlogAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
getPopularBlog()
swipe_refresh.setOnRefreshListener { getPopularBlog() }
}
private fun getPopularBlog() {
swipe_refresh.isRefreshing = false
mainViewModel!!.allBlog.observe(this, Observer { charactersList ->
prepareRecyclerView(charactersList)
})
}
private fun prepareRecyclerView(blogList: List<Blog>) {
mBlogAdapter = BlogAdapter(blogList)
if (this.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
blogRecyclerView.layoutManager = LinearLayoutManager(this)
} else {
blogRecyclerView.layoutManager = GridLayoutManager(this, 4)
}
blogRecyclerView.itemAnimator = DefaultItemAnimator()
blogRecyclerView.adapter = mBlogAdapter
}
}
My Json file looks like this:
[
{
"id": 1,
"name": "potter",
"img": "https://images.example.com/potter.jpg"
},
{ …}
]
I've created it based on this tutorial: https://itnext.io/kotlin-wrapping-your-head-around-livedata-mutablelivedata-coroutine-networking-and-viewmodel-b552c3a74eec
Any suggestions please
EDIT:
class BlogRepository() {
private var character = mutableListOf<ABCCharacters>()
private var mutableLiveData = MutableLiveData<List<ABCCharacters>>()
val completableJob = Job()
private val coroutineScope = CoroutineScope(Dispatchers.IO + completableJob)
private val thisApiCorService by lazy {
RestApiService.createCorService()
}
fun getMutableLiveData():MutableLiveData<List<ABCCharacters>> {
coroutineScope.launch {
val request = thisApiCorService.getPopularBlog()
withContext(Dispatchers.Main) {
try {
val response = request.await()
val mBlogWrapper = response;
if (/*mBlogWrapper != null &&*/ mBlogWrapper.isNotEmpty()) {
character = mBlogWrapper as MutableList<ABCCharacters>
mutableLiveData.value = character
}
} catch (e: HttpException) {
// Log exception //
} catch (e: Throwable) {
// Log error //)
}
}
}
return mutableLiveData;
}
}
You forget to call notifyDataSetChanged, when you setup your RecyclerView widget. Below the full method call, to make it works.
private fun prepareRecyclerView(blogList: List<Blog>) {
mBlogAdapter = BlogAdapter(blogList)
if (this.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
blogRecyclerView.layoutManager = LinearLayoutManager(this)
} else {
blogRecyclerView.layoutManager = GridLayoutManager(this, 4)
}
blogRecyclerView.itemAnimator = DefaultItemAnimator()
blogRecyclerView.adapter = mBlogAdapter
mBlogAdapter.notifyDataSetChanged()
}
Try using below implementation:
class MainActivity : AppCompatActivity() {
lateinit var mainViewModel: MainViewModel
var mBlogAdapter: BlogAdapter? = null
var blogList: List<Blog> = arrayListOf()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
// init your RV here
prepareRecyclerView()
getPopularBlog()
swipe_refresh.setOnRefreshListener { mainViewModel.getAllBlog() }
}
private fun getPopularBlog() {
swipe_refresh.isRefreshing = false
mainViewModel.getAllBlog().observe(this, Observer { charactersList ->
blogList = charactersList
mBlogAdapter?.notifyDataSetChanged()
})
}
private fun prepareRecyclerView() {
mBlogAdapter = BlogAdapter(blogList)
if (this.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
blogRecyclerView.layoutManager = LinearLayoutManager(this)
} else {
blogRecyclerView.layoutManager = GridLayoutManager(this, 4)
}
blogRecyclerView.itemAnimator = DefaultItemAnimator()
blogRecyclerView.adapter = mBlogAdapter
}
}
Modify your view model like below:
class MainViewModel() : ViewModel() {
val characterRepository= BlogRepository()
fun getAllBlog(): MutableLiveData<List<ABCCharacters>> {
return characterRepository.getMutableLiveData()
}
override fun onCleared() {
super.onCleared()
characterRepository.completableJob.cancel()
}
}