How can I set numerous onClick() by loop? - android

Recently, I have been making a simple board game android app. This game takes place on 7x7 grid, and I have made buttons for all of the squares.
This is not my first time doing this, and not only making the layout but also writing onClick() for each of those buttons were hard work. Thanks to the matrix array(int state[7][7] and Button board[][]=new Button[7][7]), I can shove all 49 codes into one function, but writing like
board[0][0]=(Button)findViewById(R.id.board00);
board[0][1]=(Button)findViewById(R.id.board01);
int i;
for(i=0;i<2;i++){
board[0][i].setOnClickListener(new OnClickListener() {
public void onClick(View v){
my_function(0,i);
}
}
(I had to write somewhat full code because the last time I omitted a part of the code, everyone was talking that I missed that part.)
will make all the buttons focus on the resulting i rather than the number it is originally meant for. (I know that part, don't just end up telling me "That won't work because~".)
So, my question is this: is there any way to make the [i][j] button to call my_function(i,j) for each of the i and j, rather than typing one by one or generating the code?
P.S. I didn't do much activities here, and I don't know how to look for my type of questions effectively, or verify if any question actually has my answer. If you find any question with the same answer, please tell me. I did search for this though.

If you want to keep the anonymous class then this should work
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++){
final int ii = i;
final int jj = j;
board[j][i].setOnClickListener(new OnClickListener() {
public void onClick(View v){
my_function(ii, jj);
}
}

Don't use an anonymous class. Make a full class. Then it can have a constructor you can call and pass in parameters. For example
private static class MyButtonListener implements OnClickListener {
int i;
int j;
public MyButtonListener(int i, int j) {
this.i = i;
this.j = j;
}
public void onClick(View v){
my_function(i, j);
}
}
Then in your loops, create a new MyButtonListener(i,j) instead of an anonymous class.

Related

disable button click for certain rows of buttons

I dynamically create Buttons by entering a word. If I write "met", it appears on the screen - one Button per letter. The same thing happens for the next word I enter, and it appears below the previous word --- as shown in the image above.
When I click on a Button it turns green. My question is, what is the best way to disable the clicking of a row of Buttons. Meaning, if the user clicks on the 'm' in "met" I want the user to only be able to click on the Buttons in "met" and to not be able to click on any of the Buttons in "had", "goes", or "ran"
Here is my code:
EDIT
int size = enter_txt.getText().toString().length();
for (int i=0; i<size; i++){
final Button dynamicButtons = new Button(view.getContext());
dynamicButtons.setLayoutParams(rlp);
dynamicButtons.getLayoutParams().width = 130;
dynamicButtons.getLayoutParams().height = 130;
dynamicButtons.setTag("0");
dynamicButtons.setId(1);
dynamicButtons.setText(edit_text_array[i]);
dynamicButtons.setBackgroundResource(R.drawable.button);
button_list.add(dynamicButtons);
linearLayout2.addView(dynamicButtons, rlp);
dynamicButtons.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
int i=0;
LinearLayout ll = (LinearLayout) dynamicButtons.getParent();
for(i=0; i<list_of_ll.size();i++){
if (ll == list_of_ll.get(i)){
list_of_ll.get(i).setId(i);
break;
}
}
if(list_of_ll.get(i).getId()==i)
ButtonOnClick(view);
}
});
}
linearLayout2.setId(0);
linearLayout2.setTag("0");
list_of_ll.add(linearLayout2);
EDIT
I created a List of the LinearLayouts for each row of Buttons. The Buttons turn green if the id of the LinearLayout is set to 1. When I click on a Button I want that LinearLayout to stay at 1 and have all other rows/LinearLayouts set to 0 so they become unclickable.
Currently, every Button I click turns green even if it's in a different row. Can someone please help me solve this issue?
Why you don't set Id in the for loop so that you are able to refer and set the onlicklistener to null like jpcrow already mentioned.
Set Id like:
YourCreatedBtn.setId(i+1);
//Id's setted programmatically don't.
have to be unique... But they should be
a positive number (referring to the
android documentation)
And in your on click method simply set onclicklistener for specified Id's to null. Just a hint, hope it helps
Update regarding Thread-openers Comment
I found two simple ways but i would prefer the one which is not commented out in the buttonIsClicked:
LinearLayout llrow;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
llrow = (LinearLayout) findViewById(R.id.test_layout);
//Adding 5 Buttons
for(int i = 0; i<5; i++) {
Button mybtn = new Button(this);
//set LayoutParams here
mybtn.setId(5);
mybtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
buttonIsClicked(v);
}
});
llrow.addView(mybtn);
}
}
private void buttonIsClicked(View v) {
/*ArrayList<View> myButtons = llrow.getTouchables();
for(int i = 0; i < llrow.getChildCount(); i++){
myButtons.get(i).setOnClickListener(null);
}*/
for(int i = 0; i<llrow.getChildCount(); i++){
llrow.getChildAt(i).setOnClickListener(null);
}
}
It's just a simplified Version of your code, but i'm sure you will get the Content..
What if found out is, that you don't have to set the ID in both cases.. You can easily get all the child over
YourRowLinearLayout.getChildAt(starting from 0 to n-1-Views you added)...
I didn't found a way around the for-loop... But this small-little loop will not break your neck regarding to Performance..
The outcommented-code is the second Approach, finding all the Child over getTouchables which logically leads to an ArrayList and that's exactly the reason why i don't like it. You have to initialize an arraylist...... However, this also won't break your neck regarding to Performance but a penny saved is a penny got! ;) Hope it helps and everything is clear. Both of them work! Please mark as accepted answere if it fits your Needs...
You have to distinguish between the two rows, either add them to different ViewGroups or you can use View.setTag(int key, Object tag)

