1. Download our Official Android App: Forums for Android!

Apps Button Issue

Discussion in 'Android Development' started by Conor Calby, Aug 21, 2011.

  1. Conor Calby

    Conor Calby Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    22
    Joined:
    May 3, 2011

    May 3, 2011
    22
    0
    15
    I am developing a small android application for my martial arts club however, whenever it opens, it force closes straight away.

    The way it is meant to go is like so.. You open the app (loads main.xml) then you press a button (button1) to continue to bels.xml. So far, I am trying to make the whitebelt button (button2) go to whitebelt.xml.

    I have the pages/screens created and here is the activity.java file.
    [Java] EvolutionTheoryHelperActivity.java - Pastebin.com

    Now, its this part that is causing the issue as if I remove it, it works fine... However it doesn't allow my button2 to work.
    Code (Text):
    1. Button button2 = (Button)this.findViewById(R.id.button2);
    2.     button2.setOnClickListener(new OnClickListener() {
    3.         @Override
    4.         public void onClick(View whitebelt) {
    5.            // button 1 was clicked!
    6.                 setContentView(R.layout.whitebelt);
    7.         }
    8.         });
    Do you think you could help?
    Regards,

    --Conor Calby
     

    Advertisement

  2. alostpacket

    alostpacket Over Macho Grande?
    Rank:
    None
    Points:
    513
    Posts:
    7,972
    Joined:
    Nov 29, 2009

    Nov 29, 2009
    7,972
    3,603
    513
    Android App Developer
    NY
    I personally hate when I see someone create an object within a method parameter....oh well, java.

    Basically part of the problem is scope I think. You are calling a method of the activity from within a listener. And since a listener does not extend Activity, AND it is being created inside a method of another object it has no such method itself.

    Anyways, try this -- it should be more clear this way:
    Code (Text):
    1.  
    2.  
    3. //MyActivity.java
    4.  
    5. Button button2 = (Button) findViewById(R.id.button2);
    6. button2.setOnClickListener(myButton2listener);
    7.  
    8.  
    9. // this is now an inner class and can "see" the methods in the activity
    10. // let's have it call our own protected method setSecondContentView()
    11.  
    12. View.OnClickListener myButton2listener = new View.OnClickListener()
    13. {        
    14.      @Override        
    15.      public void  onClick(View v)
    16.      {
    17.          // button 2 was clicked!                  
    18.           setSecondContentView();
    19.      }        
    20. }
    21.  
    22.  
    23.  
    24. protected void setSecondContentView()
    25. {
    26.      setContentView(R.layout.whitebelt);
    27. }
    if that doesnt work, post the stack trace and we'll see if we can figure it out from there :)
     
    Conor Calby likes this.
  3. Conor Calby

    Conor Calby Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    22
    Joined:
    May 3, 2011

    May 3, 2011
    22
    0
    15
    Please be more specific, its my first time trying to do this. I am great with PHP but not Java :p
     
  4. jonbonazza

    jonbonazza Android Expert
    Rank:
    None
    Points:
    163
    Posts:
    1,930
    Joined:
    Jul 13, 2010

    Jul 13, 2010
    1,930
    457
    163
    Male
    Your problem is, indeed, a scope issue.

    Furthermore, alostpacket's solution will not work either. The reason is that, like alostpacket stated, you are both creating an inner class. Inner classes are ultimately bad programming practices, but they are often "forgiven" in Android development (why, I am not sure). In any rate, the reason they are looked down upon in normal practice is for this reason. Scope becomes a pain in the rear end to manage and often leads to hard-to-find bugs.

    At any rate, what you both are doing is creating a new interface and attempting to call a method of another class (the Activity subclass) in your new interface (the listener). You really only have a couple ways to go about this correctly:

    1) Perhaps the simplest is to make your activity class the listener by implementing the listerner using the implements keyword.

    Example:
    Code (Text):
    1.  
    2. public class MyActivity extends Activity implements View.OnClickListener
    3. {
    4.        ...
    5.        Button button2;
    6.        ...
    7.        @override
    8.        public void onCreate(Bundle savedInstanceState)
    9.        {
    10.                super.onCreate(savedInstanceState);
    11.                ...
    12.                button2 = (Button)findViewById(R.id.button2);
    13.                button2.setOnClickListener(this);
    14.                ...
    15.        }
    16.  
    17.        @Override
    18.        public void onClick(View v)
    19.        {
    20.             if(v == button2)
    21.                  this.setContentView(R.layout.whitebelt);
    22.        }
    23. }
    24.  
    2) The second, more accepted approach, is to create another class that implements the listener and pass a pointer to the Activity subclass as a parameter of the constructor. Then, use that pointer to call the setContentView method inside onClick. Inside of your Activity subclass, you would create an instance of the new class.

    Since you are apparently new to Java, and likely OOP in general, I would recommend making things easy on yourself and using the 1st approach. Although it is not the best programming practice, it gets the job done and is easy to implement.
     
    Conor Calby likes this.
  5. alostpacket

    alostpacket Over Macho Grande?
    Rank:
    None
    Points:
    513
    Posts:
    7,972
    Joined:
    Nov 29, 2009

    Nov 29, 2009
    7,972
    3,603
    513
    Android App Developer
    NY
    Ahem :)

    I do this all the time...I'm looking at an identical method in one of my apps :p


    Anyways, the problem with my solution is that the compiler generates all those $access2000 static methods because it's not sure if inner classes accessing private/protected methods of the outer class is valid (even though it technically is)

    One way to solve that though is to make any method called by an inner class have package level scope. A bit "dangerous" but it reduces code size and is better for performance.

    The problem with your solution (#1) is you have taken a step towards making the activity the God anti-pattern. I dont like having my activities handle all the work. Making listener objects (seems at least) to make them more portable down the road for refactoring. Solution #2 is good though.

    Either way they all have ups and downs :) Also I totally agree/hate inner classes.
     
  6. Conor Calby

    Conor Calby Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    22
    Joined:
    May 3, 2011

    May 3, 2011
    22
    0
    15
    This is honestly the only app I will ever create for Android. I only started with OOP a few months ago so it is fairly new to me.

    Here is what I have.
    [Java] package com.example.android.apis.tests; import android.app.Activity; import - Pastebin.com

    Sorry for the n00bness. :p
     
  7. alostpacket

    alostpacket Over Macho Grande?
    Rank:
    None
    Points:
    513
    Posts:
    7,972
    Joined:
    Nov 29, 2009

    Nov 29, 2009
    7,972
    3,603
    513
    Android App Developer
    NY
    Are you still getting errors?
     
  8. Conor Calby

    Conor Calby Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    22
    Joined:
    May 3, 2011

    May 3, 2011
    22
    0
    15
    HAHA, , help is I explained that now wouldn't it :p

    It force closes on start up.
     
  9. alostpacket

    alostpacket Over Macho Grande?
    Rank:
    None
    Points:
    513
    Posts:
    7,972
    Joined:
    Nov 29, 2009

    Nov 29, 2009
    7,972
    3,603
    513
    Android App Developer
    NY
    The code looks correct in paste bin to me, maybe something in your manifest? did you add the activity correctly?

    What does Logcat say?
     
  10. alostpacket

    alostpacket Over Macho Grande?
    Rank:
    None
    Points:
    513
    Posts:
    7,972
    Joined:
    Nov 29, 2009

    Nov 29, 2009
    7,972
    3,603
    513
    Android App Developer
    NY
    OK it looks like button 2 is null...
    ^ check line 22... then make sure R.id.button2 is the id for your second button and that it exists in the main.xml layout
     
  11. Conor Calby

    Conor Calby Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    22
    Joined:
    May 3, 2011

    May 3, 2011
    22
    0
    15
    Button 2 does not exist in main.xml but belt.html. Could that be the problem?

    The way it goes to
    User loads app>> main.xml (click to continue type page (button 1))>>belt.xml (click belt for belt info type page. buttons 2-10)>> *User clients white belt (button 2)*>>whitebelt.xml
     
  12. alostpacket

    alostpacket Over Macho Grande?
    Rank:
    None
    Points:
    513
    Posts:
    7,972
    Joined:
    Nov 29, 2009

    Nov 29, 2009
    7,972
    3,603
    513
    Android App Developer
    NY
    ah yes, that is the problem then. You should move the part where you set the listener of button2 to AFTER you change the content view. You will also need to move the "findViewById" bit.
     
  13. alostpacket

    alostpacket Over Macho Grande?
    Rank:
    None
    Points:
    513
    Posts:
    7,972
    Joined:
    Nov 29, 2009

    Nov 29, 2009
    7,972
    3,603
    513
    Android App Developer
    NY
    basically, any time you change the contentview, you will reset what objects are available.

    You might want to look at something like a viewstub, instead of changing your whole content view
     
    Conor Calby likes this.
  14. alostpacket

    alostpacket Over Macho Grande?
    Rank:
    None
    Points:
    513
    Posts:
    7,972
    Joined:
    Nov 29, 2009

    Nov 29, 2009
    7,972
    3,603
    513
    Android App Developer
    NY
  15. Conor Calby

    Conor Calby Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    22
    Joined:
    May 3, 2011

    May 3, 2011
    22
    0
    15
    Wow. Thanks mate! Got it now. Added
    Code (Text):
    1.     @Override
    2.     public void onClick(View v)
    3.     {
    4.          if(v == button1)
    5.               this.setContentView(R.layout.belt);
    6.          
    7.          button2 = (Button)findViewById(R.id.button2);
    8.          button2.setOnClickListener(this);
    9.          if(v == button2)
    10.              this.setContentView(R.layout.whitebelt);
    11.     };
    What you said makes sense regarding the reset objects. Thanks again!
     
  16. alostpacket

    alostpacket Over Macho Grande?
    Rank:
    None
    Points:
    513
    Posts:
    7,972
    Joined:
    Nov 29, 2009

    Nov 29, 2009
    7,972
    3,603
    513
    Android App Developer
    NY
    You're welcome :)
     
  17. jonbonazza

    jonbonazza Android Expert
    Rank:
    None
    Points:
    163
    Posts:
    1,930
    Joined:
    Jul 13, 2010

    Jul 13, 2010
    1,930
    457
    163
    Male
    Oops... after reconsidering what I said, I realize now that I was wrong.. In fact, the way he had it initially should have worked as well. Since the class was defined withing another class, all data members of the outer class would therefore be available to the inner class as well...

    I apologize for the brain fart. haha
     
  18. Conor Calby

    Conor Calby Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    22
    Joined:
    May 3, 2011

    May 3, 2011
    22
    0
    15
  19. alostpacket

    alostpacket Over Macho Grande?
    Rank:
    None
    Points:
    513
    Posts:
    7,972
    Joined:
    Nov 29, 2009

    Nov 29, 2009
    7,972
    3,603
    513
    Android App Developer
    NY

    No worries, I was thinking to myself when I read the OP "shouldn't this work?" But somehow was convinced since he was creating the inner class/object IN the param of a method it somehow lost scope.... but I guess it doesnt matter :)
     
  20. alostpacket

    alostpacket Over Macho Grande?
    Rank:
    None
    Points:
    513
    Posts:
    7,972
    Joined:
    Nov 29, 2009

    Nov 29, 2009
    7,972
    3,603
    513
    Android App Developer
    NY
  21. Conor Calby

    Conor Calby Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    22
    Joined:
    May 3, 2011

    May 3, 2011
    22
    0
    15
    Thats just because I was trying before. I did add the opening tags. Added above the first LinearLayout and straight after it. Both places didn't work.
     
  22. alostpacket

    alostpacket Over Macho Grande?
    Rank:
    None
    Points:
    513
    Posts:
    7,972
    Joined:
    Nov 29, 2009

    Nov 29, 2009
    7,972
    3,603
    513
    Android App Developer
    NY
    I think for scrollview you need a single child set to wrap content for it to work correctly..... not sure if that helps :)
     

Share This Page

Loading...