getChildCount() returns 0 when called on TableLayout - java

This question is related to one I posted earlier. Views removed using removeView() are there when I next open the Activity (Android)
Background: When a user logs into my app they are taken from the login activity to the mainpage activity. The mainpage has a TableLayout that contains dynamically generated buttons. However if the user logs out and back in again, all of these buttons are repeated so I am trying to find out how best to remove these buttons after they are generated. In my previous post it was suggested I remove the buttons at the very start of the main page activity, before the new ones are drawn, so this is what I am trying to implement.
However when I call getChildCount() on this layout it does not always return the correct answer.
So far, here is the code that is run at the start of the main page activity:
TableLayout tableLayout = (TableLayout)findViewById(R.id.MainPageTableTitle);
//removeSectionButtons(tableLayout); this is where i am trying to remove the buttons
System.out.println("there are oncreate " + tableLayout.getChildCount());
drawButtons(tableLayout);
System.out.println("there are ondraw " + tableLayout.getChildCount());
The first print line returns 0 and the second print line always returns the correct answer (number of buttons drawn including all of the repeated ones). But I am not sure why getChildCount() returns the wrong answer the first time. If anyone can explain I would be incredibly grateful
My drawButtons() method is as follows (it draws two buttons per row):
public void drawButtons(TableLayout tableLayout){
//get the number of buttons
int noOfButtons = mySectionTableHandler.getSectionDetails().size();
//calculate the number of rows needed (there are 2 columns)
//set flag to say if buttons are odd as it affects how many are drawn
int noOfRows;
boolean evenNoOfButtons;
if(noOfButtons % 2 == 0){
//even no of buttons
noOfRows = noOfButtons/2;
evenNoOfButtons = true;
} else {
//odd no of buttons
noOfRows = (noOfButtons+1)/2;
evenNoOfButtons = false;
}
//counter to give each button a unique id
int counter = 1;
for(int i = 0; i<noOfRows;i++){
TableRow newRow = new TableRow(this);
Button a = new Button(MainPageActivity.this);
a.setId(counter);
sectionButtons.put(counter, a);
counter++;
newRow.addView(a);
//if there are even buttons OR if there are an odd no
//of buttons but this isn't the last row then add
//second button to row
if(evenNoOfButtons || (!evenNoOfButtons && (noOfRows-1!=i))){
Button b = new Button(MainPageActivity.this);
b.setId(counter);
sectionButtons.put(counter, b);
counter++;
newRow.addView(b);
}
tableLayout.addView(newRow);
}
}

This was my bad, turns out I was re-adding data to the sqlite database each time the user logged in without wiping previous details.
So my code was generating a button for every field in the database as it should have been.

Related

Why I can't update my database when saving data from 10 radioButtons?

I have 10 toggleGroup Buttons with 4 radio buttons each. When you click one radio button within a toggle group, It will add the index value of the selected radio button to an Arraylist. THen I have a "save" button to save those values to a database.
public ArrayList<Integer> RightInt(){
for(ToggleGroup tg: toggleRDB()) {
tg.selectedToggleProperty().addListener((observable, oldValue, newValue) ->{
if(newValue != null) {
//adds the index of the selected RadioButton to selectedRDBIndex list
selectedRDBIndex.add(tg.getToggles().indexOf(newValue));
}
});
}
return selectedRDBIndex;
}
//selectedRDBIndex is an ArrayList<Integer> storage.
The code above returns a list of Integer with 10 values.
This code is the action performed by the save button.
for(int i = 0; i < 10; i++) {
//answerStore.storeRDB connects to my dataBase to save the values returned by the RightInt() function.
answerStore.storeRDB(i+1, TB, RightInt().get(i));
}
RightInt().clear();
The code above works well. It saves and updates values to my database.
Then I decided to use those values again here:
for(int i = 0; i<10 ; i++) {
toggleRDB().get(i).getToggles().get(answerStoration.retrieveDataRDBSet(i+1,TB)).setSelected(true);
}
//toggleRDB() returns a list of toggleGroups.
//answerStoration.retrieveDataRDBSet gets the radioButton integer data in the database that i used to setSelect an index of radioButton in each toggle group.
I used all these codes so that when the user selected a radioButton that progress will be saved. But after using the code above I can't update datas in my database. I hope you understood my situation and solve this problem. THanks in advance.
I got some hints on my problem. When I click a radio button
It adds another place on the arraylist that's why the values aren't changing. Now I need figure out where to place a set () method or how to replace those values. I would like to say that clearing the list is not an option.

