java - How to change data in dynamically added Android Views at runtime -
i have , android
app adds tableviews,
tablerows
, textviews
dynamically @ run time according data found in firebase
repository. more specifically, tableview
added each "poll" found in repo static linearlayout
, each "election" found in poll tablerow
added tablelayout
, , each "nominee" in election tablerow
containing 2 textviews
data added tablelayout
well. potentially have multiple tables added @ runtime, each containing rows multiple elections, , each election having multiple data rows nominees. here's static layout measure....
<?xml version="1.0"?> <scrollview android:layout_height="android:layout_width="match_parent" android:id="@+id/scrollview1" xmlns:android="http://schemas.android.com/apk/res/android"> <linearlayout android:layout_height="match_parent" android:layout_width="match_parent" android:id="@+id/linearlayout" android:orientation="vertical"> </linearlayout> </scrollview>
..and here's representation of firebase
repo...
-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) - ...
so question has 2 threads. first android oriented...
- what's best way iterate through
android
views added dynamically changetextview
data when data in repo changes, being case have no idea how many suchtableview
, ortablerows
there @ compile time?
right i'm doing this, it's slow going feel there has better way...
private void appendcandidatesandvotes(datasnapshot election, tablelayout tbl) { random randgen = new random(); datasnapshot nominees = election.child("nominations"); (datasnapshot nominee : nominees.getchildren()) { // create row candidate name , number of votes tablerow rownameandvotes = new tablerow(this); // generating random row id here allows pass // valueeventlistener , locate row in // case of data change (someone has cast vote) // 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 table tbl.addview(rownameandvotes); // lets firebase reference nominee , // attach listener alert future changes of // values therein, 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(); (int = 0; < layoutchildcount; i++) { view layoutchildview = layout.getchildat(i); // if table, loop through row if (layoutchildview instanceof tablelayout) { tablelayout tbl = (tablelayout)layoutchildview; int tablechildcount = tbl.getchildcount(); (int j = 0; j < tablechildcount; j++) { view tblchildview = tbl.getchildat(i); if (tblchildview instanceof tablerow) { tablerow row = (tablerow)tblchildview; int rowchildren = row.getchildcount(); (int k = 0; k < rowchildren; k++) { textview tv = (textview)(row.getchildat(k)); string rowcandidatename = tv.gettext().tostring(); if (rowcandidatename) ... } } } } } }
i think way layed out, layout can directly refer base linearlayout
. can give tablerows
unique ids setid()
, far know can't pass data valueeventlistener
, nor can refer variables in enclosing scope (i hope i'm wrong this, make things way easier). know can refer static final variables inside valueeventlistener
, don't see how me since don't know how many tables or rows i'll dealing @ runtime.
so, in short, how can link particular call valueeventlistener
tablerow
it's data associated with?
now question 2, bit more firebase
specific....
- it seems
valueeventlistener
called once when activity loaded, , again changes underlying data. want called changes underlying data, not on loading. using wrong eventlistener? or there way avoid behavior?
for firebase specific question - design. firebase doesn't encourage distinguishing between initial data , data updates, since in real-time scenario can never "caught up" latest data.
if don't want retrieve data on startup, i'd use queries , limits restrict data can receive. instance, if want receive latest 100 polls, like:
firebase ref = new firebase(url); query q = ref.limit(100); q.addchildeventlistener(...);
and child event listener called once per poll. when new poll added called again (and there child-removed event oldest poll in list of 100).
hope helps!
Comments
Post a Comment