onClickListener not triggering - android

I'm doing a rather round about way of making a solitaire app. What's happening right now is that I'm trying to click on a button that is supposed to deal cards from the deck to the state that you can play cards from. However, the listener is never triggering.
I put a system.out.println statement in to test to see if it ever enters the code block with the listener, and it does not.
public class SolitaireGame extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game);
buttonSound = MediaPlayer.create(SolitaireGame.this, R.raw.button_click);
//instance variables
theDeck = new Deck();
botCardStacks = new ArrayList<BotCardStack>(7);
aceStacks = new ArrayList<AceCardStack>(4);
playableCards = new CardStack(52);
deckButton = (Button) this.findViewById(R.id.deckButton);
deckButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
buttonSound.start();
dealCardsToPlayableStack();
}
});
As requested, here is my add cards to playable stack method
public void dealCardsToPlayableStack() {
Stack<Card> tempStack = new Stack<Card>();
int i = 0;
Card temp, temp1, temp2, temp3;
if(theDeck.getValueOfNext() == 0) {
while(!playableCards.isEmpty()) {
temp = playableCards.popCard();
temp.setVisible(false);
tempStack.push(temp);
}
while(!tempStack.isEmpty()) {
theDeck.addCard(tempStack.pop());
}
}
else if(theDeck.getValueOfNext() >= 3) {
temp1 = theDeck.popCard();
temp1.setVisible(true);
temp2 = theDeck.popCard();
temp2.setVisible(true);
temp3 = theDeck.popCard();
temp3.setVisible(true);
playableCards.addCard(temp3);
playableCards.addCard(temp2);
playableCards.addCard(temp1);
}
else if(theDeck.getValueOfNext() == 2) {
temp1 = theDeck.popCard();
temp1.setVisible(true);
temp2 = theDeck.popCard();
temp2.setVisible(true);
playableCards.addCard(temp2);
playableCards.addCard(temp1);
}
else if(theDeck.getValueOfNext() == 1) {
temp1 = theDeck.popCard();
temp1.setVisible(true);
playableCards.addCard(temp1);
}
}

First you should use buttonSound.prepare() before buttonSound.start() (I prefer using SoudPool Class instead of Mediaplayer for sound effects as it is less costly in memory). Secondly, can you share the dealCardsToPlayableStack() method. You can put it outside the onClick() method (in onCreate()) and if you have the same behaviour, then the problem is in this method, not the OnClick() method.

Related

Showing results for a quiz app (Android Studio)

