Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

Adding Extra Buttons To The Fun Facts App

OK,

So having my FunFacts App built with new colours & facts, I thought I'd try to add 2 new buttons - 1 that changes just the colour, & 1 that changes just the fact.

I thought that this would be a good way to test that I understand things correctly. I'm getting a bit of an issue. I've rewritten fun_facts.java to display as follows:

package net.app.funfacts;

import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast;

public class fun_facts extends AppCompatActivity {

public static final String Tag = fun_facts.class.getSimpleName();

private FactBook mFactBook = new FactBook();
private ColorWheel mColorWheel = new ColorWheel();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_fun_facts);
    final TextView factLabel = (TextView) findViewById(R.id.factTextView);
    final Button showFactButton = (Button) findViewById(R.id.showFactButton);
    final Button justAFactButton = (Button) findViewById(R.id.justafactbutton);
    final Button justColourButton = (Button) findViewById(R.id.justchangecolourbutton);
    final RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);

    View.OnClickListener Listener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String fact = mFactBook.getfact();
            int color = mColorWheel.getcolor();
            factLabel.setText(fact);
            relativeLayout.setBackgroundColor(color);
            showFactButton.setTextColor(color);
            justAFactButton.setTextColor(color);
            justColourButton.setTextColor(color);
        };
    };
    showFactButton.setOnClickListener(Listener);

    View.OnClickListener Listener2 = new View.OnClickListener() {

        public void onClickFact(View v) {
            String fact = mFactBook.getfact();
            factLabel.setText(fact);
        };
    };
    justAFactButton.setOnClickListener(Listener2);

    Toast.makeText(this, "App has booted up!", Toast.LENGTH_LONG).show();
    Log.d(Tag, "We're logging from the onCreate() Method");
}

}

However I get a fault appear when building:

Error:(43, 69) <anonymous net.app.funfacts.fun_facts$2> is not abstract and does not override abstract method onClick(android.view.View) in android.view.View.OnClickListener

Presumably, it doesn't allow 2 onClickListeners to run at once? Am I trying to bite off more than I can chew just yet?

OK.

I've nailed this. Did a quick search & landed on a useful Stack Exchange page:

http://stackoverflow.com/questions/5646418/how-to-go-about-multiple-buttons-and-onclicklisteners

Anyway, here is my revised code for the above & it works a treat!

package net.pantri.funfacts;

import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast;

public class fun_facts extends AppCompatActivity {

public static final String Tag = fun_facts.class.getSimpleName();

private FactBook mFactBook = new FactBook();
private ColorWheel mColorWheel = new ColorWheel();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_fun_facts);
    final TextView factLabel = (TextView) findViewById(R.id.factTextView);
    final Button showFactButton = (Button) findViewById(R.id.showFactButton);
    final Button justAFactButton = (Button) findViewById(R.id.justafactbutton);
    final Button justColourButton = (Button) findViewById(R.id.justchangecolourbutton);
    final RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);

    View.OnClickListener Listener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            String fact = mFactBook.getfact();
            int color = mColorWheel.getcolor();

            switch (v.getId()) {

                case R.id.showFactButton:
                    factLabel.setText(fact);
                    relativeLayout.setBackgroundColor(color);
                    showFactButton.setTextColor(color);
                    justAFactButton.setTextColor(color);
                    justColourButton.setTextColor(color);
                    break;
                case R.id.justafactbutton:
                    factLabel.setText(fact);
                    break;
                case R.id.justchangecolourbutton:
                    relativeLayout.setBackgroundColor(color);
                    showFactButton.setTextColor(color);
                    justAFactButton.setTextColor(color);
                    justColourButton.setTextColor(color);
                    break;
            };
        };
    };
    showFactButton.setOnClickListener(Listener);
    justAFactButton.setOnClickListener(Listener);
    justColourButton.setOnClickListener(Listener);

    Toast.makeText(this, "App has booted up!", Toast.LENGTH_LONG).show();
    Log.d(Tag, "We're logging from the onCreate() Method");
}

}

1 Answer

Hi Joe

Well done for getting there by yourself, just in case you were wondering what caused the error it was in the code section below. The OnClickListener class requires you to implement the method onClick() method and use the @override annotatation to override it from the parent class. I have commented out your original code and replaced it with what it should have been however I personally prefer your switch statement anyway as it is much tidier.

View.OnClickListener Listener2 = new View.OnClickListener() {

        //public void onClickFact(View v) { This causes an error as the method is named onClickFact and no onClick is
       //included
            @override
            public void onClick(View v) {

                  String fact = mFactBook.getfact();
                  factLabel.setText(fact);
        };
    };
    justAFactButton.setOnClickListener(Listener2);

Just for reference

Daniel

OK.

Thanks for the help. Typo! I guess with a bit more experience, I'd have had the conviction to find out the typo, rather than thinking my code is duff!

Just so that I understand fully, are you saying that this would have worked?

public static final String Tag = fun_facts.class.getSimpleName();

private FactBook mFactBook = new FactBook();
private ColorWheel mColorWheel = new ColorWheel();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_fun_facts);
    final TextView factLabel = (TextView) findViewById(R.id.factTextView);
    final Button showFactButton = (Button) findViewById(R.id.showFactButton);
    final Button justAFactButton = (Button) findViewById(R.id.justafactbutton);
    final Button justColourButton = (Button) findViewById(R.id.justchangecolourbutton);
    final RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);

    View.OnClickListener Listener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String fact = mFactBook.getfact();
            int color = mColorWheel.getcolor();
            factLabel.setText(fact);
            relativeLayout.setBackgroundColor(color);
            showFactButton.setTextColor(color);
            justAFactButton.setTextColor(color);
            justColourButton.setTextColor(color);
        };
    };
    showFactButton.setOnClickListener(Listener);

    View.OnClickListener Listener2 = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String fact = mFactBook.getfact();
            factLabel.setText(fact);
        };
    };
    justAFactButton.setOnClickListener(Listener2);

    Toast.makeText(this, "App has booted up!", Toast.LENGTH_LONG).show();
    Log.d(Tag, "We're logging from the onCreate() Method");
}

Been reading up about @override. Still ever so slightly confused as to exactly what it does. Going to challenge myself further by seeing if I can have 2 funfacts java files & call different ones based on the button thats pressed...

Hi Joe

Yes your example looks like it would work to me, the override annotation is a little more of an advanced topic. There is a course just been added to treehouse on annotations (in Java) but is is to be taken after the Java track really to fully understand about classes and inheritance, it may be a little overwhelming if you're just starting out but trust me within no time at all it will all click.

Thanks Daniel