Is it possible to convert a table row into string in Android?

I am developing my first Android app. I have a table layout in my app, which will add rows dynamically. But, I want to convert the table rows into string. I tried "row.toString()" but I am not getting the expected result. Please find the following code snippet:
View view = null;
for(i = 0, j = tblayout.getChildCount(); i < j; i++)
{
view = tblayout.getChildAt(i);
TableRow rw = (TableRow)tblayout.getChildAt(i);
ColorDrawable viewColor = (ColorDrawable) view.getBackground();
int colorId = viewColor.getColor();
if(colorId == Color.parseColor("#E143ED23")) {
num ++;
//temCnt = view.toString();
temCnt = rw.toString();
}
}
Toast.makeText(getApplicationContext(),temCnt, Toast.LENGTH_LONG).show();
But it is not showing the actual table row data. It is showing some ids' or garbage value.
My requirement is:
I have 2 text boxes and 2 buttons. When the first button "Ok" is pressed the value inside the text boxes will be populated into the Table layout along with a checkbox. By default the row will be checked. But user can uncheck each items. After that, when the second button "Save All" is pressed, then it will search for all the table rows which are checked and it should insert the table rows into the my MS SQL table.
Is there any way for converting the table row into a string in Java? I really trapped on this. It would be very helpful if someone can help me on this.
Please help...
toString() is a very basic method in Java, C# and other programming languages. Java's Object class has a basic implementation for it and you can override this method in any class that inherits from Object (that is, every class whatsoever :)). I don't know if those that developed the TableRow class of Android have overridden this method. It could be that what you're getting is some unreadable, meaningless representation of a TableRow object.
Let's say you have a TextView called txtName within the TableRow, followed by a second TextView called txtNumber. You can get what you want by doing the following:
...
ColorDrawable viewColor = (ColorDrawable) view.getBackground();
int colorId = viewColor.getColor();
if(colorId == Color.parseColor("#E143ED23")) {
num ++;
//temCnt = view.toString();
TextView nameField = (TextView) rw.findViewById(R.id.txtName);
TextView numberField = (TextView) rw.findViewById(R.id.txtNumber);
temCnt = nameField.getText().toString() + ": " + numberField.getText().toString();
}
...

Is it possible to retrieve the drawable name that's occupying an imageView that's using a random array

I have a educational kids game where the object is to match the image with the correct answer, 4 buttons provided for potential answers. The first part was to randomly fill the imageView with drawables that never repeat up to end of game. This part I have figured out and works. The part I'm having trouble with is dealing with the idea on how to compare what random image is in the imageView at that moment to
1. Make sure one of the four options is a correct answer and
2. To compare whatever is clicked to what is in the imageView at that time.
I tried imgView.getId(); , but it didn't work.
Array
private ArrayList<Integer> res1 = new ArrayList<Integer>();
int arrPos = 0;
Method that randomizes
private void randomImage1() {
Collections.shuffle(res1);
imgView.setImageResource(res1.get(arrPos));
arrPos = arrPos + 1;
}
onclick
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(counter <= 2){
imgView.setImageResource(res1.get(arrPos));
//randomImage1();
counter = counter + 1;
arrPos = arrPos+1;
System.out.println(arrPos);
Toast.makeText(getApplicationContext(), Integer.toString(counter) ,
Toast.LENGTH_SHORT).show();
}else if(counter == 3){
Toast.makeText(getApplicationContext(), Integer.toString(counter) + "Game Over",
Toast.LENGTH_SHORT).show();
}
}
});
My idea is to assign an id for each image + correct answer and maintain a list of available ids (with corresponding images and correct answers). So for your questions:
Make sure one of the four options is a correct answer
Get a random id, get the corresponding image to display and corresponding correct answer to be one of the 4 options. Take the id out from the list, get 3 other options from the rest of the id and their corresponding answers.
To compare whatever is clicked to what is in the imageView at that time.
When you display ImageView and options you can use android:tag to keep the ids of the correct answers and incorrect answers.
Then in your code, use getTag() on the view to get the ids of the image and the chosen answer for comparison.
Hope it helps.
Set an id for each image and get the id of image on click. Maintain the HashMap for comparison between the image selected and its answers.

