In my project I use resource files with arrays of strings in them, then I get a single String and check if it is in this array, which doesn't work
Here's some code:
//putting an array from resource file into variable
val categoryOne: Array<String> = resources.getStringArray(R.array.categoryOne_array)
val values: Array<String> = resources.getStringArray(R.array.categories_array)
//getting the string from spinner
var text = "blank"
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
text = values[p2]
Log.d("ASDASD", text)
}
override fun onNothingSelected(p0: AdapterView<*>?) {
return
}
}
//checking if string is in the array
var currentGroup = "0"
if(categoryOne.contains(text)){
currentGroup = "1"
}
No matter what the value of "text" is, value of currentGroup stays 0
Here's the resource files also:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="categories_array">
<item>Бег. ОРУ</item>
<item>Кросс</item>
<item>Игры</item>
<item>Сил. упр.</item>
<item>Скор. эст.</item>
<item>Плавание</item>
<item>Борьба</item>
<item>Имит. упр</item>
<item>Упр. со скакалкой</item>
<item>Упр. с эспандером</item>
<item>Бой с тенью</item>
<item>Имит. упр. с утяж.</item>
<item>Упр. с медболом</item>
<item>Прыжковая работа</item>
<item>Стрейчинг</item>
<item>Отр. со слабым парт.</item>
<item>Отр. с сильным парт.</item>
<item>Слабый партнер</item>
<item>Сильный партнер</item>
<item>Мешки</item>
<item>Подушки</item>
<item>Груши</item>
<item>Лапы</item>
<item>Вольные бои</item>
<item>Спаринг</item>
<item>Соревн. бои</item>
</string-array>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="categoryOne_array">
<item>Бег. ОРУ</item>
<item>Кросс</item>
<item>Игры</item>
<item>Сил. упр.</item>
<item>Скор. эст.</item>
<item>Плавание</item>
<item>Борьба</item>
<item>Имит. упр</item>
<item>Упр. со скакалкой</item>
<item>Упр. с эспандером</item>
<item>Бой с тенью</item>
<item>Имит. упр. с утяж.</item>
<item>Упр. с медболом</item>
<item>Прыжковая работа</item>
<item>Стрейчинг</item>
</string-array>
</resources>
I hope I shared all code relevant to the question, if I didn't, please tell me and I shall provide it
Problem is "contains" is also case-sensitive. You have to use ignore case.
Something like
val array:Array<String> = resources.getStringArray(R.array.yourarray);
val test = "two"
for(item in array) {
if(item.equals(test, ignoreCase = true)) {
return true
}
}
Related
I am trying to discriminate the selected item of a Spinner by its (multilanguage) text.
Here is my default strings.xml content:
<string-array name="spinner_items">
<item>length</item>
<item>weight</item>
<item>temperature</item>
</string-array>
And this is another strings.xml (Italian language) content:
<string-array name="spinner_items">
<item>lunghezza</item>
<item>peso</item>
<item>temperatura</item>
</string-array>
I set up my Spinner items in this way:
val items = resources.getStringArray(R.array.spinner_items)
spinner.adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, items)
And then I add the item selected listener:
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
when(spinner.getItemAtPosition(position).toString()) {
"length" -> actionLength()
"lunghezza" -> actionLength()
"weight" -> actionWeight()
"peso" -> actionWeight()
"temperature" -> actionTemperature()
"temperatura" -> actionTemperature()
}
}
override fun onNothingSelected(parent: AdapterView<*>) {}
}
Everything works fine but the problem is that everytime I add a new language locale, I have to remember to add the specific string translation inside the when block.
Is there a more "dynamic" way to do this?
I had the same problem in the past and here is how I solved it.
Edit your strings.xml files by adding a string resource name for each items in your array, for example:
Default strings.xml
<string name="length">length</string>
<string name="weight">weight</string>
<string name="temperature">temperature</string>
<string-array name="spinner_items">
<item>#string/length</item>
<item>#string/weight</item>
<item>#string/temperature</item>
</string-array>
Italian strings.xml
<string name="length">lunghezza</string>
<string name="weight">peso</string>
<string name="temperature">temperatura</string>
<string-array name="spinner_items">
<item>#string/length</item>
<item>#string/weight</item>
<item>#string/temperature</item>
</string-array>
So in your code, you'll have:
when(spinner.getItemAtPosition(position).toString()) {
getString(R.string.length) -> actionLength()
getString(R.string.weight) -> actionWeight()
getString(R.string.temperature) -> actionTemperature()
}
I hope I was helpful!
Just use the position:
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
when(position) {
0 -> actionLength()
1 -> actionWeight()
2 -> actionTemperature()
}
}
override fun onNothingSelected(parent: AdapterView<*>) {}
}
In your array use:
<string-array name="spinner_items">
<item>#string/length</item>
<item>#string/weight</item>
<item>#string/temperature</item>
</string-array>
How do I change the value of a variable using the spinner widget.
strings.xml
<string name="selected_item">Selected item:</string>
<string-array name="Languages">
<item>English</item>
<item>Latin</item>
<item>French</item>
</string-array>
mainactivity
val spinner = findViewById<Spinner>(R.id.spinner)
if (spinner != null) {
val adapter = ArrayAdapter(
this,
android.R.layout.simple_spinner_item, languages
)
spinner.adapter = adapter
spinner.onItemSelectedListener = object :
AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>,
view: View, position: Int, id: Long
) {
//what to do here?
}
}
}
suppose I want to change the value of this variable
strokeManager.lang = "en"
So you will want to use the position to access it from the list that you used to populate the spinner.
strokeManager.lang = languageMapToLangCode[languages.get(position)]
This should be defined in your class somewhere the spinner can access it
val languageMapToLangCode: HashMap<String, String> = hashMapOf("French" to "fr", "Latin" to "ln", "English to "en")
I'm updating the font size of all the texts on the app, what I want to achieve is, when I select the font size, i should be able to update the font sizes of all the texts on that activity.
My only problem is i can't find the size property on the Spinner Object.
This is what I did for Text Views, is it possible to apply a code similar to this one for Spinners ?
const val HEADER_TEXT = 24
const val NORMAL_TEXT = 14
private fun updateAssetSize(textView: TextView, additionalSize: Int, type: Int) {
val size = additionalSize + type
textView.setTextSize(COMPLEX_UNIT_SP, size.toFloat());
}
//calling the method:
updateAssetSize(screenText, additionalFontSize, HEADER_TEXT)
Note: This should be done from code, since this will be updated on run time.
Based on #Zain Suggestion, I resolved this by using an adapterlist object. Instead of using String I created a custom class with fontSize and text properties in it.
class SpinnerItem(
val text: String,
var fontSize: Int
) {
// this is necessary, in order for the text to display the texts in the dropdown list
override fun toString(): String {
return text
}
}
Here's the AdapterList that I created:
class SpinnerItemListAdapter(
context: Context,
val resourceId: Int,
var list: ArrayList<SpinnerItem>
) : ArrayAdapter<SpinnerItem>(context, resourceId, list) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val text = this.list[position].text
val size = this.list[position].fontSize
val inflater = LayoutInflater.from(context)
val convertView = inflater.inflate(resourceId, parent, false)
val simpleTextView = convertView.findViewById(R.id.simpleTextView) as TextView
simpleTextView.text = text
simpleTextView.setTextSize(size.toFloat())
return convertView
}
// We'll call this whenever there's an update in the fontSize
fun swapList(list: ArrayList<SpinnerItem>) {
clear()
addAll(list)
notifyDataSetChanged()
}
}
Here's the custom XML File spinner_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/simpleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:padding="12dp"
android:textSize="16sp" />
The Spinner to be updated:
var fontSizes = arrayListOf(
SpinnerItem("Small", NORMAL_TEXT, "Default"),
SpinnerItem("Normal", NORMAL_TEXT, "Default"),
SpinnerItem("Large", NORMAL_TEXT, "Default"),
SpinnerItem("Largest", NORMAL_TEXT, "Default")
)
var fontSizeAdapterItem = SpinnerItemListAdapter(
this,
R.layout.spinner_item,
toSpinnerItemList(fontSizes, newSize)
)
Here's What will happen when we update it:
private fun updateSpinnerSize(additional: Int) {
val newSize = additional + NORMAL_TEXT
fontSizes = toSpinnerItemList(fontSizes, newSize)
fontSizeAdapterItem?.let {
it.swapList(fontSizes)
}
}
private fun toSpinnerItemList(
list: ArrayList<SpinnerItem>,
newSize: Int
): ArrayList<SpinnerItem> {
val itemList = ArrayList<SpinnerItem>()
for (item in list) {
item.fontSize = newSize
itemList.add(item)
}
return itemList
}
Ok from the Start, I have a RecyclerView where I want to change the color of the entries, if they are clicked.
The Recyclerview gets a list from a database, where I added a bool value, if the View is selected.
In my holder I check if the view is selected and change the color with a selector.
So far so good, but now there is the problem.
The Activity Starts, the old selected Entry is colored, but when I click on an other Entry the color of the old entry disappears and on the one tapped nothing happens. I have to reclick on the old entry again and from this point the color changing works fine.
method called in viewHolder
itemView.view_foreground_nav.isSelected = (table.isSelected)
selector
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#android:color/darker_gray"
android:state_pressed="true"/>
<item
android:drawable="#android:color/darker_gray"
android:state_selected="true"/>
<item
android:drawable="#android:color/darker_gray"
android:state_focused="true"/>
<item android:drawable="#android:color/white"/>
</selector>
RelativeLayout from viewholder where color should changed
android:id="#+id/view_foreground_nav"
android:layout_width="match_parent"
android:layout_height="#dimen/ic_delete"
android:background="#drawable/recycler_nav_item_background">
variable in the Activity which is set in onCreate
private var selectedTable: Table? = null
onClick Method
if (selectedTable != null) {
var oldSelectedTable = selectedTable
oldSelectedTable?.isSelected = false
productViewModel.updateTable(oldSelectedTable!!)
data.isSelected = true
productViewModel.updateTable(data)
selectedTable = data
} else {
data.isSelected = true
productViewModel.updateTable(data)
selectedTable = data
}
button_add_note.isEnabled = true
observerProduct(selectedTable)
Diffutil
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int):Boolean{
return oldListTable[oldItemPosition].idTable == newListTable[newItemPosition].idTable
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldListTable[oldItemPosition].title == newListTable[newItemPosition].title&&
oldListTable[oldItemPosition].isSelected == newListTable[newItemPosition].isSelected
}
The ProductViewModel is a lateinit in the MainActivity
private lateinit var productViewModel: ProductViewModel
In OnCreate I set the ViewModel
productViewModel =
ViewModelProviders.of(this).get(ProductViewModel::class.java)
GenericAdapter Call
private fun observerTable() {
productViewModel.getAllTables().observe(this, Observer<List<Table>> { it ->
adapterNav.setItems(it as MutableList<Any>)
})
}
Table Dao
#Query("Select * from main_table")
fun getAllTables(): LiveData<MutableList<Table>>
ProductRepro
private var tableDao: TableDao
private var allTables: LiveData<MutableList<Table>>
init {
var database: ProductDatabase? = ListMasterApplication.database
this.tableDao = database!!.tableDao()
this.allTables = tableDao.getAllTables()
}
var database: ProductDatabase? = ListMasterApplication.database
fun getAllTable(): LiveData<MutableList<Table>> {
return allTables
}
ProductVieModel
private var productRepository: ProductRepository = ProductRepository()
private var liveDataTable: LiveData<MutableList<Table>>
init {
this.liveDataTable = productRepository.getAllTable()
}
fun getAllTables():LiveData<MutableList<Table>>{
return liveDataTable
}
Observer in MainActivity
private fun observerTable() {
productViewModel.getAllTables().observe(this, Observer<MutableList<Table>> { it ->
adapterNav.setItems(it as MutableList<Any>)
})
}
In GenericAdapter set Items
fun setItems(items: MutableList<T>) {
val diffCallback = DiffCallback(listItems ,items)
val diffResult = DiffUtil.calculateDiff(diffCallback)
listItems.clear()
listItems.addAll(items)
diffResult.dispatchUpdatesTo(this)
}
I logged my Diffutil and on each click on different items the Log was
always correct. I logged the selected table variable an it is always
correct.
I don't know where to go from this point. It only happens in the start
of the activity and then it works fine. Do you have some hints or
something, which i could try. If you need some more insight of the
code, let me know and I publish more.
I have to create offline app and I want to attach the profile image along the contact name and place the first letter of the as the profile image.But I do not understand how to code this.
I have searched but found nothing.
1.
class Inbox : AppCompatActivity(){
private val requestReceiveSms: Int =1
private val requestReadSms: Int = 2
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.readsms)
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.SEND_SMS) !=
PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this, arrayOf(android.Manifest.permission.SEND_SMS,android.Manifest.permission.READ_CONTACTS),
requestReadSms
)
} else {
refreshSmsInbox()
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>,
grantResults: IntArray) {
if(requestCode == requestReadSms) refreshSmsInbox()
}
private fun refreshSmsInbox() {
val smsList = ArrayList<SmsData>()
val cursor = contentResolver.query(Uri.parse("content://sms/inbox"),null,null,null,null)
if(cursor!!.moveToFirst()){
val nameID = cursor.getColumnIndex("address")
val messageID = cursor.getColumnIndex("body")
val dateID = cursor.getColumnIndex("date")
do{
val dateString = cursor.getString(dateID)
smsList.add(SmsData(cursor.getString(nameID),cursor.getString(messageID),Date(dateString.toLong()).toString()))
}while (cursor.moveToNext())
}
cursor.close()
val adapter = ListAdapter(this, smsList)
sms_list_view.adapter = adapter
}
}
XML FILE
2.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/sms_list_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="6"
tools:ignore="Suspicious0dp"></ListView>
</LinearLayout>
Expected
Profile image along with contact name.
Actual Result
Just contact name.
You can place a TextView in the ListView's item layout. Now we set a circular coloured background to this TextView. First, we define a background drawable for our TextView,
profile_background.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="#android:color/holo_blue_bright"/>
</shape>
</item>
</selector>
We set this background to a TextView in the ListView's item layout.
listview_item_layout.xml
<TextView
android:id="#+id/profile_text"
android:layout_width="56dp"
android:layout_height="56dp"
android:background="#drawable/sample"
/>
Now, we need to set the first letter of the nameId to this TextView,
val firstLetter = nameId.subString( 0 , 1 ).toUpperCase()
profile_text.text = firstLetter