Android onClick(View) with switch incorrect case - java

I have a single OnClickListener instance to direct clicks to multiple other handler methods, generally:
void onClick(View v) {
switch (v.getId()) {
case R.id.viewA:
handleButtonA();
break;
case R.id.viewB:
handleButtonB();
break;
default:
handleDefaultCondition();
break;
}
}
When I click view A, handleButtonA() is called. When I click view B, nothing happens. When I click any other view it calls handleDefaultCondition(). I had the same behavior with a series of if/else if statements, so I don't think the problem is related to my use of switch.
Here is the complete code:
public class MyClickListener implements View.OnClickListener {
public void onClick(View view) {
int viewId = view.getId();
switch (viewId) {
case R.id.time_frag_mark_button:
handleMarkButton(); //just calls dummy method with a Log statement inside for testing
break;
case R.id.finalize_entry_button:
handleFinalizeButton(); //just calls dummy method with a Log statement inside for testing
break;
default:
openTimePickerDialog(view.getId()); //just calls dummy method with a Log statement inside for testing
break;
}
}
}
And an excerpt from my R file:
public static final class id {
public static final int action_settings=0x7f08000e;
public static final int finalize_entry_button=0x7f08000d;
public static final int separator=0x7f080002;
public static final int time_frag_current_time=0x7f080003;
public static final int time_frag_date_string=0x7f080001;
public static final int time_frag_in_label=0x7f08000b;
public static final int time_frag_in_picker=0x7f08000c;
public static final int time_frag_mark_button=0x7f080004;
}
As requested, the code to initialize the listeners:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myClickListener = new MyClickListener();
myTimeFilter = new IntentFilter(Intent.ACTION_TIME_TICK);
myTimeTicker = new MyTimeTicker();
getApplicationContext().registerReceiver(myTimeTicker, myTimeFilter);
systemTime = (TextView) findViewById(R.id.time_frag_current_time);
systemTime.setText(sdf.format(new Date()));
systemDate = (TextView) findViewById(R.id.time_frag_date_string);
outTimeView = (TextView) findViewById(R.id.time_frag_out_picker);
outTimeView.setOnClickListener(myClickListener);
offTimeView = (TextView) findViewById(R.id.time_frag_off_picker);
offTimeView.setOnClickListener(myClickListener);
onTimeView = (TextView) findViewById(R.id.time_frag_on_picker);
onTimeView.setOnClickListener(myClickListener);
inTimeView = (TextView) findViewById(R.id.time_frag_in_picker);
inTimeView.setOnClickListener(myClickListener);
markButton = (Button) findViewById(R.id.time_frag_mark_button);
markButton.setOnClickListener(myClickListener);
//should error check this, only open a new one if one is not in progress
//need to start saving the Entry to disk during onPause() and move this check to onStart() or something
currentEntry = new LogEntry();
}

Have you tried looking to see what ID is output when you press the R.id.finalize_entry_button to see if it is what you expect?
Also, can you post the code that hooks up the OnClick handler to your controls?

Related

Java class extends MainActivity but findViewById comes back null?

