TextViews getting repositioned after calling setText(). Is this a bug? - android

I'm experiencing the weirdest problem I've ever seen. I have a basic two-pane view. There's a pane that lists medications, and clicking a medication brings up the second pane, which contains the details about that medication. The details fragment is supposed to be arranged like this:
[Med Name]
[Med Dosage]
[Date Filled]
[Duration]
And the XML code bears this out, as far as I can tell:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/nameDetailsView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="48dp"
android:freezesText="true"
android:layout_centerHorizontal="true"
android:text="name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/dosageDetailsView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/nameDetailsView"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:freezesText="true"
android:text="dosage"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/dateFilledDetailsView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/dosageDetailsView"
android:layout_centerHorizontal="true"
android:layout_marginTop="34dp"
android:text="date"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/durationDetailsView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/dateFilledDetailsView"
android:layout_centerHorizontal="true"
android:layout_marginTop="29dp"
android:text="duration"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
I set the strings to be displayed by each field using this code:
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor mCursor) {
int count = mCursor.getCount();
String str = "There are " + count + " rows.";
// TODO: REMOVE THIS TOAST
Toast.makeText(getActivity(), str, Toast.LENGTH_SHORT).show();
int nameIndex = mCursor.getColumnIndex(MedTable.MED_NAME);
int dosageIndex = mCursor.getColumnIndex(MedTable.MED_DOSAGE);
int dateIndex = mCursor.getColumnIndex(MedTable.MED_DATE_FILLED);
int durationIndex = mCursor.getColumnIndex(MedTable.MED_DURATION);
if(mCursor != null) {
// Moves to the next row in the cursor.
while(mCursor.moveToNext()) {
// Create the name string
String medName = "Name: " + mCursor.getString(nameIndex);
// Create the dosage string
String medDosage = "Dosage: " + mCursor.getString(dosageIndex);
// Create a date format to parse the date string
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
String epochString = mCursor.getString(dateIndex);
long epoch = Long.parseLong(epochString);
String date = sdf.format(new Date(epoch * 1000));
// Create the date string
String medDate = "Date Filled: " + date;
// Create the duration string
String medDuration = "Duration: " + mCursor.getString(durationIndex) + " days";
// Setting the name
TextView nameView = (TextView) getActivity().findViewById(R.id.nameDetailsView);
nameView.setText(medName);
// Setting dosage
TextView dosageView = (TextView) getActivity().findViewById(R.id.dosageDetailsView);
dosageView.setText(medDosage);
// Setting the date
TextView dateView = (TextView) getActivity().findViewById(R.id.dateFilledDetailsView);
dateView.setText(medDate);
// Setting the duration
TextView durationView = (TextView) getActivity().findViewById(R.id.durationDetailsView);
durationView.setText(medDuration);
// end of while loop
}
}
}
But when I run the program, the weirdest thing happens. Namely, the TextViews get reordered somehow.
Instead of the desired order, I somehow get
[Date Filled]
[Dosage]
[Name]
[Duration]
Can anyone tell me why on earth this might be happening?
EDIT: Commenting out the various calls to setText() causes the TextViews to display in the correct order, albeit with the hardcoded text, instead of what I want.
EDIT AGAIN: Turns out all I needed to do was clean the project. Now I know.

First try and remove + sign from all android:layout_below tags and make it like:
android:layout_below="#id/dateFilledDetailsView". The + sign in the id declaration should be used only on the first appearance of the id. So have something as follows and comment the result:
<TextView
android:id="#+id/nameDetailsView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="48dp"
android:freezesText="true"
android:layout_centerHorizontal="true"
android:text="name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/dosageDetailsView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/nameDetailsView"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:freezesText="true"
android:text="dosage"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/dateFilledDetailsView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/dosageDetailsView"
android:layout_centerHorizontal="true"
android:layout_marginTop="34dp"
android:text="date"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/durationDetailsView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/dateFilledDetailsView"
android:layout_centerHorizontal="true"
android:layout_marginTop="29dp"
android:text="duration"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
Update:
For the sake keeping the answer updated, #Squonk's comment worked perfectly. The real issue was that R.java got corrupt. Cleaning the project solved the problem.

I don't think you should find view in Fragment like this:
TextView nameView = (TextView) getActivity().findViewById(R.id.nameDetailsView);
Why don't you inflate layout file in onCreateView method in Fragment, then find view by inflated layout view.

Related

EditText, when setting to maxLines = 1 and enter is pressed it erases and crashes

