How to sort reccyclerview in kotlin android - android

Here I wrote a function where when a particular textView is clicked it will sort the recycler view according to that property but the function only does sorting in descending order. I want functionality where when click the text the first time it sort in ascending order and in the second time it will sort in descending or vice versa. Can please anyone help?
private fun sortTheData(){
binding.statusTextTV.setOnClickListener {
statusAsc = if(statusAsc){
vehicleList.sortedBy {
it.status
}
false
}else{
vehicleList.sortByDescending {
it.status
}
true
}
}
binding.permitTextTV.setOnClickListener {
Log.e(TAG, "sortTheData: $permitAsc", )
permitAsc = if(permitAsc){
vehicleList.sortedBy { vehicle ->
vehicle.permit
}.forEach { println(it.permit) }
false
}else{
vehicleList.sortByDescending { vehicle ->
vehicle.permit
}
true
}
adapter.updateList(vehicleList)
}
binding.licenseTextTV.setOnClickListener {
licenseAsc = if(licenseAsc){
vehicleList.sortedBy {
it.license
}
adapter.updateList(vehicleList)
false
}else{
vehicleList.sortByDescending {
it.license
}
adapter.updateList(vehicleList)
true
}
}
binding.spaceTextTV.setOnClickListener {
spaceAsc = if(spaceAsc){
vehicleList.sortedBy {
it.space
}
vehicleList.forEach{
println(it.space)
}
false
}else{
vehicleList.sortByDescending {
it.space
}
vehicleList.forEach{
println(it.space)}
true
}
}
}

You need to keep a boolean flag and sort accordingly. Pseudo code:
var reversed = false
textView.setOnClickListener {
reversed = !reversed
list = vehicleList.sortedBy { it.license }
if (reversed) {
list = list.reversed()
}
}

You can use type varaible or enum
e.g
var sortType : Int = 1 // 1 or asc & 2 for desc. You can use enum as well
Your sort function will be
fun sort() {
if(sortType == 1) {
sortType = 2
vehicleList.sortByDescending {it.license}
} else {
sortType = 1
vehicleList.sortBy {it.license}
}
adapter.updateList(vehicleList)
}

Related

How to show multiple edit text error simultaneously?

I want to validate text input, but how to show multiple edit text error simultaneously??
Here is my code
binding.btnCalculate.setOnClickListener() {
val panjang = binding.etPanjang.text
val lebar = binding.etLebar.text
val tinggi = binding.etTinggi.text
if (TextUtils.isEmpty(binding.etPanjang.text)) {
binding.etPanjang.setError("Field must be filled")
} else if (TextUtils.isEmpty(binding.etLebar.text)) {
binding.etLebar.setError("Field must be filled")
} else if (TextUtils.isEmpty(binding.etLebar.text)) {
binding.etTinggi.setError("Field must be filled")
} else {
val action = InputFragmentDirections.actionInputFragmentToOutputFragment(
panjang.toString().toInt(),
lebar.toString().toInt(),
tinggi.toString().toInt()
)
findNavController().navigate(
action
)
}
}
Result
I Want all edit text that empty is showing error, not only one edit text
You just need to change if .. else to if only for each condition so each condition can be checked and set error if input is not valid
replace your code with below
binding.btnCalculate.setOnClickListener() {
val panjang = binding.etPanjang.text
val lebar = binding.etLebar.text
val tinggi = binding.etTinggi.text
var isAnyError = false
if (TextUtils.isEmpty(binding.etPanjang.text)) {
binding.etPanjang.setError("Field must be filled")
isAnyError = true
}else{
binding.etPanjang.setError(null)
}
if (TextUtils.isEmpty(binding.etLebar.text)) {
binding.etLebar.setError("Field must be filled")
isAnyError = true
}else{
binding.etLebar.setError(null)
}
if (TextUtils.isEmpty(binding.etLebar.text)) {
binding.etTinggi.setError("Field must be filled")
isAnyError = true
}else{
binding.etTinggi.setError(null)
}
if(!isAnyError){
val action = InputFragmentDirections.actionInputFragmentToOutputFragment(
panjang.toString().toInt(),
lebar.toString().toInt(),
tinggi.toString().toInt()
)
findNavController().navigate(
action
)
}
}

In compose, why modify the properties of the List element, LazyColumn does not refresh