I have a quiz app that is working properly, but the thing is the user must answer all questions correctly in order to win the game(if the player gets it wrong the game will be over) .
What I wanted to do is have the questions answered and then at the end there will be an activity that will show how many the player has answered then there will be the options to retry and go back to menu
This is the code for the maingameactivity
public class MainGameActivity extends AppCompatActivity {
FButton buttonA, buttonB, buttonC, buttonD;
TextView questionText, triviaQuizText, timeText, resultText, coinText;
TriviaQuizHelper triviaQuizHelper;
TriviaQuestion currentQuestion;
List<TriviaQuestion> list;
int qid = 0;
int timeValue = 20;
int coinValue = 0;
CountDownTimer countDownTimer;
Typeface tb, sb;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_main);
//Initializing variables
questionText = (TextView) findViewById(R.id.triviaQuestion);
buttonA = (FButton) findViewById(R.id.buttonA);
buttonB = (FButton) findViewById(R.id.buttonB);
buttonC = (FButton) findViewById(R.id.buttonC);
buttonD = (FButton) findViewById(R.id.buttonD);
triviaQuizText = (TextView) findViewById(R.id.triviaQuizText);
timeText = (TextView) findViewById(R.id.timeText);
resultText = (TextView) findViewById(R.id.resultText);
coinText = (TextView) findViewById(R.id.coinText);
//Setting typefaces for textview and buttons - this will give stylish fonts on textview and button etc
tb = Typeface.createFromAsset(getAssets(), "fonts/TitilliumWeb-Bold.ttf");
sb = Typeface.createFromAsset(getAssets(), "fonts/shablagooital.ttf");
triviaQuizText.setTypeface(sb);
questionText.setTypeface(tb);
buttonA.setTypeface(tb);
buttonB.setTypeface(tb);
buttonC.setTypeface(tb);
buttonD.setTypeface(tb);
timeText.setTypeface(tb);
resultText.setTypeface(sb);
coinText.setTypeface(tb);
//Our database helper class
triviaQuizHelper = new TriviaQuizHelper(this);
//Make db writable
triviaQuizHelper.getWritableDatabase();
//It will check if the ques,options are already added in table or not
//If they are not added then the getAllOfTheQuestions() will return a list of size zero
if (triviaQuizHelper.getAllOfTheQuestions().size() == 0) {
//If not added then add the ques,options in table
triviaQuizHelper.allQuestion();
}
//This will return us a list of data type TriviaQuestion
list = triviaQuizHelper.getAllOfTheQuestions();
//Now we gonna shuffle the elements of the list so that we will get questions randomly
Collections.shuffle(list);
//currentQuestion will hold the que, 4 option and ans for particular id
currentQuestion = list.get(qid);
//countDownTimer
countDownTimer = new CountDownTimer(22000, 1000) {
public void onTick(long millisUntilFinished) {
//here you can have your logic to set text to timeText
timeText.setText(String.valueOf(timeValue) + "\"");
//With each iteration decrement the time by 1 sec
timeValue -= 1;
//This means the user is out of time so onFinished will called after this iteration
if (timeValue == -1) {
//Since user is out of time setText as time up
resultText.setText(getString(R.string.timeup));
//Since user is out of time he won't be able to click any buttons
//therefore we will disable all four options buttons using this method
disableButton();
}
}
//Now user is out of time
public void onFinish() {
//We will navigate him to the time up activity using below method
timeUp();
}
}.start();
//This method will set the que and four options
updateQueAndOptions();
}
public void updateQueAndOptions() {
//This method will setText for que and options
questionText.setText(currentQuestion.getQuestion());
buttonA.setText(currentQuestion.getOptA());
buttonB.setText(currentQuestion.getOptB());
buttonC.setText(currentQuestion.getOptC());
buttonD.setText(currentQuestion.getOptD());
timeValue = 20;
//Now since the user has ans correct just reset timer back for another que- by cancel and start
countDownTimer.cancel();
countDownTimer.start();
//set the value of coin text
coinText.setText(String.valueOf(coinValue));
//Now since user has ans correct increment the coinvalue
coinValue++;
}
//Onclick listener for first button
public void buttonA(View view) {
//compare the option with the ans if yes then make button color green
if (currentQuestion.getOptA().equals(currentQuestion.getAnswer())) {
buttonA.setButtonColor(ContextCompat.getColor(getApplicationContext(),R.color.lightGreen));
//Check if user has not exceeds the que limit
if (qid < list.size() - 1) {
//Now disable all the option button since user ans is correct so
//user won't be able to press another option button after pressing one button
disableButton();
//Show the dialog that ans is correct
correctDialog();
}
//If user has exceeds the que limit just navigate him to GameWon activity
else {
gameWon();
}
}
//User ans is wrong then just navigate him to the PlayAgain activity
else {
gameLostPlayAgain();
}
}
//Onclick listener for sec button
public void buttonB(View view) {
if (currentQuestion.getOptB().equals(currentQuestion.getAnswer())) {
buttonB.setButtonColor(ContextCompat.getColor(getApplicationContext(),R.color.lightGreen));
if (qid < list.size() - 1) {
disableButton();
correctDialog();
} else {
gameWon();
}
} else {
gameLostPlayAgain();
}
}
//Onclick listener for third button
public void buttonC(View view) {
if (currentQuestion.getOptC().equals(currentQuestion.getAnswer())) {
buttonC.setButtonColor(ContextCompat.getColor(getApplicationContext(),R.color.lightGreen));
if (qid < list.size() - 1) {
disableButton();
correctDialog();
} else {
gameWon();
}
} else {
gameLostPlayAgain();
}
}
//Onclick listener for fourth button
public void buttonD(View view) {
if (currentQuestion.getOptD().equals(currentQuestion.getAnswer())) {
buttonD.setButtonColor(ContextCompat.getColor(getApplicationContext(),R.color.lightGreen));
if (qid < list.size() - 1) {
disableButton();
correctDialog();
} else {
gameWon();
}
} else {
gameLostPlayAgain();
}
}
//This method will navigate from current activity to GameWon
public void gameWon() {
Intent intent = new Intent(this, GameWon.class);
startActivity(intent);
finish();
}
//This method is called when user ans is wrong
//this method will navigate user to the activity PlayAgain
public void gameLostPlayAgain() {
Intent intent = new Intent(this, PlayAgain.class);
startActivity(intent);
finish();
}
//This method is called when time is up
//this method will navigate user to the activity Time_Up
public void timeUp() {
Intent intent = new Intent(this, Time_Up.class);
startActivity(intent);
finish();
}
//If user press home button and come in the game from memory then this
//method will continue the timer from the previous time it left
#Override
protected void onRestart() {
super.onRestart();
countDownTimer.start();
}
//When activity is destroyed then this will cancel the timer
#Override
protected void onStop() {
super.onStop();
countDownTimer.cancel();
}
//This will pause the time
#Override
protected void onPause() {
super.onPause();
countDownTimer.cancel();
}
//On BackPressed
#Override
public void onBackPressed() {
Intent intent = new Intent(this, HomeScreen.class);
startActivity(intent);
finish();
}
//This dialog is show to the user after he ans correct
public void correctDialog() {
final Dialog dialogCorrect = new Dialog(MainGameActivity.this);
dialogCorrect.requestWindowFeature(Window.FEATURE_NO_TITLE);
if (dialogCorrect.getWindow() != null) {
ColorDrawable colorDrawable = new ColorDrawable(Color.TRANSPARENT);
dialogCorrect.getWindow().setBackgroundDrawable(colorDrawable);
}
dialogCorrect.setContentView(R.layout.dialog_correct);
dialogCorrect.setCancelable(false);
dialogCorrect.show();
//Since the dialog is show to user just pause the timer in background
onPause();
TextView correctText = (TextView) dialogCorrect.findViewById(R.id.correctText);
FButton buttonNext = (FButton) dialogCorrect.findViewById(R.id.dialogNext);
//Setting type faces
correctText.setTypeface(sb);
buttonNext.setTypeface(sb);
//OnCLick listener to go next que
buttonNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//This will dismiss the dialog
dialogCorrect.dismiss();
//it will increment the question number
qid++;
//get the que and 4 option and store in the currentQuestion
currentQuestion = list.get(qid);
//Now this method will set the new que and 4 options
updateQueAndOptions();
//reset the color of buttons back to white
resetColor();
//Enable button - remember we had disable them when user ans was correct in there particular button methods
enableButton();
}
});
}
//This method will make button color white again since our one button color was turned green
public void resetColor() {
buttonA.setButtonColor(ContextCompat.getColor(getApplicationContext(),R.color.white));
buttonB.setButtonColor(ContextCompat.getColor(getApplicationContext(),R.color.white));
buttonC.setButtonColor(ContextCompat.getColor(getApplicationContext(),R.color.white));
buttonD.setButtonColor(ContextCompat.getColor(getApplicationContext(),R.color.white));
}
//This method will disable all the option button
public void disableButton() {
buttonA.setEnabled(false);
buttonB.setEnabled(false);
buttonC.setEnabled(false);
buttonD.setEnabled(false);
}
//This method will all enable the option buttons
public void enableButton() {
buttonA.setEnabled(true);
buttonB.setEnabled(true);
buttonC.setEnabled(true);
buttonD.setEnabled(true);
}
}
Edited
Just remove the wrapper if else inside all the buttons better to keep it as, don't repeat the code. I am assuming the screen that shows result is handled inside gameWon and you have implemented functionality for inCorrectDialog
public void buttonA(View view) {
Button button = (Button) view;
buttonPressed(button);
}
public void buttonB(View view) {
Button button = (Button) view;
buttonPressed(button);
}
public void buttonC(View view) {
Button button = (Button) view;
buttonPressed(button);
}
public void buttonD(View view) {
Button button = (Button) view;
buttonPressed(button);
}
public void buttonPressed(Button button) {
button.setButtonColor(ContextCompat.getColor(getApplicationContext(), R.color.lightGreen));
if (qid < list.size() - 1) {
disableButton();
if (currentQuestion.getOptA().equals(currentQuestion.getAnswer())) {
correctDialog();
} else {
inCorrectDialog();
}
} else {
gameWon();
}
}

