-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement autocompleteDropDownMenu #37
base: master
Are you sure you want to change the base?
Changes from 8 commits
40f8a02
f0c0362
5da6470
6236bce
3eac721
a262a39
b4607c2
3952bd9
c2e8f8a
584d338
a27bccf
8270927
a710d93
5e97bd7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package com.skyyo.samples.features.autoComplete | ||
|
||
import android.widget.ArrayAdapter | ||
import android.widget.AutoCompleteTextView | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.platform.LocalContext | ||
import androidx.compose.ui.viewinterop.AndroidView | ||
import com.google.android.material.textfield.TextInputLayout | ||
import com.skyyo.samples.R | ||
|
||
@Composable | ||
fun AndroidViewTextFieldWithDropDownSample( | ||
modifier: Modifier = Modifier, | ||
suggestions: List<String>, | ||
selectedValue: String = "", | ||
onSelect: (Int) -> Unit = {}, | ||
) { | ||
val context = LocalContext.current | ||
val adapter = remember(suggestions) { | ||
ArrayAdapter(context, android.R.layout.simple_list_item_1, suggestions) | ||
} | ||
val textInputLayout = remember { | ||
(TextInputLayout.inflate( | ||
context, | ||
R.layout.text_input_field, | ||
null | ||
) as TextInputLayout).also { til -> | ||
(til.editText as AutoCompleteTextView).setOnItemClickListener { _, _, index, _ -> | ||
onSelect(index) | ||
} | ||
} | ||
} | ||
val autoCompleteTextView = remember { textInputLayout.editText as? AutoCompleteTextView } | ||
|
||
AndroidView( | ||
modifier = modifier, | ||
factory = { textInputLayout }, | ||
update = { | ||
autoCompleteTextView?.setAdapter(adapter) | ||
autoCompleteTextView?.setText(selectedValue, false) | ||
}, | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package com.skyyo.samples.features.autoComplete | ||
|
||
import androidx.compose.foundation.layout.* | ||
import androidx.compose.material.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.collectAsState | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.unit.dp | ||
import androidx.hilt.navigation.compose.hiltViewModel | ||
|
||
@Composable | ||
fun AutoCompleteScreen( | ||
viewModel: AutoCompleteViewModel = hiltViewModel() | ||
) { | ||
val query = viewModel.query.collectAsState() | ||
val isExpanded = viewModel.isExpanded.collectAsState() | ||
val suggestions = viewModel.suggestions.collectAsState() | ||
|
||
Column( | ||
Modifier | ||
.fillMaxSize() | ||
.padding(top = 32.dp, start = 16.dp, end = 16.dp), | ||
horizontalAlignment = Alignment.CenterHorizontally | ||
) { | ||
Spacer(modifier = Modifier.height(16.dp)) | ||
Text(text = "AndroidView") | ||
AndroidViewTextFieldWithDropDownSample( | ||
modifier = Modifier.fillMaxWidth(), | ||
suggestions = viewModel.countries, | ||
selectedValue = "", | ||
) | ||
Spacer(modifier = Modifier.height(16.dp)) | ||
Text(text = "Native exposed dropdown menu") | ||
NativeExposedDropDownMenuSample( | ||
modifier = Modifier.fillMaxWidth(), | ||
countries = viewModel.countries | ||
) | ||
Spacer(modifier = Modifier.height(60.dp)) | ||
Text(text = "Custom exposed dropdown menu") | ||
CustomExposedDropdownMenuSample( | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.padding(horizontal = 32.dp), | ||
onSuggestionSelected = viewModel::onCountrySelected, | ||
onExpandedChange = viewModel::onExpandedChange, | ||
onValueChange = viewModel::onCountryEntered, | ||
onClick = viewModel::onExpandedFieldClick, | ||
suggestions = suggestions.value, | ||
expanded = isExpanded.value, | ||
query = query.value, | ||
) | ||
Spacer(modifier = Modifier.height(16.dp)) | ||
Text(text = "AndroidView") | ||
AndroidViewTextFieldWithDropDownSample( | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.padding(horizontal = 32.dp), | ||
suggestions = viewModel.countries, | ||
selectedValue = "", | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.skyyo.samples.features.autoComplete | ||
|
||
import androidx.lifecycle.SavedStateHandle | ||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import com.skyyo.samples.extensions.getStateFlow | ||
import dagger.hilt.android.lifecycle.HiltViewModel | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.launch | ||
import java.util.* | ||
import javax.inject.Inject | ||
|
||
@HiltViewModel | ||
class AutoCompleteViewModel @Inject constructor( | ||
handle: SavedStateHandle | ||
) : ViewModel() { | ||
|
||
val countries = provideCountries() | ||
val query = handle.getStateFlow(viewModelScope, "query", "") | ||
val suggestions = handle.getStateFlow(viewModelScope, "suggestions", countries) | ||
val isExpanded = handle.getStateFlow(viewModelScope, "isExpanded", false) | ||
|
||
fun onCountryEntered(input: String) { | ||
query.value = input | ||
|
||
viewModelScope.launch(Dispatchers.Default) { | ||
suggestions.value = if (input.isEmpty()) { | ||
countries.also { onExpandedChange(false) } | ||
} else { | ||
val filteredList = countries.filter { country -> | ||
country | ||
.lowercase() | ||
.startsWith(input.lowercase()) && country != input | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. seems we are not using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we actually use: handle[SUGGESTIONS] = if (input.isEmpty()) countries else ... filteredList |
||
filteredList.also { onExpandedChange(true) } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there any reason not to do |
||
} | ||
} | ||
} | ||
|
||
fun onExpandedChange(value: Boolean) { | ||
isExpanded.value = value | ||
} | ||
|
||
fun onCountrySelected(value: String) { | ||
query.value = value | ||
} | ||
|
||
fun onExpandedFieldClick() { | ||
onExpandedChange(!isExpanded.value) | ||
} | ||
|
||
private fun provideCountries(): List<String> { | ||
val locales = Locale.getAvailableLocales() | ||
val countries = ArrayList<String>() | ||
for (locale in locales) { | ||
val country: String = locale.displayCountry | ||
if (country.trim { it <= ' ' }.isNotEmpty() && !countries.contains(country)) { | ||
countries.add(country) | ||
} | ||
} | ||
countries.sort() | ||
|
||
return countries | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
? can be deleted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
about suggestions - I'll check