Want to show images from internal storage in android studio using recycler view, did that but now want to use pagination, can it be done using pagination?
class TestingAdapter(var URI_String: ArrayList<String>, var activity: Activity) :
RecyclerView.Adapter<TestingAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view: View = LayoutInflater.from(parent.context).inflate(R.layout.view, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
Glide.with(activity).load(URI_String[position]).into(holder.imageView)
}
override fun getItemCount(): Int {
return URI_String.size
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var imageView: ImageView
init {
imageView = itemView.findViewById(R.id.imageView2)
}
}
}
Related
Where in the code should i be using the following lines to work with my widgets:
binding = WorkoutCardBinding.inflate(layoutInflater)
setContentView(binding.root)
I know it should be used in an activiy's onCreate function but I can't seem to get it to work with the below adapter class
class WorkoutAdaptor (
var workouts: List<Workout>
) : RecyclerView.Adapter<WorkoutAdaptor.WorkoutViewHolder>() {
private lateinit var binding: WorkoutCardBinding
inner class WorkoutViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WorkoutViewHolder {
binding = WorkoutCardBinding.inflate(layoutInflater)
setContentView(binding.root)
val view = LayoutInflater.from(parent.context).inflate(R.layout.workout_card, parent, false)
return WorkoutViewHolder(view)
}
override fun onBindViewHolder(holder: WorkoutViewHolder, position: Int) {
holder.itemView.apply {
binding.tvWorkoutCard.text = workouts[position].
}
}
override fun getItemCount(): Int {
return workouts.size
}
val binding = WorkoutCardBinding.inflate(
LayoutInflater.from(parent.context), parent, false)
return WorkoutViewHolder(binding)
//Change you onCreateViewHolder completely to this code
You don't have to create a binding variable in the adapter class. To use view binding in recyclerView adapter there are a few things that you've to change.
Firstly, change your viewHolder class constructor to accept viewBinding instead of a view
inner class WorkoutViewHolder(private val workoutCardBinding: WorkoutCardBinding) :
RecyclerView.ViewHolder(workoutCardBinding.root) {
fun bind(workout: Workout) {
workoutCardBinding.apply {
// create your view here
}
}
Change onCreateViewHolder, to return a viewHolder object using binding.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WorkoutViewHolder {
val workoutCardBinding=
WorkoutCardBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return WorkoutCardBinding(workoutCardBinding)
}
Your complete adapter class will look like this -
class WorkoutAdaptor (
var workouts: List<Workout>
) : RecyclerView.Adapter<WorkoutAdaptor.WorkoutViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WorkoutViewHolder {
val workoutCardBinding =
WorkoutCardBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return WorkoutCardBinding(workoutCardBinding)
}
override fun onBindViewHolder(holder: WorkoutViewHolder, position: Int) {
holder.bind(workouts[position])
}
override fun getItemCount(): Int {
return workouts.size
}
inner class WorkoutViewHolder(private val workoutCardBinding: WorkoutCardBinding) :
RecyclerView.ViewHolder(workoutCardBinding.root) {
fun bind(workout: Workout) {
workoutCardBinding.apply {
// create your view here
}
}
}
}
TodoAdapter.kt
class TodoAdapter (var todos:List<Todo>) : RecyclerView.Adapter<TodoAdapter.TodoViewHolder>(){
inner class TodoViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {
val view= LayoutInflater.from(parent.context).inflate(R.layout.todo_layout, parent, false)
return TodoViewHolder(view)
}
override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
holder.itemView.apply {
}
}
override fun getItemCount(): Int {
return todos.size
}
}
Above is the Recycler View Adapter Class.
I already have an inner class TodoAdapter. How do I use ViewBinding with this?
The layout file from where I want to access views is todo_layout.xml
I am assuming you are familiar with ViewBinding. Here is how you can use ViewBinding with your RecyclerViewAdapter.
Here will be your TodoAdapter.kt
class TodoAdapter (var todos:List<Todo>) : RecyclerView.Adapter<TodoAdapter.TodoViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {
val binding = TodoLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return TodoViewHolder(binding)
}
override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
holder.bind()
}
override fun getItemCount(): Int {
return todos.size
}
inner class TodoViewHolder(private val binding: TodoLayoutBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(){
binding.apply{
// Assign Values
}
}
}
}
And now inside your TodoViewHolder bind function call, you can access all your views.
It shows like this. DataBindingUtil and getRoot() are shown in red. When I hover over it android studio asks me to create class,enum,interface,etc and for getRoot() it shows to create reference and create an extension function
Primary Constructor Call Expected Error on super(binding.root)
I am using recyclerview to display images in cardview. When I load images from the url. It loads well from first time but when It loads for second time it is not displayed properly.
How to fix it? Here is the code
override fun getItemCount(): Int {
dataList = FlickrDBOperation.dataArray
if (dataList!!.isEmpty())
return 0
Log.e("count",dataList!!.size.toString())
return dataList!!.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
var itemView: View = LayoutInflater.from(parent.context).inflate(R.layout.imagelist_row,parent,false)
var viewHolder: FlickrAdapter.Holder = FlickrAdapter.Holder(itemView)
return viewHolder
}
override fun onBindViewHolder(holder: Holder, position: Int) {
holder.image_name.text = dataList!!.get(position).name
Picasso.with(context).load(dataList!!.get(position).preUrl).into(holder.row_image)
}
class Holder(itemView: View?) : RecyclerView.ViewHolder(itemView) {
val row_image: ImageView
val image_name: TextView
init {
row_image = itemView!!.findViewById<ImageView>(R.id.row_image)
image_name = itemView!!.findViewById<TextView>(R.id.image_name)
}
}
My recycler view has two types of item view. One type of them has MPAndroidChart in it. I need to do some chart view configuration that cannot be done in XML. How can I do it given that I am using RecyclerView data binding with a single base view holder (as recommended by George Mount) ?
open class BaseViewHolder(private val binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(obj: Any) {
binding.setVariable(BR.obj, obj)
binding.executePendingBindings()
}
}
abstract class BaseAdapter : RecyclerView.Adapter<BaseViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = DataBindingUtil.inflate<ViewDataBinding>(layoutInflater, viewType, parent, false)
return BaseViewHolder(binding)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val obj = getObjForPosition(position)
holder.bind(obj)
}
override fun getItemViewType(position: Int): Int {
return getLayoutIdForPosition(position)
}
protected abstract fun getObjForPosition(position: Int): Any
protected abstract fun getLayoutIdForPosition(position: Int): Int
}
You can still access
holder.itemView.myChartViewId.doSomeStuff()
on the onBindViewHolder() call.
You can also implement a function to "initialize" your charts in your view holder like this:
open class BaseViewHolder(private val binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(obj: Any) {
binding.setVariable(BR.obj, obj)
binding.executePendingBindings()
}
fun initCharts() {
if (itemView.myChartViewId == null) return
itemView.myChartViewId.doSomwStuff()
}
}
and call it whenever you need.
Adapter Calling:
adherenceDetails.hasFixedSize()
adherenceDetails.layoutManager= GridLayoutManager(this#PatientPlanStatus,3)
adherenceDetails.adapter= PatientPlanDetails(this#PatientPlanStatus, patientPlanAdherenceData.data?.get(0)?.adherence!!)
Adapter:
class PatientPlanDetails(var mcontext: Context, var patientDatas:ArrayList<AdherencePoJo>): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun getItemCount(): Int {
return patientDatas.size
}
val TAG="PatientPlanDetails"
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
val v = LayoutInflater.from(mcontext).inflate(R.layout.patient_plan_adherence, parent, false)
return Item(v)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
//Log.i(TAG,"On Bind")
(holder as Item).bindData(patientDatas.get(position),mcontext)
}
class Item(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindData(patienData: AdherencePoJo, context: Context) {
val TAG="PatientPlanDetails"
}
}
}
getItemCount() returning the correct size. But only first row is showing. Please check the image
Card has actual height but the item inside it are not visible.
I am getting no log in the logout also.
Make your patient_plan_adherence layout height as wrap_content
Try with this property in your RecyclerView:
app:layout_behavior="#string/appbar_scrolling_view_behavior"