'How to retrieve image from fire base
I have a question that how to get the image from a real-time database. In my code, I want to get the data from the database ( one is text form, one is image form ) and insert them in the recycler view. I get the reference from the internet and find these codes to realise my function. However, after inserting it, it still cannot be shown because my image is in string form but I cannot find any solution to solve it. Can somebody help me? Maybe the main problem is I do not know how to insert the URL of the real-time database.
Problem faced :
java.lang.ClassCastException: com.google.android.material.imageview.ShapeableImageView cannot be cast to android.widget.TextView
at com.example.assignment_mad.NotificationAdapter$MyViewHolder.<init>(Notificatiion_Adapter.kt:118)
at com.example.assignment_mad.NotificationAdapter.onCreateViewHolder(Notificatiion_Adapter.kt:85)
at com.example.assignment_mad.NotificationAdapter.onCreateViewHolder(Notificatiion_Adapter.kt:63)
Main code :
package com.example.assignment_mad
import android.content.ContentValues.TAG
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.example.assignment_mad.databinding.ActivityMainBinding
import com.example.assignment_mad.databinding.FragmentNotificationBinding
import com.example.assignment_mad.databinding.FragmentSearchPageBinding
import com.google.android.material.imageview.ShapeableImageView
import com.google.android.material.tabs.TabLayout
import com.google.firebase.database.*
import com.google.firebase.database.ktx.database
import com.google.firebase.ktx.Firebase
import kotlinx.android.synthetic.*
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_notification_.*
class Notification_Fragment : Fragment( ) {
val database=Firebase.database
val myRef=database.getReference("message")
private var _binding:FragmentNotificationBinding?=null
private val binding get()=_binding!!
private lateinit var dbref: DatabaseReference
private lateinit var newRecyclerView: RecyclerView
private lateinit var newArrayList: ArrayList<Company>
private lateinit var tempArrayList: ArrayList<Company>
lateinit var imageId:Array<Int>
lateinit var heading:Array<String>
lateinit var news:Array<String>
private var layoutManager: RecyclerView.LayoutManager? = null
private var adapter: RecyclerView.Adapter<NotificationAdapter.MyViewHolder>? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
var views =inflater.inflate(R.layout.fragment_notification_, container, false)
newRecyclerView=views.findViewById(R.id.recyclerView)
newArrayList= arrayListOf<Company>()
// Inflate the layout for this fragment
return views
}
override fun onViewCreated(itemView: View, savedInstanceState: Bundle?) {
super.onViewCreated(itemView, savedInstanceState)
adapter=NotificationAdapter(newArrayList)
getUserdata()
}
private fun getUserdata() {
dbref=FirebaseDatabase.getInstance("https://recyclerview-e3e96-default-rtdb.asia-southeast1.firebasedatabase.app/").getReference("Notification")
dbref.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.exists()){
for (companySnapshot in snapshot.children){
val company=companySnapshot.getValue(Company::class.java)
newArrayList.add(company!!)
}
adapter?.notifyDataSetChanged()
}
}
override fun onCancelled(error: DatabaseError) {
Log.w(TAG, "Failed to read value.", error.toException())
}
})
newRecyclerView.layoutManager=LinearLayoutManager(activity)
newRecyclerView.setHasFixedSize(true)
newRecyclerView.adapter=adapter
}
}
The recyclerview adapter :
package com.example.assignment_mad
import android.provider.Settings.System.getString
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.google.android.material.imageview.ShapeableImageView
import kotlinx.android.synthetic.main.dropdown_item.view.*
class NotificationAdapter(private val companysList:ArrayList<Company>):RecyclerView.Adapter<NotificationAdapter.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView=LayoutInflater.from(parent.context).inflate(R.layout.list_item,parent,false)
return MyViewHolder(itemView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem=companysList[position]
holder.titleImage.text=currentItem.titleImage
//holder.titleImage.setImageResource(currentItem.titleImage)
holder.tvHeading.text=currentItem.heading
}
override fun getItemCount(): Int {
return companysList.size
}
class MyViewHolder(itemView: View):RecyclerView.ViewHolder(itemView){
//original
//val titleImage:ShapeableImageView=itemView.findViewById(R.id.title_image)
val titleImage: TextView =itemView.findViewById(R.id.title_image)
val tvHeading: TextView =itemView.findViewById(R.id.tvHeading)
}
}
the xml file and list_item xml :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".Notification_Fragment">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recyclerView"
tools:listitem="@layout/list_item"/>
<!-- TODO: Update blank fragment layout -->
</FrameLayout>
------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="8dp">
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/title_image"
android:scaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearanceOverlay="@style/RoundCorner"
android:src="@drawable/company_logo_1"/>
<TextView
android:id="@+id/tvHeading"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:text="Candidate Biden Called Saudi Arable a Pareft eaft."
android:textSize="16dp"
android:textStyle="bold"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/title_image"
app:layout_constraintTop_toTopOf="parent"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_image"
android:background="@color/underline"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The realtime firebase resource :
Solution 1:[1]
The specific error you are seeing is because you define a ShapeableImageView in xml with id title_image, but you are casting it to a TextView in this line:
val titleImage: TextView =itemView.findViewById(R.id.title_image)
Once you resolve this, consider using an image loading library like Glide to load the image URL you get from the Realtime Database into your ImageView.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Alex Mamo |