Edit dynamically created button in android

I am working on an android server-client application. There is a connection between the android application and the server.
Based on the first message from the server, a number of buttons is created and displayed on the screen. This number usually is between 1 and 10.
I don't want to initialise 10 buttons in my activity, as maybe, in the future, the number of buttons will increase to 20.
This is the way I initialise buttons and show them on the screen:
actionButtons = server.getActionButtons();
TableLayout buttonLayout =
(TableLayout) rootView.findViewById(R.id.tblLayoutButtons);
for(int i=0; i< actionButtons.length; i++)
{
btnAction.setWidth(100);
btnAction.setHeight(50);
btnAction.setTag(actionButtons[i]);
btnAction.setText(actionButtons[i].getName());
btnAction.setOnClickListener(btnActionClick);
buttonLayout.addView(btnAction);
}
This all works well. But my problem is that the server sends statusupdates for the buttons, every 3 seconds. Each button stands for a light, that can be on or off. A button that is 'ON' should have another background than a button that is 'OFF'. The buttons should be updated every time an update from the server is received.
How could this be done?
I would make it like this:
public void createButtons() {
actionButtons = server.getActionButtons();
TableLayout buttonLayout = (TableLayout) rootView.findViewById(R.id.tblLayoutButtons);
for(int i=0; i< actionButtons.length; i++)
{
btnAction.setWidth(100);
btnAction.setHeight(50);
btnAction.setTag(actionButtons[i]);
btnAction.setText(actionButtons[i].getName());
btnAction.setOnClickListener(btnActionClick);
btnAction.setId(i);
buttonLayout.addView(btnAction);
}
}
public void updateButton() {
//Get the ID of the button to toggle from the server and get the related view
ToggleButton buttonToToggle = (ToggleButton) findViewById(Integer.parseInt(server.getMessage()));
if (buttonToToggle.isChecked()) {
buttonToToggle.setChecked(false);
buttonToToggle.setBackground(R.drawable.offImage)
}
else {
buttonToToggle.setChecked(true);
buttonToToggle.setBackground(R.drawable.onImage)
}
}
This has the advantage, that you just have to send the ID of the Button and it gets toggled.
Alternatively you could send the binary value off all buttons, so you have to send also just a few bytes... In this case, you can assign the buttons their value in a for loop, almost like you create them.
Hope I helped ;)
If you want to change status of an already created Button then while creating them at run time assign them unique Id's using setID(int) method from the View class.
So for your button1 you can,
button1.setId(100);
and when you want to change thngs you can fetch the ID for the button and change it appropriately.
if(toChangeButton.getID() == 100){
//Change button1
}
Hope this helps.
Try to use the listview to add the buttons.When you get the data from the server,just update the adapter of the listview.
Hope this helps.

Displaying empty rows in Android listview

