I'm trying to set the dynamic height for my recycler view, because I have the Add button below it, that adds a new item to the list.
I'm using Constraint Layout in my parent fragment. I followed this advice, and when I add first item, it shows up and the ADD button slides down as expected, but the problem is that when I add the second one it just doesn't appear.
Here is the layout of my parent fragment:
<?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:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".SecondFragment">
<Button
android:id="#+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="444dp"
android:text="#string/cancel"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/cancel_button2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/addItemActionButton" />
<Button
android:id="#+id/cancel_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="76dp"
android:text="#string/ok"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toRightOf="#id/cancel_button"
app:layout_constraintTop_toBottomOf="#+id/addItemActionButton"
app:layout_constraintVertical_bias="1.0" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="372dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="#id/addItemActionButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.41"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.065" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/addItemActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="492dp"
android:clickable="true"
android:src="#android:drawable/ic_input_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/recyclerView"
tools:ignore="SpeakableTextPresentCheck" />
</androidx.constraintlayout.widget.ConstraintLayout>
And here's the one for the recycler item layout:
<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:padding="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textInputLayout"
android:layout_width="288dp"
android:layout_height="51dp"
android:layout_marginBottom="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.495"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.024">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/item"
android:layout_width="300dp"
android:layout_height="71dp"
android:hint="#string/item" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Here's my fragment code:
package com.example.progresstracker
import android.os.Bundle
import android.util.Log
import android.util.Log.INFO
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.progresstracker.databinding.FragmentSecondBinding
/**
* A simple [Fragment] subclass as the second destination in the navigation.
*/
class SecondFragment : Fragment() {
private var layoutManager: RecyclerView.LayoutManager? = null
private var adapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>? = null
private var _binding: FragmentSecondBinding? = null
private var items: ArrayList<String> = ArrayList()
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentSecondBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.recyclerView.apply {
// set a LinearLayoutManager to handle Android
// RecyclerView behavior
layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
// set the custom adapter to the RecyclerView
adapter = RecyclerAdapter(items)
}
// linearLayoutManager = LinearLayoutManager(context)
// binding.recyclerView.layoutManager = linearLayoutManager
binding.cancelButton.setOnClickListener {
findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment)
}
binding.addItemActionButton.setOnClickListener {
items.add("Testing..")
adapter = RecyclerAdapter(items)
adapter?.notifyItemInserted(items.size - 1)
binding.recyclerView.adapter = adapter
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
And the adapter:
package com.example.progresstracker
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class RecyclerAdapter(private val items: ArrayList<String>) : RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var item: TextView
init {
item = itemView.findViewById(R.id.item)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_item_row, parent, false)
return ViewHolder(v)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.item.text = items[position]
}
override fun getItemCount(): Int {
return items.size
}
}
Related
I have faced the problem that my application will keep stopping when clicking search page fragments. I do not understand why this problem will happen? I directly used my other success code in another fragment but in this fragment suddenly appear this problem. Can somebody help me? Thank you for your help!!
My problem error :
java.lang.NullPointerException: Attempt to invoke virtual method
'void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)'
on a null object reference at com.example.assignment_mad.Search_Page_Fragment.onViewCreated(Search_Page_Fragment.kt:153)
My main frgment ( Search_Page_Fragment ) :
package com.example.assignment_mad
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.fragment_notification_.*
class Search_Page_Fragment : Fragment() {
private lateinit var newRecyclerView: RecyclerView
private lateinit var newArrayList: ArrayList<Company_Search>
private lateinit var tempArrayList: ArrayList<Company_Search>
lateinit var imageId:Array<Int>
lateinit var job_name:Array<String>
lateinit var saveicon:Array<Int>
lateinit var company_name:Array<String>
lateinit var place:Array<String>
lateinit var salary:Array<String>
lateinit var news:Array<String>
private var layoutManager: RecyclerView.LayoutManager? = null
private var adapter: RecyclerView.Adapter<Search_Page_Adapter.MyViewHolder>? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
var views =inflater.inflate(R.layout.fragment_search__page_, container, false)
newRecyclerView=views.findViewById(R.id.recyclerView_Search)
// Inflate the layout for this fragment
return views
}
override fun onViewCreated(itemView: View, savedInstanceState: Bundle?) {
imageId= arrayOf(
R.drawable.company_logo_1,
R.drawable.company_logo_2,
R.drawable.company_logo_3,
R.drawable.company_logo_4,
R.drawable.company_logo_5,
R.drawable.company_logo_6,
R.drawable.company_logo_7,
R.drawable.company_logo_8,
R.drawable.company_logo_9,
R.drawable.company_logo_10
)
job_name= arrayOf(
"Engineer",
"Computer",
"Coder",
"Teacher",
"Engineer",
"Engineer",
"Engineer",
"Engineer",
"Engineer",
"Engineer"
)
saveicon= arrayOf(
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24,
R.drawable.ic_baseline_bookmark_added_24
)
company_name= arrayOf(
"Phonix Sdn Bhd",
"Computer Sdn Bhd",
"Coder",
"Teacher",
"Engineer",
"Engineer",
"Engineer",
"Engineer",
"Engineer",
"Engineer"
)
place= arrayOf(
"Kuala Lumpur",
"Kuala Lumpur",
"Selangor",
"Rimbunan",
"Kuala Lumpur",
"Kuala Lumpur",
"Kuala Lumpur",
"Kuala Lumpur",
"Kuala Lumpur",
"Kuala Lumpur"
)
salary= arrayOf(
"RM3000",
"RM4000",
"RM3500",
"RM2000",
"RM1000",
"RM3000",
"RM3000",
"RM3000",
"RM3000",
"RM3000",
)
news= arrayOf(
getString(R.string.news_a),
getString(R.string.news_b),
getString(R.string.news_c),
getString(R.string.news_d),
getString(R.string.news_e),
getString(R.string.news_f),
getString(R.string.news_g),
getString(R.string.news_h),
getString(R.string.news_i),
getString(R.string.news_j)
)
newArrayList= arrayListOf<Company_Search>()
tempArrayList= arrayListOf<Company_Search>()
getUserdata()
super.onViewCreated(itemView, savedInstanceState)
newRecyclerView.apply {
layoutManager= LinearLayoutManager(activity)
newRecyclerView.setHasFixedSize(true)
}
recyclerView.apply {
// set a LinearLayoutManager to handle Android
// RecyclerView behavior
layoutManager= LinearLayoutManager(activity)
// set the custom adapter to the RecyclerView
adapter = Search_Page_Adapter(newArrayList)
}
}
private fun getUserdata() {
for (i in imageId.indices){
val companySearch=Company_Search(imageId[i],job_name[i],saveicon[i],company_name[i],place[i],salary[i])
newArrayList.add(companySearch)
}
// tempArrayList.addAll(newArrayList)
//
// val adapter = Notification_Fragment(tempArrayList)
var adapter=Search_Page_Adapter(newArrayList)
newRecyclerView.adapter=adapter
adapter.setOnItemClickListener(object :Search_Page_Adapter.onItemClickListener{
override fun onItemClick(position: Int) {
Toast.makeText(context,"You clicked in item no . $position",Toast.LENGTH_SHORT).show()
val intent= Intent(context,Search_Page_Detail::class.java)
intent.putExtra("name",newArrayList[position].job_name)
intent.putExtra("imageId",newArrayList[position].titleImage)
intent.putExtra("news",news[position])
startActivity(intent)
}
})
}
}
The page adapter :
package com.example.assignment_mad
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.imageview.ShapeableImageView
class Search_Page_Adapter(private val companysList:ArrayList<Company_Search>):RecyclerView.Adapter<Search_Page_Adapter.MyViewHolder>() {
private var mListener:onItemClickListener?=null
interface onItemClickListener{
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener: onItemClickListener){
mListener=listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView=LayoutInflater.from(parent.context).inflate(R.layout.list_item_search,parent,false)
return MyViewHolder(itemView,mListener)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem=companysList[position]
holder.titleImage.setImageResource(currentItem.titleImage)
holder.job_name.text=currentItem.job_name
holder.save_icon.setImageResource(currentItem.save_icon)
holder.company_name.text=currentItem.company_name
holder.place.text=currentItem.place
holder.salary.text=currentItem.salary
}
override fun getItemCount(): Int {
return companysList.size
}
//to insert the post detail
class MyViewHolder(itemView: View,listener: onItemClickListener?):RecyclerView.ViewHolder(itemView){
val titleImage:ShapeableImageView=itemView.findViewById(R.id.title_image2)
val job_name:TextView=itemView.findViewById(R.id.job_name)
val save_icon:ShapeableImageView=itemView.findViewById(R.id.save_icon)
val company_name:TextView=itemView.findViewById(R.id.company_name)
val place:TextView=itemView.findViewById(R.id.detail_place)
val salary:TextView=itemView.findViewById(R.id.detail_salary)
init {
itemView.setOnClickListener{
listener?.onItemClick(adapterPosition)
}
}
}
}
The xml file for Search_Page_Fragment :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
tools:context=".Search_Page_Fragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/search_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Search Job"
android:inputType="text"
android:minHeight="48dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/place_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:text="Area, City or Town"
android:textSize="16sp"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/search_bar"
app:layout_constraintStart_toStartOf="parent"/>
<Spinner
android:id="#+id/spinner_job"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="200dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/place_name" />
<TextView
android:id="#+id/job_specialize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:text="Job Specialize"
android:textSize="16sp"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/search_bar"
app:layout_constraintEnd_toEndOf="parent" />
<Spinner
android:id="#+id/spinner_place"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="200dp"
app:layout_constraintTop_toBottomOf="#+id/job_specialize"
app:layout_constraintEnd_toEndOf="parent"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView_Search"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="108dp"
app:layout_constraintTop_toBottomOf="#+id/spinner_job"
tools:layout_editor_absoluteX="-16dp"
tools:listitem="#layout/list_item_search" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
The list_item_search_xml :
<?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_image2"
android:scaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearanceOverlay="#style/RoundCorner"
android:src="#drawable/company_logo_1"/>
<TextView
android:id="#+id/job_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#color/blue"
android:text="Gradute Engineer"
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/title_image2"/>
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:id="#+id/save_icon"
android:scaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/title_image2"
android:layout_marginEnd="32dp"
app:shapeAppearanceOverlay="#style/RoundCorner"
android:src="#drawable/ic_baseline_bookmark_added_24"/>
<TextView
android:id="#+id/company_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:text="Neric Compat"
android:textSize="18sp"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/job_name"/>
<TextView
android:id="#+id/detail_place"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:text="Petaling Jaya"
android:textSize="16sp"
android:textStyle="bold"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/company_name"/>
<TextView
android:id="#+id/detail_salary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:text="MYR 3,700 - 4,300 /Month"
android:textSize="16sp"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/detail_place"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="8dp"
style="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/detail_salary"
android:background="#color/underline"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Your NullPointerException indicates that when this line of code is reached...
layoutManager= LinearLayoutManager(activity)
...that your newRecyclerView is null. Are you sure that you have the right resource ID here when you attempt to set it?
newRecyclerView=views.findViewById(R.id.recyclerView_Search)
Try using the debugger and set a breakpoint on these two lines to confirm is newRecyclerView is indeed null.
You must assign the RecyclerView a LayoutManager. Since you have both of them, place this line as the last statement of recyclerView.apply { … } block(s):
setLayoutManager(layoutManager)
// ↑↑↑↑↑↑↑↑↑↑↑↑↑
// Your LayoutManager
i'm facing a real strange problem, my recyclerview is showing only 1 item! I have tried multiple solutions seen on the net but none of them worked.
Here is my ListFragmentImmeuble.kt:
package com.example.mydata.fragments.list
import android.app.AlertDialog
import android.os.Bundle
import android.view.*
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.mydata.R
import com.example.mydata.viewmodel.EntrepriseViewModel
import com.example.mydata.viewmodel.ImmeubleViewModel
import kotlinx.android.synthetic.main.fragment_list_entreprise.view.*
import kotlinx.android.synthetic.main.fragment_list_immeuble.view.*
class ListFragmentImmeuble : Fragment() {
private lateinit var mImmeubleViewModel: ImmeubleViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_list_immeuble, container, false)
val adapter = ListAdapterImmeuble()
val recyclerView = view.recyclerView1
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(requireContext())
mImmeubleViewModel = ViewModelProvider(this).get(ImmeubleViewModel::class.java)
mImmeubleViewModel.readAllData.observe(viewLifecycleOwner, Observer { immeuble ->
adapter.setData(immeuble)
})
view.floatingActionButton.setOnClickListener{
findNavController().navigate(R.id.action_listFragmentImmeuble_to_addFragmentImmeuble)
}
setHasOptionsMenu(true)
return view
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.delete_menu, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId==R.id.menu_delete){
deleteAllImmeubles()
}
return super.onOptionsItemSelected(item)
}
private fun deleteAllImmeubles() {
val builder = AlertDialog.Builder(requireContext())
builder.setPositiveButton("Oui"){ _, _ ->
mImmeubleViewModel.deleteAllImmeubles()
Toast.makeText(requireContext(), "Immeubles supprimés", Toast.LENGTH_SHORT).show()
}
builder.setNegativeButton("Non"){ _, _ ->
}
builder.setTitle("Supprimer la liste des immeubles? ")
builder.setMessage("Êtes vous sure de supprimer toutes les immeubles?")
builder.create().show()
}
}
and here is my ListAdapterImmeuble.kt:
package com.example.mydata.fragments.list
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.findNavController
import androidx.recyclerview.widget.RecyclerView
import com.example.mydata.R
import com.example.mydata.model.Immeuble
import kotlinx.android.synthetic.main.custom_row.view.*
class ListAdapterImmeuble : RecyclerView.Adapter<ListAdapterImmeuble.MyViewHolder>(){
private var immeubleList = emptyList<Immeuble>()
class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.custom_row,
parent, false))
}
override fun getItemCount(): Int {
return immeubleList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = immeubleList[position]
holder.itemView.id_txt.text = currentItem.idI.toString()
holder.itemView.type_et.text = currentItem.type
holder.itemView.rue_et.text = currentItem.nomRue
holder.itemView.rowLayout1.setOnClickListener{
val action =
ListFragmentImmeubleDirections.actionListFragmentImmeubleToUpdateFragmentImmeuble(currentItem)
holder.itemView.findNavController().navigate(action)
}
}
fun setData (immeuble: List<Immeuble>){
this.immeubleList = immeuble
notifyDataSetChanged()
}
}
and here is my custom_row.xml:
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="24sp"
android:id="#+id/rowLayout1">
<TextView
android:id="#+id/id_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:textSize="40sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/type_et"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:text="Immoblier"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/id_txt"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/rue_et"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:text="Boulevard X"
android:textSize="18dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/type_et"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
and here is fragment_list_immeuble.xml:
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.list.ListFragmentImmeuble">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:layout_marginBottom="24dp"
android:clickable="true"
android:focusable="true"
android:tint="#color/white"
android:src="#drawable/ic_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
I spent hours trying to find out what's wrong.. I'd be pleased if anybody could help!
I faced a strange problem : I can't add more than one object dynamically on a LinearLayout , if they were already things , that works, So That can display multiple views
I tried with different views , there is only problems when i try to push one after the other
(there is two buttons in index 0 and 1 to test for multiple objects on the layout)
CODE :
val view = layoutInflater.inflate(R.layout.sensor_item, container, false)
val view2 = layoutInflater.inflate(R.layout.nosensor_item, container, false)
val insertPoint = viewOfLayout.findViewById(R.id.box_Parent) as LinearLayout
insertPoint.addView(view, 2)
//insertPoint.addView(view2, 3) //works
This Works too :
//insertPoint.addView(view, 3)
insertPoint.addView(view2, 2) //works
This doesn't works :
insertPoint.addView(view, 2)
insertPoint.addView(view2, 3) //doesn't works
Full Code (fragments.kt):
package com.corrupted.radheat.TEMPER
import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import kotlinx.android.synthetic.main.sensor_item.view.*
class EditFragment : Fragment() {
lateinit var option : Spinner
lateinit var result : TextView
private lateinit var viewOfLayout: View
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
viewOfLayout = inflater.inflate(R.layout.edit_fragment, container, false)
//create a view to inflate the layout_item (the xml with the textView created before)
val view = layoutInflater.inflate(R.layout.sensor_item, container, false)
val view2 = layoutInflater.inflate(R.layout.nosensor_item, container, false)
val insertPoint = viewOfLayout.findViewById(R.id.box_Parent) as LinearLayout
insertPoint.addView(view, 2)
insertPoint.addView(view2, 3)
option = view.spinner as Spinner
result = view.textView7 as TextView
val options = arrayOf("A","V")
option.adapter = ArrayAdapter<String>(activity,android.R.layout.simple_list_item_1,options)
option.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onNothingSelected(parent: AdapterView<*>?) {
result.text = "0"
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
result.text = options[position]
}
}
return viewOfLayout
}
class InfoFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.info_fragment, container, false)
}
}
class ParamsFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.parameters_fragment, container, false)
}
}
Code of the fragment :
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
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/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:id="#+id/box_Parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:id="#+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="#+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
Code of the added view :
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:fillViewport="true"
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="12dp"
android:background="#color/background_Item_light"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/textView9"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:text=".0 C°"
android:textColor="#color/Text_Color_Light"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="#+id/textView8"
app:layout_constraintStart_toEndOf="#+id/textView8"
app:layout_constraintTop_toTopOf="#+id/textView8"
app:layout_constraintVertical_bias="0.625" />
<TextView
android:id="#+id/textView7"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:layout_marginStart="4dp"
android:text=".0 C°"
android:textColor="#color/Text_Color_Light"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="#+id/textView5"
app:layout_constraintStart_toEndOf="#+id/textView5"
app:layout_constraintTop_toTopOf="#+id/textView5"
app:layout_constraintVertical_bias="0.79" />
<TextView
android:id="#+id/textView8"
android:layout_width="wrap_content"
android:layout_height="56dp"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="00"
android:textColor="#color/Text_Color_Light"
android:textSize="36sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/imageButton"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.937" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:text="#string/ROOMtext"
android:textColor="#color/Text_Color_Light"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Spinner
android:id="#+id/spinner"
android:layout_width="45dp"
android:layout_height="43dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="8dp"
android:background="#color/UI_ITEM_OVERLAP_LIGHT"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="#+id/imageButton"
android:layout_width="40dp"
android:layout_height="36dp"
android:layout_marginStart="8dp"
android:layout_marginTop="6dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_keyboard_arrow_up_black_24dp" />
<ImageButton
android:id="#+id/imageButton3"
android:layout_width="40dp"
android:layout_height="36dp"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageButton"
app:srcCompat="#drawable/ic_keyboard_arrow_down_black_24dp" />
<TextView
android:id="#+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="00"
android:textColor="#color/Text_Color_Light"
android:textSize="36sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.652" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
MainActivity.kt :
package com.corrupted.radheat.TEMPER
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.design.widget.BottomNavigationView
import android.support.v4.app.Fragment
import android.widget.*
class MainActivity : AppCompatActivity() {
private val fragmentManager = supportFragmentManager
private val fragmentTransaction = fragmentManager.beginTransaction()
private val editfragment = EditFragment()
private val infofragment = InfoFragment()
private val parametersfragment = ParamsFragment()
private fun showFragment(fragment: Fragment) {
val fragmentManager = supportFragmentManager
fragmentManager.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit()
}
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.action_edit -> {
showFragment(editfragment)
return#OnNavigationItemSelectedListener true
}
R.id.action_info-> {
showFragment(infofragment)
return#OnNavigationItemSelectedListener true
}
R.id.action_Settings-> {
showFragment(parametersfragment)
return#OnNavigationItemSelectedListener true
}
}
false
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
fragmentTransaction.add(R.id.fragment_container, infofragment)
fragmentTransaction.commit()
setContentView(R.layout.activity_main)
val navigation = findViewById<BottomNavigationView>(R.id.activity_main_bottom_navigation)
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
// Create a GLSurfaceView instance and set it
// as the ContentView for this Activity.
}
}
Pic of it working : https://imgur.com/gallery/mLb4G5b
Thanks
I am trying to access a Floating Action Button inside a fragment but for some reason, I cannot. I keep getting errors. I have tried everything and nothing seems to work. Here is the code inside my fragment:
import android.os.Bundle
import android.support.design.widget.FloatingActionButton
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.FirebaseDatabase
import com.ntx_deisgns.cyberchatter.cyberchatter.Message
import com.ntx_deisgns.cyberchatter.cyberchatter.R
import kotlinx.android.synthetic.main.groups.*
import kotlinx.android.synthetic.main.groups2.*
class groups2 : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// inflater.inflate(R.layout.groups2, container, false)
val fab = R.id.fab as FloatingActionButton
fab.setOnClickListener {
if (!mainActivityEditText.text.toString().isEmpty()){
sendData()
}else{
// Toast.makeText(this, "Please enter a message", Toast.LENGTH_SHORT).show()
}
}
return inflater.inflate(R.layout.groups2, container, false)
}
private fun sendData(){
val editText = groupInput
val database = FirebaseDatabase.getInstance()
val myRef = database.getReference("message")
myRef.setValue(Message(editText.text.toString()))
val mDatabase: DatabaseReference? = null
mDatabase?.
child("messages")?.
child(java.lang.String.valueOf(System.currentTimeMillis()))?.
setValue(Message(editText.text.toString()))
//clear the text
editText.setText("")
}
companion object {
fun newInstance(): groups2 = groups2()
}
}
What am I doing wrong? Why is it so hard to access a setOnClickListener within a fragment?
UPDATE:
Here's my groups2.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/groups2_relative"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="60dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="55dp"
tools:context="com.ntx_deisgns.cyberchatter.cyberchatter.MainActivity">
<android.support.design.widget.FloatingActionButton
android:id="#+id/myFab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:clickable="true"
android:focusable="true"
android:src="#drawable/ic_send_black_24dp"
android:tint="#android:color/white"
app:fabSize="mini" />
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_toStartOf="#id/myFab">
<EditText
android:id="#+id/groupInput"
android:layout_width="match_parent"
android:layout_height="57dp"
android:hint="Please enter your text here" />
</android.support.design.widget.TextInputLayout>
<ListView
android:id="#+id/list_of_messages"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/myFab"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="16dp"
android:divider="#android:color/transparent"
android:dividerHeight="16dp" />
</RelativeLayout>
You need to inflate the view before calling findViewById on it. Accessing the floating action button before inflation is causing the null pointer exception.
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
//inflate and store view
val view = inflater.inflate(R.layout.groups2, container, false)
val fab = view.findViewById(R.id.fab) as FloatingActionButton
//If using kotlinx then above line is not needed
fab.setOnClickListener {
//do your thing...
}
return view
}
I got an error when I scroll down the list view. When scroll reached to bottom of activity, the error occurred. And one strange thing is here. On kotlin code, there is "DataController.getDataList()" function. This function get 10 data list as ArrayList, but I got only 9 data in my emulator. What's wrong with my code?
activity_spiral_test_list.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".spiralTestListActivity"
android:background="#color/Background">
<ListView
android:id="#+id/patientList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ViewStub
android:id="#+id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout="#layout/empty"/>
<android.support.design.widget.FloatingActionButton
android:layout_width="80dp"
android:layout_height="80dp"
android:src="#drawable/add"
android:layout_margin="40dp"
android:scaleType="center"
android:tint="#android:color/white"
android:backgroundTint="#color/Primary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:borderWidth="0dp"/>
</android.support.constraint.ConstraintLayout>
patient_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="30dp"
android:orientation="vertical">
<TextView
android:id="#+id/patientName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test Patient"
android:textSize="40sp"
android:textColor="#android:color/black"
android:textStyle="bold"/>
<TextView
android:id="#+id/patientDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test Explanation"
android:textSize="25sp"/>
</LinearLayout>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:layout_marginEnd="40dp"
android:orientation="vertical">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:src="#drawable/assignment"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test"
android:textSize="20sp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
spiralTestListActivity.kt
import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView
import myPackage.DataController
import myPackage.PatientData
import kotlinx.android.synthetic.main.activity_spiral_test_list.*
class spiralTestListActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_spiral_test_list)
patientList.adapter = patientAdapter(this, DataController.getDataList())
patientList.emptyView = empty
}
private inner class ViewHolder {
lateinit var name: TextView
lateinit var description: TextView
}
inner class patientAdapter(context: Context, val listItem: ArrayList<PatientData>) : BaseAdapter() {
private val mInflator: LayoutInflater = LayoutInflater.from(context)
override fun getCount(): Int {
return this.listItem.size
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItem(position: Int): Any {
return this.listItem[position]
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val view: View
val holder: ViewHolder
if (convertView == null) {
view = mInflator.inflate(R.layout.patient_list_item, parent, false)
holder = ViewHolder()
holder.name = view.findViewById(R.id.patientName) as TextView
holder.description = view.findViewById(R.id.patientDescription) as TextView
}
else {
view = convertView
holder = convertView.tag as ViewHolder
}
val patient = getItem(position) as PatientData
val name = holder.name
val description = holder.description
name.text = patient.name
description.text = patient.description
return view
}
}
}
I solve this problem. This problem is occurred because of thread. Surely, controller of data is adapter. But, I add data in my dialog class.(There are some different part of code above. I changed it..) So, when thread ask to get data from adapter, the data is different with ListView's data. It occurred an error.
I fix the code in my adapter class and dialog class. In the adapter class, I add a function named add.
fun add(data: PatientData) {
DataController.addData(data)
}
Also, there is one more thing. In SpiralTestListActivity.ky, I don't add
convertView.tag = holder
above the else part in Adapter class..!!
These parts make my app work correctly..!