This class extends my main Activity.
public class Numbers extends MainActivity{
public ArrayList<ImageView> getNumbers () {
ArrayList<ImageView> numbers = new ArrayList<>();
ImageView one = (ImageView) findViewById(R.id.one);
numbers.add(one);
return numbers;
}
And I've done some digging but can figure out why my variable "one" is coming back null.
My MainActivity has a ContentView set.
This is the content of my onCreate in MainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView start = (ImageView) findViewById(R.id.start);
sceneRoot = (ViewGroup) findViewById(R.id.scene_root);
questionView = findViewById(R.id.questionView);
startView = findViewById(R.id.startView);
gameOverView = findViewById(R.id.gameOver);
animSlide = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide);
animSlide.setAnimationListener(this);
animZoom = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.zoom_fade);
animZoom.setAnimationListener(this);
set.addTransition(new Fade())
.addTransition(new Slide(Gravity.RIGHT));
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getQuestion();
TransitionManager.beginDelayedTransition(sceneRoot, set);
startView.setVisibility(View.GONE);
questionView.setVisibility(View.VISIBLE);
}
});
}
public void getQuestion (){
time = (TextView) findViewById(R.id.timeBar);
time.startAnimation(animSlide);
}
I don't call getNumbers() until after start has been clicked and the animation has started.
public void onAnimationStart(Animation animation){
if(animation == animSlide) {
final Questions questions = new Questions();
Numbers n = new Numbers();
for (int i = 0; i < n.getNumbers().size(); i++) {
n.getNumbers().get(i).setVisibility(View.GONE);
n.getNumbersTen().get(i).setVisibility(View.GONE);
}
n.getNumbers().get(0).setVisibility(View.VISIBLE);
EDIT:
If anyone was wondering, I got it to work by extending the class as a Fragment instead of my MainActivity. Then I just used the fragment in my xml.
Because you extended an Activity class doesn't mean setContentView gets called for that class also. It will only do so if properly started and you call super.onCreate(bundle) from your own implementation of onCreate within Numbers
Basically, you should never new any Activity. It has no life-cycle, and therefore no content view, so findViewById just won't work.
Numbers n = new Numbers();
You could not extend anything and have a data-only class around your list of images.
public class Numbers {
private List<ImageView> numbers = new ArrayList<ImageView>();
public Numbers() {}
public void addNumber(ImageView v) { numbers.add(v); }
public List<ImageView> getNumbers() { return numbers; }
}
And from MainActivity you can find and add as you want.
Number n = new Numbers();
n.addNumber((ImageView) findViewById(R.id.one));
However, I don't know if that is useful, really...
Maybe a Fragment would serve a better purpose if you want a "sub-view" of your Activity, but it's hard to tell.

How to update method to return updated information from textwatcher after pressing button

I have declared my variable, 'changed' too null so that I can check if it changes when the edittext is changed,
The problem I think is, when I press either the save button or the cancel button, it will always produce the value null, as upon clicking the button it is still null. However, I thought that the textwatcher would listen to the EditText and even if nothing was changed in the EditText it would by default change the SetChanged() to false as it provided "live updates", however clearly this isn't the case, am I doing something wrong? or am I supposed to approach it in a different way?, is there some way of refreshing it?
Advise would be greatly appreciated.
(P.S Some code was deleted to reduce the size and make it look easy on the eye, so excuse me for any missing braces. Furthermore, the activity does run properly as it shows the layout.However upon pressing any of the buttons it causes it to crash.)
public class EditNewItemActivity extends AppCompatActivity{
private Boolean changed = null;
private TextView title,content;
private Button saveBtn,cancelBtn;
private String date;
private int id;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_item);
title = (TextView) findViewById(R.id.editItemTitle);
content = (TextView) findViewById(R.id.editItemDescription);
saveBtn = (Button) findViewById(R.id.editItemSaveBtn);
cancelBtn = (Button) findViewById(R.id.editItemCancelBtn);
Bundle extras = getIntent().getExtras();
title.setText(extras.getString("title"));
content.setText(extras.getString("content"));
date = extras.getString("date");
id = extras.getInt("id");
GenericTextWatcher textWatcher = new GenericTextWatcher();
title.addTextChangedListener(textWatcher);
content.addTextChangedListener(textWatcher);
ClickEvent clickEvent = new ClickEvent();
saveBtn.setOnClickListener(clickEvent);
cancelBtn.setOnClickListener(clickEvent);
}
private class ClickEvent implements View.OnClickListener{
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.editItemSaveBtn:
save();
break;
case R.id.editItemCancelBtn:
cancel();
break;
}
}
}
private void cancel() {
if (getChanged() == null){
//This was used to simply verify that getchanged was still null.
}
if (title.getText().toString() != "" || content.getText().toString() != ""){
if (getChanged() == false) {
// if nothing has been changed let it cancel etc
}else {
}
}
}
private void save() {
if (tempTitle != "" || tempContent != "") {
if(getChanged() == true){
}
}
public Boolean getChanged() {
return changed;
}
public void setChanged(Boolean changed) {
this.changed = changed;
}
private class GenericTextWatcher implements TextWatcher{
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
Log.v("Beforetext:", s.toString());
EditNewItemActivity editItem = new EditNewItemActivity();
editItem.setChanged(false);
}
#Override
public void afterTextChanged(Editable s) {
Log.v("afterTextChanged:", s.toString());
EditNewItemActivity editItem = new EditNewItemActivity();
editItem.setChanged(true);
Log.v("Status:", editItem.getChanged().toString());
}
}
You had change the changed. But which you changed is in your new EditNewItemActivity not in your current page.
This is where you made mistake (beforeTextChanged and afterTextChanged in your GenericTextWatcher):
EditNewItemActivity editItem = new EditNewItemActivity();
editItem.setChanged(false); //or true
You should just call:
setChanged(false); // or true
In fact, you should not new an activity yourself, activity must be create by the Android Framework so that it can be managed by the system.