I have an issue regarding the EditText. Doing a simple math game where the player will get an example such as this: 9 x 9 = __ . The empty space (= EditText, limited to only numbers) is where the player has to fill in correct answer from the equation and press an [ CORRECT ]-button to correct the equation.
Problem:
I have currently set android.maxLines = "1". Now each time the player presses the Enter-key any written text will be erased. If you re-type back and press the Correct-button the app stopps working. However, for as long as you don't press enter the app works just fine using the Correct-button. How do I prevent it from crashing/stop working? But also stop it from erasing any numbers when pressing the Enter-key.
XML-file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_play"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.android.laboration2.EasyActivity">
<TextView
android:id="#+id/textEasyMultiply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/textEasyNumber1"
android:layout_centerHorizontal="true"
android:layout_gravity="start"
android:text="#string/multiply"
android:textAlignment="textStart"
android:textColor="#android:color/black"
android:textSize="40sp" />
<TextView
android:id="#+id/textEasyNumber1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginEnd="25dp"
android:layout_marginRight="25dp"
android:layout_marginTop="49dp"
android:layout_toLeftOf="#+id/answerButton"
android:layout_toStartOf="#+id/answerButton"
android:text="#string/number_1"
android:textAlignment="center"
android:textColor="#android:color/black"
android:textSize="50sp" />
<TextView
android:id="#+id/textEasyEqual"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textEasyNumber1"
android:layout_centerHorizontal="true"
android:layout_marginTop="18dp"
android:text="#string/equal"
android:textAlignment="center"
android:textColor="#android:color/black"
android:textSize="50sp" />
<EditText
android:id="#+id/editTextEasyResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textEasyEqual"
android:layout_centerHorizontal="true"
android:hint=" "
android:maxLines="1"
android:textAlignment="center"
android:textColor="#android:color/black"
android:textSize="50sp" />
<TextView
android:id="#+id/textEasyScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="start"
android:layout_marginBottom="31dp"
android:layout_toLeftOf="#+id/answerButton"
android:layout_toStartOf="#+id/answerButton"
android:text="#string/score_0"
android:textAlignment="textStart"
android:textColor="#android:color/black"
android:textSize="24sp" />
<Button
android:id="#+id/answerButton"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_below="#+id/editTextEasyResult"
android:layout_centerHorizontal="true"
android:layout_marginTop="36dp"
android:background="#android:color/holo_orange_dark"
android:text="#string/button_result"
android:textAllCaps="false"
android:textColor="#android:color/white"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="#+id/textEasyNumber2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textEasyEqual"
android:layout_alignEnd="#+id/textEasyLevel"
android:layout_alignRight="#+id/textEasyLevel"
android:layout_marginEnd="12dp"
android:layout_marginRight="12dp"
android:inputType="number"
android:text="#string/number_2"
android:textAlignment="center"
android:textColor="#android:color/black"
android:textSize="50sp" />
<TextView
android:id="#+id/textEasyLevel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/textEasyScore"
android:layout_alignBottom="#+id/textEasyScore"
android:layout_toEndOf="#+id/answerButton"
android:layout_toRightOf="#+id/answerButton"
android:text="#string/level_0"
android:textAlignment="center"
android:textColor="#android:color/black"
android:textSize="24sp" />
</RelativeLayout>
JAVA-file:
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.answerButton:
int easyNum1 = Integer.parseInt(textEasyNumber1.getText().toString());
int easyNum2 = Integer.parseInt(textEasyNumber2.getText().toString());
int easyResult = Integer.parseInt(editTextEasyResult.getText().toString());
if(easyNum1 * easyNum2 == easyResult){
currentScore++;
currentLevel++;
textEasyScore.setText("Score: " + currentScore);
textEasyLevel.setText("Level: " + currentLevel);
Toast.makeText(getApplicationContext(), "Good job!", Toast.LENGTH_LONG).show();
editTextEasyResult.setText("");
}else{
currentScore = 0;
currentLevel = 0;
Toast.makeText(getApplicationContext(),"Wrong! :(", Toast.LENGTH_LONG).show();
}
//Updates Scores & Level
textEasyScore.setText("Score: " + currentScore);
textEasyLevel.setText("Level: " + currentLevel);
break;
}//switch ends here
//stores the Score into the High Score page, when new High Score is reached it will auto-update
SharedPreferences sharedPrefsHighScore = getSharedPreferences("Prefs_HighScore",MODE_PRIVATE);
SharedPreferences.Editor editorScore = sharedPrefsHighScore.edit();
int storedHighScore = sharedPrefsHighScore.getInt("highScore",0);
if (currentScore>storedHighScore) {
editorScore.putInt("highScore", currentScore);
editorScore.commit();
//if a new High Score is achieved, the toastmessage "NEW HIGH SCORE!" will be shown (with modifications)
Toast highScoreToast = Toast.makeText(getApplicationContext(), "NEW HIGH SCORE!", Toast.LENGTH_LONG);
TextView toastMessage = (TextView) highScoreToast.getView().findViewById(android.R.id.message);
toastMessage.setTextColor(Color.WHITE);
toastMessage.setTextSize(25);
highScoreToast.show();
}//if-statement ends here
randomNumbersForEquation();
}//onClick ends here
//adds a random number for our Equation (for textEasyNumber1 and textEasyNumber2)
void randomNumbersForEquation(){
int addingOneTocurrentLevel = currentLevel + 1;
int numberRange = addingOneTocurrentLevel * 3;
Random randInt = new Random();
int Number1 = randInt.nextInt(numberRange);
Number1++;//don't want a zero value
int Number2 = randInt.nextInt(numberRange);
Number2++;//don't want a zero value
textEasyNumber1.setText("" + Number1);
textEasyNumber2.setText("" + Number2);
}//setQuestion ends here
Try these together
android:imeOptions="actionDone"
android:inputType="number"
android:maxLines="1"
Well, when you press "enter" key, the text doesn't get erased, rather it shifts up. After hitting enter key, press the up arrow key and you will find your text. The problem might be with the logic you have written for "Correct" button. Please share the code which is executed upon pressing "Correct" button
UPDATED --- Try using trim() method to remove trailing spaces. Since you are parsing the value into an int, the extra space might be causing the issue Something like this:
Integer.parseInt(editTextEasyResult.getText().toString().trim());
Another suggestion is, since you are developing a maths related app, you can restrict your EditText to accept numbers only. Do so by mentioning the following attribute for your edit text file:
android:inputType="number"
Doing so will present a numerical keyboard to the user without the enter key.

