I'm new to android development. I'm developing an app which needs vertical RecyclerView inside another vertical RecyclerView . I created it but the problem is that I want to group the inner RecyclerView elements according to the outer RecyclerView elements.
I have attached the code for reference!
private fun ResponsibilityExpListFun() {
CommonFunctions.hideSoftKeyboard(this#DailyTasksPage)
builder = AlertDialog.Builder(this#DailyTasksPage)
inflater = layoutInflater
dialogView = inflater!!.inflate(R.layout.expandable_list_dialog, null)
dialog = builder!!.create()
expandableListView = dialogView!!.findViewById(R.id.expandablelistview) as ExpandableListView
dialog!!.setView(dialogView)
expandableListView?.setAdapter(TaskResponsibiltyExpandableAdapter(this, expandableListView!!, header, body))
dialog!!.show()
dialog!!.setCancelable(true)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_daily_tasks)
setSupportActionBar(daily_task_toolbar)
daily_task_toolbar.navigationIcon = resources.getDrawable(R.drawable.back_icon)
daily_task_toolbar.setNavigationOnClickListener { finish() }
/* daily_Task_Refresh.setOnRefreshListener {
try {
onStart()
} catch (e: Exception) {
e.printStackTrace()
}
}*/
daily_Task_Refresh.isEnabled = false
val sharedPreferences = getSharedPreferences("App_Details", Context.MODE_PRIVATE)
strMobileIdentifier = sharedPreferences.getString("IMEI_NUMBER", null)
strTokenSecret = sharedPreferences.getString("TOKEN_SECRET", null)
var linearLayoutManager = LinearLayoutManager(this)
Daily_Tasks_recyclerview?.layoutManager = linearLayoutManager
ahowalltaskadapter = AllTaskAdapter(slotIDarrayList)
Daily_Tasks_recyclerview.adapter = ahowalltaskadapter
cayyoverslotadapter = CarryOverSlotAdapter(previousSlotarrayList)
//ahowalltaskadapter = ahowalltaskadapter(slotIDarrayList)
/* preplan_Image_Toggle.setOnClickListener {
preplan_Image_ToggleUp.visibility = View.VISIBLE
preplan_Image_Toggle.visibility = View.GONE
PrePlanTaskRecyclerView.visibility = View.VISIBLE
}
preplan_Image_ToggleUp.setOnClickListener {
preplan_Image_Toggle.visibility = View.VISIBLE
preplan_Image_ToggleUp.visibility = View.GONE
PrePlanTaskRecyclerView.visibility = View.GONE
}*/
fab_btn_DailyTask.setOnClickListener { it ->
builder = AlertDialog.Builder(this)
inflater = layoutInflater
dialogView = inflater!!.inflate(R.layout.edit_curremt_slot, null)
dialog = builder!!.create()
layout = dialogView!!.findViewById(R.id.edit_current_slot_cardview) as CardView
taskName = dialogView!!.findViewById(R.id.edit_content) as TextInputEditText
taskResp = dialogView!!.findViewById(R.id.edit_resp_content) as TextView
taskPackage = dialogView!!.findViewById(R.id.edit_prod_content) as TextView
taskPriority = dialogView!!.findViewById(R.id.edit_priority_content) as TextView
SaveBtn = dialogView!!.findViewById(R.id.SaveEditSlot) as Button
CancelBtn = dialogView!!.findViewById(R.id.cancelEditSlot) as Button
layout!!.setOnClickListener {
CommonFunctions.hideSoftKeyboard(activity = this#DailyTasksPage)
}
CancelBtn!!.setOnClickListener {
dialog!!.dismiss()
}
// expandableListView = dialogView!!.findViewById(R.id.expandablelistview) as ExpandableListView
dialog!!.show()
taskResp!!.setOnClickListener {
count = 1
ResponsibilityExpListFun()
}
taskPackage!!.setOnClickListener {
count = 2
PackageExpListFun()
}
taskPriority!!.setOnClickListener {
PriorityFun()
}
SaveBtn!!.setOnClickListener {
strTaskName = taskName!!.text.toString()
if (strTaskName.isNullOrEmpty()) {
Snackbar.make(dialogView!!, "Task Name field is empty", Snackbar.LENGTH_LONG).show()
return#setOnClickListener
}
if (taskResp!!.text.isNullOrEmpty()) {
Snackbar.make(dialogView!!, "Task Responsibility field is empty", Snackbar.LENGTH_LONG).show()
return#setOnClickListener
}
if (taskPriority!!.text.isNullOrEmpty()) {
Snackbar.make(dialogView!!, "Task Priority field is empty", Snackbar.LENGTH_LONG).show()
return#setOnClickListener
}
AddTaskFunction()
dialog!!.dismiss()
}
// expandableListView?.setAdapter(TaskResponsibiltyExpandableAdapter(this, expandableListView!!, header, body))
dialog!!.setView(dialogView)
dialog!!.show()
// dialog!!.setCancelable(false)
}
}
inner class AllTaskAdapter(val alltaskList: ArrayList<SlotIDClass>) : RecyclerView.Adapter<AllTaskAdapter.ViewHolderAdapter>() {
var slotName: String? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AllTaskAdapter.ViewHolderAdapter {
val View = LayoutInflater.from(parent.context).inflate(R.layout.previous_slot_format, parent, false)
val sharedPreferences = View.context.getSharedPreferences("App_Details", Context.MODE_PRIVATE)
slotName = sharedPreferences.getString("SlotName", null)
return ViewHolderAdapter(View)
}
override fun getItemCount(): Int {
return alltaskList.size
}
override fun onBindViewHolder(holder: AllTaskAdapter.ViewHolderAdapter, position: Int) {
val layoutManager = CustomLinearLayoutManager(holder.itemView.context)
taskinnerAdapter = RunningTaskAdapter(currTaskarrayList)
holder.DailyTasks_Recyclerview!!.setLayoutManager(layoutManager)
holder.DailyTasks_Recyclerview!!.addItemDecoration(DividerItemDecoration(holder.DailyTasks_Recyclerview!!.context, DividerItemDecoration.VERTICAL))
holder.DailyTasks_Recyclerview!!.adapter = taskinnerAdapter
println("Running tASK aDaPtEr------------------------------" + ahowalltaskadapter.toString())
holder.SlotName!!.text = alltaskList.get(position).SlotName
if (holder.SlotName!!.text.equals(slotName)) {
holder.title_prev_slot!!.setBackgroundColor(holder.itemView.resources.getColor(R.color.dark_orange))
holder.strShowime!!.visibility = View.VISIBLE
var SlotTime = (ToMilliseconds!! - CurrentMilliseconds!!).toLong()
object : CountDownTimer(SlotTime.toLong(), 1000) {
override fun onTick(millisUntilFinished: Long) {
strShowime = String.format(Locale.getDefault(), "Time Remaining %02d hour %02d min %02d sec",
TimeUnit.MILLISECONDS.toHours(millisUntilFinished),
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60)
holder.strShowime!!.setText(strShowime)
}
override fun onFinish() {
onStart()
GetCurrentSlot()
}
}.start()
Toast.makeText(holder.itemView.context.applicationContext, strShowime, Toast.LENGTH_LONG).show()
}
}
inner class ViewHolderAdapter(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
override fun onClick(v: View?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
var DailyTasks_Recyclerview: RecyclerView? = null
var SlotName: TextView? = null
var title_prev_slot: RelativeLayout? = null
var strShowime: TextView? = null
init {
this.DailyTasks_Recyclerview = view.findViewById(R.id.Daily_Tasks_recyclerview) as RecyclerView
this.SlotName = view.findViewById(R.id.prev_SlotName) as TextView
this.title_prev_slot = view.findViewById(R.id.title_prev_slot) as RelativeLayout
this.strShowime = view.findViewById(R.id.strShowime) as TextView
}
}
}
inner class RunningTaskAdapter(val runningtaskList: ArrayList<TaskDetailsDataClass>) : RecyclerView.Adapter<RunningTaskAdapter.RunningTaskViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RunningTaskAdapter.RunningTaskViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.runningtasks_format, parent, false)
return RunningTaskViewHolder(view)
}
override fun getItemCount(): Int {
return runningtaskList.size
}
override fun onBindViewHolder(holder: RunningTaskAdapter.RunningTaskViewHolder, position: Int) {
holder.tasknameText?.text = runningtaskList.get(position).strTaskName
holder.respnameText?.text = runningtaskList.get(position).strRespName
holder.priorityIDText?.text = runningtaskList.get(position).intPriorityID.toString()
holder.TaskStatusText?.text = runningtaskList.get(position).intTaskStatusID.toString()
holder.PackageText?.text = runningtaskList.get(position).PackageName
holder.intTaskID?.text = runningtaskList.get(position).intTaskID.toString()
holder.intTimeElapsed?.text = runningtaskList.get(position).intTimeElapsed.toString()
holder.intinitial_time_elapsed?.text = runningtaskList.get(position).intinitial_time_elapsed.toString()
holder.strRemarks?.text = runningtaskList.get(position).strRemarks
// holder.ResumeTime?.text = runningtaskList.get(position).ResumeTime
if (holder.TaskStatusText!!.text.equals("1")) {
holder.running_task_Image!!.visibility = View.VISIBLE
} else {
holder.running_task_Image!!.visibility = View.INVISIBLE
}
holder.RunningTaskCardView!!.setOnClickListener {
holder.itemView.context.startActivity(Intent(holder.itemView.context, CurrentTaskDetails::class.java)
.putExtra("Task_Name", holder.tasknameText?.text.toString())
.putExtra("Responsibility_Name", holder.respnameText?.text.toString())
.putExtra("Package_Name", holder.PackageText?.text.toString())
.putExtra("TaskStatusID", holder.TaskStatusText?.text.toString())
.putExtra("Task_ID", holder.intTaskID?.text.toString())
.putExtra("Time_Elapsed", holder.intTimeElapsed?.text.toString())
.putExtra("Initial_Time_Elapsed", holder.intinitial_time_elapsed?.text.toString())
.putExtra("PriorityID", holder.priorityIDText?.text.toString())
.putExtra("Remarks", holder.strRemarks?.text.toString()))
// val activity = holder.itemView.getContext() as AppCompatActivity
// val fragment = CurrentTaskDetails()
// val arguments = Bundle()
// arguments.putString("Task_Name", holder.tasknameText?.text.toString())
// arguments.putString("Responsibility_Name", holder.respnameText?.text.toString())
// fragment.setArguments(arguments)
// activity.supportFragmentManager.beginTransaction().replace(R.id.daily_task_layout, fragment).addToBackStack(null).commit()
}
}
inner class RunningTaskViewHolder(v: View) : RecyclerView.ViewHolder(v), View.OnClickListener {
override fun onClick(v: View?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
var running_task_Image: ImageView? = null
var tasknameText: TextView? = null
var respnameText: TextView? = null
var priorityIDText: TextView? = null
var TaskStatusText: TextView? = null
var RunningTaskCardView: CardView? = null
var PackageText: TextView? = null
var intTaskID: TextView? = null
var intTimeElapsed: TextView? = null
var intinitial_time_elapsed: TextView? = null
var strRemarks: TextView? = null
init {
this.tasknameText = v.findViewById(R.id.task_name_rt_format) as TextView
this.respnameText = v.findViewById(R.id.task_responsibilty_rt_format) as TextView
this.running_task_Image = v.findViewById(R.id.running_task_Image) as ImageView
this.priorityIDText = v.findViewById(R.id.priority_id_rt_format) as TextView
this.TaskStatusText = v.findViewById(R.id.task_status_rt) as TextView
this.PackageText = v.findViewById(R.id.task_package_rt_format) as TextView
this.RunningTaskCardView = v.findViewById(R.id.running_task_cardview) as CardView
this.intTaskID = v.findViewById(R.id.intTaskID) as TextView
this.intTimeElapsed = v.findViewById(R.id.intTimeElapsed) as TextView
this.intinitial_time_elapsed = v.findViewById(R.id.intinitial_time_elapsed) as TextView
this.strRemarks = v.findViewById(R.id.strRemarks) as TextView
}
}
}
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
}
}
I have implemented a onClicklistener in my recycleview which works but the onLongClickListener is not responding? I have added the code in the Adapter, which is being called from a fragment. The onClickListener works well. Whn I click onLongClick -> it needs to display an AlertDialog, but in this case on running the app, there are no errors and no longclick too. This is in Kotlin, what am I doing wrong - any thoughts please?
class UserMsgAdapter(
mContext: Context,
userMsgList: List<MessageList>,
mUsers: List<Users>,
isChatCheck: Boolean
): RecyclerView.Adapter<UserMsgAdapter.ViewHolder?>()
{
private val mContext: Context
private val userMsgList: List<MessageList>
private val mUsers:List<Users>
private var isChatCheck: Boolean
init{
this.mUsers = mUsers
this.userMsgList = userMsgList
this.mContext = mContext
this.isChatCheck = isChatCheck
}
var lastMsg: String = ""
var timeMsg: Long = 0
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
val view: View = LayoutInflater.from(mContext).inflate(
R.layout.user_search_item_layout,
viewGroup,
false
)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val message: MessageList? = userMsgList[position]
//Accessing the receiverId from the ChatList
val receiverId = message!!.getId()
val ref = FirebaseDatabase.getInstance().reference.child("Users").child(receiverId!!)
ref.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(p0: DataSnapshot) {
val user = p0.getValue(Users::class.java)
holder.userNameText.text = user!!.getUserName()
Picasso.get().load(user.getProfile())
.placeholder(R.drawable.ic_baseline_whatshot_24).fit().centerCrop().into(
holder.profileImageView
)
//Showcasing Last Message
if (isChatCheck) {
retrieveLastMessage(
user.getUID(),
holder.lastMessagetxt,
holder.timestamptxt,
holder.new_message_count
)
} else {
holder.lastMessagetxt.visibility = View.GONE
}
//Calling the Message Activity
holder.itemView.setOnClickListener {
val intent = Intent(mContext, MessageActivity::class.java)
intent.putExtra("visit_id", user.getUID())
mContext.startActivity(intent)
}
//Menu on Search Fragment
holder.itemView.setOnLongClickListener {
val options = arrayOf<CharSequence>(
"Delete Chat",
"Visit Profile"
)
val builder: AlertDialog.Builder = AlertDialog.Builder(mContext)
builder.setTitle("What would you like to do?")
builder.setItems(options, DialogInterface.OnClickListener { _, which ->
if (which == 0) {
val intent = Intent(mContext, MessageActivity::class.java)
intent.putExtra("visit_id", user.getUID())
mContext.startActivity(intent)
}
if (which == 1) {
val intent = Intent(mContext, VisitUserProfile::class.java)
intent.putExtra("visit_id", user.getUID())
mContext.startActivity(intent)
}
})
builder.show()
true
}
}
override fun onCancelled(error: DatabaseError) {
}
})
}
override fun getItemCount(): Int {
return userMsgList.size
}
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)
{
var userNameText: TextView = itemView.findViewById(R.id.username)
var profileImageView: ShapeableImageView = itemView.findViewById(R.id.profile_image)
var lastMessagetxt: TextView = itemView.findViewById(R.id.last_message)
var timestamptxt: TextView = itemView.findViewById(R.id.time_stamp)
var new_message_count: TextView = itemView.findViewById(R.id.new_message_count)
}
//print last message and timestamp
private fun retrieveLastMessage(
messageUserId: String?, lastMessagetxt: TextView,
timestamptxt: TextView, new_message_count: TextView,
)
{
lastMsg = "defaultMsg"
timeMsg = 0
var countUnreadMessages = 0
val firebaseUser = FirebaseAuth.getInstance().currentUser
val reference = FirebaseDatabase.getInstance().reference.child("Chats")
reference.addValueEventListener(object : ValueEventListener {
override fun onDataChange(p0: DataSnapshot) {
for (dataSnapshot in p0.children) {
val message: Message? = dataSnapshot.getValue(Message::class.java)
if (firebaseUser != null && message != null) {
if (message.getReceiver() == firebaseUser.uid && message.getSender() == messageUserId ||
message.getReceiver() == messageUserId && message.getSender() == firebaseUser.uid
) {
lastMsg = message.getMessage()!!
timeMsg = message.getTimestamp()!!
}
if (message.getReceiver() == firebaseUser.uid && message.getSender() == messageUserId && !message.isIsSeen()) {
countUnreadMessages += 1
}
}
}
when (lastMsg) {
"defaultMsg" -> lastMessagetxt.text = ""
"Shared an image with you." -> lastMessagetxt.text = "Shared an image"
else -> lastMessagetxt.text = lastMsg
}
//Display count of unread messages
if (countUnreadMessages != 0) {
new_message_count.text = countUnreadMessages.toString()
new_message_count.setBackgroundResource(R.drawable.new_chat_bg)
} else {
new_message_count.setBackgroundResource(0)
new_message_count.text = ""
}
countUnreadMessages = 0
//Display formatted date and time
val time = dateFormatter(timeMsg)
when (time) {
"01-01-1970" -> timestamptxt.text = ""
else -> timestamptxt.text = time
}
}
override fun onCancelled(error: DatabaseError) {
}
})
}
}
I am am trying to put filter in expandable recylerview but not able to achieve:
Please find the code below:
class adapter1(internal var context: Context, internal var mData: MutableList<faqBody?>,val
fragmentInterface: FragmentInterface) : RecyclerView.Adapter<adapter1.myViewHolder>()
,Filterable {
internal var mfilter: NewFilter
var orginallist: MutableList<faqBody?> = ArrayList()
override fun getFilter(): Filter {
return mfilter
}
init {
mfilter = NewFilter(this#adapter1)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): adapter1.myViewHolder {
val view =
LayoutInflater.from(context).inflate(R.layout.recyclerview_adapter12, parent, false)
return myViewHolder(view)
}
override fun onBindViewHolder(holder: adapter1.myViewHolder, position: Int) {
val countryDataItem = mData[position]
val intMaxNoOfChild = 0
holder.country.text = countryDataItem!!.menuText
val noOfChildTextViews = holder.linearLayout_childItems.childCount
val noOfChild = countryDataItem.childItem.size
for (index in 0 until noOfChildTextViews) {
val currentTextView =
holder.linearLayout_childItems.getChildAt(index) as TextView
currentTextView.visibility = View.VISIBLE
}
if (noOfChild < noOfChildTextViews) {
for (index in noOfChild until noOfChildTextViews) {
val currentTextView =
holder.linearLayout_childItems.getChildAt(index) as TextView
currentTextView.visibility = View.GONE
}
}
for (textViewIndex in 0 until noOfChild) {
val currentTextView =
holder.linearLayout_childItems.getChildAt(textViewIndex) as TextView
currentTextView.setText(countryDataItem.childItem[textViewIndex].menuText)
}
}
override fun getItemCount(): Int {
return mData.size
}
inner class myViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
View.OnClickListener {
internal var country: TextView
val linearLayout_childItems: LinearLayout
init {
country = itemView.findViewById(R.id.country)
linearLayout_childItems = itemView.findViewById(R.id.ll_child_items)
linearLayout_childItems.visibility = View.GONE
var intMaxNoOfChild = 0
for (index in mData.indices) {
val intMaxSizeTemp = mData[index]!!.childItem.size
if (intMaxSizeTemp > intMaxNoOfChild) intMaxNoOfChild = intMaxSizeTemp
}
for (indexView in 0 until intMaxNoOfChild) {
val textView = TextView(context)
textView.id = indexView
textView.setPadding(5, 20, 0, 20)
// textView.background = ContextCompat.getDrawable(context, R.drawable.background_sub_module_text)
val layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
textView.setOnClickListener(this)
linearLayout_childItems.addView(textView, layoutParams)
}
country.setOnClickListener(this)
}
override fun onClick(view: View) {
if (view.getId() == R.id.country) {
if (linearLayout_childItems.visibility == View.VISIBLE) {
linearLayout_childItems.visibility = View.GONE
} else {
linearLayout_childItems.visibility = View.VISIBLE
}
} else {
val textViewClicked = view as TextView
Toast.makeText(
context, "" + textViewClicked.text.toString(), Toast.LENGTH_SHORT
).show()
fragmentInterface.onClick(textViewClicked.text.toString())
}
}
}
inner class NewFilter(var mAdapter: adapter1) : Filter() {
override fun performFiltering(charSequence: CharSequence): FilterResults {
orginallist.clear()
orginallist.addAll(mData)
val results = FilterResults()
if (charSequence.length == 0) {
mData.addAll(orginallist)
} else {
val filterPattern = charSequence.toString().toLowerCase().trim { it <= ' ' }
for (i in 0..orginallist.size) {
val newList: ArrayList<childItem> = ArrayList<childItem>()
for (childmenu in orginallist[i]!!.childItem) {
if (childmenu.menuText.toLowerCase().contains(filterPattern)) {
newList.add(childmenu)
}
}
val faqBody = faqBody(menuText = orginallist[i]!!.menuText, childItem = newList)
mData.add(faqBody)
}
}
results.values = mData
results.count = mData.size
return results
}
override fun publishResults(charSequence: CharSequence, filterResults: FilterResults) {
mAdapter.notifyDataSetChanged()
}
}
}
Can anyone help on the above.
mData is the list of faqBody that contains chilitems of the same.
faqbody (
menutext: String
childItem : List<childItem>
)
chilitem(
menutext: String
)
I have backend firebase which i am using to populate the listview , i was implementing the search functionality suddenly i found a weird behavior in listview ,it is creating duplicates in numbers like 30-40 and above.
Please help me i was batteling for it from 3 days. i am very new to development so any suggestions to code optimizing will also be taken as help!
class Menu : AppCompatActivity(){
private var prevKey : String? = null
var listAdapter : CustomAdapter ? = null
private val listItemArrayList = ArrayList<ListItem>()
var rootRef : FirebaseDatabase? = null
var adminRef : DatabaseReference? = null
var mAuth : FirebaseAuth? = null
var helper : CustomAdapter?=null
private var user : String?=null
var mAuthListener: FirebaseAuth.AuthStateListener? = null
var Items = ArrayList<String>()
var isSectionBoolean = ArrayList<Boolean>()
var ItemCategory= ArrayList<String>()
var ItemCost = ArrayList<Int>()
var listView : ListView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_menu)
mAuth = FirebaseAuth.getInstance()
mAuthListener = FirebaseAuth.AuthStateListener { }
rootRef = FirebaseDatabase.getInstance()
user =mAuth!!.currentUser!!.phoneNumber as String
adminRef = rootRef!!.getReference("AdminCafe").child(user!!)
listView = findViewById(R.id.admindynamiclist)
listAdapter = CustomAdapter(listItemArrayList,this)
listView!!.adapter = listAdapter
listView!!.isTextFilterEnabled = true
SearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
listAdapter!!.filter(newText.toString())
return false
}
})
getData()
}
fun addAct(v:View)
{
val intent = Intent(applicationContext,AddActivity::class.java)
startActivity(intent)
}
private fun getData() {
println("getData")
var menucatRef = adminRef!!.child("MenuItem")
menucatRef.addValueEventListener(object : ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
for(Snap in p0.children)
{
println("wtfff")
println("Child"+Snap.childrenCount)
getDataFromKey(Snap.key.toString(),Snap.childrenCount.toInt())
}
}
})
}
private fun getDataFromKey(key: String, child :Int) {
listItemArrayList.clear()
println("called")
var count = 0
var counter = 0
var Category = CategoryHeader()
var menuRef = adminRef!!.child("MenuItem").child(key)
menuRef.addListenerForSingleValueEvent(object : ValueEventListener{
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
var catKey = p0.key.toString()
for(snap in p0!!.children)
{
if(count == 0)
{
Category!!.setheader(catKey)
listItemArrayList!!.add(Category)
println("Seperator will be added")
}
else
{
var hashMap = snap.value as HashMap<String,String>
var itemName = snap.key
var isVeg = hashMap["isVeg"]
var itemCost = hashMap["itemCost"]!!.toInt()
var isSig = hashMap["isSig"]
var ItemHelper = Item()
if(itemName!=null)
{
ItemHelper.setItemName(itemName)
}
if(itemCost!=null)
{
ItemHelper.setItemCost(itemCost)
}
listItemArrayList!!.add(ItemHelper)
}
count++
}
listAdapter!!.notifyDataSetChanged()
}
})
}
interface ListItem {
fun isHeader(): Boolean
fun getName(): String
fun getItemCost() : Int
}
fun editAct(v:View)
{
println("Inside edit")
}
}
And Adapter class
class CustomAdapter(private var listItem : ArrayList<Menu.ListItem>, private val context: Activity) : BaseAdapter() {
var orig = ArrayList<Menu.ListItem> ()
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
orig.addAll(listItem)
println("List Item is"+listItem)
println("List Item is"+orig)
var holder = ViewHolder()
var customView = convertView
var flag = true
if (convertView == null) {
val layoutInflater = context.layoutInflater
if(listItem.get(position).isHeader()) {
println("position"+position)
customView = layoutInflater.inflate(R.layout.seperator, null)
holder.tvLabel = customView.categoryText
} else {
println("position"+position)
customView = layoutInflater.inflate(R.layout.list_item, null)
holder.tvLabel = customView.itemad
holder.itemCost = customView.cost
flag = false
}
customView.setTag(holder)
}
else
{
customView = convertView
holder = convertView!!.tag as ViewHolder
}
if(flag) {
println("Custoom Flag is"+flag)
holder!!.tvLabel!!.text = listItem.get(position).getName()
}
else {
println("Custoom Flag is"+flag)
holder!!.tvLabel!!.text = listItem.get(position).getName()
holder.itemCost!!.text = listItem.get(position).getItemCost().toString()
}
return customView!!
}
override fun getItem(position: Int): Any {
return listItem.get(position)
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getCount(): Int {
return listItem.size
}
private inner class ViewHolder {
var tvLabel: TextView? = null
var itemCost: TextView? = null
}
fun filter(query : String)
{
println("called")
listItem.clear()
var search = query
search = search.toLowerCase(Locale.getDefault())
if(search.isEmpty())
{
listItem.addAll(orig!!)
println("Inside size 0")
}
else
{
var counter = 0
for(result in orig!! )
{
if(result.getName().toLowerCase().contains(search))
{
println("Result is "+result.getName())
println("listItem"+listItem)
}
}
}
}
}
I have two recyclerViews, which represent my grocery list.
When I click on an item it gets "transferred" to the other list.
The problem is that the images are loaded with Glide and Firebase Storage and they don't show the correct images even if the listitem does not have a path.
I have tried every notifyDataSetChanged(), recyclerView.notifyItemChanged() and recyclerView.invalidate() and others. Maybe you could help me.
This is my Adapter:
class RecyclerViewAdapterEinkaufslisteDetail(
val context: Context,
val lebensmittelList: ArrayList<Inventarstueck>
) :
RecyclerView.Adapter<RecyclerViewAdapterEinkaufslisteDetail.ViewHolder>() {
override fun onBindViewHolder(holder: RecyclerViewAdapterEinkaufslisteDetail.ViewHolder, position: Int) {
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
//Es wird der Name, die Anzahl, die Einheit (gramm, kg, etc) das Bild und ein Warnzeichen angezeigt, falls ein Produkt abläufty
holder.mName.text = lebensmittelList[position].name_de.toString()
val array = holder.itemView.getContext().getResources().getStringArray(R.array.einheit_kurz)
val placeholder =
lebensmittelList[position].restlichemenge.toString() + " " + array[lebensmittelList[position].einheit!!]
holder.mAnzahl.text = placeholder
// holder.txtTitle.text = userList[position]
holder.mZeichen.visibility = View.INVISIBLE
//KLEINEs Anzeigebild der Produkte runterladen
if (!(lebensmittelList[position].fotoURL.isNullOrEmpty() || lebensmittelList[position].fotoURL.isNullOrBlank())) {
//Überprüfen, ob im Feld die Endung gespeichert ist, wenn nicht, immer png!!
val url:String
if(lebensmittelList[position].fotoURL!!.endsWith(".png")){
url = lebensmittelList[position].fotoURL!!
}else{
url = lebensmittelList[position].fotoURL + ".png"
}
val storage = FirebaseStorage.getInstance()
val storageRef = storage.reference
// Points to "images"
val imagesRef = storageRef.child(Constants.FIREBASE_STORAGE_PRODUKTFOTO_KLEIN_PFAD)
val fotoRef = imagesRef.child(url)
GlideApp.with(this.context).load(fotoRef).into(holder.mProduktfoto)
}
}
override fun getItemCount(): Int {
return lebensmittelList.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewAdapterEinkaufslisteDetail.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_item_inventar, parent, false)
return ViewHolder(v)
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener, View.OnLongClickListener{
init {
itemView.setOnClickListener(this)
itemView.setOnLongClickListener(this)
}
override fun onClick(v: View) {
clickListener!!.onItemClick(adapterPosition, v);
}
override fun onLongClick(v: View): Boolean {
clickListener!!.onItemLongClick(adapterPosition, v)
return true
}
val mName = itemView.findViewById<TextView>(R.id.rvInventar_tv_Produktname)
val mAnzahl = itemView.findViewById<TextView>(R.id.rvInventar_tv_Anzahl)
val mProduktfoto = itemView.findViewById<ImageView>(R.id.rvInventarProduktFoto)
val mZeichen = itemView.findViewById<ImageView>(R.id.rvInventar_Icon)
// val txtTitle = itemView.findViewById<TextView>(R.id.txtTitle)
val mCard = itemView.findViewById<MaterialCardView>(R.id.rvCardInventar)
}
fun setOnItemClickListener(clickListener: ClickListener) {
RecyclerViewAdapterEinkaufslisteDetail.clickListener = clickListener
}
interface ClickListener {
fun onItemClick(position: Int, v: View)
fun onItemLongClick(position: Int, v: View)
}
companion object {
private var clickListener: RecyclerViewAdapterEinkaufslisteDetail.ClickListener? = null
}
}
This is where I change the data:
rvKaufen = findViewById(R.id.rvEinkaufslisteDetailKaufen)
val layoutmanager = GridLayoutManager(this, 3)
rvKaufen.layoutManager = layoutmanager
rvGekauft = findViewById(R.id.rvEinkaufslisteDetailGekauft)
val layoutmanager2 = GridLayoutManager(this, 3)
rvGekauft.layoutManager = layoutmanager2
rvadapter = RecyclerViewAdapterEinkaufslisteDetail(this, itemsInEinkaufsliste)
// val rvadapter = RecyclerViewAdapterInventar(this.context!!, lebensmittelliste)
rvadapterGekauft = RecyclerViewAdapterEinkaufslisteDetail(this, itemsGekauft)
//nur einmal itemclicklistener zuweisen, sonst megafehler! intern abrufen aus welchem Recyclerview der Click gekommen ist
/**/ rvadapter.setOnItemClickListener(object : RecyclerViewAdapterEinkaufslisteDetail.ClickListener {
override fun onItemClick(position: Int, v: View) {
Log.d("Click", "onItemClick position: $position")
val parentId = (v.parent as View).id
if (parentId == rvKaufen.id) {
Toast.makeText(this#EinkaufslisteDetail, "GeKAUFt", Toast.LENGTH_SHORT).show()
/* val inventarstueck = rvadapter.lebensmittelList[position].copy()
//Hier auch aus den Listen löschen??
//TODO
rvadapterGekauft.lebensmittelList.add(inventarstueck)
rvadapterGekauft.notifyDataSetChanged()
rvadapter.lebensmittelList.removeAt(position)
// itemsInEinkaufsliste.removeAt(position)
rvadapter.notifyItemRemoved(position)
// rvadapter.lebensmittelList.removeAt(position)
*/
//rvadapter.notifyDataSetChanged()
val inventarstueck = itemsInEinkaufsliste[position].copy()
//itemsGekauft.add(inventarstueck)
itemsGekauft.add(inventarstueck)
rvadapterGekauft.notifyItemInserted(itemsGekauft.size-1)
// rvadapterGekauft.notifyItemRangeChanged(0,itemsGekauft.size)
itemsInEinkaufsliste.removeAt(position)
rvadapter.notifyItemRemoved(position)
rvadapter.notifyItemRangeChanged(position,itemsInEinkaufsliste.size)
/* rvKaufen.adapter = null
rvKaufen.layoutManager = null
rvKaufen.adapter = rvadapter
val layoutmanager3 = GridLayoutManager(this#EinkaufslisteDetail, 3)
rvKaufen.layoutManager = layoutmanager3
rvadapter.notifyDataSetChanged()
//rvKaufen.removeViewAt(position)
// rvGekauft.add
rvGekauft.adapter = null
rvGekauft.layoutManager = null
rvGekauft.adapter = rvadapterGekauft
val layoutmanager4 = GridLayoutManager(this#EinkaufslisteDetail, 3)
rvKaufen.layoutManager = layoutmanager4
rvadapterGekauft.notifyDataSetChanged()*/
} else if (parentId == rvGekauft.id) {
Toast.makeText(this#EinkaufslisteDetail, "Zurück geschoben", Toast.LENGTH_SHORT).show()
/* val inventarstueck = rvadapterGekauft.lebensmittelList[position].copy()
rvadapter.lebensmittelList.add(inventarstueck)
rvadapter.notifyDataSetChanged()
rvadapterGekauft.lebensmittelList.removeAt(position)
rvadapterGekauft.notifyItemRemoved(position)*/
val inventarstueck = itemsGekauft[position].copy()
//itemsGekauft.add(inventarstueck)
itemsInEinkaufsliste.add(inventarstueck)
rvadapter.notifyItemInserted(itemsInEinkaufsliste.size-1)
// rvadapter.notifyItemRangeChanged(0,itemsInEinkaufsliste.size)
itemsGekauft.removeAt(position)
rvadapterGekauft.notifyItemRemoved(position)
rvadapterGekauft.notifyItemRangeChanged(position,itemsGekauft.size)
/* rvKaufen.adapter = null
rvKaufen.layoutManager = null
rvKaufen.adapter = rvadapter
val layoutmanager3 = GridLayoutManager(this#EinkaufslisteDetail, 3)
rvKaufen.layoutManager = layoutmanager3
rvadapter.notifyDataSetChanged()
rvGekauft.adapter = null
rvGekauft.layoutManager = null
rvGekauft.adapter = rvadapterGekauft
val layoutmanager4 = GridLayoutManager(this#EinkaufslisteDetail, 3)
rvKaufen.layoutManager = layoutmanager4
rvadapterGekauft.notifyDataSetChanged()*/
}
}
override fun onItemLongClick(position: Int, v: View) {
Log.d("Click", "onItemLongClick pos = $position")
Log.d("Click", "onItemClick position: $position")
val parentId = (v.parent as View).id
if (parentId == rvKaufen.id) {
Toast.makeText(this#EinkaufslisteDetail, "Verändern", Toast.LENGTH_SHORT).show()
val inventarstueck = rvadapter.lebensmittelList[position].copy()
val intent = Intent(this#EinkaufslisteDetail, EinkaufslisteProduktBearbeiten::class.java)
intent.putExtra("swissID",inventarstueck.swiss_id)
intent.putExtra("scandatum",inventarstueck.scandatum)
intent.putExtra("einkaufslistenID",einkaufslistenID)
startActivityForResult(intent,_resultCODE)
}else if (parentId == rvGekauft.id) {
Toast.makeText(this#EinkaufslisteDetail, "Keine Aktion möglich", Toast.LENGTH_SHORT).show()
}
}
})
When I call the SetItemClickListener on the second recyclerView as well, then the whole process doesn't work.
It is very rare that there are two recyclerViews used so I haven't found anything either.
EDIT
I found the solution for my Problem:
I set the ImageView to a default picture, in case there is no URL.,
if (!(lebensmittelList[position].fotoURL.isNullOrEmpty() || lebensmittelList[position].fotoURL.isNullOrBlank())) {
.
.
. GlideApp.with(this.context).load(fotoRef).into(holder.mProduktfoto)
}else{
holder.mProduktfoto.setImageResource(R.drawable.logo_384_384)
}