I want a central way to control my buttons

Hi I have 2 lines each with a name textfield, 2 buttons and a textfield to show the amount. There will be more lines later.
I want 1 button to add 1 to the amount and the other to decrease the amount by 1.
But I don't know how to get the ID from the button I press. I have gotten this far.
I hope someone can let me know. How I can get the indexvalue depending on which button is pressed.
public class MainActivity extends AppCompatActivity {
private ArrayList<Integer> ButtonUp;
private ArrayList<Integer> Amount;
private ArrayList<Integer> ButtonDown;
int ArrayIndex = 0;
int Value = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButtonUp();
Amount();
ButtonDown();
}
// ArrayList ButtonUp
public void ButtonUp(){
ButtonUp.add(R.id.Bup1);
ButtonUp.add(R.id.Bup2);
}
// ArrayList Amount
public void Amount(){
Amount.add(R.id.Aantal1);
Amount.add(R.id.Aantal2);
}
// ArrayList ButtonDown
public void ButtonDown() {
ButtonDown.add(R.id.Bdown1);
ButtonDown.add(R.id.Bdown2);
}
// Get position ArrayList on press
// Publish new Value
public void buttonPress(View v) {
switch (v.getId()) {
case R.id.Bup1:
SetAmountUp(id);
displayQuantity(Value);
break;
case R.id.Bup2:
SetAmountUp(R.id.Bup2);
displayQuantity(Value);
break;
case R.id.Bdown1:
SetAmountDown(R.id.Bdown1);
displayQuantity(Value);
break;
case R.id.Bdown2:
SetAmountDown(R.id.Bdown1);
displayQuantity(Value);
break;
}
}
public void SetAmountUp(int indexNumberUp){
Value = Amount.get(ButtonUp.indexOf(indexNumberUp));
Value++;
Amount.set(ArrayIndex,Value);
}
public void SetAmountDown(int indexNumberDown){
Value = Amount.get(ButtonDown.indexOf(indexNumberDown));
Value--;
Amount.set(ArrayIndex,Value);
}
// Publish number
private void displayQuantity(int NewAmount) {
int ID = Amount.get(ArrayIndex);
TextView quantityTextView = (TextView) findViewById(ID);
quantityTextView.setText(NewAmount);
}
}
In the layout, declare an unique id to each button, then add android:onClick="increment" to each button.
In your class, create the method
public void increment(View view) {
switch (view.getId()){
case R.id.yourbuttonid1:
// do what you whant
break;
case R.id.yourbuttonid2:
// do with second editext
break
// ....
}
}
Same approach to decrease method.
It will be much easier for you if you used a recyclerView for that

How can I get the value of the ArrayList without returning size = 0?

