XML code of spinner:
<Spinner
android:id="#+id/mySpinner"
https://stackoverflow.com/questions
style="#style/Widget.AppCompat.DropDownItem.Spinner"
android:layout_width="match_parent"
android:layout_height="70dp" />`
.kotlin:
val myStrings = arrayOf("One", "Two" , "Three", "Four")
mySpinner.adapter = ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, myStrings)
mySpinner.onItemSelectedListener = object :
AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("not implemented")
//To change body of created functions use File | Settings | File Templates.
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
TODO("not implemented")
//To change body of created functions use File | Settings | File Templates.
}
}}
Equal to the "hint" option in Edittext, I need a default text in a Spinner.
There is not any default way to display hint in spinner.
For this you need to add one item manually in the array like below.
val myStrings = arrayOf("Select","One", "Two" , "Three", "Four")
Now,
Define custom Adapter for the Spinner and disable the first item like below.
#Override
public boolean isEnabled(int position) {
if (position == 0) {
// Disable the first item from Spinner
// First item will be use for hint
return false;
} else {
return true;
}
}
You can change the color like below
#Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
View view = super.getDropDownView(position, convertView, parent);
TextView tv = (TextView) view;
if (position == 0) {
// Set the hint text color gray
tv.setTextColor(Color.GRAY);
} else {
tv.setTextColor(Color.BLACK);
}
return view;
}
For more info please visit:-
Add hint in spinner
Related
I'm trying to set a Background color for alternate items in my ListView. I'm doing the following in my Custom ArrayAdapter class:
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val currentExpense:Expense? = getItem(position)
itemExpenseListBinding = ExpensesRowDesignBinding.inflate(
LayoutInflater.from(context),
parent,
false)
val itemView = itemExpenseListBinding.root
// if(itemView == null){
// itemView = convertView as LinearLayout
// }
for ((index, item) in dataSource.withIndex()){
if (index%2 == 0){
itemExpenseListBinding.linearExpensesRow.setBackgroundColor(Color.parseColor("#FEF8DD")
)
}
}
However, I'm getting end up with Background color being set on all my rows. I would like to have it set on just the even number rows in my ListView.
Update: Fixed this doing the following:
if (position%2 == 0){
itemExpenseListBinding.linearExpensesRow.setBackgroundColor(Color.parseColor("#FEF8DD"))
}
Can't believe I missed the position parameter lol.
Long story short. I want my spinner to always show same first item "Add". When item selected from the list it should be gone from the list and the specific action happen. The text "Add" should still appear on spinner. So my question is how to make that spinner always show first item on his dataList? PS. I made that first item in the list don't show when drop down is open.
My layout:
<Spinner
android:id="#+id/spinner_add"
style="#style/Widget.AppCompat.Spinner.Underlined"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:backgroundTint="#color/colorButton" />
Method to set spinner adapter with data list:
private fun fillAddSpinner() {
val spinner: Spinner = findViewById(R.id.spinner_add)
val titles: MutableList<String> = ArrayList()
titles.add(resources.getString(R.string.add_advanced_filter))
for (filter in tableAdvancedFilters) {
titles.add(filter.title)
}
val dataAdapter = object : ArrayAdapter<String?>(this, R.layout.spinner_item,
titles as List<String?>
) {
override fun getDropDownView(
position: Int,
convertView: View?,
parent: ViewGroup
): View {
var v: View? = null
// If this is the initial dummy entry, make it hidden
if (position == 0) {
val tv = TextView(context)
tv.height = 0
tv.visibility = View.GONE
v = tv
} else { // Pass convertView as null to prevent reuse of special case views
v = super.getDropDownView(position, null, parent)
}
// Hide scroll bar because it appears sometimes unnecessarily, this does not prevent scrolling
parent.isVerticalScrollBarEnabled = false
return v!!
}
}
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = dataAdapter
}
I want it stay the same like it is now:
After user selects one item from spinner I will render specific filter choices.
If you want to programmatically set spinner selected item use the following: spinnerObject.setSelection(INDEX_OF_ITEM)
Is it possible to have an item in my spinner which is clickable but not selectable?
The scenario here is that i have a Category spinner and i want the user to input his category himself. So i want the "add Item" selection to appear at the end of the Spinner's list and make it clickable only. Can someone help ?
You can do one thing, in listener if you got last position by default select 0 position and do you click action whatever you want.
yourSpinner?.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onNothingSelected(parent: AdapterView<*>?) {
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
// if position == n, open dialog here
// and then
yourSpinner?.setSelectablePosition(0);
}
}
you can do like
txtTimeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if(position == last){
txtTimeSpinner.setSelection(0);
}else {
//your code here for selection
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
and array first position is as default like ("Select Time")
I know there have been several questions that dealt with the problem how to add the "Select one..." hint for the Spinner before the first selection is made. But that's not my case.
What I need is to display the hint only when the SpinnerAdapter is empty. By default in such case, nothing happens on click (but that is not the major problem), and most of all, the spinner doesn't display any text, so it looks like this, which obviously doesn't feel right:
Any idea how to simply handle this problem? I've come up with 2 possible solutions, but I don't like any of them very much:
If the SpinnerAdapter is empty, hide the Spinner from the layout and display a TextView with the same background as the Spinner instead.
Implement a custom SpinnerAdapter whose getCount() returns 1 instead of 0 if the internal list is empty, and at the same time, have its getView() return a TextView with the required "Empty" message, possibly grey-coloured. But that would require specific checking if the selected item is not the "Empty" one.
You can use this SpinnerWithHintAdapter class below
class SpinnerWithHintAdapter(context: Context, resource: Int = android.R.layout.simple_spinner_dropdown_item) :
ArrayAdapter<Any>(context, resource) {
override fun isEnabled(position: Int): Boolean {
return position != 0
}
override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
return (super.getDropDownView(position, convertView, parent) as TextView).apply {
if (position == 0) {
// Set the hint text color gray
setTextColor(Color.GRAY)
} else {
setTextColor(Color.BLACK)
}
}
}
fun attachTo(spinner: Spinner, itemSelectedCallback: ((Any?) -> Unit)? = null) {
spinner.apply {
adapter = this#SpinnerWithHintAdapter
itemSelectedCallback?.let {
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
val selectedItem = parent?.getItemAtPosition(position)
// If user change the default selection
// First item is disable and it is used for hint
if (position > 0) {
it(selectedItem)
}
}
}
}
}
}
}
How to use? Let's assume I have data class called City
data class City(
val id: Int,
val cityName: String,
val provinceId: Int
) {
/**
* By overriding toString function, you will show the dropdown text correctly
*/
override fun toString(): String {
return cityName
}
}
In the activity, initiate the adapter, add hint(first item), add main items, and finally attach it to your spinner.
SpinnerWithHintAdapter(this#MyActivity)
.apply {
// add hint
add("City")
// add your main items
for (city in cityList) add(city)
// attach this adapter to your spinner
attachTo(yourSpinner) { selectedItem -> // optional item selected listener
selectedItem?.apply {
if (selectedItem is City) {
// do what you want with the selected item
}
}
}
}
I have two spinners that trigger the onItemSelected event. The question is How can I know which one triggered such event ? So far I tried:
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
Log.d("form","onitemselected");
switch (view.getId()) {
case R.id.region_spinner:
Region r = (Region)sregions.getSelectedItem();
Log.d("form","regionid:" + r.id);
break;
case R.id.state_spinner:
Log.d("form","state id:");
break;
}
But only the first Log is displayed, so there's no match in the switch.
use:
switch(parent.getId()) {
...
}
instead is what you need.
The view in your parameter is the actual 'row' (i.e. the clicked child of spinner item), and the parent is the actual 'spinner' that you are after.
Use below code if you have multiple spinners in one activity and you are using onItemSelected override method
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (parent!!.id == R.id.spinner_1) {
// first spinner selected
} else if (parent!!.id == R.id.spinner_2) {
// second spinner selected
}
}
either you can use switch case
Spinner is a subclass of AdapterView. The parent object passed into the method is the spinner in which the item was selected.
At first in onCreate :
Spinner cit_for_bus, bus_number;
cit_for_bus = (Spinner) findViewById(R.id.cit_for_bus);
bus_number = (Spinner) findViewById(R.id.bus_number);
cit_for_bus.setOnItemSelectedListener(this);
bus_number.setOnItemSelectedListener(this);
don't forget to use :
you have to bind/tie spinners to onItemSelected
cit_for_bus.setOnItemSelectedListener(this);
bus_number.setOnItemSelectedListener(this);
and use implement for class :
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener
outSide of onCreate use this :
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
if (adapterView.getId() == R.id.cit_for_bus) {
Toast.makeText(getApplicationContext(), adapterView.getId() + "/ " + adapterView.getCount() + "/" + adapterView.getSelectedItem(), Toast.LENGTH_LONG).show();
} else if (adapterView.getId() == R.id.bus_number) {
Toast.makeText(getApplicationContext(), adapterView.getId() + "/ " + adapterView.getCount() + "/" + adapterView.getSelectedItem(), Toast.LENGTH_LONG).show();
}
}
If you import your XML on Kotlin you can use it as so:
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id:
Long) {
when (parent)
firstSpinner -> {
// first spinner selection
}
secondSpinner -> {
// second spinner selected
}
}
}