Here i have a spinner and some text fields below the spinner. when one of the text field has focus, i select an item from spinner and i see the focus is still on that text field, Now what i want to do is, on spinner item selected i want to change focus from that text field to the spinner.
Is there any way to set focus to spinner?like,
#Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
//set focus to the spinner
}
}
I had a similar problem and found part of the answer here.
However, I also had to set focusable(true) and focusableInTouchMode(true) from my code and not the XML file. I couldn't get it to work until I set the focusable properties in the code. Here is a sample from my project:
spinUoM.setFocusable(true);
spinUoM.setFocusableInTouchMode(true);
spinUoM.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus)
DialogDefineRecipeActivity.this.spinUoM.performClick();
}
});
worked in my case doing
#Override
public void onItemSelected(final AdapterView<?> parent, View view,
final int position, long id) {
parent.post(new Runnable() {
#Override
public void run() {
spinner.requestFocusFromTouch();
}
});
}
Related
I am working on a project which uses a TableLayout, and the user can add a new row to the table layout. Each new row is inflated as a new view and then the view is added to the table layout. One of the controls within the row is an AutoCompleteTextView.
The user can start typing into the AutCompleteTextView and then select one of the items in the suggestion list, when the user selects the item, the selected item is added to the text box as expected, but I want to then set the cursor position as the user can then change the value of the text. For example, the selected item might be sometext() but they can amend the text after selecting it to become sometext(25), so I am trying to set the position of the cursor within the brackets.
This is working fine for one AutoCompleteTextView in the layout but I can't figure out how to do it when its dynamically generated.
I'm finding the AutoCompleteTextView from the inflated layout and creating a set on item click listener, and using the view parameter in the OnItemClick function to ensure I am using the correct view that triggered the event handler, but on the setSelection I am getting an exception java.lang.ClassCastException: android.support.v7.widget.AppCompatTextView cannot be cast to android.widget.AutoCompleteTextView
Below is the code I am using:
private void addRow()
{
TableRow row = (TableRow)LayoutInflater.from(this).inflate(R.layout.create_table_column_row, createTable, false);
txtColumnName = row.findViewById(R.id.txtColumnName);
txtDataType = row.findViewById(R.id.txtDataType);
txtDataType.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
txtDataType.showDropDown();
}
});
txtDataType.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
String selectedItem = parent.getItemAtPosition(position).toString();
//Check if the string has a ( and if so, set the cursor to be just after it so the user can enter the size
int bracketPos = selectedItem.indexOf("(");
if (bracketPos > 0)
{
//Crashes on this line
((AutoCompleteTextView)view).setSelection(bracketPos+1);
}
}
});
List<String> datatypes = Arrays.asList(getResources().getStringArray(R.array.table_datatypes));
datatypeAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, datatypes);
txtDataType.setAdapter(datatypeAdapter);
rowViews.add(row);
createTable.addView(row);
}
I tried casting the view to AppCompatTextView but then this doesn't have the setSelection() method.
The view in onItemClick() is the AppCompatTextView that is clicked in the drop down box for the AutoCompleteTextView. That is why you can't cast it.
Since you have multiple AutoCompleteTextViews, use a focus change listener to capture which AutoCompleteTextView is being addressed by the user. You can then use that value to set the position of the cursor.
private AutoCompleteTextView textView;
private AutoCompleteTextView mAuto;
textView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
mAuto = (AutoCompleteTextView) v;
}
});
textView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("MainActivity", "<<<<onItemClicked");
int bracketPos = textView.getText().toString().indexOf("(");
if (bracketPos > 0) {
mAuto.setSelection(bracketPos + 1);
}
}
});
I believe that the AutoCompleteTextView is already populated when this method is called, so you could just search for ( within that field.
Here is a slightly different way. After
txtDataType = row.findViewById(R.id.txtDataType);
add
txtDataType.setOnClickListener(new View.OnClickListener() {
private AutoCompleteTextView mAutoView;
#Override
public void onClick(View v) {
mAutoView = (AutoCompleteTextView) v;
mAutoView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("MainActivity", "<<<<onItemClicked");
int bracketPos = mAutoView.getText().toString().indexOf("(");
if (bracketPos > 0) {
mAutoView.setSelection(bracketPos + 1);
}
}
});
}
});
You can delete your other listeners.
I am using the below code to get the value of the spinner and set it to the EditText tehsil but it doesn't work. The dropdown is working fine but the value is not setting the tehsil
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
//first spinner item position
int districtSpinnerPosition = spinnerdistrict.getSelectedItemPosition();
switch (districtSpinnerPosition) {
case 0: //1st item of 1st spinner selected
//fill data for second spinner
fillKharanTehsils();
////////////// Set EditText of Tehsil
tehsil.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View arg0, boolean hasFocus) {
// TODO Auto-generated method stub
if (hasFocus) {
spinnertehsil.setVisibility(View.VISIBLE);
}
}
});
You should do tehsil.setText("My text");
Is there a way to get the item position on Spinner Object by only focusing and not by OnItemSelected in Android?
Cause i need to add/increment an item when everytime the last item of spinner is focus..
Try this.It is working fine.
#Override
public void onItemSelected(final AdapterView<?> parent, View view,
final int position, long id) {
parent.post(new Runnable() {
#Override
public void run() {
spinner.requestFocusFromTouch();
long pos = spinner.getItemIdAtPosition(position+1);
Toast.makeText(getApplicationContext(), "Position : " +pos, Toast.LENGTH_SHORT).show();
}
});
}
I have a spinner named spinnerArray
hot can I get the selected item's ID of spinner by integer data type after click a button?
(when I have selected First one of spinner, I want to get integer 0,Second one,integer 1)
Use
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(final AdapterView<?> parent, final View view, final int position, final long id) {
// position is what you want i think
}
#Override
public void onNothingSelected(final AdapterView<?> parent) {
}
});
And to get the position when clicked on other views use spinner.getSelectedItemPosition();
You can do this in your button's onClick method:
mySpinner.getSelectedItemPosition() + 1;
getSelectedItemPosition() gives you the item position starting at 0, so you need to add 1.
i think you are looking for position in spinner
code sample
spinner.setOnItemSelectedListener(new OnItemSelectedListener()
{
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView,
int position, long id) {
// your code here
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
Are you looking to see when the items on the spinner have been clicked? Then OnItemSelectedListener will allow you to override onItemClick(AdapterView parent, View view, int position, long id).
I have a spinner in my Android app, and its onItemSelected() event automatically gets triggered upon entering the activity.
How do I avoid this?
We can use a flag, and just enable it when the spinner is really touched.
private boolean isSpinnerTouched = false;
spinner.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
isSpinnerTouched = true;
return false;
}
});
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapter, View arg1,
int arg2, long arg3) {
if (!isSpinnerTouched) return;
// do what you want
}
});
To add on Jerry Abraham, You should clear selection before enabling setOnItemSelectedListener
Spinner mSpinner=(Spinner)findViewById(R.id.mySpinner);
int initialSelectedPosition=mSpinner.getSelectedItemPosition();
mSpinner.setSelection(initialSelectedPosition, false); //clear selection
mSpinner.setOnItemSelectedListener(this); //set listener after clearing section
I have solved this issue,
You can avoid this issue by not setting any default values to the spinner
int initialposition=spinner.getSelectedItemPosition();
spinner.setSelection(initialposition, false);
This will avoid entering into onItemSelected()
There are no any way to avoid this.
You may add some flag, indicating readiness of your application and use it in your onItemSelected() method to decide, what to do in each case.
Well, you can add a dummy selection to the initial adapter, and ignore position number in the setOnItemSelectedListener. It's not pretty but it works. See this code for setting up the items for an array adapter.
List<String> names = new ArrayList<String>();
names.add("");
names.addAll(realValues);
Then in your setOnItemSelectedListener you can do this:
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
if (position > 0)
{
String name = names.get(position - 1);
}
else
{
Log.d(TAG, "selected nothing or perhaps the dummy value");
}
}
I have found a solution for this problem and posted it here (with code sample):
Spinner onItemSelected() executes when it is not suppose to
Simple and easy is this...
validate with a boolean to see if is first time...
Spinner mySpinner = (Spinner)findViewById(R.id.spinner_xml_pro);
mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
if(isSpinnerInitial){ // globar var boolean isSpinnerInitial = false;
//do something
}else
isSpinnerInitial=true;
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
Check this with spinner.post(new Runnable()...)
or this other my source
I think that you can use spinner position which is a better approach in my opinion.
Create a global variable where you store the spinner position, in onItemSelected method the position is provided you can compare them, if they are the same do not make an action.
private int spinnerPosition; \\ Global variable
mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
if(spinnerPosition != position){
// Do whatever you like
// Do not forget to save the new position
spinnerPosition = position;
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
You can avoid it by ignoring the first click by,
private boolean isSpinnerInitial = true; //As global variable
public void onItemSelected(xxx xxx, xxx xxx, xxx xxx, xxx xxx) {
if(isSpinnerInitial) {
isSpinnerInitial = false;
return;
}
// Write your code here
}