When I get the value of the arraylist, I get size = 0. I boot the ArrayList in Class Screen1, but I can not get the value of the Class Screen2 cont.
public class Variables {
public Variables() {
}
private int cont = 0;
private int correct = 0;
public int getCont(){
return cont;
}
public void setCont(int cont){
this.cont = cont;
}
public int getCorrect(){
return correct;
}
public void setCorrect(int correct){
this.correct = correct;
}}
Class Screen1
public class Screen1 extends ActionBarActivity {
Variables variables = new Variables();
ArrayList<Variables> variablesArrayList = new ArrayList<Variables>();
public int cont;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen1);
variables.setCorrect(1);
variables.setCont(1);
variablesArrayList.add(variables);
}
public void sendTela1(View view){
cont = variables.getCont();
cont++;
variablesArrayList.get(0).setCont(cont);
}
}
Class Screen 2
This class I'm trying to get the value of ArrayList
public class Screen2 extends ActionBarActivity {
Variables variables = new Variables();
ArrayList<Variables> variablesArrayList = new ArrayList<Variables>();
int cont;
ImageView progressbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen2);
progressbar = (ImageView) findViewById(R.id.progressbar);
//this line, the arraylist is returning size = 0
cont = variablesArrayList.get(1);
switch (cont){
case 1:
progressbar.setImageResource(R.drawable.progressbar1);
break;
case 2:
progressbar.setImageResource(R.drawable.progressbar2);
break;
case 3:
progressbar.setImageResource(R.drawable.progressbar3);
break;
case 4:
progressbar.setImageResource(R.drawable.progressbar4);
break;
case 5:
progressbar.setImageResource(R.drawable.progressbar5);
break;
}}
You're getting a return size of 0 because in screen2 activity you are creating a new list when you do: ArrayList<Variables> variablesArrayList = new ArrayList<Variables>();
To fix this, you need to pass the arraylist you created in screen1 into screen2. You will have to implement parcelable, but that will allow you to pass the data using intents and bundles.
If you create a new object as you are doing in your screen2 with the line
ArrayList<Variables> variablesArrayList = new ArrayList<Variables>();
you will of course receive an empty arrayList. There are multiple ways of sending data from one Activity to another. I suggest you look into bundles and using putExtras and later getExtras via Intents. However, since you have a model class why not use that?
In your model class add
private static ArrayList<Variables> variablesArrayList;
Now add some setters and getters to update and retrieve your list
// getter
public static ArrayList<Variables> getList() {
return variablesArrayList;
}
// setter
public static void setList(ArrayList<Variables> varArryList) {
this.variablesArrayList = varArryList;
}
Now on screen1 set your arrayList and in screen2 (or 3, or 4, or 5, ect) retrieve it! Cheers!

Text view if statement not working

Can anyone help me work out where I'm going wrong here. On the button click the media player plays one of the mfiles at random and I'm trying to set a textview depending on which file was played. Currently the setText if statements only match the audio playing half the time. Really not sure where I'm going wrong here.
private final int SOUND_CLIPS = 3;
private int mfile[] = new int[SOUND_CLIPS];
private Random rnd = new Random();
MediaPlayer mpButtonOne;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mfile[0] = R.raw.one;
mfile[1] = R.raw.two;
mfile[2] = R.raw.three;
//Button setup
Button bOne = (Button) findViewById(R.id.button1);
bOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final TextView textOne = (TextView)findViewById(R.id.textView1);
mpButtonOne = MediaPlayer.create(MainActivity.this, mfile[rnd.nextInt(SOUND_CLIPS)]);
if (mpButtonOne==null){
//display a Toast message here
return;
}
mpButtonOne.start();
if (mfile[rnd.nextInt(SOUND_CLIPS)] == mfile[0]){
textOne.setText("one");
}
if (mfile[rnd.nextInt(SOUND_CLIPS)] == mfile[1]){
textOne.setText("two");
}
if (mfile[rnd.nextInt(SOUND_CLIPS)] == mfile[2]){
textOne.setText("three");
}
mpButtonOne.setOnCompletionListener(new soundListener1());
{
}
So just to clarify the problem I am having is that the setText only matches the audio occasionally, not on every click. The rest of the time it displays the wrong text for the wrong audio.
You are choosing another random file
mfile[rnd.nextInt(SOUND_CLIPS)]
set that to a variable in onClick() then check against that variable in your if statement
public void onClick(View v) {
int song = mfile[rnd.nextInt(SOUND_CLIPS)];
final TextView textOne = (TextView)findViewById(R.id.textView1);
mpButtonOne = MediaPlayer.create(MainActivity.this, song);
if (song == mfile[0]){
textOne.setText("one");
}
Edit
To make it a member variable so you can use it anywhere in the class, just declare it outside of a method. Usually do this before onCreate() just so all member variables are in the same place and it makes your code more readable/manageable.
public class SomeClass extends Activity
{
int song;
public void onCreate()
{
// your code
}
then you can just initialize it in your onClick()
public void onClick(View v) {
song = mfile[rnd.nextInt(SOUND_CLIPS)];
final TextView textOne = (TextView)findViewById(R.id.textView1);
mpButtonOne = MediaPlayer.create(MainActivity.this, song);

Categories

Resources