How get the child count same as shown in the picture in the header.
API RESPONSE: -
data class ToDoListResponse(
val message: String = "",
val success: Int = 0,
val todays_task_list: MutableList<TodaysTask>,
val todays_task_total: Int = 0,
val tomorows_task_list: MutableList<TodaysTask>,
val tomorrow_task_total: Int = 0,
val upcomming_task_list: MutableList<TodaysTask>,
val upcomming_task_total: Int = 0)
{
data class TodaysTask(
val created_at: String = "",
val description: String = "",
val due_date: String= "",
val is_completed: String= "",
val is_pinned_task: String= "",
val remind_me: String= "",
val task_id: String= "",
var title: String= "",
val updated_at: String= "",
val user_id: String= ""
)
ADPATER: -
package com.coronation.jackpotplus.adapter
import android.annotation.SuppressLint
import android.app.DatePickerDialog
import android.content.Context
import android.graphics.Typeface
import android.os.Build
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.annotation.RequiresApi
import com.coronation.jackpotplus.R
import com.coronation.jackpotplus.model.CommonResponse
import com.coronation.jackpotplus.model.ToDoListResponse
import com.coronation.jackpotplus.network.ApiClient
import com.coronation.jackpotplus.network.ApiService
import com.coronation.jackpotplus.view.ToDoListActivity
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.textfield.TextInputEditText
import org.jetbrains.anko.layoutInflater
import retrofit2.Call
import retrofit2.Response
import java.text.SimpleDateFormat
import java.time.LocalDate
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.*
@Suppress("NAME_SHADOWING", "DEPRECATED_IDENTITY_EQUALS")
class CustomExpandableListAdapter(
context: Context,
expandableListTitle: ArrayList<String>,
expandableListDetail: HashMap<String,
MutableList<ToDoListResponse.TodaysTask>>)
: BaseExpandableListAdapter()
{
private val context: Context
private val expandableListTitle: ArrayList<String>
private val expandableListDetail: HashMap<String, MutableList<ToDoListResponse.TodaysTask>>
private lateinit var edtTitle: TextInputEditText
private lateinit var edtDes: TextInputEditText
private lateinit var dueDate: TextView
private lateinit var txtreminddate: TextView
private lateinit var createAt: String
private lateinit var taskId: String
private var ChildCount: String? = null
private lateinit var dialog: BottomSheetDialog
override fun getChild(listPosition: Int, expandedListPosition: Int): Any
{
return expandableListDetail[expandableListTitle[listPosition]]?.get(expandedListPosition)!!
}
override fun getChildId(listPosition: Int, expandedListPosition: Int): Long
{
return expandedListPosition.toLong()
}
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("InflateParams", "SimpleDateFormat")
override fun getChildView(listPosition: Int, expandedListPosition: Int, isLastChild: Boolean, convertView: View?, parent: ViewGroup?): View
{
var convertView = convertView
if (convertView == null)
{
val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
convertView = layoutInflater.inflate(R.layout.list_item, null)
}
val expandedListTextView = convertView?.findViewById(R.id.expandedListItem) as TextView
val expandedItem = convertView.findViewById(R.id.expandedItem) as LinearLayout
val txtDelete = convertView.findViewById(R.id.delete) as FrameLayout
val unpin = convertView.findViewById(R.id.unpin) as FrameLayout
val pin = convertView.findViewById(R.id.pin) as FrameLayout
val complete = convertView.findViewById(R.id.complete) as FrameLayout
val mainPin = convertView.findViewById(R.id.mainPin) as ImageView
val getset = getChild(listPosition, expandedListPosition) as ToDoListResponse.TodaysTask
expandedListTextView.text = getset.title
createAt = getset.created_at
unpin.visibility = View.GONE
if (getset.is_pinned_task == "1")
{
mainPin.visibility = View.VISIBLE
unpin.visibility = View.VISIBLE
pin.visibility = View.GONE
}
else
{
mainPin.visibility = View.GONE
pin.visibility = View.VISIBLE
}
unpin.setOnClickListener {
pinnedtask(getset.task_id)
}
pin.setOnClickListener {
pinnedtask(getset.task_id)
}
complete.setOnClickListener {
markascomplete(getset.task_id)
}
txtDelete.setOnClickListener {
deleteTask(getset.task_id)
}
expandedItem.setOnClickListener {
openTaskDetails()
taskId = getset.task_id
edtTitle.setText(getset.title)
edtDes.setText(getset.description)
dueDate.visibility = View.VISIBLE
txtreminddate.visibility = View.VISIBLE
val dueDate1 = getset.due_date
val sdf = SimpleDateFormat("yyyy-MM-dd")
val date = Date(dueDate1.toLong() * 1000)
dueDate.text = sdf.format(date)
val remindDate = getset.remind_me
val sdf1 = SimpleDateFormat("yyyy-MM-dd")
val date1 = Date(remindDate.toLong() * 1000)
txtreminddate.text = sdf1.format(date1)
}
return convertView
}
private fun pinnedtask(taskId: String)
{
val retIn = ApiClient.client!!.create(ApiService::class.java)
retIn.pintask(taskId).enqueue(object : retrofit2.Callback<CommonResponse> {
override fun onResponse(call: Call<CommonResponse>, response: Response<CommonResponse>) {
showToast(response.body()?.message)
notifyDataSetChanged()
if (context is ToDoListActivity) {
context.tasklistAPI("1")
}
}
override fun onFailure(call: Call<CommonResponse>, t: Throwable) {
showToast("Shomwthing wents wrong")
}
})
}
private fun markascomplete(taskId: String)
{
val retIn = ApiClient.client!!.create(ApiService::class.java)
retIn.markcomplete(taskId).enqueue(object : retrofit2.Callback<CommonResponse> {
override fun onResponse(call: Call<CommonResponse>, response: Response<CommonResponse>) {
showToast(response.body()?.message)
notifyDataSetChanged()
if (context is ToDoListActivity) {
context.tasklistAPI("1")
}
}
override fun onFailure(call: Call<CommonResponse>, t: Throwable) {
showToast("Shomwthing wents wrong")
}
})
}
private fun deleteTask(taskId: String)
{
val retIn = ApiClient.client!!.create(ApiService::class.java)
retIn.deteletask(taskId).enqueue(object : retrofit2.Callback<CommonResponse> {
override fun onResponse(call: Call<CommonResponse>, response: Response<CommonResponse>) {
showToast(response.body()?.message)
notifyDataSetChanged()
if (context is ToDoListActivity) {
context.tasklistAPI("1")
}
}
override fun onFailure(call: Call<CommonResponse>, t: Throwable) {
showToast("Shomwthing wents wrong")
}
})
}
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("InflateParams")
private fun openTaskDetails()
{
try
{
val modalbottomsheet = context.layoutInflater.inflate(R.layout.custom_view_todo, null)
dialog = BottomSheetDialog(context, R.style.DialogStyle)
dialog.setContentView(modalbottomsheet)
edtTitle = dialog.findViewById(R.id.edtTitle)!!
edtDes = dialog.findViewById(R.id.edtDes)!!
dueDate = dialog.findViewById(R.id.dueDate)!!
txtreminddate = dialog.findViewById(R.id.txtreminddate)!!
val imgDatePicker = dialog.findViewById<ImageView>(R.id.imgDatePicker)
val imgDatePickerReminder = dialog.findViewById<ImageView>(R.id.imgDatePickerReminder)
val button = dialog.findViewById<Button>(R.id.Button)
imgDatePicker?.setOnClickListener {
showDatePicker(context)
}
imgDatePickerReminder?.setOnClickListener {
showDatePickerForRemind(context)
}
button?.setOnClickListener {
updateTaskAPI()
}
dialog.show()
}
catch (e: Exception)
{
e.printStackTrace()
}
}
@RequiresApi(Build.VERSION_CODES.O)
private fun updateTaskAPI()
{
val l = LocalDate.parse(dueDate.text, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
val dueDateTimestamp = l.atStartOfDay(ZoneId.systemDefault()).toInstant().epochSecond
Toast.makeText(context, dueDateTimestamp.toString(), Toast.LENGTH_SHORT).show()
val l1 = LocalDate.parse(txtreminddate.text, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
val remindMeTimestamp = l1.atStartOfDay(ZoneId.systemDefault()).toInstant().epochSecond
Toast.makeText(context, remindMeTimestamp.toString(), Toast.LENGTH_SHORT).show()
val retIn = ApiClient.client!!.create(ApiService::class.java)
retIn.taskupdate(
createAt,
edtDes.text?.trim().toString(),
dueDateTimestamp.toString(),
remindMeTimestamp.toString(),
taskId, edtTitle.text?.trim().toString(),
"1").enqueue(object : retrofit2.Callback<CommonResponse>
{
override fun onResponse(call: Call<CommonResponse>, response: Response<CommonResponse>)
{
if (response.body()!!.success == 1)
{
dialog.dismiss()
showToast(response.body()?.message)
}
}
override fun onFailure(call: Call<CommonResponse>, t: Throwable)
{
showToast("Something not right, Please try again.")
}
}
)
}
@SuppressLint("InflateParams")
fun showToast(msg: String?)
{
try
{
val inflater = context.layoutInflater
val layout = inflater.inflate(R.layout.custom_toast, null)
val text = layout.findViewById<View>(R.id.text) as TextView
text.text = msg
val toast = Toast(context)
toast.duration = Toast.LENGTH_SHORT
toast.view = layout
if (toast.view.isShown)
{
toast.cancel()
}
else
{
toast.show()
}
}
catch (e: Exception)
{
e.printStackTrace()
}
}
private fun showDatePickerForRemind(context: Context)
{
val cal = Calendar.getInstance()
val dateSetListener =
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
cal.set(Calendar.YEAR, year)
cal.set(Calendar.MONTH, monthOfYear)
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth)
val myFormat = "yyyy-MM-dd" // mention the format you need
val sdf = SimpleDateFormat(myFormat, Locale.US)
txtreminddate.visibility = View.VISIBLE
txtreminddate.text = sdf.format(cal.time)
}
var datepicker: DatePickerDialog? = null
if (txtreminddate.text.isNotBlank())
{
try
{
val date: String = txtreminddate.text.trim().toString()
val datearr = date.split("-").toTypedArray()
val yearint = datearr[2].toInt()
val monthint = datearr[1].toInt()
val dateint = datearr[0].toInt()
datepicker = DatePickerDialog(
context,
dateSetListener,
dateint,
monthint - 1,
yearint
)
}
catch (e: Exception)
{
e.printStackTrace()
}
}
else
{
try
{
val calendar = Calendar.getInstance()
val dd = calendar[Calendar.DAY_OF_MONTH]
val mm = calendar[Calendar.MONTH]
val yy = calendar[Calendar.YEAR]
datepicker = DatePickerDialog(context, dateSetListener, dd, mm, yy)
}
catch (e: Exception)
{
e.printStackTrace()
}
}
datepicker!!.show()
}
private fun showDatePicker(context: Context)
{
val cal = Calendar.getInstance()
val dateSetListener =
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
cal.set(Calendar.YEAR, year)
cal.set(Calendar.MONTH, monthOfYear)
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth)
val myFormat = "yyyy-MM-dd" // mention the format you need
val sdf = SimpleDateFormat(myFormat, Locale.US)
dueDate.visibility = View.VISIBLE
dueDate.text = sdf.format(cal.time)
}
var datepicker: DatePickerDialog? = null
if (dueDate.text.isNotBlank())
{
try
{
val date: String = dueDate.text.toString()
val datearr = date.split("-").toTypedArray()
val dateint = datearr[0].toInt()
val monthint = datearr[1].toInt()
val yearint = datearr[2].toInt()
datepicker = DatePickerDialog(
context,
dateSetListener,
yearint,
monthint - 1,
dateint
)
}
catch (e: java.lang.Exception)
{
e.printStackTrace()
}
}
else
{
try
{
val calendar = Calendar.getInstance()
val yy = calendar[Calendar.YEAR]
val mm = calendar[Calendar.MONTH]
val dd = calendar[Calendar.DAY_OF_MONTH]
datepicker = DatePickerDialog(context, dateSetListener, yy, mm, dd)
}
catch (e: java.lang.Exception)
{
e.printStackTrace()
}
}
datepicker!!.show()
}
override fun getChildrenCount(listPosition: Int): Int
{
ChildCount = expandableListDetail[expandableListTitle[listPosition]]?.size.toString()
Log.e("TAG",ChildCount)
return expandableListDetail[expandableListTitle[listPosition]]?.size!!
}
override fun getGroup(listPosition: Int): Any
{
return expandableListTitle[listPosition]
}
override fun getGroupCount(): Int
{
return expandableListTitle.size
}
override fun getGroupId(listPosition: Int): Long
{
return listPosition.toLong()
}
@SuppressLint("InflateParams")
override fun getGroupView(listPosition: Int, isExpanded: Boolean, convertView: View?, parent: ViewGroup?): View
{
var convertView: View? = convertView
val listTitle = getGroup(listPosition) as String
if (convertView == null)
{
val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
convertView = layoutInflater.inflate(R.layout.list_group, null)
}
val listTitleTextView = convertView?.findViewById(R.id.listTitle) as TextView
val listCount = convertView.findViewById(R.id.listCount) as TextView
val arrowicon = convertView.findViewById(R.id.arrowicon) as ImageView
listTitleTextView.setTypeface(null, Typeface.BOLD)
listTitleTextView.text = listTitle
listCount.text = "($ChildCount)"
if (getChildrenCount(listPosition) === 0)
{
arrowicon.visibility = View.INVISIBLE
}
else
{
arrowicon.visibility = View.VISIBLE
arrowicon.setImageResource(if (isExpanded) R.drawable.ic_arrow_up else R.drawable.ic_arrow_down)
}
return convertView
}
override fun hasStableIds(): Boolean
{
return false
}
override fun isChildSelectable(listPosition: Int, expandedListPosition: Int): Boolean
{
return true
}
init
{
this.context = context
this.expandableListTitle = expandableListTitle
this.expandableListDetail = expandableListDetail
}
}
ACTIVITY: -
fun tasklistAPI(userId: String)
{
if (isOnline())
{
llNoInternet.gone()
llLoading.visible()
apiService.todotasklist(userId).enqueue(object :
Callback<ToDoListResponse>
{
override fun onFailure(call: Call<ToDoListResponse>, t: Throwable)
{
llLoading.gone()
}
override fun onResponse(call: Call<ToDoListResponse>, response: Response<ToDoListResponse>)
{
if (response.isSuccessful)
{
if (response.body()!!.success == 1)
{
try
{
llLoading.gone()
expandableListDetail = HashMap()
val todaytask = response.body()!!.todays_task_list
expandableListTitle = ArrayList()
todaystitle = ArrayList()
todayslist = ArrayList()
Log.e("<>list", todaystitle.toString())
for (i in todaytask.indices)
{
todaystitle.add(todaytask[i])
}
val tommrowtask = response.body()!!.tomorows_task_list
val tommorowtitle: MutableList<ToDoListResponse.TodaysTask> = ArrayList()
for (i in tommrowtask.indices)
{
tommorowtitle.add(tommrowtask[i])
}
val upcomingtask = response.body()!!.upcomming_task_list
val upcomingtitle: MutableList<ToDoListResponse.TodaysTask> = ArrayList()
for (i in upcomingtask.indices)
{
upcomingtitle.add(upcomingtask[i])
}
expandableListTitle.add("Today's Task")
expandableListTitle.add("Tommorow's Task")
expandableListTitle.add("Upcoming Task")
expandableListDetail.put(expandableListTitle[0], todaystitle)
expandableListDetail.put(expandableListTitle[1], tommrowtask)
expandableListDetail.put(expandableListTitle[2], upcomingtask)
Log.e("task", expandableListTitle.get(0) + " = " + expandableListDetail.put(expandableListTitle.get(0), todaystitle))
Log.e("task", expandableListTitle.get(1) + " = " + expandableListDetail.put(expandableListTitle.get(1), tommrowtask))
Log.e("task", expandableListTitle.get(2) + " = " + expandableListDetail.put(expandableListTitle.get(2), upcomingtask))
expandableListAdapter = CustomExpandableListAdapter(activity, expandableListTitle, expandableListDetail)
expandableListView!!.setAdapter(expandableListAdapter)
}
catch (e: Exception)
{
e.printStackTrace()
}
}
}
else
{
llLoading.gone()
}
}
})
}
else
{
llNoInternet.visible()
}
}
Here is the code that show that how can i add add data into hashmap and the expandable list view. as u see there is an hashmap for expandable list view and and in the adaoter i put the title from api respose but the header for listview parent is static and the data in the child re dynamic so you can see the diffrance
You've added a lot of code but I think this is the only one which is important for your question :-
expandableListTitle.add("Today's Task")
expandableListTitle.add("Tommorow's Task")
expandableListTitle.add("Upcoming Task")
expandableListDetail.put(expandableListTitle[0], todaystitle)
expandableListDetail.put(expandableListTitle[1], tommrowtask)
expandableListDetail.put(expandableListTitle[2], upcomingtask)
Log.e("task", expandableListTitle.get(0) + " = " + expandableListDetail.put(expandableListTitle.get(0), todaystitle))
Log.e("task", expandableListTitle.get(1) + " = " + expandableListDetail.put(expandableListTitle.get(1), tommrowtask))
Log.e("task", expandableListTitle.get(2) + " = " + expandableListDetail.put(expandableListTitle.get(2), upcomingtask))
expandableListAdapter = CustomExpandableListAdapter(activity, expandableListTitle, expandableListDetail)
expandableListView!!.setAdapter(expandableListAdapter)
So As much as I have understood from the image you have added in the link what you need is you need to show the number of elements present in the child in your header right.
What you can do is simply add the total number of elements present in your list like this :-
expandableListTitle.add("Today's Task (${todaystitle.count()})") //.count() gives the total number of elements present in list
It will add title as Today's Task (10)
\\ here 10 would be the number of elements present in your list
. Now you can simply format in any way you want