Combine object data value into single string in kotlin - kotlin

Hey I have object of Event. I want to combine all property value into single string. I did this without any problem. I want to know is there any better way to optimise this code in memory, efficiency etc.
SingleEventString.kt
fun main() {
var newString: String? = null
val eventList = createData()
eventList.forEachIndexed { index, event ->
val title = event.title
val status = event.status
if (!title.isNullOrEmpty()) {
newString = if(index == 0){
"$title"
}else{
"$newString $title"
}
}
if (!status.isNullOrEmpty()) {
newString = "$newString $status"
}
}
println(newString)
}
data class Event(val title: String? = null, val status: String? = null)
fun createData() = listOf(
Event("text 1", "abc"),
Event("text 2", "abc"),
Event("text 3", "abc"),
Event("text 4", "abc"),
Event("", "abc"),
Event(null, "abc")
)

data class Event(val title: String? = null, val status: String? = null)
fun createData() = listOf(
Event("text 1", "abc"),
Event("text 2", "abc"),
Event("text 3", "abc"),
Event("text 4", "abc"),
Event("", "abc"),
Event(null, "abc")
)
val newString = createData()
.joinToString(" ") { "${it.title?: ""} ${it.status?: ""}".trim() }
println(newString)

Related

kotlin how to remove duplicate through some value in object array?

how to remove duplicate through some value in object array?
data class Person(
val id: Int,
val name: String,
val gender: String
)
val person1 = Person(1, "Lonnie", "female")
val person2 = Person(2, "Noah", "male")
val person3 = Person(3, "Ollie", "female")
val person4 = Person(4, "William", "male")
val person5 = Person(5, "Lucas", "male")
val person6 = Person(6, "Mia", "male")
val person7 = Person(7, "Ollie", "female")
val personList = listOf(person1,person2,person3,person4,person5,person6,person7)
Person 3 and person 7 have a "female" gender and have the same name. So person7 needs to be removed.
But "male" gender can have duplicated name.
And the order of the list must be maintained.
expect result
[
Person(1, "Lonnie", "female"),
Person(2, "Noah", "male"),
Person(3, "Ollie", "female"),
Person(4, "William", "male"),
Person(5, "Lucas", "male"),
Person(6, "Mia", "male"),
]
You could do something like this, assuming the order is indicated by the id field of the Person class:
val personList = listOf(person1,person2,person3,person4,person5,person6,person7)
.partition { it.name == "male" }
.let { (males, females) -> males + females.distinctBy { it.name } }
.sortedBy { it.id }
I believe this does what you want:
val result = personList.filter {
person -> person.gender == "male" || (personList.first {
person.name == it.name && person.gender == it.gender
} == person)
}

Why rememberCoilPainter is not working in project?