how do I set up a next and previous button

Hello as the title state I'm trying to setup a next and previous buttons but I'm still new at coding so this has me a little confused.
I tried to use if statements with an enum within a single button but it defaults to last if statement when the event is handled here's the code-
private enum EVENT{
pe1, pe2, pe3, pe4;
}
EVENT currentEvent = EVENT.pe1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one_liners);
nextBtn = (Button) findViewById(R.id.nextBtn);
olText = (TextView) findViewById(R.id.olText);
nextBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (currentEvent==EVENT.pe1) {
olText.setText("PE1");
olText.startAnimation(AnimationUtils.loadAnimation(olText.this, android.R.anim.slide_in_left));
currentEvent=EVENT.pe2;
}
if (currentEvent==EVENT.pe2){
olText.setText("PE2");
olText.startAnimation(AnimationUtils.loadAnimation(olText.this, android.R.anim.slide_in_left));
currentEvent=EVENT.pe3;
}
}
});
}
I tried to use the enumerator to assign a number to each if statement so when the user hit previous it would subtract and when they hit next it would add, each number would have some text or image within its if statement but as I said it defaults to the last if statement- Any help is much appreciated.
How about this?
int eventNum = 0;
int maxEvents = XXX;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one_liners);
prevBtn = (Button) findViewById(R.id.prevBtn);
nextBtn = (Button) findViewById(R.id.nextBtn);
olText = (TextView) findViewById(R.id.olText);
setEventData(true);
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if(v.equals(prevBtn) && eventNum > 0) {
eventNum--;
setEventData(false);
return;
}
if(v.equals(nextBtn) && eventNum < maxEvents - 1) {
eventNum++;
setEventData(true);
return;
}
}
}
nextBtn.setOnClickListener(listener);
prevBtn.setOnClickListener(listener);
}
private void setEventData(boolean animLeft) {
olText.setText("PE" + (eventNum + 1));
if(animLeft) {
olText.startAnimation(AnimationUtils.loadAnimation(olText.this, android.R.anim.slide_in_left));
} else {
olText.startAnimation(AnimationUtils.loadAnimation(olText.this, android.R.anim.slide_in_right));
}
}
You'll want to create a class variable that keeps track of which text your TextView is showing. So in the following example, I create a list of Strings that I just store in a String array. Then I create an iterator variable which stores which String from the list I'm currently viewing in the TextView. Every time you click the previous or next button, you simply store your current state in the iterator variable so you can recall it the next time a click event comes in.
String[] labels = {"one", "two", "three", "four"};
int currentView = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onPreviousButtonClicked(View view) {
TextView textView = (TextView) findViewById(R.id.clickableLink);
currentView--; //decrement our iterator
if(currentView < 0) currentView = 0; //check to make sure we didn't go below zero
textView.setText(labels[currentView]);
}
public void onNextButtonClicked(View view) {
TextView textView = (TextView) findViewById(R.id.clickableLink);
currentView++; //increment our iterator
if(currentView > labels.length-1) currentView = labels.length-1; //check to make sure we didn't go outside the array
textView.setText(labels[currentView]);
}

