Currently I am using a string array to hold some data that is used by my adapter, but I need to use the data in a listof:
Currently I am using this:
<string-array name="vegetables">
<item> Onion </item>
<item> Chillis </item>
<item> Tomatoes </item>
<item> Garlic Beans</item>
This is the data format I need to use:
val VegName = listOf(
Veg(0, "Onion", R.drawable.onion),
Veg(1, "Chillis", R.drawable.chilli),
Veg(2, "Tomatoes (indoor)", R.drawable.tomatoe),
Veg(3, "Garlic", R.drawable.garlic)
)
The adapter code:
class SearchActivity : AppCompatActivity() {
private lateinit var toolbar: Toolbar
lateinit var adapter: ArrayAdapter<*>
private lateinit var listView: ListView
private lateinit var emptyView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.search_main)
title = "Search Veg"
toolbar = findViewById(R.id.toolbar)
listView = findViewById(R.id.listView)
emptyView = findViewById(R.id.emptyView)
adapter = ArrayAdapter<Any?>(this, android.R.layout.simple_list_item_1,
resources.getStringArray(R.array.vegetables))
adapter = ArrayAdapter<Any?>(this, android.R.layout.simple_list_item_1,
resources.getStringArray(R.array.vegetables)) // I THINK THIS IS WHERE IT NEEDS CHANGING?
listView.adapter = adapter
listView.onItemClickListener = OnItemClickListener { adapterView, _, i, _ ->
Toast.makeText(this@SearchActivity, adapterView.getItemAtPosition(i).toString(),
Toast.LENGTH_SHORT).show()
}
listView.emptyView = emptyView
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.nav_menu, menu)
menuInflater.inflate(R.menu.menu, menu)
val search = menu.findItem(R.id.appSearchBar)
val searchView : SearchView? = search?.actionView as SearchView?
searchView?.queryHint = "Search"
listView.setOnItemClickListener(OnItemClickListener { parent, view, position, id ->
val intent = Intent()
val theItemClicked = String()
Toast.makeText(this@SearchActivity, listView.getItemAtPosition(position).toString(),
Toast.LENGTH_SHORT).show()
intent.putExtra("result", listView.getItemAtPosition(position).toString() )
intent.putExtra("position", position.toString())
setResult(RESULT_OK, intent)
finish()
})
searchView?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
adapter.filter.filter(newText)
return true
}
})
return super.onCreateOptionsMenu(menu)
}
}
Any help on changing the data format would be really appreciated!
Cheers
2
Answers
You can build your list based on string-array data, and pass it to the adapter:
You can pull out the
Array
ofString
s by doingresources.getStringArray(R.array.vegetables)
, but then you still have to associate those strings with your other data (like its drawable). You’d need to store that data in another structure, and linking it to a particular string or index in the array is brittle.If you can, I’d recommend adding the strings as separate resources, and referencing them in the array:
Then your code can just reference those strings when you define each item and its related data:
and when you need to display that text, you can just
context.getString(veg.stringId)
with that ID property, same as how you’re providing a drawable ID when it needs to be displayed.If you don’t want to do that, or you can’t change the
Veg
class, you’ll have to define your data separately and then convert it (which you’d have to do if you were pulling from thestring-array
anyway). I like enums for this, I think it’s neat:That way you have one source of truth for the name of each thing, and everything that uses it can just reference that. You have the string array if you still need it, you have your
Veg
list, and they’re all just referencing the same string resources. If you ever update the strings it doesn’t matter, if you support multiple languages it just pulls the correct ones