I am trying to verify TextView of an app which shows the price of the products listed when a category is searched.
I am using Robotium for automation.
The hierarchy when i get the current view (solo.getCurrentViews(ListView.class)) is something like:
ListView
--> (0)FrameLayout
--> (1)RelativeLayout
--> (0)ImageView
--> (1)RelativeLayout
-->(0)ImageView
-->(1)TextView //id - name
-->(2)TextView //id - price
-->(3)TextView //id - other
--> (2)RelativeLayout
--> (0)ImageView
--> (1)RelativeLayout
-->(0)ImageView
-->(1)TextView //id - name
-->(2)TextView //id - price
-->(3)TextView //id - other
--> (3)RelativeLayout
--> (0)ImageView
--> (1)RelativeLayout
-->(0)ImageView
-->(1)TextView //id - name
-->(2)TextView //id - price
-->(3)TextView //id - other
--> (4)RelativeLayout
--> (0)ImageView
--> (1)RelativeLayout
-->(0)ImageView
-->(1)TextView //id - name
-->(2)TextView //id - price
-->(3)TextView //id - other
--> (5)RelativeLayout
--> (0)ImageView
--> (1)RelativeLayout
-->(0)ImageView
-->(1)TextView //id - name
-->(2)TextView //id - price
-->(3)TextView //id - other
I could figure out two ways of getting the price:
Traverse through children of list view and get to the price via index. Like below code
int index = 1;
ListView view = null;
List<ListView> productList = solo.getCurrentViews(ListView.class);
view = productList.get(0);
for (int i = 1; i < view.getChildCount(); i++) {
RelativeLayout relativeLayoutDetails = (RelativeLayout) view.getChildAt(index++); // get the first RelativeLayout
RelativeLayout productDetails = (RelativeLayout) relativeLayoutDetails.getChildAt(2); //get the inner child RelativeLayout
TextView productName = (TextView) productDetails.getChildAt(0);
System.out.println("********" + productDetails.getChildCount());
TextView price = (TextView) productDetails.getChildAt(2);
System.out.println(productName.getText().toString() + "---"+ price.getText().toString());
}
The problem with this code is TextView price = (TextView) hotelDetails.getChildAt(2); doesn't give me price but gives me other TextView (Don't know why). Also this works only for current views. I am not able to scroll down the complete list and get details for each and every product.
Second is, getting all the TextViews for current views and filter them based on the price id. Something like below:
ListView l = (ListView) solo.getView(android.R.id.list);
int viewShown = l.getChildCount();
int total = l.getCount();
int i;
int index=1;
if (hotelsShown != 0) {
for (i = 0; i < total / viewShown; i++) {
List<TextView> textViews = solo.getCurrentViews(TextView.class, l); //get all the text views
//filter for price
for(TextView priceView: textViews){
if(priceView.id equals "price-id")
//get this TextView.
}
solo.scrollDown();
solo.sleep(500);
}
The problem I am facing with this approach is i don't know how do i filter those views based on the ID. Also, while scrolling, this skips one or two products from current views and am not able to fix that.
If someone could suggest something on this, that would be great.
I will refer to one of my earlier answers which you can use to get you a view at the index of a list here.
Once you have this you can combine the function with a new one that get all the child elements of a view:
private List<View> getAllChildren(View v) {
if (!(v instanceof ViewGroup)) {
ArrayList<View> viewArrayList = new ArrayList<View>();
viewArrayList.add(v);
return viewArrayList;
}
ArrayList<View> result = new ArrayList<View>();
ViewGroup viewGroup = (ViewGroup) v;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
ArrayList<View> viewArrayList = new ArrayList<View>();
viewArrayList.add(v);
viewArrayList.addAll(getAllChildren(child));
result.addAll(viewArrayList);
}
return result;
}
and then finally the last one is to filter a list of views by id
public View(List<View> views, int idToMatch) {
for (View view : views) {
if (view.getId() == idToMatch) {
return view;
}
}
return null;
}
You can probably figure out hwo to combine these all into one function that will do what you want nicely. (Hint an R.id.price is an integer so just pass that into the last functon once you have th elist of children at the index you wanted to get)
Related
IN my Activity class i get child of Recyclerview like:
final int itemsCount = recly_list_lab.getChildCount();
but it gave me 7 item count but i have 10 item then how to get 10 items in Main Activity
this my code for getting child item for recyclerView:
final int itemsCount = recly_list_lab.getChildCount();
Log.e("itemsCount::",itemsCount+"");
if (itemsCount != 0) {
try {
for (int i = 0; i <itemsCount; i++) {
final View viewtestcategoryname = recly_list_lab.getChildAt(i);
AutoCompleteTextView autoctv_testcategory = (AutoCompleteTextView) viewtestcategoryname.findViewById(R.id.autoctv_testcategory);
String TestCategoryName = autoctv_testcategory.getText().toString();
Log.e("TestCategoryname:",TestCategoryName);
AutofitRecyclerView grid_labreferal_checkboxes_test = (AutofitRecyclerView) viewtestcategoryname.findViewById(R.id.grid_labreferal_checkboxes_test);
final int itemcheckTestCount = grid_labreferal_checkboxes_test.getChildCount();
Log.e("itemcheckTestCount:",itemcheckTestCount+"");
RecyclerView recly_testsubcategory = (RecyclerView) viewtestcategoryname.findViewById(R.id.recly_testsubcategory);
final int itemSubCategoryName = recly_testsubcategory.getChildCount();
Log.e("itemSubCategoryName:",itemSubCategoryName+"");
for (int test_check = 0; test_check < itemcheckTestCount; test_check++) {
final View viewTestCheck = grid_labreferal_checkboxes_test.getChildAt(test_check);
CheckBox grid_labreferal_checkbox = (CheckBox) viewTestCheck.findViewById(R.id.grid_labreferal_checkbox);
TextView txt_item_id = (TextView) viewTestCheck.findViewById(R.id.txt_item_id);
if (grid_labreferal_checkbox.isChecked()) {
Log.e("%sgrid_lcheckbox", grid_labreferal_checkbox.getText().toString());
if (txt_item_id != null && txt_item_id.getText().toString().trim().length() != 0) {
}
}
}
for (int subcatname = 0; subcatname< itemSubCategoryName; subcatname++){
final View SubCategory = recly_testsubcategory.getChildAt(subcatname);
AutoCompleteTextView autoctv_testsubcategory = (AutoCompleteTextView) SubCategory.findViewById(R.id.autoctv_testsubcategory);
Log.e("subcategoryname::",autoctv_testsubcategory.getText().toString());
AutofitRecyclerView grid_labreferal_checkboxes_subtest= (AutofitRecyclerView) SubCategory.findViewById(R.id.grid_labreferal_checkboxes_subtest);
final int itemcheckSubtestCount = grid_labreferal_checkboxes_subtest.getChildCount();
Log.e("itemcheckTestCount:",itemcheckSubtestCount+"");
for (int test_check = 0; test_check < itemcheckSubtestCount; test_check++) {
// jsonObjectMulti = new JSONObject();
final View viewTestCheck = grid_labreferal_checkboxes_subtest.getChildAt(test_check);
CheckBox grid_labreferal_checkbox = (CheckBox) viewTestCheck.findViewById(R.id.grid_labreferal_checkbox);
TextView txt_item_id = (TextView) viewTestCheck.findViewById(R.id.txt_item_id);
if (grid_labreferal_checkbox.isChecked()) {
Log.e("%sgrid_subtestcheckbox", grid_labreferal_checkbox.getText().toString());
if (txt_item_id != null && txt_item_id.getText().toString().trim().length() != 0) {
//testUpload.put(txt_item_id.getText().toString().trim(), grid_labreferal_checkbox.getText().toString().trim());
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
views inside the recyler view may be less than the total number of item inside the view as views will get recycled and reused to display multiple items.
You can use adapter.getItemCount() method to know how many view item will be displayed inside recyler view.
Not all adapter items are attached to the parent. The getChildCount() method returns the number of views displayed. If you want to get the item count of the adapter, you have to query the adapter for it.
final int itemsCount = recly_list_lab.getAdapter().getItemCount();
But considering your code, you're just miss-using the RecyclerView. You're not supposed to access child views of the recycler directly. Everything you need to do with it should go through the adapter and the view holders!
RecyclerView doesn't hold views for all list items in memory, it only has for example - 7 in your case. When you scroll, it reuses those 7 views for displaying different items. The purpose of this is improving the rendering performance.
In my application I'am creating 10 EditText by dynamically. Now I want to give different value in run time and I want to add it to the list. I have assigned EditText object to the String variable like object.getText.toString(). But i cant get any value.I'am a beginner in android. Can anyone help me how to achieve this? Thanks in advance.
for(int i=0;i<=10;i++)
{
requirement = require.get(i);
RelativeLayout rl1 = new RelativeLayout(getActivity());
rl1.addView(req1);
req1estimate_value = new EditText(getActivity());
String value = req1estimate_value.getText().toString();
rl2.addView(req1estimate_value);
}
Try this. You should instantiate relative layout (rl1) at out of for loop, and should add child views with in that, so that all views could belongs to a parent layout. After that for accessing the values of all EditText you can use following:
String viewValue;
ViewGroup rootView = (ViewGroup) rl1;
int count = rootView.getChildCount();
for (int i = 0; i < count; i++) {
View view = rootView.getChildAt(i);
if (view instanceof EditText) {
viewValue = ((EditText) view).getText().toString();
Log.v("Value:: ", i + " " + viewValue);
} else if (view instanceof Spinner) {
viewValue = ((Spinner) view).getSelectedItem()
.toString();
Log.v("Value:: ", i + " " + viewValue);
}
}
Now after getting values you can put on a List or anywhere you want to use.
I have many controls in an activity layout in Android, and
i want to get their value in a simple for, the problem is that
Eclipse assigns the ID randomy, so I cannot get controls ID in a
sequential way to access the controls in a for loop because
they are not sequential IDs.
Here is why I am trying to do:
int visibleId = R.id.fieldVisible1;
int editId = R.id.editField2;
int spinnerId = R.id.spinner1;
for(int nIndex = 0; nIndex < 12; nIndex++)
{
CheckBox checkBox = (CheckBox)findViewById(visibleId + nIndex);
checkBox.setChecked(_fieldsInfoArray.get(nIndex).getVisible() == 1);
EditText edit = (EditText)findViewById(editId );
edit.setText(_fieldsInfoArray.get(nIndex).getName());
Spinner spinner = (Spinner)findViewById(spinnerId + nIndex);
spinner.setSelection(_fieldsInfoArray.get(nIndex).getOffset());
}
how can I make Eclipse to assign sequential IDs to controls so I can
just increment by 1 the id in a loop?
A better way of doing this may possibly to look into the use of:
int children = layout.getChildCount();
for (int i=0; i < children; i++){
View v = ll.getChildAt(i);
}
This would allow you to loop over all views inside the layout without needing to know their IDs.
I am new to Android development and I am trying to handle clicks on a grid of items. What is the best way to do that? So far I have something like this to set the onclicklistener:
TableLayout layout = (TableLayout) findViewById(R.id.tableLayout1);
for (int i = 0; i < layout.getChildCount(); i++) {
View v = layout.getChildAt(i);
if (v instanceof TableRow) {
for (int j = 0; j < ((TableRow)v).getChildCount(); j++) {
View v2 = ((TableRow)v).getChildAt(j);
v2.setOnClickListener(this);
}
}
}
Now I want to handle the clicks on the items contained in the table. As there are many items I want to avoid writing a long "switch". The items have logical IDs containing the number of the row and the column. Is there a way to get the actual ID of the item that has been clicked (the ID in the XML) and then parse it? If not, what would be the solution.
Thanks
You have a few options. You can set the onClickListener inline:
v2.setOnClickListener(new OnClickListener() {
public void onClick (View viewClicked) {
Log.d("View row: " + i + ", column: " + j);
// or something else
}
});
Or you can use the View.setTag(), which will allow you to store key-value pairs to the view, similar to a map.
1: I have a List view as below:
sort
game
play
home
How can we get all the Text of the above List either One by one or all in robotium.
2: Is there any way we are able to create a file in SDcard(Emulator).
Please suggest a way.
For the first Question, My solution is:
RelativeLayout rowItem;
for (int i = 0; i < listView.getChildCount(); i++) {
rowItem = (RelativeLayout) listView.getChildAt(i);
TextView tv = (TextView) rowItem
.findViewById(R.id.my_tv);
String text = tv.getText();
}
Second Question:
Definitely, You can
You can use solo.getCurrentTextViews(View parent) where the parent is the list.
Answering the second question try this one
Context ctx = getInstrumentation().getContext();
AssetManager assetManager = ctx.getAssets();
File a = ctx.getFilesDir();
a.createNewFile();
Here is my solution how to get unique names from ListView items:
//check if ListView contains elements by getting ListView size
int index = 0;
int elemCount = 0;
ListView listView = (ListView) solo.getCurrentListViews().get(index);
elemCount = listView.getAdapter() != null ? listView.getAdapter().getCount() : 0;
//Creating a Map of existing elements
Map<String, Integer> namesMap = new HashMap<String, Integer>();
//Going through the list of elements and mapping it's names
for (int i = 0; i < elemCount ; i++) {
String name = ((StructureElement) listView.getAdapter().getItem(i)).getName();
namesMap.put(name , i);
}
Log.i("Names and indexes are : " + namesMap);
Just create additional method which will return namesMap in case you want to get ListItem index by it's name and "vice versa" if you want to get ListItem name by it's index.
Feel free to reuse it)