Add dynamic text to RelativeLayout

I want to create a "Enter your name"-page (for the highscore) for my Android-game but I’m experiencing some problems.
I want it to look like this:
You have reached (=enthst1)
.........here’s the score..............
points! (=enthst2)
Please type in your name to save your score! (= enthst3)
........EditText for name.....
Back (=button) ................... Enter (=button)
But I don’t seem to be able to add the score (int) to my ContentView!
Here’s the code:
Java in "onCreate":
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter_hs);
layo = new RelativeLayout(this);
MySco = new TextView(this) ;
Back = (Button)findViewById(R.id.enthsre1);
Back.setOnClickListener(this);
Enter =(Button)findViewById(R.id.enthsok1);
Enter.setOnClickListener(this);
Eingabe = (EditText) findViewById(R.id.editText1) ;
Texta = (TextView) findViewById(R.id.enthst1) ;
Textb = (TextView) findViewById(R.id.enthst2) ;
Textc = (TextView) findViewById(R.id.enthst3) ;
Intent intentk = getIntent();
kontro = intentk.getStringExtra("from").equals("MainActivity") ;
score = 0 ;
if(kontro == false){
score = punkteRechnen(tuleb, le0leb, le1leb, le2leb) ; //calculate the score
} else {
score = 10 ;
}
scoint = "" + score ;
MySco.setText(scoint) ;
MySco.setTextColor(Color.WHITE) ;
MySco.setTextSize(20);
/*I know that this will throw me an IllegalStateException (the specified child already has a parent)
layo.addView(Texta) ;
layo.addView(MySco) ;
layo.addView(Textb) ;
layo.addView(Textc) ;
layo.addView(Eingabe) ;
layo.addView(Back) ;
layo.addView(Enter) ;
*/
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black"
android:orientation="vertical"
tools:context=".EnterHSActivity" >
<TextView
android:id="#+id/enthst1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="#string/enthst1a"
android:textColor="#color/white"
android:textColorHint="#color/white"
android:textSize="20sp" />
<TextView
android:id="#+id/enthst2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_centerHorizontal="true"
android:text="#string/enthst1b"
android:textColor="#color/white"
android:textColorHint="#color/white"
android:textSize="20sp" />
<TextView
android:id="#+id/enthst3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:layout_centerHorizontal="true"
android:text="#string/enthst1c"
android:textColor="#color/white"
android:textColorHint="#color/white"
android:textSize="18sp" />
<Button
android:id="#+id/enthsre1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="20dp"
android:layout_marginLeft="100dp"
android:text="#string/retour" />
<Button
android:id="#+id/enthsok1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="20dp"
android:layout_marginRight="100dp"
android:text="#string/allesklar" />
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/enthsre1"
android:layout_alignRight="#+id/enthsok1"
android:layout_below="#+id/enthst3"
android:ems="10"
android:inputType="text"
android:textColor="#color/white"
android:textColorHint="#color/white"
android:textColorLink="#color/red" >
<requestFocus />
</EditText>
</RelativeLayout>
So, how do I add the score to my layout?
You should not add a view to a layout if it is already a child of that layout. When you call setcontentview your XML layout is inflated and all those views are created and added to your view hierarchy.
I would add the MySco text view to your layout XML then call findviewbyid to get it. I would avoid dynamically adding views. You can always create a view that is hidden and then show it later to get a similar effect.
Here is the modified / stripped down code for your onCreate method.
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter_hs);
MySco = (TextView)findViewById(R.id.score);
Intent intentk = getIntent();
kontro = intentk.getStringExtra("from").equals("MainActivity") ;
score = 0 ;
if(kontro == false){
score = punkteRechnen(tuleb, le0leb, le1leb, le2leb) ; //calculate the score
} else {
score = 10 ;
}
scoint = "" + score ;
MySco.setText(scoint) ;
MySco.setTextColor(Color.WHITE) ;
MySco.setTextSize(20);
In your layout add this:
<TextView
android:id="#+id/score"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:textColorHint="#color/white"
android:textSize="20sp" />
You can't call addView on textA, textB, etc, because they're already existant in your XML file, and are already children of a view. Instead you should make an empty RelativeLayout in your XML file, then create textA, etc, with new TextView(), and add those to the layout instead.
Try this it might help you.
Add the textview in relative layout to add score on layout.
MySco.setLayoutParams(new RelativeLayout.LayoutParams(300,300);
layo.addView(MySco);

textview does not display text (one text view push another far away from the screen)

Now textview shows the statement if i will scroll far away to the bottom. Looks like promis textview become to large. Is there a way to fix it?
everything under stars is part of promis textview. It is a single string with several newline characters
another screenshot
code that generate promises
prm = doc.getElementsByTagName("promise");
for (int j = 0; j < prm.getLength(); j++) {
prom += parser.getValue(e, KEY_PROMISES, j) + "\n";
}
prom.substring(0,prom.lastIndexOf('\n'));
layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/widget32"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:id="#+id/top"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/face"
android:layout_width="68dp"
android:layout_height="68dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<TextView
android:id="#+id/name"
android:layout_width="243dp"
android:layout_height="35dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="#id/face"
android:text="from" />
<TextView
android:id="#+id/office"
android:layout_width="242dp"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/face"
android:layout_alignParentRight="true"
android:layout_below="#+id/name"
android:layout_toRightOf="#id/face"
android:text="subject" />
</RelativeLayout>
<RatingBar
android:id="#+id/ratingBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/top"
android:numStars="6"
android:singleLine="false" />
<TextView
android:id="#+id/promises"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/ratingBar1"
android:layout_marginTop="5dp"
android:text="TextView" />
<ScrollView
android:id="#+id/scroll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/promises"
android:layout_marginRight="22dp"
android:layout_marginTop="26dp" >
<TextView
android:id="#+id/statement"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</ScrollView>
</RelativeLayout>
activity for my app
public class SingleMenuItemActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.candidate);
Log.d("here ?", "No ");
int loader = R.drawable.loader;
// getting intent data
Intent in = getIntent();
Log.d("here ?", "No ");
// Get XML values from previous intent
String name = in.getStringExtra("name");
Log.d("Name ", name);
Log.d("here ?", "No ");
DatabaseHandler db = new DatabaseHandler(this);
Log.d("here ?", "No ");
Candidate p = db.getCandidate(name);
Log.d("Did i take candidate? ", "yea ");
db.close();
Log.d("Statement", p.get_statment());
// Displaying all values on the screen
TextView lblName = (TextView) findViewById(R.id.name);
TextView lblOffice = (TextView) findViewById(R.id.office);
TextView lblPromise = (TextView) findViewById(R.id.promises);
TextView lblStatement = (TextView) findViewById(R.id.statement);
ImageView lblFace = (ImageView) findViewById(R.id.face);
RatingBar lblRating = (RatingBar) findViewById(R.id.ratingBar1);
ImageLoader imgLoader = new ImageLoader(this);
lblName.setText(p.get_name());
lblOffice.setText(p.get_office());
lblPromise.setText(p.get_promises());
lblStatement.setText(p.get_statment());
lblRating.setRating(p.get_ranking());
imgLoader.DisplayImage(p.get_photograph(), loader, lblFace);
}
}
logcat says p.get_statment() has proper value in it
12-16 05:07:16.089: D/Statement(279): I strive for the highest standards of appearance and personal grooming. If, like me, you think that the University's reputation is being dragged down by lecturers who have little or no regard for fashion and are content to wear ill-fitting or patched clothes then vote for me: the stylish choice.
reputation is to low to post image %)
It looks like your RatingBar is covering your statement TextView:
<RatingBar
android:layout_above="#+id/statement"
... />
Perhaps you meant layout_below?
Also your promises TextView has a very large top margin, it could be pushing the statement TextView off the bottom of the screen:
<TextView
android:id="#+id/promises"
android:layout_marginTop="124dp"
... />
Addition
Apparently there are also a number of newline characters at the end of your promises TextView. If you cannot remove these character from the source you can use trim():
prom = prom.trim();
Your code seems correct.
If the textView with the id lblStatement doesn't show the text probably you have a background where you cannot discern the text (so try to change color), or the margin are inadequate for the textview position.
If p.get_statment() has the correct value there are no others possible reasons.
Ok i found solution, besides i dont understand why textview expanded so much i know how to fix it now:)
first of all we need to know number of lines, which string will produce
private static int countLines(String str){
String[] lines = str.split("\r\n|\r|\n");
return lines.length;
}
then simply limit textview in the size
lblPromise.setMaxLines(countLines(p.get_promises()));

