I am new to android studio and just starter 1 month ago for learning it.
I currently try to written the app that has list of data class with name, price, quantity and unit cost.
I have done the recycle view and i am facing the problem that how to update the editText value whenever the user input the quantity in the data classs
Below are my data class code
data class food (val food: String, val price: Int, var quantity: Int, var cost: Int = price*quantity)
object ABC {
var food_List = listOf<food>(
ABC ("A", 28 ,5) ,
ABC ("B", 28, 0)
)}
Below are my recycle view adaptor
class customAdaptor (val context: Context, val food_List:List<food>):RecyclerView.Adapter<customAdaptor.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(context).inflate(R.layout.list_layout,parent, false)
return ViewHolder(v)
}
override fun getItemCount(): Int {
return food_List.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val listused= food_List[position]
holder.setData(listused,position)
}
inner class ViewHolder (itemView: View): RecyclerView.ViewHolder(itemView) {
fun setData(listused: food?, pos: Int) {
itemView.listFoodName.text = listused!!.food
itemView.listUnitPrice.text =listused.price.toString()
itemView.listUnitTotalPrice.text=listused.cost.toString()
}
}}
Below are my mainactivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_page_budget)
val layoutManager = LinearLayoutManager(this)
layoutManager.orientation = LinearLayoutManager.VERTICAL
recyclerview.layoutManager = layoutManager
val adapter = customAdaptor(this, ABC.food_List)
recyclerview.adapter = adapter}
Below are my layout for card view.
<androidx.cardview.widget.CardView
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="270dp"
android:layout_height="wrap_content"
android:textAlignment="center"
android:id="#+id/listFoodName"/>
<TextView
android:layout_width="50dp"
android:layout_height="wrap_content"
android:textAlignment="center"
android:id="#+id/listUnitPrice"/>
<EditText
android:layout_width="50dp"
android:layout_height="wrap_content"
android:textAlignment="center"
android:inputType="numberDecimal"
android:id="#+id/listQuantity"/>
<TextView
android:layout_width="50dp"
android:layout_height="wrap_content"
android:textAlignment="center"
android:id="#+id/listUnitTotalPrice"/> -->
</LinearLayout>
</androidx.cardview.widget.CardView>
Then i didnt know how to write the editText for the update.
Please help. Thank you very much.
You should use this:
editText.afterTextChanged{doSomethingWithText(it)}
Your code would be something like:
fun setData(listused: food?, pos: Int) {
itemView.listFoodName.text =listused!!.food
itemView.listUnitPrice.text =listused.price.toString()
itemView.listUnitTotalPrice.text=listused.cost.toString()
itemView.listQuantity.afterTextChanged {
listused?.quantity = it.toInt()
itemView.listUnitTotalPrice.text=listused.cost.toString()
}
}
Related
I show a list of items using adapter and recyclerview. Each item shows only 4 lines of biography-textView. In order to see whole biography, user clicks 'expand' textView. My code functions but there is a problem because sometimes (somehow randomly) one 'expand' click (f.e. in item No 1) causes expanding 2-3 biography textView more in another items(f.e. items No 7 and 12). What is wrong with my code? How to check it/identify why items textView are extra expand?
Can anyone help?
class ShowMastersAdapter (
private val masterList: ArrayList<Master>,
private val itemListener: OnItemClickListener
) : RecyclerView.Adapter<ShowMastersAdapter.ShowMasterViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShowMasterViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_master, parent, false)
return ShowMasterViewHolder(view)
}
override fun onBindViewHolder(holder: ShowMasterViewHolder, position: Int) {
holder.bindData(position)
}
override fun getItemCount(): Int {
return masterList.size
}
inner class ShowMasterViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun bindData(position: Int) {
val masterBiography = itemView.findViewById<TextView>(R.id.item_master_biography)
val masterExpandBiography =itemView.findViewById<TextView>(R.id.item_master_expand_text)
masterBiography.text = masterList[position].biography
masterExpandBiography.setOnClickListener {
itemListener.onReadMoreTextClick(masterExpandBiography, masterBiography)
}
}
}
interface OnItemClickListener {
fun onReadMoreTextClick(expandText: TextView, biographyText: TextView)
}
}
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/layout_top_part">
<TextView
android:id="#+id/item_master_biography"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/item_master_margin_start"
android:layout_marginEnd="#dimen/item_master_margin_end"
android:ellipsize="end"
android:maxLines="4"
android:text="unknown"
android:textSize="#dimen/font_main_size_item_master"
app:layout_constraintBottom_toTopOf="#+id/item_master_expand_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/item_master_biography_label" />
<TextView
android:id="#+id/item_master_expand_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:text="#string/it_master_expand_text"
android:textColor="#color/text_as_link"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
class FragmentShowMasters() : Fragment(), ShowMastersAdapter.OnItemClickListener{
private var listOfMasters: ArrayList<Master> = ArrayList()
private lateinit var myRecycler: RecyclerView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState:Bundle?): View {
myView = inflater.inflate(R.layout.fragment_show_masters, container, false)
myRecycler = myView.findViewById(R.id.recycler_show_masters)
myRecycler.setHasFixedSize(true)
myRecycler.adapter = ShowMastersAdapter(listOfMasters, this, highlightSearchText)
myRecycler.adapter?.notifyDataSetChanged()
myRecycler.layoutManager = LinearLayoutManager(this.context)
return myView
}
override fun onReadMoreTextClick(expandText: TextView, biographyText: TextView) {
if (biographyText.maxLines == 4) {
biographyText.maxLines = Int.MAX_VALUE
expandText.text = getString(R.string.it_master_shrink_text)
} else {
biographyText.maxLines = 4
expandText.text = getString(R.string.it_master_expand_text)
}
}
}
I am new to mobile development with kotlin and I am trying to add a new item to the recyclerview.
The item is added to the recycler view but the text is not visible. I don't get what it's wrong.
I am using Kotlin in Android Studio 4.2
The class AgentAttributes only contains two properties:val Name:String ,val Value:String
**activity_main.xml**
<EditText
android:id="#+id/etSearch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="No emp"
app:layout_constraintEnd_toStartOf="#+id/btnSearch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/btnSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#android:string/search_go"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvAgentAttributes"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/etSearch" />
**MainActivity.kt**
private lateinit var agentAttributesAdapter:AgentAttributesAdapter
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
//setContentView(R.layout.activity_main)
//constructor
agentAttributesAdapter = AgentAttributesAdapter(mutableListOf())
//Definition of Recycler view adapter
binding.rvAgentAttributes.adapter = agentAttributesAdapter
binding.rvAgentAttributes.layoutManager = LinearLayoutManager(this)
//THIS IS THE WAY THAT I AM TRYING TO ADD A NEW ITEM
val agentAttr = AgentAttributes("Nombre","JOEL ROMUALDO LOPEZ SALIDO")
agentAttributesAdapter.addAttributes(agentAttr)
**AgentAttributesAdapter**
class AgentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AgentViewHolder {
return AgentViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.agent_details,
parent,
false
)
)
override fun onBindViewHolder(holder: AgentViewHolder, position: Int) {
val layoutInflater = LayoutInflater.from(holder.itemView.context)
binding = AgentDetailsBinding.inflate(layoutInflater)
//val view = binding.root
val currentAgent = agent_attributes[position]
holder.itemView.apply {
binding.tvAttribute.text = currentAgent.Name.toString()
}
}
override fun getItemCount(): Int {
return agent_attributes.size
}
fun addAttributes(attr:AgentAttributes){
agent_attributes.add(attr)
notifyItemInserted(agent_attributes.size - 1)
}
There's no need to inflate your layout in the "binding" step:
override fun onBindViewHolder(viewHolder: ChoicesViewHolder, pos: Int) {
AgentDetailsBinding.bind(viewHolder.itemView).apply {
val currentAgent = agent_attributes[position]
tvAttribute.text = currentAgent.Name.toString()
}
}
PS: variables should be lower case, so currentAgent should have a name, no Name
As I have implemented a room library in my project ,
I add data to database , But Recyclerview is showing only one item .
class NotesAdapter : RecyclerView.Adapter<NotesAdapter.NotesViewHolder>() {
class NotesViewHolder(val binding: NotesCardLayoutBinding) :
RecyclerView.ViewHolder(binding.root)
private val differCallback = object : DiffUtil.ItemCallback<Notes>() {
override fun areItemsTheSame(oldItem: Notes, newItem: Notes): Boolean {
return oldItem.noteId == newItem.noteId
}
override fun areContentsTheSame(oldItem: Notes, newItem: Notes): Boolean {
return oldItem == newItem
}
}
val differ = AsyncListDiffer(this,differCallback)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NotesViewHolder {
val view =
NotesCardLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return NotesViewHolder(view)
}
override fun onBindViewHolder(holder: NotesViewHolder, position: Int) {
val notes = differ.currentList[position]
holder.binding.tvTitle.text = notes.noteTitle.toString()
holder.binding.tvDesc.text = notes.notesDesc.toString()
}
override fun getItemCount(): Int {
return differ.currentList.size
}
}
" My Notes Fragment where recylerview is intialized "
class NotesFragment : Fragment() {
private lateinit var binding: FragmentNotesBinding
private lateinit var notesViewModel: NotesViewModel
private lateinit var notesAdapter : NotesAdapter
private fun recyclerviewSetup() {
notesAdapter = NotesAdapter()
val recyclerView = binding.rvNotes
recyclerView.adapter = notesAdapter
recyclerView.setHasFixedSize(true)
recyclerView.layoutManager = LinearLayoutManager(requireContext())
activity?.let {
notesViewModel.getAllNotes.observe(viewLifecycleOwner , Observer { noteList->
notesAdapter.differ.submitList(noteList)
})
}
}
}
It may be the problem of database or Adapter
please gyzz help me out
github
The problem is not with fetching data, I've cloned your repo and checked, it is while inserting, do not user Int? for primary key, just use Int
Notes.kt
#Entity(tableName = "Notes Table")
data class Notes(
#PrimaryKey(autoGenerate = true)
var noteId: Int,
#ColumnInfo(name = "Title of Notes")
val noteTitle: String?,
#ColumnInfo(name = "Description of Notes")
val notesDesc: String?
)
Also you have another problem is notes_card_layout, you are setting height to match_parent which is not correct, use below
notes_card_layout.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:paddingBottom="4dp"
android:paddingTop="4dp"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:cardElevation="5dp"
app:cardCornerRadius="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="5dp"
android:layout_marginVertical="5dp"
android:orientation="vertical">
<TextView
android:id="#+id/tvTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:text="#string/title_card" />
<TextView
android:id="#+id/tvDesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:text="#string/desc_card" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
replace above two code snippets and try, below is a snapshot from my modified changes
I'm unable to update my RecyclerView. Tried every solution on stackoverflow but nothing helps. I've tried to add layoutmanager in code, hardcode number of items, made new files, checked if I had duplicate files etc.. I also debugged and confirmed that "onAttachedToRecyclerView" is called, but getItemCount and the others i've listed in the adapter are not called except for the constructor
Adapter:
class BaseAdapter(context: Context, val items: List<Item>) :
RecyclerView.Adapter<LineBoxAdapter.BaseAdapter>() {
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.textView.text = items[position].text
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
ViewHolder {
return ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.simple_item,
parent,
false
)
)
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textView = itemView.findViewById<TextView>(R.id.title)
}
}
Function that updates recyclerView:
val listView =
LayoutInflater.from(context).inflate(R.layout.list, viewGroup,
false)
val list = listView.findViewById<RecyclerView>(R.id.
LinearLayoutManager(context)
val adapter = BaseAdapter(context, items)
list.adapter = adapter
adapter.notifyDataSetChanged()
RECYCLERVIEW:
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/items_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:overScrollMode="never"
android:requiresFadingEdge="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
SIMPLE_ITEM:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:orientation="horizontal">
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="25" />
</LinearLayout>
You should avoid using existing class names from API.
I will post my working code.
simple_item:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text_simple_item"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
RecyclerAdapter:
class RecyclerAdapter(context: Context, val items: List<Item>) :
RecyclerView.Adapter<RecyclerAdapter.MyViewHolder>() {
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.textView.text = items[position].itemName
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
MyViewHolder {
return MyViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.simple_item,
parent,
false
)
)
}
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textView = itemView.findViewById<TextView>(R.id.text_simple_item)
}
}
My Activity:
class RecyclerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_recycler)
val recyler = findViewById<RecyclerView>(R.id.rv_activity_recycler)
val list = mutableListOf(Item("Me"), Item("You"), Item("We"))
val adapter = RecyclerAdapter(this, list)
recyler.layoutManager = LinearLayoutManager(this)
recyler.adapter = adapter
}
}
My Item:
class Item(val itemName: String)
I was trying to make a custom RecyclerView with Adapter which takes a HashMap as parameter, I succeeded but now only 1 item is showing in recyclerView list and I have no idea why.
Here my code snippet:
Custom RecyclerAdapter:
class ProductsRecyclerAdapter(private val dataSet: HashMap<Int, ProductEntry>) : RecyclerView.Adapter<ProductsRecyclerAdapter.ViewHolder>() {
class ViewHolder(val linearLay: LinearLayout) : RecyclerView.ViewHolder(linearLay)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : ProductsRecyclerAdapter.ViewHolder {
val linearLay = LayoutInflater.from(parent.context).inflate(R.layout.test_text_view, parent, false) as LinearLayout
return ViewHolder(linearLay)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.linearLay.textView.text = dataSet[position]?.pName
holder.linearLay.textView2.text = dataSet[position]?.pExpiry
}
override fun getItemCount(): Int {
return dataSet.size
}
}
Initialization:
// Setup RecyclerView
val prod1 = ProductEntry("Milk", "04/06/1996")
val prod2 = ProductEntry("Bread", "04/01/2012")
val testArray : HashMap<Int, ProductEntry> = hashMapOf(1 to prod1, 2 to prod2)
viewManager = LinearLayoutManager(this)
viewAdapter = ProductsRecyclerAdapter(testArray)
recyclerView = findViewById<RecyclerView>(R.id.productsRecyclerView).apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = viewAdapter
}
And finally, custom XML for row:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/linearLay"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_weight="1"
android:text="TextView" />
Despite everything seems to be OK, I get only 1 row showing "milk".
Thanks for all help!
position in override fun onBindViewHolder(holder: ViewHolder, position: Int) starts at index 0.
So in your case, it will be [0, 1] and your map keys are [1, 2]. Only key "1" will be displayed correctly.
try:
val testArray : HashMap<Int, ProductEntry> = hashMapOf(0 to prod1, 1 to prod2)
But no need to use a map here! Just use a simple list of ProductEntry.