what I am trying to do is to call on one of three sounds on this button click. The sounds are in a preference screen. On the button click it is also supposed to display an animation. What is currently happening is I will click on the button and everything will work perfectly, but then I stop the animation and sound the second time I click the button. When I click the button again to start back up the animation and sound I cant hear the sound, but the animation still works. I honestly have no idea whats wrong. Here's my code...
public void buttonClick() {
imgView = (ImageView) findViewById(R.id.imageView);
button = (Button) findViewById(R.id.button);
blade = (ImageView)findViewById(R.id.imageView4);
final Animation animRotate = AnimationUtils.loadAnimation(this, R.anim.rotate);
1stSound = MediaPlayer.create(this, R.raw.file.mp3);
2ndSound = MediaPlayer.create(this, R.raw.file.mp3);
3rdSOund = MediaPlayer.create(this, R.raw.file.mp3);
button.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences getPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
boolean option1 = getPrefs.getBoolean("alternate", false);
boolean option2 = getPrefs.getBoolean("white", false);
boolean option3 = getPrefs.getBoolean("standard",false);
if (blade.getAnimation() == null) {
// no animation, start it
if (option1 == true){
1stSound.start();
blade.startAnimation(animRotate);
} else if (option2 == true){
3rdSound.start();
blade.startAnimation(animRotate);
} else if (option3 == true) {
2ndFan.start();
blade.startAnimation(animRotate);
}
} else {
//animation is showing, stop it
blade.clearAnimation();
3rdSound.stop();
2ndSound.stop();
1stSound.stop();
}
current_image_index++;
current_image_index = current_image_index % images.length;
imgView.setImageResource(images[current_image_index]);
imgView.invalidate();
}
}
);
}
Take a look at the MediaPlayer state diagram. After calling stop() you'll need to also call prepare() (or prepareAsync()) to be able to play it again.
In short, do this:
3rdSound.stop();
3rdSound.prepareAsync();
2ndSound.stop();
2ndSound.prepareAsync();
1stSound.stop();
1stSound.prepareAsync();
Related
I know that was already asked but it is outdated:
I have 2 buttons that represent 2 choices and if one is selected the background color gets changed to yellow. But if i want to change the choice i need to somehow reset the button:
I already try to set it back but some old design comes out. Can you provide me the id of the modern button style? And show me how to implement it?
int myChoice;
if (view == findViewById(R.id.choice1)){
myChoice = 1;
choice1.setBackgroundColor(getResources().getColor(R.color.highlightButton));
choice2.setBackgroundResource(android.R.drawable.btn_default);
}
else if (view == findViewById(R.id.choice2)){
myChoice = 2;
choice2.setBackgroundColor(getResources().getColor(R.color.highlightButton));
choice1.setBackgroundResource(android.R.drawable.btn_default);
}
}
Use Tags with getBackground(). This will assure you are always setting back to original.
Add following in beginning of function
if (v.getTag() == null)
v.setTag(v.getBackground());
Then instead of setBackgroundResource, use
v.setBackground(v.getTag());
Starting from here, you can store the default color of the button into a Drawable and grab the selection color (Yellow in your case) into anther Drawable, then toggle background colors of buttons with these Drawable variables
please check below demo
public class MainActivity extends AppCompatActivity {
private Drawable mDefaultButtonColor;
private Drawable mSelectedButtonColor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btn1 = findViewById(R.id.btn1);
final Button btn2 = findViewById(R.id.btn2);
mDefaultButtonColor = (btn1.getBackground());
mSelectedButtonColor = ContextCompat.getDrawable(this, R.color.buttonSelected);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
toggleButton(btn1, true);
toggleButton(btn2, false);
}
});
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
toggleButton(btn1, false);
toggleButton(btn2, true);
}
});
}
private void toggleButton(Button button, boolean isSelected) {
button.setBackground(isSelected ? mSelectedButtonColor : mDefaultButtonColor);
}
}
I am trying to display a dialog based on the number of clicks that have occurred. I have two little issues with it which I will explain below:
So I clear the data on my app so that the number of clicks starts on 0. Basically what I am trying to do is that when I access the class below, if the number of clicks = 4, 8 or 12, then output the relevant message associated to them in my if else statements. If it doesn't equal any of those numbers then for every 4 clicks (16, 20, 24 ,28 etc) display the default message of 'You are rewarded with a video.
So starting from fresh on zero clicks, when I navigate to this page I notice for each click (1,2,3,4 etc) it displays the default dialog message which is not what I require. I want it to display the messages for 4, 8, 12 which have their own specific messages and then there after (16, 20, 24, 28 etc) should display the general message.
What I have also noticed is that if I come out of the page by selecting the back button and then access the page again, every time the dialog appears it takes me many taps on the ok button for the dialog to close. Initially before I went back from the page it only took me one tap to close the dialog but when I re-enter the page then it takes many taps and I am not sure why.
How can these 2 issues be fixed?
Code below:
import java.util.Random;
public class Content extends AppCompatActivity {
Button backButton;
Button selectAnotherButton;
TextView clickCountText;
int getClickCountInt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content);
final SharedPreferencesManager prefManager = SharedPreferencesManager.getInstance(Content.this);
clickCountText = findViewById(R.id.click_count);
clickCountText.setText(Integer.toString(prefManager.getClicks()));
getClickCountInt = Integer.parseInt(clickCountText.getText().toString());
backButton = findViewById(R.id.button_back);
selectAnotherButton = findViewById(R.id.button_select_another);
setContent();
selectAnotherButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clickCountText.setText(Integer.toString(prefManager.increaseClickCount()));
if (getClickCountInt == 4){
ShowRewardDialog("You are rewarded with a the yellow smiley face in the homepage");
} else if (getClickCountInt == 8) {
ShowRewardDialog("You are rewarded with a the green smiley face in the homepage");
} else if (getClickCountInt == 12) {
ShowRewardDialog("You are rewarded with a the red smiley face in the homepage");
} else {
for(int i = 0; i <= getClickCountInt; i+=4) {
ShowRewardDialog("You are rewarded with a video\"");
}
}
setContent();
}
});
backButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
private void ShowRewardDialog(String message) {
final Dialog dialog = new Dialog(Content.this);
dialog.setContentView(R.layout.custom_dialog);
SpannableString title = new SpannableString("YOU GAINED A REWARD");
title.setSpan(new ForegroundColorSpan(Content.this.getResources().getColor(R.color.purple))
, 0, title.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// set the custom dialog components - text, image and button
TextView text = dialog.findViewById(R.id.dialog_text);
dialog.setTitle(title);
text.setText(message);
Button dialogButton = dialog.findViewById(R.id.dialog_button_OK);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
}
UPDATE
Ok to make it easier I will say what is the current problem and how I want it to work.
I have disabled the else statement for now in the Content class where it displays a generic message in the dialog box.
Ok so I have created a class for my Shared Preferences and I can get an instance of it from both the MainActivity class (this is my homepage) and Content class (this is second page).
Lets say the click counts starts on 0 (and I display this as a text) and I am on the homepage. When I select the jokes button from the homepage, I will navigate to the second page and the count starts at 1. If I select 'Select Another' button which is displayed in second page, then the count goes to 2 (as I can see by the text displayed), click again then three and click again it will go to 4 and the dialog box for count 4 is displayed. This works for when I go to 8 and 12 as well.
When I select the 'Back' button to go from second page to front page, I can see the count remains the same as the count displayed in the second page. E.g if count was set to 8 on page 2 and I click back, the homepage displays the count of 8 as well when I view the text.
This seems all well and good. However lets start again from 0. If I click on the jokes button then I am on 1, I select 'Select Another' button twice so the count is on 3 and then click back button. Count is currently on 3 when I view the homepage. If I click on the jokes button again then the count is on 4 which is correct, however the dialog for if count equals to 4 does not appear. However if I click on the 'Select Another' button 3 more times then it will display the dialog for 4. So it seems like the dialog will only appear for 4 if the 'Select Another' button is clicked four in a row, rather than how I want it which is if the total number of clicks count equals 4 then show the dialog.
What will I need to do to fix this?
Below is the code:
SharedPreferencesManager class:
public class SharedPreferencesManager{
private static final String APP_PREFS = "AppPrefsFile";
private static final String NUMBER_OF_CLICKS = "numberOfClicks";
private SharedPreferences sharedPrefs;
private static SharedPreferencesManager instance;
private SharedPreferencesManager(Context context) {
sharedPrefs = context.getApplicationContext().getSharedPreferences(APP_PREFS, MODE_PRIVATE);
}
public static synchronized SharedPreferencesManager getInstance(Context context){
if(instance == null)
instance = new SharedPreferencesManager(context);
return instance;
}
public int increaseClickCount() {
int clickCount = sharedPrefs.getInt(NUMBER_OF_CLICKS, 0);
clickCount++;
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putInt(NUMBER_OF_CLICKS, clickCount);
editor.apply();
return clickCount;
}
public int getClicks(){
return sharedPrefs.getInt(NUMBER_OF_CLICKS, 0);
}
}
MainActivity class (page 1)
public class MainActivity extends AppCompatActivity {
SharedPreferencesManager prefManager = SharedPreferencesManager.getInstance(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button jokesButton = findViewById(R.id.button_jokes);;
jokesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
prefManager.increaseClickCount();
openContentPage("jokes");
}
});
TextView clickCountText = findViewById(R.id.click_count);
clickCountText.setText(Integer.toString(prefManager.increaseClickCount()));
}
private void openContentPage(String v) {
Intent intentContentPage = new Intent(MainActivity.this, Content.class);
intentContentPage.putExtra("keyPage", v);
startActivity(intentContentPage);
}
}
Content class (page 2):
public class Content extends AppCompatActivity {
Button backButton;
Button selectAnotherButton;
TextView clickCountText;
int getClickCountInt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content);
final SharedPreferencesManager prefManager = SharedPreferencesManager.getInstance(Content.this);
clickCountText = findViewById(R.id.click_count);
clickCountText.setText(Integer.toString(prefManager.getClicks()));
getClickCountInt = Integer.parseInt(clickCountText.getText().toString());
backButton = findViewById(R.id.button_back);
selectAnotherButton = findViewById(R.id.button_select_another);
setContent();
selectAnotherButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getClickCountInt++;
clickCountText.setText(Integer.toString(prefManager.increaseClickCount()));
if (getClickCountInt == 4){
ShowRewardDialog("You are rewarded with a the yellow smiley face in the homepage");
} else if (getClickCountInt == 8) {
ShowRewardDialog("You are rewarded with a the green smiley face in the homepage");
} else if (getClickCountInt == 12) {
ShowRewardDialog("You are rewarded with a the red smiley face in the homepage");
} //else {
//for(int i = 0; i <= getClickCountInt; i+=4) {
//ShowRewardDialog("You are rewarded with a video\"");
//}
//}
}
});
backButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
private void ShowRewardDialog(String message) {
final Dialog dialog = new Dialog(Content.this);
dialog.setContentView(R.layout.custom_dialog);
SpannableString title = new SpannableString("YOU GAINED A REWARD");
title.setSpan(new ForegroundColorSpan(Content.this.getResources().getColor(R.color.purple))
, 0, title.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// set the custom dialog components - text, image and button
TextView text = dialog.findViewById(R.id.dialog_text);
dialog.setTitle(title);
text.setText(message);
Button dialogButton = dialog.findViewById(R.id.dialog_button_OK);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
}
The first problem with your algorithm is that you're not adding the current clicks to your click count.
Inside the onClick of selectAnotherButton.setOnClickListener you should add a getClickCountInt++ (and dont forget to update clickCountText with this new value).
Also, on your onCreate you should get the value for getClickCountInt from SharedPreferences, and then use it to set the value on clickCountText, not the other way around.
This answear shows how to read/store data in SharedPreferences.
I want to make a slideshow of numbers starting from 0 to 9 in pictures. When i click next button , show the picture of 1 and play sound as 'one' and so on.I want previous button to properly work.. like when I click previous button then go to previous pic and play sound which is related to that pic.
public class Numbers extends Activity {
int i = 1;
private ImageView iv;
Button next;
Button previous;
MediaPlayer ourSong;
private int currentImage = 0;
public int currentAudio = 0;
int[] images = { R.drawable.p1, R.drawable.p2, R.drawable.p3,
R.drawable.p4, R.drawable.p5, R.drawable.p6, R.drawable.p7,
R.drawable.p8, R.drawable.p9, R.drawable.p10};
int[] audios = { R.raw.a1, R.raw.a2, R.raw.a3, R.raw.a4, R.raw.a5,
R.raw.a6, R.raw.a7, R.raw.a8, R.raw.a9, R.raw.a10};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nextpre);
iv = (ImageView) findViewById(R.id.ivn);
next = (Button) findViewById(R.id.buttonn);
previous = (Button) findViewById(R.id.buttonp);
// Just set one Click listener for the image
next.setOnClickListener(iButtonChangeImageListener);
previous.setOnClickListener(gButtonChangeImageListener);
}
View.OnClickListener iButtonChangeImageListener = new View.OnClickListener() {
public void onClick(View v) {
try {
// Increase Counter to move to next Image
currentImage++;
currentImage = currentImage % images.length;
iv.setImageResource(images[currentImage]);
ourSong = MediaPlayer.create(Numbers.this,
audios[currentAudio+1]);
ourSong.start();
currentAudio++;
} catch (Exception e) {
}
}
};
View.OnClickListener gButtonChangeImageListener = new View.OnClickListener() {
public void onClick(View v) {
try {
// Decrease Counter to move to previous Image
currentImage--;
currentImage = (currentImage + images.length) % images.length;
iv.setImageResource(images[currentImage]);
MediaPlayer.create(Numbers.this, audios[currentAudio]);
ourSong.start();
currentAudio--;
} catch (Exception e) {
}
}
};
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
ourSong.release();
finish();
}
#Override
protected void onStart() {
super.onStart();
ourSong = MediaPlayer.create(Numbers.this,
audios[0]);
ourSong.start();
}
}
Hmm if you're trying to make a slide show, you might want to look into view pagers they look like this:
View pagers are highly customizable, You can add buttons and images and pretty much almost anything a fragment can hold on each screen. Not sure what your skill level is but ill tell you whats involved in getting this to work.
Create a layout with a view pager in it.
Create a class that extends the FragmentPagerAdapter
Override getItem() method in the adapter (this is where you define your different "screens"
Create a class that extends fragment for each screen you want to show your users.
Doing it this way in order to switch screens u just have to call setCurrentItem to change pages (when user clicks next or prev)
--edit--
Apparently theres also a something called an ImageSwitcher.
They look like this:
This is actually better for your case since you only want images. It looks a lot easier to implement than a view pager. This describes how to implement it: http://www.tutorialspoint.com/android/android_imageswitcher.htm
I'm looking to call a few buttons but seem to be getting a NULL when trying to findbyviewid. When I activate this activity, it crashes.
//CREATE INSTANCE OF GLOBAL - QUESTIONS/ANSWERS
Global global = Global.getInstance();
//CURRENT QUESTION
static int QQ = 0;
//CORRECT ANSWER COUNT
static int correctAnswers = 0;
//CREATE VARIABLE FOR TEXTVIEW/QUESTION
TextView textQuestion = (TextView) findViewById(R.id.textQuestion);
//CREATE VARIABLES FOR BUTTONS/ANSWERS
Button buttonOne = (Button) findViewById(R.id.answerOne);
Button buttonTwo = (Button) findViewById(R.id.answerTwo);
Button buttonThree = (Button) findViewById(R.id.answerThree);
Button buttonFour = (Button) findViewById(R.id.answerFour);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_practice_questions);
setButtons();
buttonOne.setOnClickListener(this);
buttonTwo.setOnClickListener(this);
buttonThree.setOnClickListener(this);
buttonFour.setOnClickListener(this);
}
public void setButtons()
{
//SET QUESTION STRING TO TEXTVIEW
textQuestion.setText(global.getQ(QQ));
//SET ANSWER STRINGS TO BUTTONS' TEXT
buttonOne.setText(global.getA(QQ, 0));
buttonTwo.setText(global.getA(QQ, 1));
buttonThree.setText(global.getA(QQ, 2));
buttonFour.setText(global.getA(QQ, 3));
}
#Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.answerOne:
checkAnswer(0, buttonOne);
break;
case R.id.answerTwo:
checkAnswer(1, buttonTwo);
break;
case R.id.answerThree:
checkAnswer(2, buttonThree);
break;
case R.id.answerFour:
checkAnswer(3, buttonFour);
break;
default:
break;
}
}
public void checkAnswer(int a, Button b){
//IF AN INCORRECT ANSWER WAS CHOSEN, MAKE THE BACKGROUND RED
if(!global.getS(QQ, a))
{
b.setBackgroundColor(Color.RED);
}
else
{
//INCREMENT THE CORRECT ANSWER COUNTER
correctAnswers++;
}
//SET BACKGROUND OF CORRECT BUTTON TO GREEN
if(global.getS(QQ, 0))
{
buttonOne.setBackgroundColor(Color.GREEN);
}
else if(global.getS(QQ, 1))
{
buttonTwo.setBackgroundColor(Color.GREEN);
}
else if(global.getS(QQ, 2))
{
buttonThree.setBackgroundColor(Color.GREEN);
}
else if(global.getS(QQ, 3))
{
buttonFour.setBackgroundColor(Color.GREEN);
}
else
{
//IF NO ANSWER IS CORRECT, SET ALL TO BLUE
buttonOne.setBackgroundColor(Color.BLUE);
buttonTwo.setBackgroundColor(Color.BLUE);
buttonThree.setBackgroundColor(Color.BLUE);
buttonFour.setBackgroundColor(Color.BLUE);
}
//MOVE TO NEXT QUESTION
}
I have 4 buttons in the XML file and want to be able to set the text to them, as well as run a listener for the set of buttons (answers to a question). When one of the buttons is clicked, it should determine if it's the correct answer by pulling the status (true/false) and highlighting it red if it's incorrect. It then highlights the correct answer green.
At least, some of this is in theory and I'm trying to test it out, but I can't start the activity without crashing.
I'm not 100% sure but I think you can't do the findViewById at the instance constructions. You need to those inside onCreate() (after you called setContentView)
Just how i said in comment, you should initialize it in OnCreate method, cause you set view layout for activity here. And before you do it, all findViewById returns null.
So, here your code:
Button buttonOne;
Button buttonTwo;
Button buttonThree;
Button buttonFour;
TextView textQuestion;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_practice_questions);
buttonOne = (Button) findViewById(R.id.answerOne);
buttonTwo = (Button) findViewById(R.id.answerTwo);
buttonThree = (Button) findViewById(R.id.answerThree);
buttonFour = (Button) findViewById(R.id.answerFour);
textQuestion = (TextView) findViewById(R.id.textQuestion);
[...]
}
I'm going through the Sams Android Development book, and I put an animation code and a code to move it to the next screen. I tested it on my phone and the AVD and it's not working. Here's the code:
public class QuizSplashActivity extends QuizActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
TextView logo1 = (TextView) findViewById(R.id.TextViewTopTitle);
Animation fade1 = AnimationUtils.loadAnimation(this, R.anim.fade_in);
logo1.startAnimation(fade1);
TextView logo2 = (TextView) findViewById(R.id.BottomView1);
Animation fade3 = AnimationUtils.loadAnimation(this, R.anim.fade_in);
logo1.startAnimation(fade3);
Animation spinin= AnimationUtils.loadAnimation(this, R.anim.custom_anim);
LayoutAnimationController controller = new LayoutAnimationController(spinin);
TableLayout table = (TableLayout) findViewById(R.id.TableLayout01); {
for (int i = 0; i < table.getChildCount(); i++) {
TableRow row = (TableRow) table.getChildAt(i);
row.setLayoutAnimation(controller);
}
}
Animation fade2 = AnimationUtils.loadAnimation(this, R.anim.custom_anim);
fade2.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation){
startActivity(new Intent(QuizSplashActivity.this, QuizMenuActivity.class));
QuizSplashActivity.this.finish();
}
public void onAnimationStart(Animation a) { }
public void onAnimationRepeat(Animation a) { }
});
}
#Override
protected void onPause() {
super.onPause();
TextView logo1= (TextView) findViewById(R.id.TextViewTopTitle);
logo1.clearAnimation();
TextView logo2= (TextView) findViewById(R.id.BottomView1);
logo2.clearAnimation();
}
}
`
Please help, I want to move onto the next chapter.
Again, if I run this code, the animation doesn't run and the app doesn't move onto the next screen.
Thanks
First of all, onAnimationEnd of fade2 is where you start your next Activity but I don't see you using it anywhere.
I think you've got confused about which views you want to animate and which animations to use here:
TextView logo1 = (TextView) findViewById(R.id.TextViewTopTitle);
Animation fade1 = AnimationUtils.loadAnimation(this, R.anim.fade_in);
logo1.startAnimation(fade1); // <----- is this right?
TextView logo2 = (TextView) findViewById(R.id.BottomView1);
Animation fade3 = AnimationUtils.loadAnimation(this, R.anim.fade_in);
logo1.startAnimation(fade3); // <----- and this one?
Also, onAnimationEnd is not reliable. You can take a look at setRepeatCount() and setRepeatMode() and play around with those but there are multiple bugs with them and worse, those bugs vary between Android version.
Instead, you can use a delayed Runnable to do your "post animation" work:
new Handler().postDelayed(new Runnable() {
public void run() {
view.clearAnimation(); // <--- whichever view you are animating
startActivity(new Intent(QuizSplashActivity.this, QuizMenuActivity.class));
QuizSplashActivity.this.finish();
}
}, fade2.getDuration());
This runnable will be delayed for however long fade2 is set to animate for. When it fires, it clears the current animation and starts the activity.
Good luck!