I'm having a hard time getting the childobjects of a listview. So, there are multiple objects in it, visible and not yet visible. When I ask for the size, it returns 5 (those 5 are the visible ones).
I tried to scroll the list view from the bottom item to the top item and store those items but than I face the issue that items from other parts in the listview are recognized. Another method that I tried is to scroll the last item a little bit up, until the new item becomes visible. But here I face the issue that a whole other items text is recognized when the item is scrolled.
The code for the first method:
Within this code, I take the listviews childObjects, iterate through them and store all the textfields. When I do this, some textfields of other items are mixed which makes it unusable.
List AccountList;
ArrayList<String> AccountArray = new ArrayList<String>();
String tempAccountInfo = "";
String AccountType="";
String LastItem = "";
String NewLastItem = "N/A";
List<WebElement> AccountListItems;
AccountList = driver.findElements(getObject("ElementsWithinAccountListView"));
AccountListItems = AccountList.get(AccountList.size() - 1).findElements(By.className("android.widget.TextView"));
while (!NewLastItem.equals(LastItem)) {
for (int i=0; i<AccountList.size();i++){
AccountList = driver.findElements(getObject("ElementsWithinAccountListView"));
AccountListItems = AccountList.get(i).findElements(By.className("android.widget.TextView"));
switch (AccountList.get(i).getAttribute("className")){
case "android.widget.LinearLayout":
if (!AccountListItems.get(0).getText().contains("New ")){
switch(AccountListItems.get(0).getText()){
case "Current accounts":
AccountType = "Current accounts";
break;
case "Savings accounts":
AccountType = "Saving accounts";
break;
case "Investments":
AccountType = "Investments";
break;
case "Credit cards":
AccountType = "Credit cards";
break;
case "Other":
AccountType = "Other";
break;
}
}
break;
case "android.widget.RelativeLayout":
AccountListItems = AccountList.get(i).findElements(By.className("android.widget.TextView"));
if (AccountListItems.size() == 5 || AccountListItems.size() == 4){
tempAccountInfo = AccountType;
for(int j=0; j<AccountListItems.size(); j++){
tempAccountInfo = tempAccountInfo + "|" + AccountListItems.get(j).getText();
LastItem = AccountListItems.get(2).getText();
}
switch(AccountType){
case "Investments":
if (!(AccountListItems.size() == 5)) {
System.out.println(tempAccountInfo);
AccountArray.add(tempAccountInfo);
}
break;
default:
System.out.println(tempAccountInfo);
AccountArray.add(tempAccountInfo);
break;
}
tempAccountInfo = "";
}
break;
}
}
driver.swipe(AccountList.get(AccountList.size()-1).getLocation().x + 70, AccountList.get(AccountList.size()-1).getLocation().y, AccountList.get(1).getLocation().x + 70, AccountList.get(1).getLocation().y, 3000);
Thread.sleep(20000);
AccountListItems = AccountList.get(AccountList.size() - 1).findElements(By.className("android.widget.TextView"));
try {
NewLastItem = AccountListItems.get(2).getText();
} catch (Exception e){
System.out.println("Not at the end of the listview");
NewLastItem = "N/A";
}
System.out.println("LastItem:" + LastItem);
System.out.println("NewLastItem:" + NewLastItem);
}
Objects viewed in Appium
This is the code of the second method that I've tried:
protected void swipeToNextElement(String Element) throws Exception{
List AccountList;
String LastItem;
String NewLastItem;
List<WebElement> AccountListItems;
Boolean loop = true;
AccountList = driver.findElements(getObject(Element));
AccountListItems = AccountList.get(AccountList.size()-1).findElements(By.className("android.widget.TextView"));
LastItem = AccountListItems.get(0).getAttribute("text");
NewLastItem = AccountListItems.get(0).getAttribute("text");
driver.swipe(AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y, AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y - 70, 1000);
while (loop) {
if (NewLastItem.equals(LastItem)){
AccountList = driver.findElements(getObject(Element));
AccountListItems = AccountList.get(AccountList.size()-1).findElements(By.className("android.widget.TextView"));
driver.swipe(AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y, AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y - 70, 1000);
NewLastItem = AccountListItems.get(0).getAttribute("text");
} else {
AccountList = driver.findElements(getObject(Element));
AccountListItems = AccountList.get(AccountList.size()-1).findElements(By.className("android.widget.TextView"));
driver.swipe(AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y, AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y + 70, 1000);
NewLastItem = AccountListItems.get(0).getAttribute("text");
loop = false;
}
}
System.out.println("NewLastItem: " + NewLastItem);
}
Any help is welcome ^^
Thanks in advance!
It's painful when you try to get the items from a long list on Android.
And it's hard to get the complete list if some items are invisible and even harder when some of them are the same to Appium.
So my suggestion is to avoid testing a long list.
Related
Please have a look at this code and at the bottom is the question. Thanks for your help
int i,fact=1;
String value = edtLCM.getText().toString();
for (i = Integer.parseInt(value); i >= 1; i--) {
fact = fact * i;
if (i > 1) {
String one = i + " x ";
System.out.print(i + " x ");
} else {
System.out.print(i);
String two = String.valueOf(i);
}
}
System.out.println(" = " + fact);
LCMResult.setText("");
I want to set the textview of all the 3 "System.out.println()" in one line. The desired result would be like this(if a user input 4 in the edtLCM): 4x3x2x1 = 24
Use a StringBuilder to put the new strings together instead of using system out.
int i,fact=1;
String value = edtLCM.getText().toString();
StringBuilder sb = new StringBuilder(); // find a better name
for (i = Integer.parseInt(value); i >= 1; i--) {
fact = fact * i;
if (i > 1) {
String one = i + " x ";
// System.out.print(i + " x ");
sb.append(i).append(" x ");
} else {
//System.out.print(i);
sb.append(i);
String two = String.valueOf(i);
}
}
//System.out.println(" = " + fact);
sb.append(" = ").append(fact);
String result = sb.toString(); // will be 4 x 3 x 2 x 1 = 24
LCMResult.setText("");
When the user hit the bottom of my listview, the second page is loaded and displayed. The problem is that, when it happens, the items of the first page are replaced with the ones of the second page. This video show the behaviour: https://www.ubris.design/video.mp4
and this is my code, inside the respomnse callback of my webservice:
try {
JSONObject obj = new JSONObject(result);
JSONObject response = obj.getJSONObject("response");
Integer count = Integer.parseInt(response.getString("count"));
//Toast.makeText(getApplicationContext(),count+"", Toast.LENGTH_LONG).show();
inputItems.clear();
for(int i = 0; i < count; i++){
JSONObject tmp = response.getJSONObject(i+"");
id = tmp.getString("id");
materia = tmp.getString("materia");
adsce = tmp.getString("adsce");
nomeCompleto = tmp.getString("nomeCompleto");
matricola = tmp.getString("matricola");
username = tmp.getString("username");
password = tmp.getString("password");
uni = tmp.getString("uni");
descrizione = tmp.getString("descrizione");
type = tmp.getString("type");
voto = tmp.getString("voto");
votanti = tmp.getString("votanti");
ts = tmp.getString("ts");
//url
siteTitle = tmp.getString("siteTitle");
siteDescription = tmp.getString("siteDescription");
siteImage = tmp.getString("siteImage");
address = tmp.getString("address");
//file
filename = tmp.getString("filename");
filesize = tmp.getString("filesize");
combinedSize = tmp.getString("combinedSize");
//Toast.makeText(getApplicationContext(), filename+address, Toast.LENGTH_LONG).show();
inputItems.add(new DTODocSelected(id, materia, adsce, nomeCompleto, matricola, null, null, uni, descrizione,type, voto, votanti, ts,
siteTitle, siteDescription, siteImage, address,
filename, filesize, combinedSize
));
}
} catch (Exception e){
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
if(inputItems.size() > 0){
if(page == 0){
adapter = new AdapterDocMateriaDocsSelect(getApplicationContext(),
R.id.activity_docs_doc_selected, inputItems);
listView.setAdapter(adapter);
listView.setSmoothScrollbarEnabled(true);
listView.setScrollingCacheEnabled(false);
listView.setDrawingCacheEnabled(false);
listView.destroyDrawingCache();
listView.buildDrawingCache(false);
listView.getDrawingCache(false);
double vv = Integer.valueOf(counterCC);
double pagineMax = Math.ceil( vv / 5);
int pagineMaxInt = (int) pagineMax;
if(page == (pagineMaxInt - 1)){
pagination = false;
Toast.makeText(getApplicationContext(), "pagination false", Toast.LENGTH_SHORT).show();
}
} else {
//Toast.makeText(getApplicationContext(), ""+inputItems.size(), Toast.LENGTH_SHORT).show();
double vv = Integer.valueOf(counterCC);
double pagineMax = Math.ceil( vv / 5);
int pagineMaxInt = (int) pagineMax;
if(page == (pagineMaxInt - 1)){
pagination = false;
Toast.makeText(getApplicationContext(), "pagination false", Toast.LENGTH_SHORT).show();
}
adapter.addAll(inputItems);
//inputItems.clear();
//listView.setSmoothScrollbarEnabled(true);
//listView.smoothScrollToPosition(page * 5);
}
} else {
pagination = false;
//Toast.makeText(getApplicationContext(), "zero", Toast.LENGTH_LONG).show();
}
to solve I just replaced adapter.addAll(inputItems); with adapter.notifyDataSetChanged(); and removed inputItems.clear();
OK this is driving me nuts. I was hoping to learn how to do this by today.
Here is what I have. This is a Multi choice ListView obviously.
You click the the Selection it selects, you unclick the selection it de selects.
It ALMOST works perfectly. There is only one problem. It only works when 1 item is already selected. If an item is selected, Items can be selected and de selected NP. But if nothing is selected, the last one stays selected. How to I fix that?
public void onItemClick(AdapterView<?> adapterView, View view, int Position, long l) {
int cntChoice = listview.getCount();
SparseBooleanArray sparseBooleanArray = listview.getCheckedItemPositions();
for (int i = 0; i < cntChoice; i++) {
if(sparseBooleanArray.get(i)) {
switch (Position) {
case 0:
if (listview.isItemChecked(0)) {
A = "";
A = "T";
} else if (!listview.isItemChecked(0)) {A = ""; A = "F";}
break;
case 1:
if (listview.isItemChecked(1)) {
B = "";
B = "T";
} else (listview.isItemChecked(1)) {B = ""; B = "F";}
break;
case 2:
if (listview.isItemChecked(2)) {
C = "";
C = "T";
} else (listview.isItemChecked(2)) {C = ""; C = "F";}
break;
}
Toast.makeText(Billing.this, "data" + A + ", " + B + ", " + C, Toast.LENGTH_LONG).show();
}
I'm new to Android. I'm trying to develop my first calculator. My calculator output is good, but I'm trying to make some changes to it. Please suggest. My output is 2+2=4.0 How can I get 4 if I put 2+2 and 4.0 when I put 2.8+1.2.
Also, please help me out in trying to figure out how can i keep on adding till i press =.
My code that I'm looking at is below:
private View.OnClickListener buttonClickListerner = new
View.OnClickListener() {
float r;
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.clear:
screen.setText("");
operator.setText("");
FirstNum= 0;
showtext.setText("");
break;
case R.id.buttonAdd:
mMath("+");
operator.setText("+");
showtext.setText(String.valueOf(FirstNum));
break;
case R.id.buttonMinus:
mMath("-");
operator.setText("-");
break;
case R.id.buttonMul:
mMath("*");
operator.setText("*");
break;
case R.id.buttonequal:
mResult();
break;
case R.id.buttonDiv:
mMath("/");
operator.setText("/");
break;
case R.id.buttonPercent:
mMath("%");
r = FirstNum / 100;
showtext.setText("[" + String.valueOf(FirstNum) + "%" + "]");
screen.setText(String.valueOf(r));
break;
default:
String num = ((Button) v).getText().toString();
getKeyboard(num);
break;
}
}
};
public void mMath(String str){
FirstNum = Float.parseFloat(screen.getText().toString());
operation = str;
screen.setText("");
}
public void getKeyboard(String str){
String CurrentScreen = screen.getText().toString();
if(CurrentScreen.equals("0"))
CurrentScreen = "";
CurrentScreen = CurrentScreen + str;
screen.setText(CurrentScreen);
String ExScreen = CurrentScreen;
screen.setText(ExScreen);
}
public void mResult(){
float SecondNum = Float.parseFloat(screen.getText().toString());
float ThirdNum = Float.parseFloat(screen.getText().toString());
float result = 0;
//float exresult = result;
if(operation.equals("+")){
result = FirstNum + SecondNum;
// exresult = result + ThirdNum;
}
if(operation.equals("-")){
result = FirstNum - SecondNum;
//exresult = result - ThirdNum;
}
if(operation.equals("*")){
result = FirstNum * SecondNum;
//exresult = result * ThirdNum;
}
if(operation.equals("/")){
result = FirstNum / SecondNum;
//exresult = result / ThirdNum;
}
screen.setText(String.valueOf(result));
//screen.setText(String.valueOf(exresult));
showtext.setText(String.valueOf(FirstNum + operation + SecondNum));
//showtext.setText(String.valueOf(FirstNum + operation + SecondNum +
operation + ThirdNum));
}
}
I guess you should do your calculations as double and then before setting the output to TextView (or whatever you are using), check for the output if int or not and then decide which form of output to set to the TextView.
if ((variable == Math.floor(variable)) && !Double.isInfinite(variable)) {
// integral type
}
See this
Edit:
The idea is to check that fractional part of the number is 0 (i.e.) the number is integer.
You may also Use these conditions [if true then variable is an Integer]
// check if
variable == Math.ceil(variable)
or
// check if
variable == Math.round(variable)
Also Math.round(float f) will return the interger form of the number!
To add multiple item first set up an array with a size of how long the user can input and then loop through each array adding them equivalently... i know this is a vague answer but you can ask me if anything is unclear and also an up vote would be nice. you got the right idea for the cases just try the following code
// array to sum
int[] numbers = new int[]{ 10, 10, 10, 10};
int sum = 0;
for (int i=0; i < numbers.length ; i++) {
sum = sum + numbers[i];
}
System.out.println("Sum value of array elements is : " + sum);
}
I'm coding a method that solve various kind of equation. Now I want that the method receives a String equation that could be in the forms:
ax^2+bx+c=0
or
*ax^2+c=0*
or
bx+c=0
etc. and the order shouldn't matter.
My problem is: How could I parse the equation according the "x" grade?
The eq could contains more values of the same grade for example 2x^2+4x^2+3x+8=2 (max grade x^3).
My method should assign the a value to double a[] if on the left or on the right of a there is x^2, double b[], if on the left or on the right there is x, and double c[] if there isn't any x variable near the value (and should change the value sign if the therms is after the =).
Convert a String number in a double is simple but I don't know how I could disassemble the input String according the x grade as described.
Tested for -2x + 3x^2 - 2 + 3x = 3 - 2x^2
public Double[] parseEquation(String equation)
{
Log.d(TAG, "equation: " + equation);
// Remove all white spaces
equation = equation.replaceAll("[ ]", "");
// Get the left and right sides of =
String[] sides = equation.split("[=]"); // should be of size 2
boolean leftNegative = false;
boolean rightNegative = false;
if (sides.length != 2)
{
// There is no = or more than one = signs.
}
else
{
// if sides i starts with + remove the +
// if - we remove and put it back later
for (int i = 0; i < 2; i++)
{
if (sides[i].charAt(0) == '+')
{
sides[i] = sides[i].substring(1);
}
}
if (sides[0].charAt(0) == '-')
{
leftNegative = true;
sides[0] = sides[0].substring(1);
}
if (sides[1].charAt(0) == '-')
{
rightNegative = true;
sides[1] = sides[1].substring(1);
}
}
Log.d(TAG, "left side:" + sides[0] + " right side: " + sides[1]);
// Terms without signs need to find out later
String[] leftTerms = sides[0].split("[+-]");
String[] rightTerms = sides[1].split("[+-]");
int length = leftTerms[0].length();
if (leftNegative)
{
leftTerms[0] = "-" + leftTerms[0];
}
// put in the minus sign for the rest of the terms
for (int i = 1; i < leftTerms.length; i++)
{
Log.d(TAG, "length = " + length + " " + sides[0].charAt(length));
if (sides[0].charAt(length) == '-')
{
leftTerms[i] = "-" + leftTerms[i];
length += leftTerms[i].length();
}
else
{
length += leftTerms[i].length() + 1;
}
}
length = rightTerms[0].length();
if (rightNegative)
{
rightTerms[0] = "-" + rightTerms[0];
}
for (int i = 1; i < rightTerms.length; i++)
{
Log.d(TAG, "length = " + length + " " + sides[1].charAt(length));
if (sides[1].charAt(length) == '-')
{
rightTerms[i] = "-" + rightTerms[i];
length += rightTerms[i].length();
}
else
{
length += rightTerms[i].length() + 1;
}
}
// Now we put all the factors and powers in a list
List<ContentValues> leftLists = new ArrayList<ContentValues>();
// left side
for (int i = 0; i < leftTerms.length; i++)
{
Log.d(TAG, "leftTerm: " + leftTerms[i]);
ContentValues contentValues = new ContentValues();
int indexOfX = leftTerms[i].indexOf('x');
if (indexOfX == -1)
{
// no x mean a constant term
contentValues.put("factor", leftTerms[i]);
contentValues.put("power", "0");
}
else
{
int indexOfHat = leftTerms[i].indexOf('^');
if (indexOfHat == -1)
{
// no hat mean power = 1
contentValues.put("power", "1");
String factor = leftTerms[i].substring(0, indexOfX).trim();
contentValues.put("factor", factor);
}
else
{
String power = leftTerms[i].substring(indexOfX + 2).trim();
String factor = leftTerms[i].substring(0, indexOfX).trim();
contentValues.put("factor", factor);
contentValues.put("power", power);
}
}
Log.d(TAG, contentValues.toString());
leftLists.add(contentValues);
}
List<ContentValues> rightLists = new ArrayList<ContentValues>();
for (int i = 0; i < rightTerms.length; i++)
{
Log.d(TAG, "rightTerm: " + rightTerms[i]);
ContentValues contentValues = new ContentValues();
int indexOfX = rightTerms[i].indexOf('x');
if (indexOfX == -1)
{
// no hat mean a constant term
contentValues.put("factor", rightTerms[i]);
contentValues.put("power", "0");
}
else
{
int indexOfHat = rightTerms[i].indexOf('^');
if (indexOfHat == -1)
{
// no hat mean power = 1
contentValues.put("power", "1");
String factor = rightTerms[i].substring(0, indexOfX).trim();
contentValues.put("factor", factor);
}
else
{
String power = rightTerms[i].substring(indexOfX + 2).trim();
String factor = rightTerms[i].substring(0, indexOfX).trim();
contentValues.put("factor", factor);
contentValues.put("power", power);
}
}
Log.d(TAG, contentValues.toString());
rightLists.add(contentValues);
}
// Now add the factors with same powers.
// Suppose we solve for cubic here the end result will be
// 4 terms constant, x, x^2 and x^3
// Declare a double array of dim 4 the first will hold constant
// the second the x factor etc...
// You can allow arbitrary power by looping through the lists and get the max power
Double[] result = new Double[]{0.0, 0.0, 0.0, 0.0};
for (ContentValues c : leftLists)
{
switch (c.getAsInteger("power"))
{
case 0:
//Log.d(TAG, "power = 0, factor = " + c.toString());
result[0] += c.getAsDouble("factor");
break;
case 1:
result[1] += c.getAsDouble("factor");
break;
case 2:
result[2] += c.getAsDouble("factor");
break;
case 3:
result[3] += c.getAsDouble("factor");
break;
}
}
for (ContentValues c : rightLists)
{
switch (c.getAsInteger("power"))
{
case 0:
//Log.d(TAG, "power = 0, factor = " + c.toString());
result[0] -= c.getAsDouble("factor");
break;
case 1:
result[1] -= c.getAsDouble("factor");
break;
case 2:
result[2] -= c.getAsDouble("factor");
break;
case 3:
result[3] -= c.getAsDouble("factor");
break;
}
}
Log.d(TAG, "constant term = " + result[0] + ", x^1 = " + result[1]
+ ", x^2 = " + result[2] + ", x^3 = " + result[3]);
return result;
}
If you weren't limited by Android, I'd suggest using a lexer and parser. These are code generators, so they can work anywhere the base language works, but they tend to produce bloated code. Android might not appreciate that.