Results 1 to 10 of 10
Thread: OnClick inside a loop
- 05-26-2011, 01:38 AM #1
OnClick inside a loop
I am doing some Android programming, and I had a question about onClickListeners (android is done in Java).
I am dynamically creating table rows as I walk down Cursor results of an SQL query and adding them to the table. Right before I add the table to the row, I am trying to set a listener for EACH row, and the action will be based on the row. The problem is that when the action is triggered, 'rowCount' keeps evaluating to the total # of Rows, instead of what it was at the time I created the Listener. Any way to get this to work?
Java Code:while(values.moveToNext()){ System.out.println("On Row "+RowCount); trA[RowCount] = new TableRow(this); trA[RowCount].setId(RowCount); trA[RowCount].setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { // SetValues(trA[RowCount].getId()); } }); //Add the Row to the table tl.addView(trA[RowCount]); RowCount++; }
- 05-26-2011, 02:49 AM #2
Sounds like you're not reseting the value. What shows when the println is printed on entry to the loop?'rowCount' keeps evaluating to the total # of Rows, instead of what it was at the time I created the Listener
- 05-26-2011, 03:13 AM #3
I switched it around a little bit. I set currentRow to-1 right before the loop, and do the increment as soon as I enter the loop. There are 6 rows in the table(cursor results) so I get
On Row 0
On Row 1
On Row 2
On Row 3
On Row 4
On Row 5
I think the issue is the listener. I guess when the code reaches the setOnClickListener, it doesn't actually do anything, other than recognize that a listener is created? So after the table is created, I click on a row, and the listener is activated, but the code inside the listener references 'currentRow', but I was hoping that the 'currentRow' it used was the 'currentRow' at the time I 'declare' the listener, but apparently not because when I click the row, the currentRow value it uses is 5, no matter which row I click on.
So it looks like this
Java Code:currentRow=-1; while(values.moveToNext()){ currentRow++; System.out.println("On Row "+currentRow); trA[currentRow] = new TableRow(this); trA[currentRow].setId(currentRow); trA[currentRow].setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { // SetValues(trA[currentRow].getId()); } }); //Add the Row to the table tl.addView(trA[currentRow]); }Last edited by sehudson; 05-26-2011 at 03:24 AM.
- 05-26-2011, 03:18 AM #4
Do you mean at the time you create an instance of the listener?at the time I 'declare' the listener
You could pass the current value of the variable to the listener when you create the listener.
Or when you add the listener to the component that has the actions listened for?
Add a method to the listener to call to pass the value of the variable at that time.
- 05-26-2011, 03:27 AM #5
I think I see what you are saying, you mean in the 'guts' of the listener?
This portion,
Java Code:trA[currentRow].setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { //logic here????? } });
I don't think that part gets evaluated until the event actually occurs.
- 05-26-2011, 03:32 AM #6
I gave two options, which are you referring to?
Instead of using an anonymous class, create one that you can pass args to its constructorI don't think that part gets evaluated until the event actually occurs.
Or perhaps you could add a line in what your have: ???
Java Code:trA[currentRow].setOnClickListener( new OnClickListener() { final int SavedRowCnt = currentRow; // Save current value @Override public void onClick(View v) { //logic here????? } });
- 05-26-2011, 03:57 AM #7
can you show an example of your 1st suggestion, I'm not sure what you mean.
"Instead of using an anonymous class, create one that you can pass args to its constructor"
- 05-26-2011, 01:45 PM #8
I meant to say: define a new class that is a listener with a constructor that you can pass the values to the object.
Something like:Java Code:class MyListener extends listener { MyListener(int valueToSave) { this.valueToSave = valueToSave; // save value locally
- 05-29-2011, 04:56 AM #9
I created a class called MyListener
As I create each row, I am setting up each of the Listeners in my MyClickListener[]:Java Code:public class MyListener implements OnClickListener { private int rowID; public MyListener(int valueToSave) { this.rowID = valueToSave; // save value locally System.out.println("*** Row"+valueToSave); } @Override public void onClick(View v) { // TODO Auto-generated method stub } }
ocl[rowCount] = new MyListener(rowCount)
I have a print out, so I see that the listener is being created, but for some reason, this guy isn't being triggered when I click on a row.
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}Last edited by sehudson; 05-29-2011 at 05:01 AM.
- 05-29-2011, 06:14 AM #10
Moderator
- Join Date
- Feb 2009
- Location
- New Zealand
- Posts
- 4,547
- Rep Power
- 11
Are you calling setOnClickListener() on the view to associate the listener with it?but for some reason, this guy isn't being triggered when I click on a row.
------------
As you have seen the value the listener gets is the value you give it when you create it. Using a global variable for the row count is asking for trouble: use a local one passed to the listener's constructor or just made final as in the following Swing example:
Java Code:import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class ListenerEg extends JPanel { private static final int NUM = 10; // better not to have a variable row... private int row; public ListenerEg() { super(new GridLayout(0, 1)); for(row = 0; row < NUM; row++) { JButton toAdd = new JButton("Click me!"); final int num = row; toAdd.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { System.out.println("Click! num=" + num + " row=" + row); } }); add(toAdd); } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new JFrame("ListenerEg test"); frame.add(new ListenerEg()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } }); } }
Similar Threads
-
Help with while loop inside a switch case
By Shesaid in forum New To JavaReplies: 2Last Post: 04-01-2011, 03:36 AM -
if else inside while loop??
By jonytek in forum New To JavaReplies: 3Last Post: 02-17-2011, 09:28 AM -
Loop inside a switch
By mustachMan in forum New To JavaReplies: 3Last Post: 02-26-2010, 03:25 AM -
Problem printing inside FOR loop
By cassysumandak in forum New To JavaReplies: 1Last Post: 10-04-2009, 05:02 PM -
println doesn't print from inside for loop, et.al.
By rdtindsm in forum New To JavaReplies: 5Last Post: 03-27-2009, 01:19 PM


LinkBack URL
About LinkBacks
Reply With Quote
Bookmarks