Obscure issue with string formatting from SQLite database - android

I appreciate there's a lot of helpful stack questions and answers to my question but I'm running into problems I've not had in the past.
The Problem:
I am using a cursor to populate textviews in rows on a view (without using listview - that's crazy I know). I am trying to format the string value(s) taken from from the database column STUDENT_POINTS that are put into a textview tpoints. Here is the code I am using:
public void bindView(View v, final Context context, Cursor c) {
final int id = c.getInt(c.getColumnIndex(Students.STUDENT_ID));
final String name = c.getString(c.getColumnIndex(Students.STUDENT_NAME));
final String age = c.getString(c.getColumnIndex(Students.STUDENT_AGE));
final String points = c.getString(c.getColumnIndex(Students.STUDENT_POINTS));
final String teachernote = c.getString(c.getColumnIndex(Students.TEACHERNOTE));
final byte[] image = c.getBlob(c.getColumnIndex(Students.IMAGE));
ImageView iv = (ImageView) v.findViewById(R.id.photo);
if (image != null) {
if (image.length > 3) {
iv.setImageBitmap(BitmapFactory.decodeByteArray(image, 0,image.length));
}
}
TextView tname = (TextView) v.findViewById(R.id.name);
tname.setText(name);
TextView tage = (TextView) v.findViewById(R.id.age);
tage.setText(age);
TextView tpoints = (TextView) v.findViewById(R.id.points);
tpoints.setText(String.format(points, "%1$,.2f"));
final StudentsConnector sqlCon = new StudentsConnector(context);
The rest of bindView is for buttons so I have not included it here. The problem is with the line:
tpoints.setText(String.format(points, "%1$,.2f"));
I'm intending to have commas to separate out large numbers but this does nothing! If anybody has the time could you please tell me what I'm doing wrong?
Thanks in advance.

You have your two parameters backwards-- you should have the format string followed by the data string: String.format("%1$,.2f", points );
This formatted nicely for me with this little snippet in my code:
double points = 56789.45f;
String boogie = String.format("%1$,.2f", points );
and it generated a number 56,789.45
But bigger numbers don't work well due to precision in the formater. You may want to split the mantissa off of their, format them separately and combine them.

Related

How to create a new "TextView" object,by concatenating two strings?

I want to create a new "TextView" object in "MainActivity" code by concatenating
Two String names. for example:
String s1 = "num";
String s2 = "ber";
String s3 = s1+s2;
TextView s3 = new TextView(this);
How cast s3 to TextView object,so i dont get anyy error,code above?
I mean i want to use s3 as a "TextView" name object.
You would do something like this.
TextView textView = new TextView(this);
textView.setText(s3);
or
TextView s3 = new TextView(this);
s3.setText(s1 + s2);
or programmatically in a loop
for (int i = 0; i < list.size(); i++) {
TextView textView = new TextView(this);
textView.setId(s3); //set textview id, this WILL NOT make it a variable of 'number'
linearLayout.addView(textView);
}
First problem is you declared 2 variables with the same name. Fix it by giving TextView a better name and then as #soldforapp answered already, set the text using the method .setText();
edit:
Wait, so you want to assign the value of the TextView to the string variable s3?
I don't really understand your problem. If so, if your code would look like this (so it runs)
String s1 = "num";
String s2 = "ber";
String s3 = s1+s2;
TextView tv = new TextView(this);
This line will assign the variable s3 the text inside your TextView.
s3 = tv.getText().toString();
Using the same name for the different variable in one scope is not possible in JAVA. (even with different types)
Using StringBuilder is better option than concatenating with + operation, so:
String s1 = "num";
String s2 = "ber";
String concat = new StringBuilder().append(s1).append(s2).toString();
TextView s3 = new TextView(this);
s3.setText(concat);
Edit:
What you want is not as easy as what exists in script languages like PHP but you can do it with reflection with efforts. But there is an easier option with using Map:
Map<String,TextView> map = new HashMap<>();
map.put(concat, new TextView(this));
You can get the TextViews with:
map.get(concat).setText("Your String");

Do calculations on numbers in 1 multiline textView and return result replacing numbers

I am very new to android programming and am trying to complete my first app. It is a recipe converter.
I have stored my recipe details in a SQLite DB and the text for ingredients is just one multiline string separated by carriage returns. I have used a cursor to get the ingredient data into a textview which returns text like (could be numerous variants):
100ml Water
500 g Mince
2 x 400g can crushed tomatoes
etc.
I originally had each Qty, Unit and Ingredient Description stored separately in the database which made life easy when converting but I chose to store it in a multiline string to allow copying and pasting of ingredients from the internet or another source.
I am attempting to extract the numbers and then multiply them by a percentage, then return the new converted numbers, and the corresponding unit and description to get something like this:
(multiplied by 200%)
200ml Water
1000g Mince
4 x 400g can crushed tomatoes
I just don't know how to do it though. Can anyone help please?
Thanks
UPDATE:
I have tried to do something like this to get the numbers.
public void Split() {
TextView tvSplit = (TextView) findViewById(R.id.tvSplit);
final TextView tvTest = (TextView) findViewById(R.id.tvTest);
String s = tvTest.getText().toString();
for (int i =0;i <= tvTest.getLineCount();i++){
tvSplit.setText("");
String text = s.replaceAll("\\D+", ",");
tvSplit.append(text);
tvSplit.append("\n");
}
That shows me all of the numbers with a "," between them but it also includes all numbers in the string like in the above example prior to conversion it would show 100,500,2,400 when I only need 100,500,2. Then from that point I'm not sure how I would convert them all. My "fresh to programming mind" thought that I could store these in a temp SQL table by INSERT INTO tablename (id, originalvalues) VALUES (my string ie 100,500,2).
I could then pull them back out, do the calculation, update the table, then add them back into my textview with the remaining string. I haven't got that far yet, so I'm just wondering what the correct way to do it is.
UPDATE 2:
As per my comments, this is the code I used to show an alert dialog with each item listed on a separate line, I then used the selected line to find the number before any " " to then display the text on the screen.
public void PopUpSpinnerDialogue() {
final TextView tvTest = (TextView) findViewById(R.id.tvTest);
final TextView tv2 = (TextView) findViewById(R.id.tvTest2);
String s = tvTest.getText().toString();
final ArrayAdapter myAdapter = new ArrayAdapter<String>(this,
R.layout.my_dropdown_style, s.split("\n"));
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this);
builder.setTitle("Please choose the key ingredient you need to scale your recipe by.")
.setCancelable(false)
.setAdapter(myAdapter, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
try {
String itemName = myAdapter.getItem(which).toString();
String[] parts = itemName.split(" ");
String itemNumStr = parts[0];
TextView tvLineName = (TextView) findViewById(R.id.tvIngredientSelect);
EditText et1 = (EditText) findViewById(R.id.etRecipeQtyConvert);
EditText et2 = (EditText) findViewById(R.id.etQtyHave);
tvLineName.setText(itemName);
String b4Space = itemNumStr.replaceAll("\\D+", "");
tv2.setText(b4Space);
et1.setText(b4Space);
et2.setText(b4Space);
calculateKeyIngredientPercent();
} catch (Exception e) {
Toast.makeText(SelectConvertMethod.this, "Your ingredient must have a QTY. eg. 100ml.", Toast.LENGTH_SHORT).show();
}
}
});
android.app.AlertDialog alert = builder.create();
alert.show();
}
It is this idea that I think I can use but I don't know how to code it and then display the results.
UPDATE 3:
The code or at least the idea of the code I am trying to use is this.
TextView tvSplit = (TextView) findViewById(R.id.tvSplit);
final TextView tvTest = (TextView) findViewById(R.id.tvTest);
String s = tvTest.getText().toString();
for (int i =0;i <= tvTest.getLineCount();i++){
String[] ingreds = s.split("\n");
tvSplit.setText("");
String[] parts = ingreds.split(" ");
String Qty = parts[0];
String Units = parts[1];
String Ingredients = parts[2];
Integer QtyInt = Integer.parseInt(Qty);}
ingreds.split doesn't work and also, I don't know how to specify splitting the parts for each i.
I ended up using regex. It allowed the data to be entered with or without a space. So I ended up using this code to pull out the Qty of each line, multiply it by a percentage, append the text (units,ingredient description) to the line, then add it to a string array, to add to my alert dialog.
Code is here.
public void Split() {
final TextView tv2 = (TextView) findViewById(R.id.tvTest2);
TextView tvTest = (TextView) findViewById(R.id.tvTest);
TextView tvPercent = (TextView) findViewById(R.id.tvPercent);
String tvP = tvPercent.getText().toString();
String tvNumOnly = tvP.replaceAll("\\D+", "");
Integer PercentVal = Integer.parseInt(tvNumOnly);
String s = tvTest.getText().toString();
StringBuilder sb = new StringBuilder();
Pattern p = Pattern.compile("((\\d*) ?(.*)(?:\\n*))");
Matcher m = p.matcher(s);
while (m.find()) {
String Qty = m.group(2) + ".00";
String Ingred = m.group(3);
Float QtyFloat = Float.parseFloat(Qty);
Float newQTY = (QtyFloat * PercentVal) / 100;
String newQTYstr = newQTY.toString();
sb.append(newQTYstr + " " + Ingred + "\n");
}
String[] lines = sb.toString().split("\n");
String[] IngredArray = Arrays.copyOfRange(lines, 0, lines.length - 1);
final ArrayAdapter myAdapter = new ArrayAdapter<String>(this,
R.layout.my_dropdown_style, IngredArray);
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this);
builder.setTitle("Please choose the key ingredient you need to scale your recipe by.")
.setCancelable(false)
.setAdapter(myAdapter, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
try {
String itemName = myAdapter.getItem(which).toString();
String[] parts = itemName.split(" ");
String itemNumStr = parts[0];
TextView tvLineName = (TextView) findViewById(R.id.tvIngredientSelect);
EditText et1 = (EditText) findViewById(R.id.etRecipeQtyConvert);
EditText et2 = (EditText) findViewById(R.id.etQtyHave);
tvLineName.setText(itemName);
String b4Space = itemNumStr.replaceAll("\\D.\\D+", "");
tv2.setText(b4Space);
et1.setText(b4Space);
et2.setText(b4Space);
calculateKeyIngredientPercent();
} catch (Exception e) {
Toast.makeText(SelectConvertMethod.this, "Your ingredient must have a QTY. eg. 100ml.", Toast.LENGTH_SHORT).show();
}
}
});
android.app.AlertDialog alert = builder.create();
alert.show();
// Toast.makeText(SelectConvertMethod.this, sb, Toast.LENGTH_LONG).show();
}