why method inside oncreate event doesn't work?

I have a private method like this
private void acaknomor() {
List<Integer> generated = new ArrayList<Integer>();
for (int i = 0; i <= 4; i++) {
while (true) {
Integer next = ran.nextInt(4 + 1) + 0;
if (!generated.contains(next)) {
generated.add(next);
break;
}
}
}
int[] arrayAcak = new int[generated.size()];
for (int i = 0; i < generated.size(); i++) {
arrayAcak[i] = generated.get(i);
}
}
i call that method in oncreate and test by button click to show list value with a toast like this :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
acaknomor();
btn_next.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), String.valueOf(generated), Toast.LENGTH_SHORT).show();
}
});
The Question is why the toast show null when I put it inside a method , instead showing "0,1,2,3,4" ?
I tested my code without a method (put it raw inside oncreate event and it worked...)
Your are declaring List<Integer> generated = new ArrayList<Integer>(); in side the method acaknomor(). So it is not visible for the Toast.
I suggest you to declare it at class level.
private List generated;
Now inside the the acaknomor()
private void acaknomor() {
generated = new ArrayList<Integer>(); // Modify this line
for (int i = 0; i <= 4; i++) {
...
Instead of this:
List<Integer> generated = new ArrayList<Integer>();
Use
generated = new ArrayList<Integer>();
And declare List<Integer> generated for your activity
please have a look at acaknomor method
private void acaknomor() {
List<Integer> generated = new ArrayList<Integer>();....
use generated = new ArrayList<Integer>();
and make List<Integer> generated =null; Global which will help you on this issue

why did the trafficlight doesnt work

I did this code and want to make a traffic light on and off several times and then stop and choose one of the two lights at random, but the program does the operation, but does not show the changing lights as the operation does
private ImageView redLight;
private ImageView greenLight;
private Button Button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.traffic_lights);
redLight = (ImageView) findViewById(R.id.red_light);
greenLight = (ImageView) findViewById(R.id.green_light);
Button = (Button) findViewById(R.id.start_button);
// Assign click listeners to buttons
Button.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v == Button) {
int flag = 0;
for (int i = 0; i <= 100; i++) {
if (flag == 0) {
turnOnRedLight();
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
Log.i("Traffic", "Red");
flag = 1;
} else {
turnOnGreenLight();
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
Log.i("Traffic", "Green");
flag = 0;
}
}
}
}
private void turnOnRedLight() {
redLight.setImageResource(R.drawable.red_on);
}
private void turnOnGreenLight() {
greenLight.setImageResource(R.drawable.green_on);
}
}
You are only sleeping for 100ms so you probably aren't seeing the lights change. Change that to something like 1000 or maybe even 500 and you will probably see the change
Thread.sleep(1000);
Also, a couple notes
Although with this code it may not be a problem, sleeping on the UI Thread usually isn't a good idea. Use a Thread and update UI with runOnUiThread(), use AsyncTask, or Handler.
Don't name your Button "Button". Name it something that isn't an Android keyword like button, btn, startButton, startBtn, or something similar.
When distinguishing between which Button was clicked use the Button id instead of the Object. So you would want to change it to
#Override
public void onClick(View v) {
if (v.getId() == (R.id.start_button)) {
you could also use a switch statement here but not important.

Pass a variable to an An activity while using an Intent in Android

I am creating a simple game which after a 5 second timer expires and two conditions are checked, condition one is to level up, the intent starts the same activity and I intended to increment my variable level by one every time the player met the condition which increased the game level.
The second condition starts another activity, which is the fail screen.
I didn't want a different screen for every level up increment, when I can just load the same activity and continue going through the conditions, but as the Activity starts again the level variable resets to its initialised value, the game never leaves level 1. Is there any way to pass a variable a value to an activity when starting it?
Here is the code I have for my Activity:
public class FirstOneActivity extends Activity {
/** Called when the activity is first created. */
MediaPlayer ourSong;
int counter;
Button add;
Thread timer;
TextView display;
TextView lvl;
int level = 1;
int time;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ourSong = MediaPlayer.create(FirstOneActivity.this, R.raw.click);
counter = 0;
add = (Button) findViewById (R.id.bAdd);
display = (TextView) findViewById (R.id.tvDisplay);
lvl = (TextView) findViewById (R.id.lvldisplay);
add.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
counter++;
//ourSong.start();
display.setText("Your total is "+ counter);
if(counter ==1)
{
set();
timer.start();
}
}
});
timer = new Thread(){
public void run(){
try{
sleep(time);
}catch(InterruptedException e){
e.printStackTrace();
}finally{
test();
}
}
};
}
public void test(){
if(counter>= 10 && level == 1 || counter>= 15 && level == 2)
{
Intent openSplash = new Intent("com.deucalion0.FIRSTONE");
startActivity(openSplash);
level++;
}
else if(counter<10 && level == 1 || counter< 15 && level == 2){
Intent openNext = new Intent("com.deucalion0.NEXT");
startActivity(openNext);
}
}
public void set(){
if(level == 1)
{ lvl.setText("Level is "+ level);
time = 5000;
}
else if (level == 2)
{lvl.setText("Level is "+level);
time = 5000;
}
}
}
Any advice is appreciated.
Sure. To put some data in the intent, just use the putExtra method, like so:
openNext.putExtra("levelNum", 2);
Then in the called Activity, retrieve the bundle of extras and pull out the one you want, like this:
// in onCreate() method
int levelNum = getIntent().getExtras().getInt("levelNum");
When you create the Intent this would be how to add the data:
Intent openNext = new Intent("com.deucalion0.NEXT");
openNext.putExtra("Level", yourLevelVariable);
startActivity(openNext);
Then onCreate() in the NextActivity you would get the variable by:
String level = getIntent().getStringExtra("Level");
Edit: There are other methods besides getStringExtra if you want an integer or...
Edit You could store the level in the shared preferences with a default of 1 and increment as needed.

Categories

Resources