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
androidviews added dynamically changetextviewdata when data in repo changes, being case have no idea how many suchtableview, ortablerowsthere @ 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
valueeventlistenercalled 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