Cast String to TextView

String data="tv";
Also in my xml file i have a TextView called tv1.
I have casted the textView in the Activity.
TextView tv1 = (TextView) findViewById(R.id.tv1);
I want to cast the string into TextView...
so that I can perform this operation on string instead on tv1.
data.setText("abc"); // on the string..
Can i achieve this or not..Also how to dynamically assign an id to a textView.
Thanx...
This is my activity code:
public class Winnings extends Activity {
TextView tv1, tv2, tv3, tv4, tv5, tv6, tv7, tv8, tv9, tv10, tv11, tv12,
tv13, tv14, tv15;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.winnings);
setupVariables();
// TODO Auto-generated method stub
backGroundToChange(7);
}
private void setupVariables() {
// TODO Auto-generated method stub
tv1 = (TextView) findViewById(R.id.TextView01);
tv2 = (TextView) findViewById(R.id.TextView02);
tv3 = (TextView) findViewById(R.id.TextView03);
tv4 = (TextView) findViewById(R.id.TextView04);
tv5 = (TextView) findViewById(R.id.TextView05);
tv6 = (TextView) findViewById(R.id.TextView06);
tv7 = (TextView) findViewById(R.id.TextView07);
tv8 = (TextView) findViewById(R.id.TextView08);
tv9 = (TextView) findViewById(R.id.TextView09);
tv10 = (TextView) findViewById(R.id.TextView10);
tv11 = (TextView) findViewById(R.id.TextView11);
tv12 = (TextView) findViewById(R.id.TextView12);
tv13 = (TextView) findViewById(R.id.TextView13);
tv14 = (TextView) findViewById(R.id.TextView14);
tv15 = (TextView) findViewById(R.id.TextView15);
}
void backGroundToChange(int position) {
//What i want to do is this..
String data = "tv" + position;
//The casting of string into a TextView and so that I can perform this...
data.setBackgroundResource(R.drawable.option_correct);
// so by this way i don't need the switch and case that was actually used, shown below.....
//We normally implement it this way
/*
switch (position) {
case 1:
tv1.setBackgroundResource(R.drawable.option_correct);
break;
case 2:
tv2.setBackgroundResource(R.drawable.option_correct);
break;
case 3:
tv3.setBackgroundResource(R.drawable.option_correct);
break;
case 4:
tv4.setBackgroundResource(R.drawable.option_correct);
break;
case 5:
tv5.setBackgroundResource(R.drawable.option_correct);
break;
case 6:
tv6.setBackgroundResource(R.drawable.option_correct);
break;
case 7:
tv7.setBackgroundResource(R.drawable.option_correct);
break;
case 8:
tv8.setBackgroundResource(R.drawable.option_correct);
break;
case 9:
tv9.setBackgroundResource(R.drawable.option_correct);
break;
case 10:
tv10.setBackgroundResource(R.drawable.option_correct);
break;
case 11:
tv11.setBackgroundResource(R.drawable.option_correct);
break;
case 12:
tv12.setBackgroundResource(R.drawable.option_correct);
break;
case 13:
tv13.setBackgroundResource(R.drawable.option_correct);
break;
case 14:
tv14.setBackgroundResource(R.drawable.option_correct);
break;
case 15:
tv15.setBackgroundResource(R.drawable.option_correct);
break;
default:
break;
}
*/
}
xml code....
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/TextView15"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="5 Crore"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#D4A017"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="1 Crore"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="50 Lakhs"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="25 Lakhs"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="12,50,000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="6,40,000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#D4A017"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView09"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="3,20,000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView08"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="1,60,000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView07"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="80,000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView06"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="40,000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="20,000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#D4A017"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView04"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="10,000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="5,000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="2,000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textStyle="bold" />
<TextView
android:id="#+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/option_bar"
android:gravity="center"
android:text="1,000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
Images used...
You can't "cast" a String to a TextView, so I assume that what you really meant to ask is how to find a View based on its name (not its integer ID). IOW, you have a String that contains the named identifier of your TextView.
Normally you'd need to use Java reflection to do something like this, but Android provides an alternative solution through the use of getIdentifier(). This method takes a string and returns a resource ID (int), allowing you to work with resources by name. Try something like this:
private void backGroundToChange(int position) {
String resourceName = "TextView" + position;
int resourceID = getResources().getIdentifier(resourceName, "id",
getPackageName());
if (resourceID != 0) {
TextView tv = (TextView) findViewById(resourceID);
if (tv != null) {
// Take action on TextView tv here...
tv.setBackgroundResource(R.drawable.option_correct);
}
}
}
The "id" in line #3 means you're looking at the names of the R.id.* constants. You could use the same technique to find other types of resources by name (for example, Drawables). In that case, you would replace "id" with "drawable" and provide the name of one of your R.drawable.* resources.
Finally, do take note of the warning in the Android documentation:
Note: use of this function is discouraged. It is much more efficient to retrieve resources by identifier than by name.
The above code is not very efficient at all because you are calling both getIdentifier() and findViewById(), neither of which are relatively cheap operations. See my follow-up answer for a better solution.
Why on earth would you want to assign a TextView to a String? The whole point of casting is so you can leverage polymorphism (ie, cast a parent [View] to a child [TextView, Button, etc]) for your own convenience, so you don't have to write findTextViewById(), findButtonById(), etc.
It makes no sense to run .setData() on a String, but if you really want to, you can subclass String, and add that method, and update String's internal value in it.
And, in your XML, you can say:
<TextView id="#+id/new_id" />
which will generate an id for it at runtime.
EDIT: Since you're just updating a TextView's background, and a TextView is just an integer, you can do this:
public void updateBg( TextView aView )
{
aView.setBackgroundResource( R.drawable.option_correct );
}
// usage, assuming tv1 is already pointing to a TextView
upodateBg( tv1 );
EDIT 2:
private ArrayList<TextView> views = new ArrayList<TextView>();
//populate
views.add( (TextView)findViewById(R.id.whatever) );
//
public void updateView( int index )
{
(TextView)views.get(index).setBackgroundResource();
}
//usage
updateView( 7 );
EDIT 3: Or, you can just store the id's:
private static final int[] tvIds = { R.id.tv1, ... };
public void updateBg( int index )
{
((TextView)findViewById( tvIds[index] )).setBackground(...);
}
I'm leaving my first answer because it still answers the original question, but I don't think that's the best way to solve the problem as you've rephrased it.
Based on your updated question, what you really should do is put your TextViews into an array or Collection of some sort so you can access them later by position. Even findViewById() is a relatively expensive operation, so you should minimize your use of it. Consider something like this:
List<TextView> tv = new ArrayList<TextView>();
tv.add((TextView) findViewById(R.id.TextView01));
tv.add((TextView) findViewById(R.id.TextView02));
tv.add((TextView) findViewById(R.id.TextView03));
// This will get TextView02
// Remember Collections are indexed from zero
tv.get(1);
Maybe with this approach can work for you. It is the way to represent String text in TextView programmatically
mTextViewOutput.append(outputString);
There is a setText() method in the TextView class. All you need to do is call it like this:
mMyTextViewObject.setText("some text");

