I am trying to create dynamic buttons. When clicking a button it should go to the specified url assigned to the text of the button.
For testing, first I tried to get that ID, if it is equal it prints the value of i. But whenever I clicked any one button, instead of telling that particular i value, it enters into whole loop, and prints all the values of i starting from 1 to 19 (the number of buttons that are dynamically created)
And after printing all values from 1 to 19, the program is getting force closed saying Null pointer exception.
I even tried by placing the handler code outside onCreate(), but I'm still getting the same error.
for ( i = 0; i <itemList.getTitle().size()-1; i++) {
title[i] = new TextView(this);
title[i].setTextColor( -16711936 );
title[i].setTextSize(18);
title[i].setText("Title = "+itemList.getTitle().get(i));
description[i] = new TextView(this);
description[i].setTextColor(-16776961);
description[i].setText("Description = "+itemList.getDescription().get(i)+"......");
more[i]=new Button(this);
more[i].setText(itemList.getLink().get(i));
layout.addView(title[i]);
System.out.println("Title view is set");
layout.addView(description[i]);
//System.out.println("Description view is set");
layout.addView(more[i]);
more[i].setOnClickListener(listener);
}
private OnClickListener listener=new OnClickListener(){
public void onClick(View arg) {
int index = 0;
for (i = 0; i < more.length; i++)
{
if (more[i].getId() == arg.getId())
{
index = i;
System.out.println("Value of i onclick is"+i);
}
}
//System.out.println("Vlaue of I in onclick"+i);
//Uri uri=Uri.parse(itemList.getLink().get(i));
//startActivity(new Intent(Intent.ACTION_VIEW,uri));
//Toast.makeText(getApplicationContext(), "This button is clicked"+i+more[i].getText()+itemList.getLink().get(i),Toast.LENGTH_LONG).show();
}
}
You can use setTag() and getTag() method of View to identify different button.
for (i = 0; i < itemList.getTitle().size()-1; i++) {
...
more[i].setTag(i); // Use index of itemList as the tag
}
In onClick:
int index = (Integer)arg.getTag();
you can also set the id of button
more[i].setid(i);
int index = 0;
for (i = 0; i < more.length; i++)
{
if (more[i].getId() == arg.getId())
{
index = i;
System.out.println("Value of i onclick is"+i);
}
}
As you can see here, i is still in your for loop.
Put the System.out.println("Value of i onclick is"+i); outside of your for loop and it should work
PS: format your code, it's easier to read that way and you'll notice small mistakes like these more easily
I think this will help you..
set button tag also dynamic like
more[i].setId(i);
and also changed condition like
if (more[i].getId() == i) {
index = i;
}
hope this will help you...
Related
I am having trouble with my output screen!
When I click on Click button with these inputs output screen looks like attached image, which is so far great!
But if I change my input, the program gives new answer by adding more rows with previous answers! I want only new answers on screen to be shown!
Also without updating input if I click on button same way screen adds up new rows!
I am including a picture of this also..
I used this code given below,
clickbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
aI = Double.parseDouble(Ia.getText().toString());
bI = Double.parseDouble(Ib.getText().toString());
cI = Double.parseDouble(Ic.getText().toString());
bisection();
}
});
private void bisection() {
if ((f(aI) < 0 && f(bI) > 0) || (f(aI) > 0 && f(bI) < 0)) {
for (int i = 0; i < cI; i++) {
View tableRow = LayoutInflater.from(this).inflate(R.layout.table_item, null, false);
TextView iteration = (TextView) tableRow.findViewById(R.id.index);
TextView a = (TextView) tableRow.findViewById(R.id.a);
TextView b = (TextView) tableRow.findViewById(R.id.b);
TextView x = (TextView) tableRow.findViewById(R.id.x);
TextView fx = (TextView) tableRow.findViewById(R.id.fx);
double root = (aI+bI)/2;
iteration.setText(" " + (i + 1));
a.setText(Double.toString(aI));
b.setText(Double.toString(bI));
x.setText(Double.toString(root));
fx.setText(Double.toString(f(root)));
tableLayout.addView(tableRow);
if(f(aI)*f(root) < 0){
bI = root;
}else if (f(aI)*f(root) >0) {
aI = root;
}
}
} else {
Toast.makeText(getApplicationContext(), R.string.popUpMsg,Toast.LENGTH_SHORT).show();
}
}
public static double f(double x){
return ((Math.pow(x,3))-x-4);
}
I have already found almost same problem has been solved in a post previously asked by someone else but I couldn't fix mine! Help me. Thanks!
In your button click listener method, add following line of code before calling bisection().
tableLayout.removeAllViews();
Whenever, you will click the button, previous output will be removed before calculating new input values.
Your code would look like this:
clickbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
aI = Double.parseDouble(Ia.getText().toString());
bI = Double.parseDouble(Ib.getText().toString());
cI = Double.parseDouble(Ic.getText().toString());
tableLayout.removeAllViews(); // Remove previous output
bisection();
}
});
first way; You have to use
removeAllViews();
Before adding. To do this, you have to have a layout variable around. ex;
linearLayout.removeAllViews();
Another way is adding the Textviews in the beginning with VIEW.INVISIBLE or VIEW.GONE
Whichever suits you.
I am developing a simple questionnaire-like app which includes lots of radio buttons joined into groups and spinners. I have multiple activities (6); some of them having RBs and some Spinners to let the user answer the questions.
The following step, which I have trouble with, is how to fetch lots of selections (of all the radio buttons/choices) and possibly do that in a for loop (so I don't have to initialize each new variable 30+ times in a row for just one activity). I've already assigned IDs to all of the views, but am having a hard time how to actually fetch the selection, initialize a new var corresponding to the selection (let's say radio button 1 in radio group 1 gives me a new variable with a value of 1) and then make the variables available to all of the activities (should I use global when initializing?).
My failed attempt on generating 10 variables for the first "page"
public void goTo2(View v) {
checkRB();
Intent intent1 = new Intent(Vprasalnik1.this, Vprasalnik2.class);
startActivity(intent1);
finish();
}
public void checkRB()
{
for (int i=0;i<9;i++)
{
RadioButton "vRB" + i; //I'd like to loop and initialize vars by adding a number to them (vRB1, vRB2, ...)
}
}
Put variables into array like a
int size = 9;
RadioButton[] views = new RadioButton[size];
public static checkRB()
{
for(int i=0;i<size;i++)
{
views[i] = (RadioButton)findViewByID(...);//For example
}
}
Or make a structure :
public class Choise
{
int mRadioButtonChoise;
int mSpinnerChoise;
}
And use something like this:
...
Choise c = new Choise();
c.mRadioButtonChoise = yourRadioButtonID;
c.mSpinnerChoise = youtSpinnerChoiseID;
...
Using a variable to identify a resource:
RadioButton[] rb = new RadioButton[size];
public static checkRB()
{
for(int i=0;i<size;i++)
{
int id = context.getResources().getIdentifier("vRB" + i, "id", context.getPackageName())
rb[i] = (RadioButton)findViewByID(id);
}
}
If you have an array of RadioButtons then you can get all the values at the same time, however initializing them will have to be manual.
RadioButton rb[];
boolean rbc[];
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
rbc=new boolean[200];
rb=new RadioButton[200]();
rb[0]=(RadioButton)findViewById(R.id.rb1);
rb[1]=(RadioButton)findViewById(R.id.rb2);
rb[2]=(RadioButton)findViewById(R.id.rb3);
rb[3]=(RadioButton)findViewById(R.id.rb4);
// many more.
}
public void checkRB()
{
for (int i=0;i<9;i++)
{
rbc[i]=rb.isChecked(); //I'd like to loop and initialize vars by adding a number to them (vRB1, vRB2, ...)
}
}
Then before starting your intent add all relevant data to it.
So I've managed to cramp up the radio buttons activity, so that it finally works. If anyone is interested - I've used tags in xml code to properly assign values (1, 2 and 3 for each group of buttons) and managed to get an output in my testToast. At least I didn't have to initialize all of the variables manually - I've been saving the values into an ArrayList and then appended to them via StringBuilder.
Thanks to everyone who tried to help - it turned out I've needed a bit more research, testing and teasing my half-awake brain.
btn = (Button) findViewById(R.id.v3_btn1);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
for(int i = 1; i <= 36; i++)
{
tmpRGid = "radioGroup_v3q" + i;
tmp2RGid = getResources().getIdentifier(tmpRGid, "id", getPackageName());
RGid = (RadioGroup) findViewById(tmp2RGid);
selectedOption = RGid.getCheckedRadioButtonId();
RBid = (RadioButton) findViewById(selectedOption);
addToIDList.add((String)RBid.getTag());
}
String testToast = "";
StringBuilder builder = new StringBuilder();
builder.append("Vaša izbira (");
for (int z=0; z < addToIDList.size(); z++) {
testToast = addToIDList.get(z);
builder.append(testToast + ", ");
}
builder.setLength(builder.length() - 2);
builder.append(") je bila shranjena.");
Toast.makeText(Vprasalnik3.this, builder, Toast.LENGTH_LONG).show();
I have 16 buttons, whose names are "button1", "button2", and so on. Is there a way I can iterate through them using a for loop, by somehow appending the number value upon each iteration? Something like this:
for(int i = 1; i<17; i++ ){
Button b = (Button)findViewById(R.id.buttoni);
I know I can simply initialize each button in my onCreate() method, but I was just curious if I could do it in a way similar to my example code.
Thank you.
You can use getIdentifier :
for(int i = 1; i<17; i++ ){
int buttonId = getResources().getIdentifier("button"+i, "id", getPackageName());
Button b = (Button)findViewById(buttonId);
//Your stuff with the button
}
You can create an array of Button's and use getIdentifier method that allows you to get an identifier by its name.
final int number = 17;
final Button[] buttons = new Button[number];
final Resources resources = getResources();
for (int i = 0; i < number; i++) {
final String name = "btn" + (i + 1);
final int id = resources.getIdentifier(name, "id", getPackageName());
buttons[i] = (Button) findViewById(id);
}
In case someone is interested how to achive the same result using Java only
The solution above uses Android specific methods (such as getResources, getIdentifier) and can not be used in usual Java, but we can use a reflection and write a method that works like a getIdentifier:
public static int getIdByName(final String name) {
try {
final Field field = R.id.class.getDeclaredField(name);
field.setAccessible(true);
return field.getInt(null);
} catch (Exception ignore) {
return -1;
}
}
And then:
final Button[] buttons = new Button[17];
for (int i = 0; i < buttons.length; i++) {
buttons[i] = (Button) findViewById(getIdByName("btn" + (i + 1)));
}
NOTE:
Instead of optimizing this kind of code you should rethink your layout. If you have 17 buttons on the screen, a ListView is probably the better solution. You can access the items via index and handle onClick events just like with the buttons.
I have two identical views with a number of editTexts. In one, pre-defined answers are populated in the editTexts (but not shown to the user). In the second, the user starts with all blank editTexts, and then fills them out in an attempt to make them the same as the pre-defined answers.
So I want to loop through the user's view, checking it against the pre-defined one, until an inequality is found, in which case the method will return false.
My code is below. Inside the onCreate I have a buttonListener (when the user is ready to check answers)
btnSolution.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(checkAnswer() == true){
Toast.makeText(getBaseContext(), "all good!", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getBaseContext(), "no good", Toast.LENGTH_LONG).show();
}
}
});
the checkAnswer() method is then defined as follows
public boolean checkAnswer() {
final int ROW_COUNT = 15;
final int COL_COUNT = 10;
final String ROWS[] = {"R1","R2","R3","R4","R5","R6","R7","R8","R9","R10","R11","R12","R13","R14","R15"};
final String COLS[] = {"C1","C2","C3","C4","C5","C6","C7","C8","C9","C10"};
for(int i=0; i<ROW_COUNT; i++) {
for(int j=0; j<COL_COUNT; j++) {
String a = ROWS[i];
String b = COLS[j];
int editTextBaseId = getResources().getIdentifier("box" + a + b, "id", getPackageName());
int editTextAnswerId = getResources().getIdentifier("boxA" + a + b, "id", getPackageName());
EditText editTextBase = (EditText)findViewById(editTextBaseId);
EditText editTextAnswer = (EditText)findViewById(editTextAnswerId);
String textBase = editTextBase.getText().toString();
String textAnswer = editTextAnswer.getText().toString();
if(textBase.equals(textAnswer)) {
}
else {
return false;
}
}
}
return true;
}
Unfortunately when I try and run this I am getting a crash and the following error in my LogCat
12-17 00:05:02.075: E/SKIA(16370): FimgApiStretch:stretch failed
Any obvious errors?
That's not an error itself. I guess you're using a Samsung as your target device, if so, don't worry about it.
In the other hand, maybe it's better to compare only the strings. All those findViewById are inneficient.
Looking at your code:
EditText editTextAnswer = (EditText)findViewById(editTextAnswerId);
Do you have both views in the same layout, and the one with the answers is hidden? I mean, if you have the view with blank editTexts as the content of your activity, you can't find the editText with the answer as it's in other xml (assuming you did it as a different xml).
I'm making an android application, where there is a view composed of hundreds of buttons, each with a specific callback. Now, I'd like to set these callbacks using a loop, instead of having to write hundreds of lines of code (for each one of the buttons).
My question is: How can I use findViewById without statically having to type in each button id?
Here is what I would like to do:
for(int i=0; i<some_value; i++) {
for(int j=0; j<some_other_value; j++) {
String buttonID = "btn" + i + "-" + j;
buttons[i][j] = ((Button) findViewById(R.id.buttonID));
buttons[i][j].setOnClickListener(this);
}
}
Thanks in advance!
You should use getIdentifier()
for(int i=0; i<some_value; i++) {
for(int j=0; j<some_other_value; j++) {
String buttonID = "btn" + i + "-" + j;
int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
buttons[i][j] = ((Button) findViewById(resID));
buttons[i][j].setOnClickListener(this);
}
}
You can try making an int[] that holds all of your button IDs, and then iterate over that:
int[] buttonIDs = new int[] {R.id.button1ID, R.id.button2ID, R.id.button3ID, ... }
for(int i=0; i<buttonIDs.length; i++) {
Button b = (Button) findViewById(buttonIDs[i]);
b.setOnClickListener(this);
}
Take a look at these answers:
Android and getting a view with id cast as a string
Array of ImageButtons, assign R.view.id from a variable
you can Use tag if you want to access.
in onClick
int i=Integer.parseInt(v.getTag);
But you cant access that button like this.
simply create button programatically
by Button b=new Button(this);
create Custom Button in java code rather in Xml as i shown below
Button bs_text[]= new Button[some_value];
for(int z=0;z<some_value;z++)
{
try
{
bs_text[z] = (Button) new Button(this);
}
catch(ArrayIndexOutOfBoundsException e)
{
Log.d("ArrayIndexOutOfBoundsException",e.toString());
}
}
If your top level view only has those button views as children, you could do
for (int i = 0 ; i < yourView.getChildCount(); i++) {
Button b = (Button) yourView.getChildAt(i);
b.setOnClickListener(xxxx);
}
If there are more views present you'd need to check if the selected one is one of your buttons.
If for some reason you can't use the getIdentifier() function and/or you know the possible id's beforehand, you could use a switch.
int id = 0;
switch(name) {
case "x":
id = R.id.x;
break;
etc.etc.
}
String value = findViewById(id);
To put it simply, here's a function for it
public View findViewByArrayName (String name, int i) {
buttonID = name + Integer.toString(i);
resID = getResources().getIdentifier(buttonID, "id", getPackageName());
return findViewById(resID);
}
Also unlike Python, Java is a compiled language, so it probably makes sense that there aren't any chances for dynamic variable names. Unless achieved through a certain approach like this one.