My Coil Image Implementation
val painter = rememberCoilPainter(
request = category.icon,
imageLoader = ImageLoader.invoke(context)
)
Image(
painter = painter ?: painterResource(id = R.drawable.home_active),
contentDescription = "",
modifier = modifier.size(50.dp)
)
And Data Source
data class Category(
val icon: String?,
val id: Int,
val is_subcat: String,
val name: String?,
val type: String
) {
companion object {
val fakeCategory = listOf(
Category(
id = 7,
name = "Malls",
icon = "http://appsinvodevlopment.com/walk_in/public/category_images/2.png",
is_subcat = "1",
type = "0"
),
...
}
why goes here
And if someone has time please check my code, becuase i got nullPointerExeception for that reason i use fake data list

Kotlin: Remove list in Recycerview using AlertDialog button

I hope to remove items in Recyclerview by AlertDialog button.
Do you have idea?
Adapter & Viewholer
class ProjectsRecyclerAdapter(val list:List<ProjectListDataModel>, var clickListner: OnProjectListClickListner) : RecyclerView.Adapter<ProjectRecyclerViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProjectRecyclerViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_cardview, parent, false)
return ProjectRecyclerViewHolder(
view
)
}
override fun getItemCount(): Int {
return list.count()
}
override fun onBindViewHolder(holder: ProjectRecyclerViewHolder, position: Int) {
holder.initialize(list[position], clickListner)
}
}
class ProjectRecyclerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun initialize(item: ProjectListDataModel, action: OnProjectListClickListner) {
itemView.projectNameText.text = item.name
itemView.modifiedTimeText.text = item.modTime
itemView.descriptionText.text = item.description
itemView.setOnClickListener {
action.onItemClick(item, adapterPosition)
}
}
}
interface OnProjectListClickListner {
fun onItemClick(item: ProjectListDataModel, position: Int)
}
And here is Main Activity
class LocalProjectListActivity :
AppCompatActivity(),
OnProjectListClickListner,
NavigationView.OnNavigationItemSelectedListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
val localProjectList = listOf(
ProjectListDataModel(
"Project A",
"Sun, 01/DEC/2020, 22:23GMT",
"Testing 1",
"AAAA",
"A, A",
8,
232
),
ProjectListDataModel(
"Project B",
"Sun, 01/JUL/2020, 10:23GMT",
"Testing 2",
"BBBB",
"B, B",
6,
354
),
ProjectListDataModel(
"Project C",
"Sun, 11/MAR/2020, 08:31GMT",
"Testing 3",
"CCCC",
"C,C",
15,
632
)
)
val adapter = ProjectsRecyclerAdapter(localProjectList, this)
projectNameText.adapter = adapter
projectNameText.setHasFixedSize(true)
projectNameText.layoutManager = LinearLayoutManager(this)
}
override fun onItemClick(item: ProjectListDataModel, position: Int) {
val builder = AlertDialog.Builder(this)
val ad = builder.create()
val dialogView = layoutInflater.inflate(R.layout.project_onclick, null)
dialogView.projectNameText.text = item.name
dialogView.modifiedTimeText.text = item.modTime
dialogView.descriptionText.text = item.description
dialogView.fileNumberText.text = item.fileNumber.toString() + "EA"
dialogView.fileSizeText.text = item.fileSize.toString() + "MB"
dialogView.scopeText.text = item.scope
dialogView.userIdText.text = item.resposible
ad.setView(dialogView)
ad.show()
//when click Load button
dialogView.loadButton.setOnClickListener {
ad.dismiss()
val dialog = AlertDialog.Builder(this)
dialog.setTitle("Question1")
dialog.setMessage("You want to go to the project?")
dialog.setPositiveButton("Yes", DialogInterface.OnClickListener { _, _ ->
})
dialog.setNegativeButton("No", DialogInterface.OnClickListener { _, _ ->
val fileFilterIntent = Intent(this, ProjectFileActivity::class.java)
startActivity(fileFilterIntent)
})
dialog.setNeutralButton("Cancel", DialogInterface.OnClickListener {dialog, _ ->
dialog.dismiss()
})
//if(isMarker == true) {
dialog.show()
//} else {}
}
dialogView.deleteButton.setOnClickListener {
ad.dismiss()
val dialog = AlertDialog.Builder(this)
dialog.setTitle("Delet project list")
dialog.setMessage("You want to delete project?")
dialog.setPositiveButton("Yes", DialogInterface.OnClickListener { _, _ ->
**//Delete items in RecyclerView**
})
dialog.setNeutralButton("Cancel", null)
dialog.show()
}
dialogView.cancleButton.setOnClickListener { ad.dismiss() }
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.remoteProjects -> {
val serverProjIntent = Intent(this, ServerProjectListActivity::class.java)
startActivity(serverProjIntent)
}
R.id.settings -> {
Toast.makeText(this, "Go to Settings", Toast.LENGTH_SHORT).show()
}
}
mainLocal.closeDrawer(GravityCompat.START)
return true
}
}
I posted all the code like that.
I can get the lists using Recyclerview, and made the AlertDialog But I don't know how to delete the items using the "Yes" button in AlertDialog.
Please give me some advises.
You'll need to have a reference to the list and the adapter outside of onCreate
private val localProjectList = mutableListOf(
ProjectListDataModel(
"Project A",
"Sun, 01/DEC/2020, 22:23GMT",
"Testing 1",
"AAAA",
"A, A",
8,
232
),
ProjectListDataModel(
"Project B",
"Sun, 01/JUL/2020, 10:23GMT",
"Testing 2",
"BBBB",
"B, B",
6,
354
),
ProjectListDataModel(
"Project C",
"Sun, 11/MAR/2020, 08:31GMT",
"Testing 3",
"CCCC",
"C,C",
15,
632
)
)
private lateinit var adapter: ProjectsRecyclerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
adapter = ProjectsRecyclerAdapter(localProjectList, this)
projectNameText.adapter = adapter
projectNameText.setHasFixedSize(true)
projectNameText.layoutManager = LinearLayoutManager(this)
}
And then delete the list and notify the adapter
private fun deleteItemsAndNotifyAdapter() {
localProjectList.clear()
adapter.notifyDataSetChanged()
}
You can delete and notify adapter in you dialog:
private var alertDialog: AlertDialog? = null
private fun showDeleteDialog() {
val builder = AlertDialog.Builder(activity)
builder.run {
setTitle("Delete project list")
setMessage("You want to delete project?")
setPositiveButton("Yes") { _, _ ->
deleteItemsAndNotifyAdapter()
}
setNegativeButton("Cancel") { _, _ ->
}
}
alertDialog = builder.create()
alertDialog?.show
}