Populate radiobuttons from database android

i'm developing a driving school test app and I need some help.
I have xml file like this:
<!-- language: lang-xml -->
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/widget28"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#AAC1E2" >
<LinearLayout
android:id="#+id/widget29"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="#+id/i1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/e1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enun"
android:textAppearance="?android:attr/textAppearanceMedium" />
<RadioGroup
android:id="#+id/radioGroup1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="#+id/radio0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="RadioButton" />
<RadioButton
android:id="#+id/radio1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton" />
<RadioButton
android:id="#+id/radio2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton" />
</RadioGroup>
<ImageView
android:id="#+id/i2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/e2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enun"
android:textAppearance="?android:attr/textAppearanceMedium" />
<RadioGroup
android:id="#+id/radioGroup2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="#+id/radio0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="RadioButton" />
<RadioButton
android:id="#+id/radio1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton" />
<RadioButton
android:id="#+id/radio2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton" />
</RadioGroup>
... x 30 times and a button that will correct the test and show if you passed or not. You pass the test when you fail 3 questions or less.
Questions are stored this way:
Id_question Id_topic Id_test Question AnswerA AnswerB AnswerC AnswerOK Image
Id_question Id_topic and id_test are integer fields
Question and AnswerA-C are text fields
AnswerOK is an integer field. If AnswerA is OK = 1, AnswerB = 2, AnswerC = 3
Image is the name of the related image, extracted from resources folder.
I use a database to populate every field in the xml. Images and questions are extracted from database this way:
<!-- language: lang-java -->
Cursor c = adbh.query(bundle.getString("test"));
//"test"-->"SELECT question, image FROM table WHERE id_test = 1"
Integer i = 1;
if (c.moveToFirst()) {
do {
String path = c.getString(index);
String nimage = "i"+i;
int idImage = getResources().getIdentifier(nimage, "id", this.getPackageName());
ImageView image = (ImageView) findViewById(idImage);
int idDrawable = getResources().getIdentifier(ruta, "drawable", this.getPackageName());
image.setImageResource(idDrawable);
String nenun = "e"+i;
String enun = c.getString(anotherIndex);
int idEnun = getResources().getIdentifier(nenun, "id", this.getPackageName());
TextView txtenun = (TextView) findViewById(idEnun);
txtenun.setText(enun);
i++;
} while (c.moveToNext());
How can I populate radiobuttons? The query would be "SELECT AnswerA, AnswerB, AnswerC from table WHERE id_test = 1"
And my last question is how can I correct the test. I think on storing radiobutton pressed (I don't know exactly how) in an array and then compare with correct answers. The query would be "SELECT AnswerOK from table WHERE id_test = 1".
Example:
Array of answered questions:
1 1 1 2 2 3 2 3 1 3 2...
Array of correct answers:
3 2 1 2 2 3 2 3 2 2 2...
<!-- language: lang-java -->
for (int i=0; i<30; i++)
if (a[i] == b[i])
numberOfRightAnswers++;
Thank you :)
How can I populate radiobuttons? The query would be "SELECT AnswerA,
AnswerB, AnswerC from table WHERE id_test = 1"
Will probably want to select those values directly in the first query, so instead of :
Cursor c = adbh.query(bundle.getString("test"));
//"test"-->"SELECT question, image FROM table WHERE id_test = 1"
will have:
Cursor c = adbh.query(bundle.getString("test"));
//"test"-->"SELECT question, AnswerA, AnswerB, AnswerC, image FROM table WHERE id_test = 1"
Then in that while loop assign the text to the RadioButtons like you did for TextView txtenun.
And my last question is how can I correct the test. I think on storing
radiobutton pressed (I don't know exactly how) in an array and then
compare with correct answers.
Add a OnCheckedChangeListener() to all of your RadioGroups. In that listener you'll get the RadioGroup where the user checked something and the id of the checked RadioButton. Use that to construct the array of correct answers.
Some advices:
Maybe you should modify your layout and your current approach. Making the user scroll your 30 question layout might not be such a good idea, also you're loading many resources although the user will not actually see them until it gets to that particular question(I don't know the size of your image, if they are small this probably isn't an issue). You're other alternatives are a ListView layout or a simple layout of one question that you populate on demand depending on which questions is the user at. My advice would be the second option. That option will also help you avoid the getIdentifier method calls, this method is slower then the findViewById and should be avoided. Bellow is a layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#AAC1E2" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="#+id/questionImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/questionText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enun"
android:textAppearance="?android:attr/textAppearanceMedium" />
<RadioGroup
android:id="#+id/radioGroup1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="#+id/radio0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="RadioButton" />
<RadioButton
android:id="#+id/radio1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton" />
<RadioButton
android:id="#+id/radio2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton" />
</RadioGroup>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:weightSum="3" >
<Button
android:id="#+id/previousQuestion"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="previous" />
<Button
android:id="#+id/validateTest"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="validate" />
<Button
android:id="#+id/nextQuestion"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="next" />
</LinearLayout>
</LinearLayout>
</ScrollView>
You'll make a query for all the question in that test(including all the data) and start with a static field int counter = 0. When the app is started you'll move the cursor to the counter value(which is 0 at the start):
c.moveToPosition(counter);
and use the values from that row to populate the above question layout:
ImageView questionImage = (ImageView) findViewById(R.id.questionImage);
int idDrawable = getResources().getIdentifier(ruta, "drawable", this.getPackageName());
questionImage.setImageResource(idDrawable);
String enun = c.getString(anotherIndex);
TextView txtenun = (TextView) findViewById(R.id.questionText);
txtenun.setText(enun);
// will do the same to populate the other parts of the question from the cursor
When the user presses the nextQuestion Button you'll increment the counter value(you should do some checks so you don't go overboard the 30 questions), move the cursor to the counter position again and then populate the layout like above. When the user presses previousQuestion you decrement counter, move the cursor and again populate the layout with data.
Also you'll add only one OnCheckedChangeListener to your RadioGroup. When that listener fires you should store the question id(from the counter value you should be able to tell on which question you are) and the selected RadioButton in a data structure(probably a HashMap), retrieve the correct answers for the test from the database and see if the user it's a good driver.
Also you could(probably) optimize your database.
Edit:
private ArrayList<Integer> responses = new ArrayList<Integer>(); // this will hold the number of the correct answer. Note that this will work if the user answers question one after the other
// if the user skips question you'll get in trouble, this is one of the reasons why your design is not so good.
String rg = "radioGroup" + i;
int idRg = getResources().getIdentifier(rg, "id", this.getPackageName());
RadioGroup radioGroup = (TextView) findViewById(idRg);
radioGroup.setOnChekedChangeListener(new OnCheckedChangeListener(){
public void onCheckedChanged (RadioGroup group, int checkedId) {
if (group.getChildAt(0).getId() == checkedId) {
responses.add(0); // the first answer was checked
} else if (group.getChildAt(1).getId() == checkedId) {
responses.add(1); // the first answer was checked
} else if (group.getChildAt(2).getId() == checkedId) {
responses.add(2); // the first answer was checked
}
}
});
According to #Luksprog answer this is my finally working loop:
Cursor c = adbh.query(bundle.getString("test"));
Integer i = 1;
if (c.moveToFirst()) {
do {
String ruta = c.getString(4);
String nimage = "i" + i;
int idImage = getResources().getIdentifier(nimage, "id",
this.getPackageName());
ImageView image = (ImageView) findViewById(idImage);
int idDrawable = getResources().getIdentifier(ruta, "drawable",
this.getPackageName());
image.setImageResource(idDrawable);
String rgname = "radioGroup"+i;
int idRg = getResources().getIdentifier(rgname, "id",
this.getPackageName());
RadioGroup rg = (RadioGroup) findViewById(idRg);
rg.removeAllViews();
RadioButton rb1 = new RadioButton(this);
rb1.setId(i);
rb1.setText(c.getString(1));
rg.addView(rb1);
RadioButton rb2 = new RadioButton(this);
rb2.setId(i+1);
rb2.setText(c.getString(2));
rg.addView(rb2);
RadioButton rb3 = new RadioButton(this);
rb3.setId(i+2);
rb3.setText(c.getString(3));
rg.addView(rb3);
String nenun = "e" + i;
String enun = c.getString(0);
int idEnun = getResources().getIdentifier(nenun, "id",
this.getPackageName());
TextView txtenun = (TextView) findViewById(idEnun);
txtenun.setText(enun);
i++;
} while (c.moveToNext());

Categories

Resources