Android - can not get resources from XML

Android - get resources from XML
Hi,
I am developing an android app for a quiz game, the game has 24 questions, and each question has a String(question) and four ImageButton(answer), when user select the correctImageButton`, then they go to next question.
But the problem is, after selecting the first correct answer, the screen refreshes with a new question and a new set of images, but it freezes there, and no matter what I click, it will not go to next question. I have attached my code and any help appreciated!!
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_game);
// set variables
int fourImageId[] = { R.id.1_4a, R.id.1_4b,R.id.1_4c, R.id.1_4d };
questionText = (TextView) findViewById(R.id.question1);
questionList = getResources().getStringArray(R.array.question);
correctAnswerIdList = ListOfImages.getListOfCorrectImages();
imageIdList = ListOfImages.getListOfImages(); //two dimension array
// give values to four image buttons
for (int i = 0; i < 4; i++) {
fourImages[i] = (ImageButton) findViewById(fourImageId[i]);
final int temp = fourImageId[i];
fourImages[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (temp==correctAnswerIdList[index]){
questionText.setText(questionList[index]);
for (int i = 0; i < imageIdList[index].length; i++) {
fourImages[i].setImageResource(imageIdList[index][i]);}
index++;
}
}
});}
Your temp variable never changes after all the button click listeners are set. Because of this, the if (temp==correctAnswerIdList[index]) statement will only successfully execute once.
Your for (int i = 0; i < 4; i++) statement needs to execute once for each new question. Right now it only executes once, sets up the new question and image buttons, but your app doesn't know where to go from there.

android buttons loop

I got a simple script:
int phases = 6;
final int max = 8;
final TextView[] a = new TextView[(max * phases)];
final Button[] b = new Button[phases]; // creates the buttons to display
// the single phases
for (int x = 0; x < phases; x++) {
b[x] = new Button(this);
b[x].setText("yourbutton");
// linL.addView(b[x]);
b[x].setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (a[(3)].getVisibility() == 0) {
for (int i = 0; i < max; i++)
a[i].setVisibility(View.GONE);
} else {
for (int i = 0; i < max; i++)
a[i].setVisibility(View.VISIBLE);
}
};
});
}
This checks basically if a textview is visible and if it's not then it makes it visible (plus the other way round).
My problem is now that I don't want to switch the same text views on again and again, I want to change the views depending on the x of the current loop of the button creation.
However, when i try to include this x, it says that it has to be final.
So how do i get parameters into that on click listener script? (I tried to add them, however it said then that I have to program the whole listener again...that's why I'm asking if there's a smarter way to do it)
Cheers, Christoph
You have 2 options:
Before the setOnClickListener line you can declare on another variable as final and you can assign the value of x into it. Then you will have final variable that holds the value of x that it can be used inside the function.
You can implement your own class that implements OnClickListener and you can add a constructor that get the value of x.
Some general notes:
I don't know if this is the way you write code or if you masked it when you wrote it here. (Masked, means that you change the variable names that it will be harder to understand what you are doing)
So, if you masked it, please don't, it make it much harder to answer you.
If this is the way you write code, I really encourage you to read some articles about coding standards and there importance. Your code isn't indent properly and the names of your variables have no meaning. After you finish with that project, try to read your code again a month later, you will see how hard it is for you to understand what you wrote
If I undertstand correctly, you want to pass parameters to your OnClickListener. I would suggest implementing your own OnClickListener interface - similar to rekaszeru's answer here

Two Button OnClickListeners inside for loop

I am self studying Android and now I am learning how to use buttons. I created a simple up counter which works like this:
I add the strings (eg. 1 2 3) in different text fields. Then I want to compaire those in pairs(1 with 2, 1 with 3, 2 with 3). The first string element is written on the first button, second on the second and after i press any of those buttons, the tags on the buttons has to change (if there was 1 and 2 so it should change to 1 and 3 or 2 and 3 etc) and the string element gets a higher rank. Everything seems to work well, but I think I am doing huge mistake with adding buttons. Can anyone help me? :) Can I add button listeners like I did in code bellow? :) Thank You!
public void counter()
{
int i = 0;
int a = i + 1;
for ( i = 0; i < candidates.size() - 1; i++ )
{
Log.d(TAG, "Setting button one tag: " + i );
button_one.setTag(i);
button_one.setText(candidates.get(i).name);
for (a = i + 1; a < candidates.size(); a++)
{
Log.d(TAG, "Setting button two tag: " + a );
button_two.setTag(a);
button_two.setText(candidates.get(a).name);
button_one.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view) {
/* Read the clicked tag */
int tag = (Integer) view.getTag();
/* Make higher rank */
candidates.get(tag).addRank();
}
});
button_two.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view) {
/* Read the clicked tag */
int tag = (Integer) view.getTag();
/* Make higher rank */
candidates.get(tag).addRank();
}
});
}
}
everything AndyRes said plus:
you're creating (candidates.size() * candidates.size()) number of OnClickListeners
that's A LOT of unnecessary objects hogging your memory.
You should create ONE OnClickListener mListener = new View.OnClickListener etc... etc...
and OUTSIDE the loop, probably during your OnCreate() just after you defined button_one = (Button)findViewById(R.id.button_one); you do button_one.setOnClickListener(mListener);
that way you have only 1 listener that will be serving any amount of buttons you might have, and don't need to be setting again the same listener.
In general there's not need to add the click listeners in a loop, unless you create those buttons dinamically.
Setting the click listeners in a loop for the same button, every time you cycle through the loop, will do nothing but override the previous settings, so I don't see any point in doing like this.

Android Form Reset?

I have a simple calculator that has six EditText views where users will enter numbers to perform a simple math function. This app will satisfy a repetitive task wherein the users will enter the information, press the submit button and the answer is displayed in a separate textView.
I want to add a simple 'clear' button that will reset the form so the users can begin a new calculation and the EditText views will show their hints for user input once again.
Is there a 'reset' type function that will clear all of the form data and reload the hints or do I have to kill the app and start it again? If so, whats a good starting place for how to do this?
Thanks!
The most basic way to do this would be to simply reset your EditText views. If you have logic that drives the update of these fields, then resetting them to an empty String and requesting a "recalculation" to update the hints.
Something like this:
private void onClear()
{
EditText firstField = (EditText)this.findById(R.id.firstField);
EditText secondField = (EditText)this.findById(R.id.secondField);
//...etc...
if (firstField != null) firstField.setText("");
if (secondField != null) secondField.setText("");
updateHints();
}
private void updateHints()
{
//Logic for your "hints"
}
No, you have to implement it yourself. I suggest you create an int array with the IDs of all your EditTexts you want to reset (R.id.xyz). Then create a loop to .setText() to each of the EditTexts from the array, which you can call every time you want the fields to be cleared. Something like:
private void resetFields() {
EditText temp;
for (int i = 0; i < myEditTexts.length; i++) {
temp = (EditText) findViewById(textViews[i]);
temp.setText("");
}
}
My answer is just a better way but it still a kind of hard code. Anyone could find another way faster, please share.
protected void clearForm() {
Button btnClear = (Button) findViewById(R.id.btn_clear_text);
btnClear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText temp;
final int[] txtId = new int[] {
R.id.txt_s_free_word,
R.id.txt_s_property_name,
R.id.txt_s_ad_expense_from,
R.id.txt_s_ad_expense_to,
R.id.txt_s_station
};
for (int i = 0; i < txtId.length; i++) {
temp = (EditText) findViewById(txtId[i]);
temp.setText(null);
}
}
});
}

Categories

Resources