How can I access the list from API to display data? (Kotlin)

I have a List of cars that I am trying to display. The data needed is from postman and to access the car info I need to first access the list but I'm not sure how to do so. I'm also not sure how to call the car function I made, Ive searched for ways but no has worked.
here is how the data in postman looks:
{
"listCar": [
{
"id": 204,
"adTitle": "AdTitlecar",
"adDate": "2019-11-07T11:52:40.0156875",
"adPrice": 25.0,
"category": "4X4",
"categoryId": 7,
"status": 1,
"brandId": 1,
"brand": "مرسيدس",
"brandModelId": 6,
"brandModel": "M300",
"kilometer": 300.0,
"modelYearId": 2,
"modelYear": "2010",
"fuelType": "بنزين",
"carFeatureFuelId": 3,
"gearType": "اوتوماتك",
"carFeatureGearId": 2,
"image": null,
"vendorId": 1
},
{
"id": 203,
"adTitle": "AdTitlecar",
"adDate": "2019-11-07T11:52:37.7771547",
"adPrice": 25.0,
"category": "4X4",
"categoryId": 7,
"status": 1,
"brandId": 1,
"brand": "مرسيدس",
"brandModelId": 6,
"brandModel": "M300",
"kilometer": 300.0,
"modelYearId": 2,
"modelYear": "2010",
"fuelType": "بنزين",
"carFeatureFuelId": 3,
"gearType": "اوتوماتك",
"carFeatureGearId": 2,
"image": null,
"vendorId": 1
},
{
"id": 202,
"adTitle": "AdTitlecar",
"adDate": "2019-11-07T11:52:35.5569602",
"adPrice": 25.0,
"category": "4X4",
"categoryId": 7,
"status": 1,
"brandId": 1,
"brand": "مرسيدس",
"brandModelId": 6,
"brandModel": "M300",
"kilometer": 300.0,
"modelYearId": 2,
"modelYear": "2010",
"fuelType": "بنزين",
"carFeatureFuelId": 3,
"gearType": "اوتوماتك",
"carFeatureGearId": 2,
"image": null,
"vendorId": 1
},
],
}
Here is my car Object I made:
object CarsListData {
var id = 0
var title = ""
var date = ""
var price = 0.0
var category = ""
var brand = ""
var model = ""
var distance = 0.0
var year = ""
var fuel = ""
var gear = ""
}
here is how im fetching the data as GET:
fun carsList(context: Context, complete: (Boolean) -> Unit) {
val carList = object : JsonObjectRequest(Method.GET, URL_CAR_LIST, null, Response.Listener { response ->
try {
CarsListData.id = response.getInt("id")
CarsListData.title = response.getString("adTitle")
CarsListData.date = response.getString("adDate")
CarsListData.price = response.getDouble("adPrice")
CarsListData.category = response.getString("category")
CarsListData.brand = response.getString("brand")
CarsListData.model = response.getString("brandModel")
CarsListData.distance = response.getDouble("kilometer")
CarsListData.year = response.getString("modelYear")
CarsListData.fuel = response.getString("fuelType")
CarsListData.gear = response.getString("gearType")
// UserDataService.image = response.getString("image")
val userDataChange = Intent(BROADCAST_USER_DATA_CHANGE)
LocalBroadcastManager.getInstance(context).sendBroadcast(userDataChange)
complete(true)
} catch (e: JSONException) {
Log.d("JSON", "EXC" + e.localizedMessage)
}
}, Response.ErrorListener {error ->
Log.d("ERROR", "Could not login user: $error")
complete(false)
}) {
override fun getBodyContentType(): String {
return "application/json; charset=utf-8"
}
override fun getHeaders(): MutableMap<String, String> {
val headers = HashMap<String, String>()
headers.put("Authorization", "Bearer $authToken")
return headers
}
}
Volley.newRequestQueue(context).add(carList)
}
here is how Im broadcasting the data in the listCarPage:
LocalBroadcastManager.getInstance(this).registerReceiver(userDataChangeReciever,
IntentFilter(BROADCAST_USER_DATA_CHANGE)
)
}
private val userDataChangeReciever = object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
carDetailsDate.text = CarsListData.date
carDetailsTitle.text = CarsListData.title
carDetailsCategory.text = CarsListData.category
carDetailsPrice.text = CarsListData.price.toString()
carDetailsDistance.text = CarsListData.distance.toString()
cardetailsGear.text = CarsListData.gear
carDetailsOil.text = CarsListData.fuel
carDetailsYear.text = CarsListData.year
}
}
I tried accessing the "listCar" and nothing seems to work and I just dont feel like im doing this the right way so would appreciate any suggestions!
Edit-
CarAdapter code:
class CarAdapter(context: Context, cars: List<Cars>) : BaseAdapter() {
val context = context
val cars = cars
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val carsView: View
carsView = LayoutInflater.from(context).inflate(R.layout.cars_list, null)
val carImage: ImageView = carsView.findViewById(R.id.carDetailsImage)
val carTitle: TextView = carsView.findViewById(R.id.carDetailsTitle)
val carCategory: TextView = carsView.findViewById(R.id.carDetailsCategory)
val carPrice: TextView = carsView.findViewById(R.id.carDetailsPrice)
val carDistance: TextView = carsView.findViewById(R.id.carDetailsDistance)
val carDate: TextView = carsView.findViewById(R.id.carDetailsDate)
val carGear: TextView = carsView.findViewById(R.id.cardetailsGear)
val carYear: TextView = carsView.findViewById(R.id.carDetailsYear)
val carOil: TextView = carsView.findViewById(R.id.carDetailsOil)
val car = cars[position]
carTitle.text = car.title
carCategory.text = car.category
carPrice.text = car.price
carDistance.text = car.distance
carDate.text = car.date
carGear.text = car.gear
carYear.text = car.year
carOil.text = car.oil
val resourceId = context.resources.getIdentifier(car.image, "drawable", context.packageName)
carImage.setImageResource(resourceId)
return carsView
}
override fun getItem(position: Int): Any {
return cars[position]
}
override fun getItemId(position: Int): Long {
return 0
}
override fun getCount(): Int {
return cars.count()
}
}
here is the list of cars data :
class Cars(val date: String, val id: Int, val title: String, val image: String, val category: String, val price: String,val distance: String,val gear: String,val oil: String,val year: String) {
override fun toString(): String {
return title
}
}
Try to use this code
try {
val list: List<CarsListData> = ArrayList()
val listCar = response.getJSONArray("listCar ")
for (i in 0 until listCar.length()) {
val carData=
listCar.getJSONObject(i)
CarsListData.id = response.getInt("id")
CarsListData.title = carData.getString("adTitle")
CarsListData.date = carData.getString("adDate")
CarsListData.price = carData.getDouble("adPrice")
CarsListData.category = carData.getString("category")
CarsListData.brand = carData.getString("brand")
CarsListData.model = carData.getString("brandModel")
CarsListData.distance = carData.getDouble("kilometer")
CarsListData.year = carData.getString("modelYear")
CarsListData.fuel = carData.getString("fuelType")
CarsListData.gear = carData.getString("gearType")
list.add(CarsListData)
}
val userDataChange = Intent(BROADCAST_USER_DATA_CHANGE)
LocalBroadcastManager.getInstance(context).sendBroadcast(userDataChange)
complete(true)
catch (e: JSONException) {
Log.d("JSON", "EXC" + e.localizedMessage)
}
Here is broadcasting the data in the listCarPage:
LocalBroadcastManager.getInstance(this).registerReceiver(userDataChangeReciever,
IntentFilter(BROADCAST_USER_DATA_CHANGE)
)
}
private val userDataChangeReciever = object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// Here you can loop through the list
val data = list[0] // just example
carDetailsDate.text = data.date
carDetailsTitle.text = data.title
carDetailsCategory.text = data.category
carDetailsPrice.text = data.price.toString()
carDetailsDistance.text = data.distance.toString()
cardetailsGear.text = data.gear
carDetailsOil.text = data.fuel
carDetailsYear.text = data.year
}
}

