I am having problems scrolling up in a spinner to select the first item in a Robotium test case. Here is my code:
int pos = solo.getCurrentSpinners().get(0).getSelectedItemPosition();
solo.pressSpinnerItem(0, 0 - pos);
pos is 1 when I debug, but Robotium still presses the spinner on index 1 even though I order it to press on -1. What am I doing wrong?
Thanks
Markus
Seems they took those classes out now. Just ran into this myself but found a way to do this properly and generically.
// 0 is the first spinner in the layout
View view1 = solo.getView(Spinner.class, 0);
solo.clickOnView(view1);
solo.scrollToTop(); // I put this in here so that it always keeps the list at start
// select the 10th item in the spinner
solo.clickOnView(solo.getView(TextView.class, 10));
The API to use here with Robotium is rather flaky, so I decided to go down the direct API route:
instrumentation.runOnMainSync(new Runnable() {
#Override
public void run() {
Spinner spinner = (Spinner) solo.getView(resourceId);
spinner.setSelection(position, true);
}
});
This won't show you the popup of the Spinner, but it will select the desired item.
are you able just to get the view and call the perform click on it?
solo.getCurrentSpinners().get(0).performClick()
Related
Scenario:
my adapter supports two different view types: A & B
the adapter is notified about 100 items of type A - everything is rendered correctly
the adapter is notified about one item of type B insertion using
notifyItemRangeInserted at position 0 - this item is "invisible"
by default and in order to see it I have to manually scroll up.
How can I get this first item of type B "automatically" visible?
You can use this line of code after notify item of type B:
yourRecyclerView.smoothScrollToPosition(0);
using https://stackoverflow.com/a/54899984/8144663 only wont resolve your issue.
You will need to call smoothScrollToPosition() in the next frame like,
recyclerview.post(new Runnable() {
#Override
public void run() {
recycleview.smoothScrollToPosition(n);
}
});
I am writing an android app where I am using a grid view to display some items. I want to give users a configurable view where they can change the no of columns on the activity by clicking floating action button. I am changing the column no using
gridView.setNumColumns(selectedColumnNo);
This is working fine But the problem is if a user changes no of column after some scrolling the First Visible Position is set to the first item of the array list, so the user has to scroll the view again. Can someone please tell me where I am doing wrong. Or Is this the proper way to do this or should I use a different approach.
A code snippets will be helpful
Thanks.
Update::
currently I am using the bellow snippets
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int firstPosition = gv.getFirstVisiblePosition();
if(gv.getNumColumns()==2)
{
gv.setNumColumns(1);
gv.setSelection(firstPosition);
}
else {
gv.setNumColumns(2);
gv.setSelection(firstPosition);
}
}
});
Now the problem is on every 4th switch grid view is showing the first element of the arraylist
Right before you call setNumColumns(), save the GridView's first visible position:
int firstPosition = gridView.getFirstVisiblePosition();
Then, after you change the number of columns, pass that integer to setSelection():
gridView.setSelection(firstPosition);
"Selection", counter-intuitively, is not the same thing as "activation". It will ensure that the view is on-screen, but not visibly affect it in any other way.
My problem is - I've got an ExpandableListView and want to use Contextual Action Bar (CAB) on it's child items. The bad thing is - the group items are also get selected by long-click, which is bad for me. So is there any way to make them non-selectable while in ActionMode?
I tried to use onItemLongClick; tried onLongClick inside getGroupView. Tried some other tricks but failed.
If you find this impossible - maybe there is a way to make all the child items within the selected group be selected as well? That could be a solution, but I could not do that niether.
Thank you.
Solved.
What I did is the next:
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
boolean checked) {
int type = ExpandableListView.getPackedPositionType(id);
if (checked && type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
elvBankBranches.setItemChecked(position, false);
return;
}
}
When item is checked - I check if it is a grouop - and if it is - just uncheck it. Works fine.
Note! - when uncheck the item in code - this method onItemCheckedStateChanged will be triggered once again!
Hope it helps someone )
I have an issue with the Spinner in Android. Selecting an item from the dropdown will adjust the offset of that dropdown the next time it is opened. So for example if I choose item 100 in a 500 item dropdown, the next time I open the dropdown, item 100 will be at the top of the list. This is the behaviour I want.
There seems to be an issue when I combine the selector functionality with calling setSelection(int). With the following steps I seem to have broken the offset system on dropdown spinners.
Open the Spinner and select the second item.
Open the Spinner again and this time dismiss it without selecting anything.
Call setSelection(int) on the Spinner with a value greater than 2.
Open the Spinner a third time. Note that the offset is the same as back in Step 1.
I've taken a look at the code in Spinner and AdapterView, but I can't see anything public calls that I've missed. Is this a bug in Spinner or a bug in my code?
Did you try public void setSelection (int position, boolean animate)? I haven't tried it, but I think passing true as the second parameter should make the list scroll to the selected position. The other alternative is to calculate the scroll offset (item height x selected item position) and call setDropDownVerticalOffset.
Update: I tried modifying the Spinner example in API demos to use setSelection(7, true) and it seems to work when following the 4 steps you provided in your question. I just added a Handler and modified showToast as follows:
private final Handler handler = new Handler();
void showToast(CharSequence msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
handler.postDelayed(new Runnable(){
public void run() {
Toast.makeText(Spinner1.this, "auto setting", Toast.LENGTH_SHORT).show();
Spinner s2 = (Spinner) findViewById(R.id.spinner2);
s2.setSelection(7, true);
}
}, 5000);
}
I tested as follows:
open the second spinner and picking 'Venus' (the second selection).
open the second spinner, then press back to dismiss
after 5 seconds, the postDelayed call causes 'Neptune' (the seventh selection) to be selected
open the spinner and the offset is correct
I think you can solve that problem with sending List to Adapter. When an item selected, sort your List then use notifyDataSetChanged() function of adapter. When you called setSelection(int) function again sort your List and use notifyDataSetChanged() function.
I currently have a whole bunch of spinners in my application. I wasn't thinking much and for each spinner, the first index is filled with N/A. It's not a big deal, but I was hoping to make it a bit cleaner.
I was wondering if there was a way that instead of calling setSelection( index ), I wanted to know if there was a way to set a Spinner to have nothing selected.
Basically, I want the spinner to have a list of items within it, but display none of them until you click on it. I also don't want there to be a blank index at the top.
I think its quite possible that there is no way to do this, so if anyone is sure of this, please let me know.
Thanks.
Its better to put first position as blank, so that it can be seen as nothing selected.
spinners have to have a selected state. i would recommend having a "no selection" option
Another option is to have the bottom button selected and then set that one to be invisible (the reason i set the last one to selected is so that you dont have a chunk of blank space in your app as that looks a bit trashy):
case SPINNER_OPTION_FIRST:
yourSpinnerLabel.setVisibility(View.VISIBLE);
yourTextField.setVisibility(View.VISIBLE);
break;
// do this for all your other ones if you want
case SPINNER_OPTION_LAST:
yourSpinnerLabel.setVisibility(View.GONE);
yourTextField.setVisibility(View.GONE);
maybe not the most efficient but it works so i hope that helps (still new so cut me some slack)!
Modifying the list which holds data can lead lots of errors or tough to manage the data.
Instead of manipulating the list,you can add item in adapter with NONE item.
Like this
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
adapter.add("NONE");
adapter.addAll(products);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(adapter);
I tried
// getSelectedItemPosition() returns -1 if there is nothing selected
spinner.setSelection(-1);
but it failed [spinner was setting 1st element from list].
I added "empty position" to spinner data which mimics that "nothing is selected". Note that 'empty position' is not visible on 'drop down' list.
BTW. Sorry for C#, hope the concept is clearly visible.
Custom adapter:
class CustomAdapter<T> : ArrayAdapter<T> {
public override int Count {
get { return base.Count - 1; }
}
}
Init spinner:
var data = new List<string> { "elem 1", "elem 2", "" };
spinner.Adapter = new CustomAdapter<String>(this, Resource.Layout.SimpleSpinnerItem, data);
spinner.SetSelection(2);