So I'm wondering how to go about filling a ListView with empty rows. The ListView is populated via SQLite db so say for instance there is only 3 items in the list I want to fill the rest of the screen with empty rows. Here is a screenshot of what I mean. Yes I know it's from iPhone but it demonstrates what I mean:
The cheap way is to add extra "rows" in your layout xml. Any extra rows will be cut off by the screen. This can get messy: a higher-res screen might require you add many extra TextViews. Since they get cut off, I suppose you could add as many as you'd like. It would look something like this:
<LinearLayout>
<ListView></ListView>
<TextView/>
<TextView/>
<TextView/>
...
</LinearLayout>
Another option is to add extra rows to your ListView, as mentioned previously. If you are bound to an array, add extra blank rows to the array and handle it appropriately. Coincidentally, if you are using a Cursor you can use a MaxtrixCursor & MergeCursor as described in this answer
I ended up using a combination of these methods. I try my best to calculate the number of rows I want to add to my ListView, but I error on the side of caution and have a couple TextViews underneath my ListView that make it all come together.
When you create the Array the is going to be bound to the ListView you just need to add a few rows at the end of the Array with empty strings.
Using a textview below the listview seems to give the illusion of what I was going for.
#kabir's solution works. Now if you are like me (wanted to have two alternate colors in background, this is his dispached method rewritten (or let's say edited)
#Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
int caseLastChildBottom = -1;
int caselastChildHeight = -1;
int caseNrOfLines = -1;
//makes the colors follow the order (alternateColor1 - alternateColor2 - alternateColor1 - etc.)
int plusIndex = 1;
if (this.getChildCount() % 2 == 0)
plusIndex = 0;
// ListView's height
final int currentHeight = getMeasuredHeight();
// this will let you know the status for the ListView, fitting/not fitting content
final int scrolledHeight = computeVerticalScrollRange();
//empty listview (no item)
if (scrolledHeight == 0) {
//no childs exist so we take the top
caseLastChildBottom = 0;
//last child doesn't exist, so we set a default height (took the value in dp in the item row's height)
caselastChildHeight = convertDpToPx(DEFAULT_CHILD_ROW_S_HEIGHT);
// determine the number of lines required to fill the ListView
caseNrOfLines = currentHeight / caselastChildHeight;
}
//there is a remaining gap to fill
else {
final View lastChild = getChildAt(getChildCount() - 1);
if (lastChild == null) return;
// values used to know where to start drawing lines
caseLastChildBottom = lastChild.getBottom();
// last child's height(use this to determine an appropriate value for the row height)
caselastChildHeight = lastChild.getMeasuredHeight();
// determine the number of lines required to fill the ListView
caseNrOfLines = (currentHeight - caseLastChildBottom) / caselastChildHeight;
}
// values used to know where to start drawing lines
final int lastChildBottom = caseLastChildBottom;
// last child's height(use this to determine an appropriate value for the row height)
final int lastChildHeight = caselastChildHeight;
// determine the number of lines required to fill the ListView
final int nrOfLines = caseNrOfLines;
int i = 0;
for (i = 0; i < nrOfLines; i++) {
Rect r = new Rect(0, lastChildBottom + i * lastChildHeight, getMeasuredWidth(), lastChildBottom + (i + 1) * lastChildHeight);
canvas.drawRect(r, (i + plusIndex) % 2 == 0 ? alternateColorView1 : alternateColorView2);
}
//is there a gap at the bottom of the list
if(currentHeight - (nrOfLines *lastChildHeight) > 0){
Rect r = new Rect(0, lastChildBottom + i * lastChildHeight,getMeasuredWidth(), currentHeight);
canvas.drawRect(r, (i + plusIndex) % 2 == 0 ? alternateColorView1 : alternateColorView2);
}
return;
}
I forgot these two Paint colors (just as #kabir declared the colors):
alternateColorView1.setColor(....);
alternateColorView1.setStyle(Paint.Style.FILL);
alternateColorView2.setColor(....);
alternateColorView2.setStyle(Paint.Style.FILL);

Categories