Solution 1 :
I strongly recommend using data binding and add a binding adapter to load your image using Glide
[ UPDATE 2 ]
Consider using fixed value size for Imageview (Width and Height) when you want to show images dynamically (in this case loading from Network)
[ UPDATE ]
Look closely into your RecyclerAdapter class. You have to put the imageUrl in your Intent using this code snippet:
intent.putExtra("imageUrl", itemList[position].owner.avatar_url)
then in your Description{Fragment/Activity} you have to get that url and let the glide do the rest:
val imageUrl = arguments?.getString("imageUrl")
imageUrl?.let { loadImageViaUrl(imageview, it) }
and define loadImageViaUrl as below :
private fun loadImageViaUrl(view: ImageView, url: String) {
val options = RequestOptions()
.placeholder(R.drawable.network_image_placeholder) // use any image as placeholder
Glide.with(view.context)
.setDefaultRequestOptions(options)
.load(url)
.into(view)
}
This is the most basic way to use the Glide library.
Problem :
I am using Retrofit and Glide for a simple Image and textView. In my “Description” fragment I want to display the image from the api into the ImageView just under the textView. My recyclerView images work perfectly, but how would I display a single image from the retrofit/api into this Description class.
I added
val imageView:ImageView = view!!.findViewById(R.id.item_image)
But I am lost after this.
This is the fragment with the textview and where I want to place the ImageView under the text description
class DescriptionFragment : Fragment() {
companion object {
fun newInstance() = DescriptionFragment()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.main_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val textView:TextView = view!!.findViewById(R.id.message)
val imageView:ImageView = view!!.findViewById(R.id.item_image)
// Get the arguments from the caller fragment/activity
val description = arguments?.getString("description")
description?.let {
textView.text = "Description : n$description"
}
}
}
This is the xml I would like to load the image into
<?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_id="@+id/description"
android_layout_width="match_parent"
android_layout_height="match_parent"
tools_context=".ui.main.DescriptionFragment">
<ImageView
android_id="@+id/item_image"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_marginBottom="8dp"
app_layout_constraintBottom_toTopOf="@+id/textView"
app_layout_constraintEnd_toEndOf="parent"
app_layout_constraintStart_toStartOf="parent"
app_layout_constraintTop_toTopOf="parent" />
<TextView
android_id="@+id/textView"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_marginBottom="41dp"
android_text="@string/full_repo_description"
app_layout_constraintBottom_toTopOf="@+id/message"
app_layout_constraintEnd_toEndOf="parent"
app_layout_constraintHorizontal_bias="0.503"
app_layout_constraintStart_toStartOf="parent"
app_layout_constraintTop_toTopOf="parent"
app_layout_constraintVertical_bias="1.0" />
<TextView
android_id="@+id/message"
android_layout_width="wrap_content"
android_layout_height="100dp"
android_layout_margin="36dp"
android_text="DescriptionFragment"
app_layout_constraintBottom_toBottomOf="parent"
app_layout_constraintEnd_toEndOf="parent"
app_layout_constraintStart_toStartOf="parent"
app_layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is the data class where I get the avatar_url from
data class owner(var avatar_url:String);
data class Items(var id: String, var name: String, var full_name: String,var description: String,var owner: owner)
This is my current recycler class which is working correctly
class RecyclerAdapter(private val context: Context) : RecyclerView.Adapter<RecyclerAdapter.MyViewHolder>() {
var itemList: List<Items> = listOf()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.card_layout, parent, false)
return MyViewHolder(view)
}
override fun getItemCount(): Int {
return itemList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.repoId.text = itemList[position].id
holder.repoName.text = itemList[position].name
holder.repoFullName.text = itemList[position].full_name
Glide.with(context).load(itemList[position].owner.avatar_url)
.apply(RequestOptions().centerCrop())
.into(holder.repoImage)
holder.itemView.setOnClickListener {
val intent = Intent(context, DescriptionActivity::class.java)
// To pass any data to next activity
intent.putExtra("description", itemList[position].description)
// start your next activity
context.startActivity(intent)
// Toast.makeText(context,itemList.get(position).id,Toast.LENGTH_SHORT).show()
}
}
fun setItemsList(itemList: List<Items>) {
this.itemList = itemList;
notifyDataSetChanged()
}
class MyViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView!!) {
val repoId: TextView = itemView!!.findViewById(R.id.item_id)
val repoName: TextView = itemView!!.findViewById(R.id.item_name)
val repoFullName: TextView = itemView!!.findViewById(R.id.item_fullname)
val repoImage: ImageView = itemView!!.findViewById(R.id.item_image)
}
}
And this is my current mainActivity
class MainActivity : AppCompatActivity() {
lateinit var recyclerView: RecyclerView
lateinit var recyclerAdapter: RecyclerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView = findViewById(R.id.recyclerview)
recyclerAdapter = RecyclerAdapter(this)
recyclerview.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = recyclerAdapter
val apiInterface = ApiInterface.create().getItems()
apiInterface.enqueue(object : Callback<List<Items>> {
override fun onResponse(call: Call<List<Items>>?, response: Response<List<Items>>?) {
if (response?.body() != null) {
Log.d("myTest", response.body().toString());
recyclerAdapter.setItemsList(response.body()!!)
}
}
override fun onFailure(call: Call<List<Items>>?, t: Throwable?) {
}
})
}
}
And the way I get my url with Retrofit
interface ApiInterface {
@GET("repos")
fun getItems() : Call<List<Items>>
companion object {
var BASE_URL = "https://api.github.com/orgs/square/"
fun create() : ApiInterface {
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build()
return retrofit.create(ApiInterface::class.java)
}
}
}
Comments
Comment posted by Brummerly
I have updated my classes with the layouts and classes above
Comment posted by ArMot
@Brummerly Why you have a DescriptionActivity and DescriptionFragment at the same time? what is the purpose of each? Did you manage to get the description and show it in the textView (in DescriptionFragment)? if so then You’re only problem is image not being shown, yes?
Comment posted by Brummerly
Yes the description works perfectly, its just the image I am having issues with
Comment posted by ArMot
@Brummerly , I updated my answer, If you still have problems with loading image, just let me know 🙂 so I can help you with that.
Comment posted by ArMot
@Brummerly : one more thing, You are doing good … but your code can be refactored and be more readable 🙂 , I recommend you reading some articles about