Grouping classes in kotlin

I have a class called as Student, with three fields, I need to convert that class into a GroupedStudent. How can this be achieved?
var students: List<Student> = mutableListOf(Student("A", "X", 1), Student("A", "Y", 2), Student("B", "X", 2), Student("B", "Y", 2))
I need to convert the above list to a GroupedStudent List, how can i do that?
They should be grouped by studentName, and have the SubjectMarks as list.
class Student {
var name: String
var subject: String
var marks: Int
}
class GroupedStudent {
var name: String
var subMarks: MutableList<SubjectMarks>
}
class SubjectMarks {
var subject: String
var marks: Int
}
Use the Kotlin stdlib Collections functions:
var students: List<Student> = mutableListOf(Student("A", "X", 1), Student("A", "Y", 2), Student("B", "X", 2), Student("B", "Y", 2))
val groupedMap = students.groupBy { it.name }
val groupedStudents = mutableListOf<GroupedStudent>()
groupedMap.forEach { key, value ->
val groupedStudent = GroupedStudent(key, value.map { SubjectMarks(it.subject, it.marks) }.toMutableList())
groupedStudents.add(groupedStudent)
}
This will result in a List of GroupedStudent, with each GroupedStudent containing a list of students' marks who have that name.
You can group by the student's name and then do two simple mappings:
students.groupBy(Student::name).map { (name, students) ->
GroupedStudent(name, students.map { SubjectMarks(it.subject, it.marks) }.toMutableList())
}
If your Student class is correct, i.e. marks should be Int and not array or list of integers and you really want to convert it to "GroupedStudent List" you can use sortedWith and map methods:
class Student(var name: String, var subject: String, var marks: Int) {
override fun toString(): String = "name: $name, subject: $subject, marks: $marks"
}
class GroupedStudent(var name: String, var subMarks: MutableList<SubjectMarks>) {
override fun toString(): String = "name: $name, subject: $subMarks"
}
class SubjectMarks(var subject: String, var marks: Int) {
override fun toString(): String = "subject name: $subject, marks: $marks"
}
fun main(args: Array<String>) {
val students: List<Student> = mutableListOf(Student("B", "Y", 2),
Student("A", "X", 1),
Student("B", "X", 2),
Student("A", "Y", 2))
val groupedStudents: List<GroupedStudent> = students.sortedWith(compareBy({ it.name }))
.map { student -> GroupedStudent(student.name, mutableListOf(SubjectMarks(student.subject, student.marks))) }
println(groupedStudents)
}
The result:
[name: A, subject: [subject name: X, marks: 1], name: A, subject: [subject name: Y, marks: 2], name: B, subject: [subject name: Y, marks: 2], name: B, subject: [subject name: X, marks: 2]]
BUT if you want to group your Student objects in a map with name as key and list of subject/marks as list of Pairs, you can use groupBy:
class Student(var name: String, var subject: String, var marks: Int) {
override fun toString(): String = "name: $name, subject: $subject, marks: $marks"
}
class GroupedStudent(var name: String, var subMarks: MutableList<SubjectMarks>) {
override fun toString(): String = "name: $name, subject: $subMarks"
}
class SubjectMarks(var subject: String, var marks: Int) {
override fun toString(): String = "subject name: $subject, marks: $marks"
}
fun main(args: Array<String>) {
val students: List<Student> = mutableListOf(Student("B", "Y", 2),
Student("A", "X", 1),
Student("B", "X", 2),
Student("A", "Y", 2))
val groupedStudentsMap = mutableMapOf<String, List<Pair<String, Int>>>()
students.groupBy { it.name }
.forEach({ (key, value) ->
groupedStudentsMap[key] = value.map { element -> Pair(element.subject, element.marks) } })
println(groupedStudentsMap)
}
The result:
{B=[(Y, 2), (X, 2)], A=[(X, 1), (Y, 2)]}