When I modify the properties of the objects in the List, the UI does not update
my code:
#OptIn(ExperimentalFoundationApi::class)
#Composable
fun ContactCard(
) {
var stateList = remember {
mutableStateListOf<ListViewData>()
}
viewModel!!.recordRespListLiveData!!.observe(this) { it ->
it.forEach {
stateList.add(ListViewData(false, it))
}
}
LazyColumn() {
stateList.forEachIndexed { index, bean ->
stickyHeader() {
Box(Modifier.clickable {
stateList[index].visible = true
}) {
ContactNameCard(bean.data.contact, index)
}
}
items(bean.data.records) { data ->
if (bean.visible) {
RecordItemCard(record = data)
}
}
}
}
}
When I click on the Box, visible is set to true, but the RecordItemCard doesn't show,why?
For SnapshotList to trigger you need to add, delete or update existing item with new instance. Currently you are updating visible property of existing item.
If ListViewData is instance from data class you can do it as
stateList[index] = stateList[index].copy(visible = true)

Jetpack Compose general item in LazyColumn

In the following code, I have two parts A and B. I need to extract part B as a common part for more of my pages.
But it contains item, I cannot extract item, but item must be included in the if judgment because paging3 will scroll to the top for extra item.
Is there a way to extract item?
LazyColumn(Modifier.fillMaxSize()) {
// Part A
items(pagingItems) { wind ->
WindRow(navController, wind!!)
}
val refresh = pagingItems.loadState.refresh
val append = pagingItems.loadState.append
// Part B
if (refresh is LoadState.NotLoading && append is LoadState.NotLoading) {
if (pagingItems.itemCount == 0) {
item {
PosterCompose() {
navController.navigate("blowWind")
}
}
}
} else {
item {
LoadStateView(path = FOLLOW_WIND_LIST, refresh = refresh, append = append) {
pagingItems.retry()
}
}
}
}
I solved this problem
fun <T : Any> LazyListScope.newItems(pagingItems: LazyPagingItems<T>) {
val refresh = pagingItems.loadState.refresh
val append = pagingItems.loadState.append
if (refresh is LoadState.NotLoading && append is LoadState.NotLoading) {
if (pagingItems.itemCount == 0) {
item {
PosterCompose() {
}
}
}
}else{
item {
LoadStateView(path = FOLLOW_WIND_LIST, refresh = refresh, append = append) {
pagingItems.retry()
}
}
}
}
This is how to use
LazyColumn(Modifier.fillMaxSize()) {
items(pagingItems) { wind ->
WindRow(navController, wind!!)
}
newItems(pagingItems)
}

Android NavigationView prevent selecting item, setCheckedItem not working inside onNavigationItemSelected

This is the code in onNavigationItemSelected
R.id.nav_subscribed -> {
if (prefs.getLong("userid", 0L) == 0L) {
when (currentGal) {
"top" -> {
// navView.setCheckedItem(R.id.nav_top)
// navView.menu.getItem(R.id.nav_top).isChecked = true
}
}
val i = Intent(this, Login::class.java)
this.startActivity(i)
} else {
if(currentGal != "subscriptions"){
getMemes("subscriptions", 0)
}
}
}
I try to prevent nav_subscribed to be checked when the user isn't logged in and check/keep checked nav_top
navView.setCheckedItem(R.id.nav_top)
isn't working and
navView.menu.getItem(R.id.nav_top).isChecked = true
crashed the app. So how to do this? Btw android is awful broken garbage software
navigationView?.setOnNavigationItemSelectedListener {
when (it.itemId) {
R.id.nav_subscribed -> {
// if you don't want an item to be selected return false
return#setOnNavigationItemSelectedListener false
}
R.id.nav_top -> {
}
}
//return true to select the other items
true
}

How it is possible using Kotlin function features make this piece of code nicer?

I have these piece of codes and I don't like that I have mapNotNull and inside I have else cases which returns null, I think my kotlin knowledge is not enough to make it better, any thoughts?
return config.mainMenus.mapNotNull { mainMenu ->
val subPage = config.subPages.find {
if (mainMenu.actions.isNotEmpty()) {
it.id == mainMenu.actions.first().contentId
} else {
false
}
}
if (subPage?.items?.isNotEmpty() != null) {
MenuItem(mainMenu.type, mainMenu.titles, mainMenu.actions[0].type, subPage.items)
} else {
null
}
}
}
val programs = cards.mapNotNull { card ->
if (card is Program) {
epgRepository.getProgramProgress(currentTime = currentTime, program = card)
} else {
null
}
}
You can replace the previous code with
return config.mainMenus.mapNotNull { mainMenu ->
config.subPages
.find{mainMenu.actions.firstOrNull()?.contentId?.equals(it.id)?:false}
?.let{menu->
MenuItem(mainMenu.type, mainMenu.titles, mainMenu.actions[0].type, menu.items).takeIf{menu.items?.isNotEmpty()==true}
}?:null
}
}
Te second one could be
val programs = cards.
filterIsInstance<Program>().
map { epgRepository.getProgramProgress(currentTime = currentTime, program = card)}
In this case you firstly filter the collection getting only the elements that are programs and only those are converted to the type that the function getProgramProcess return

Categories

Resources