title: How to change data in dynamically added Android Views at runtime
body: <p>I have and <code>Android</code> app which adds <code>TableViews,</code> <code>TableRows</code> and <code>TextViews</code> dynamically at run time according to data found in a <code>Firebase</code> repository. More specifically, a <code>TableView</code> is added for each "Poll" found in the repo to the static <code>LinearLayout</code>, for each "Election" found in the Poll a <code>TableRow</code> is added to that <code>Tablelayout</code>, and for each "Nominee" in the Election a <code>TableRow</code> containing two <code>TextViews</code> for data is added to the <code>TableLayout</code> as well. So potentially I could have multiple tables added at runtime, each containing rows for multiple elections, and each election having multiple data rows for nominees. Here's my static layout for good measure....</p>
  
  <pre><code>     &lt;?xml version="1.0"?&gt;
      &lt;ScrollView android:layout_height="android:layout_width="match_parent" android:id="@+id/scrollView1" xmlns:android="http://schemas.android.com/apk/res/android"&gt;
  
  &lt;LinearLayout android:layout_height="match_parent" android:layout_width="match_parent" android:id="@+id/linearLayout" android:orientation="vertical"&gt; 
  &lt;/LinearLayout&gt;
  
      &lt;/ScrollView&gt;
  </code></pre>
  
  <p>..and here's a representation of my <code>Firebase</code> repo...</p>
  
  <pre><code>-POLLS
      NUMPOLLS - 5
      (pollskey) - NAME - Poll1
              NUMELECTIONS - 2
              ELECTIONS 
                  (electionskey) - NAME - Election1
                          NUMNOMINATIONS - 2
                          NUMVOTERS - 2
                          NUMBERTOELECT - 1
                          VOTERS - (votesrkey) - NAME - Charles
                                           NUMBER - (678) 333-4444
                                   .
                                   .
                                   .
                                   (voterskey) - ...
                          NOMINATIONS - (nominationskey) - NAME - Richard Nixon
                                                NUMBEROFVOTES - 2
                                         .
                                         .
                                         .
                                        (nominationskey) - ...
              .
              .
              .
              (electionskey) - ...
       .
       .
       .
       (pollskey) - ...
  </code></pre>
  
  <p>So my question really has two threads. The first is Android oriented...</p>
  
  <ol>
  <li>What's the best way to iterate through <code>Android</code> views added dynamically to change <code>TextView</code> data when data in the repo changes, it being the case that I have no idea how many such <code>TableView</code>, or <code>TableRows</code> there will be at compile time? </li>
  </ol>
  
  <p>Right now I'm doing something like this, but it's very slow going I feel like there has to be a better way...</p>
  
  <pre><code>private void appendCandidatesAndVotes(DataSnapshot election, TableLayout tbl) {
          Random randGen = new Random();
          DataSnapshot nominees = election.child("Nominations");
          for (DataSnapshot nominee : nominees.getChildren()) {
  
              // Create row for candidate name and number of votes
              TableRow rowNameAndVotes = new TableRow(this);
              // Generating a random row ID here allows us to pass this to 
              // the valueEventListener and quickly locate this row in 
              // the case of a data change (someone has cast a vote) so we 
              // can update
              int uniqueRowId = randGen.nextInt(1000);
              rowNameAndVotes.setId(uniqueRowId);
              rowNameAndVotes.setBackgroundColor(Color.WHITE);
              rowNameAndVotes.setLayoutParams(new TableRow.LayoutParams (
                      LayoutParams.MATCH_PARENT,
                      LayoutParams.WRAP_CONTENT));
  
              // Create candidate name view
              TextView viewCandidateName = new TextView(this);
              viewCandidateName.setId(2);
              viewCandidateName.setText(nominee.child("Name").getValue(String.class));
              viewCandidateName.setTextColor(Color.BLACK);
              viewCandidateName.setPadding(5,  5,  5, 5);
              rowNameAndVotes.addView(viewCandidateName);
  
              // Create number of votes view
              TextView viewNumVotes = new TextView(this);
              viewNumVotes.setId(3);
              viewNumVotes.setText(nominee.child("NumberOfVotes").getValue(String.class));
              viewNumVotes.setTextColor(Color.BLACK);
              viewNumVotes.setPadding(3,  5,  5,  5);
              rowNameAndVotes.addView(viewNumVotes);
  
              // Add row to table
              tbl.addView(rowNameAndVotes);
  
              // Lets get a Firebase reference for this nominee and
              // attach a listener to alert us to all future changes of
              // the values therein, so we can update vote counts dynamically
              Firebase nomineeRef = nominee.getRef();
              nomineeRef.addValueEventListener(new ValueEventListener() {
  
                  @Override
                  public void onDataChange(DataSnapshot nomineeSnapshot) {
  
                      String nomineeName = nomineeSnapshot.child("Name").getValue(String.class);
                      LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
                      int layoutChildCount = layout.getChildCount();
                      for (int i = 0; i &lt; layoutChildCount; i++) {
                          View layoutChildView = layout.getChildAt(i);
                          // If its a Table, loop through all row
                          if (layoutChildView instanceof TableLayout) {
                              TableLayout tbl = (TableLayout)layoutChildView;
                              int tableChildCount = tbl.getChildCount();
                              for (int j = 0; j &lt; tableChildCount; j++) {
                                  View tblChildView = tbl.getChildAt(i);
                                  if (tblChildView instanceof TableRow) {
                                      TableRow row = (TableRow)tblChildView;
                                      int rowChildren = row.getChildCount();
                                      for (int k = 0; k &lt; rowChildren; k++) {
                                          TextView tv = (TextView)(row.getChildAt(k));
                                          String rowCandidateName = tv.getText().toString();
                                          if (rowCandidateName) ...
                                      }
                                  }
                              }
                          }
                      }
                  }
  </code></pre>
  
  <p>I <em>think</em> the way this is layed out, the only layout I can directly refer to is the base <code>LinearLayout</code>. I can give all <code>TableRows</code> unique ids with <code>setId()</code>, but as far as I know I can't pass any data to the <code>ValueEventListener</code>, nor can I refer to any variables in the enclosing scope (I hope I'm wrong about this, it would make things way easier). I know I can refer to static final variables inside the <code>ValueEventListener</code>, but I don't see how this will help me since I don't know how many Tables or Rows I'll be dealing with at runtime. </p>
  
  <p>So, in short, how can I link a particular call to the <code>ValueEventListener</code> with the <code>TableRow</code> it's data is associated with?</p>
  
  <p>Now for question 2, which is a bit more <code>Firebase</code> specific....</p>
  
  <ol>
  <li>It seems like <code>ValueEventListener</code> is called once when the activity is loaded, and then again for any changes to the underlying data. But I only want it called for changes to underlying data, not on loading. Am I using the wrong EventListener? Or is there some way to avoid this behavior?</li>
  </ol>