Robotium get String using ArrayList<TextView>

Hi i have a listview add random string
now i can using arraylist click item but now need the item string
string is resource not text...
ArrayList<TextView> listtest = solo.getCurrentViews(TextView.class);
View lt = listtest.get(1);
String text;
text = lt.toString();
solo.clickOnView(lt);
Your question isn't completely clear but what i suspect you want is the following:
TextView lt = listtest.get(1);
text = lt.getText().toString();

textview with multiple hyperlinks

I have for example the following String
\n 3 Doors Down is a http://www.last.fm/tag/post-grunge\" class=\"bbcode_tag\" rel=\"tag\">post-grunge band from Escatawpa, Mississippi, United States, formed in 1996, consisting of Brad Arnold (vocals), Matt Roberts (guitars), Todd Harrell (bass), Chris Henderson (guitar), and Greg Upchurch (drums). The band signed to Universal Records in 2000 for their first album, http://www.last.fm/music/3+Doors+Down/The+Better+Life\" class=\"bbcode_album\">The Better Life. They received international attention with the release of the single "http://www.last.fm/music/3+Doors+Down/_/Kryptonite\" class=\"bbcode_track\">Kryptonite". The album went on to sell over 6 million copies. \n\n http://www.last.fm/music/3+Doors+Down\">Read more about 3 Doors Down on Last.fm.\n \n \nUser-contributed text is available under the Creative Commons By-SA License and may also be available under the GNU FDL.\n
I want to show the entire string in a textview with the hyperlinks clickable. I also don't want to see the actual url, just the text that's shown in place of the url. Reading other posts on the subject they all suggest defining a textview similar to this
<TextView
android:id="#+id/tvArtistOverview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:autoLink="web"
android:linksClickable="true" />
and setting the SetMovementMethod of the textview to
myTextView.setMovementMethod(LinkMovementMethod.getInstance());
When I follow these steps, my links are clickable, however they are not displayed as I wish. What am I missing?
Here is an example of how it currently looks.
Use below code.
TextView tv = ....
tv.setMovementMethod(LinkMovementMethod.getInstance());
String content = tv.getText().toString();
List<String> links = new ArrayList<String>();
Pattern p = Patterns.WEB_URL;
Matcher m = p.matcher(content);
while (m.find()) {
String urlStr = m.group();
links.add(urlStr);
}
SpannableString f = new SpannableString(content);
for (int i = 0; i < links.size(); i++) {
final String url = links.get(i);
f.setSpan(new InternalURLSpan(new OnClickListener() {
public void onClick(View v) {
Context ctx = v.getContext();
String urlToOpen = url;
if (!urlToOpen.startsWith("http://") || !urlToOpen.startsWith("https://"))
urlToOpen = "http://" + urlToOpen;
openURLInBrowser(urlToOpen, ctx);
}
}), content.indexOf(url), content.indexOf(url) + url.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
tv.setText(f);

Comparing string array with string and posting my result to main.xlm

I am having trouble with understanding how to compare strings in Java for Android. I have written code to do this in JavaScript and Palm but am new to Java and am a little confused. Case in point, I am trying to modify the example on the Android Developers site for SpinnerActivity (http://developer.android.com/resources/samples/Spinner/src/com/android/example/spinner/SpinnerActivity.html). In my application I am looking at pipe sizes in the spinner not planets. When the user picks a pipe size I want to reference an array of pipe sizes and be able to pick other parameters associated with that pipe size like the outside diameter (OD) of the pipe. I have modified the above sample code and added and array for the pipe sizes and the OD sizes. I then try to compare what the user picked in the pipe sizes spinner with my pipe sizes array and use the number of the array that matches to pick the associated OD. There is something wrong with the way I am trying to make this comparision. I set both of these values as stings but they never seem to find one another.
HelloSpinner1.java section I have changed is:
public void onItemSelected(AdapterView<?> parent, View v, int pos, long row) {
HelloSpinner1.this.mPos = pos;
HelloSpinner1.this.mSelection = parent.getItemAtPosition(pos).toString();
/*
* Set the value of the text field in the UI
*/
TextView resultText = (TextView)findViewById(R.id.SpinnerResult);
resultText.setText(HelloSpinner1.this.mSelection);
String[] OD; // array of pipe ODs
OD = new String[30]; // allocates memory for 30 floating point numbers
OD[0] = "0.405";
OD[1] = "0.540";
OD[2] = "0.675";
OD[3] = "0.840";
OD[4] = "1.050";
OD[5] = "1.315";
OD[6] = "1.660";
OD[7] = "1.9";
OD[8] = "2.375";
OD[9] = "2.875";
OD[10] = "3.5";
OD[11] = "4";
OD[12] = "4.5";
OD[13] = "5.563";
OD[14] = "6.625";
OD[15] = "8.625";
OD[16] = "10.750";
OD[17] = "12.75";
OD[18] = "14";
OD[19] = "16";
OD[20] = "18";
OD[21] = "20";
OD[22] = "22";
OD[23] = "24";
OD[24] = "26";
OD[25] = "28";
OD[26] = "30";
OD[27] = "32";
OD[28] = "34";
OD[29] = "36";
String [] Size;
Size = new String [30];
Size[0] = "1/8";
Size[1] = "1/4";
Size[2] = "3/8";
Size[3] = "1/2";
Size[4] = "3/4";
Size[5] = "1";
Size[6] = "1-1/4";
Size[7] = "1-1/2";
Size[8] = "2";
Size[9] = "2-1/2";
Size[10] = "3";
Size[11] = "3-1/2";
Size[12] = "4";
Size[13] = "5";
Size[14] = "6";
Size[15] = "8";
Size[16] = "10";
Size[17] = "12";
Size[18] = "14";
Size[19] = "16";
Size[20] = "18";
Size[21] = "20";
Size[22] = "22";
Size[23] = "24";
Size[24] = "26";
Size[25] = "28";
Size[26] = "30";
Size[27] = "32";
Size[28] = "34";
Size[29] = "36";
String ODSize;
for (int i = 0; i <= 29; i++){
if (Size.equals("HelloSpinner1.this.mSelection")) {
ODSize = OD[i];
break;
}
}
}
The associated strings.xml rorm the android site with slight modifications is:
Pipe and Tube
1/8
1/4
3/8
3/4
1
1-1/4
1-1/2
2
2-1/2
3
3-1/2
4
5
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
Select a Pipe Size
Just a quick note, but I see two things here:
1) You have "HelloSpinner1.this.mSelection" in quotes. Inside .equals, that is comparing your variable Size directly to that string ... not the value stored in that object. For example, you're asking: "1/8" ?= "HelloSpinner1.this.mSelection" ... not, "1/8" ?= "1/4" in this case. That might be most of your problem here.
2) You could just use the position of the spinner inside your Listener method. That gives you the position of the selection on the spinner. If you aren't modifying those values, you would already know the index into your array. If you were modifying them, /then/ you could do a string comparison (or concurrently modify your array to keep them up to date).
You might also want to check what you're comparing against once you eliminate the quotes problem. A very simple way to do that would be to declare a String for each value, then run it in the debugger or log the output.
Lastly, as personal preference, I don't like to store long arrays which aren't going to change in the xml file. Just code that up as an array which doesn't have to be interpreted later. That'll give you the array access directly, and speed up execution some.

Categories

Resources