Very basic yet frustrating question

Discussion in 'Android Hacks and Help' started by Jett, May 6, 2010.

  1. Jett
    Offline

    Jett New Member

    Joined:
    Apr 30, 2010
    Messages:
    15
    Likes Received:
    0
    Trophy Points:
    1
    Ratings:
    +0
    Alright, I've taken Java before but never used it outside of the extremely simple programs for class. My strong suit was certainly in other languages.

    Basically, I'll explain the problem rather than writing out code and saying 'fix it.' All I want to do is expand my simple HelloWorld app so that there's 2 buttons, and each one does a separate action. This was simple and is done.

    I want an app so that when I click a button, it enables/disables the other button. I was going to accomplish this using isClickable() and setClickable()

    Now the big problem. Because the method for what the button does is within the method that the buttons are defined in, you cannot access the variables (nor the buttons) within the code that is executed upon a click.

    Now the solution: Make the buttons public. Pretty simple solution... I mean, who wouldn't think to do that?

    Couldn't tell you why, but when I define the buttons as public and a part of the class rather than the onCreate method, it simply crashes without giving a reason why. I do not modify the code in any way, is the problem, I only copy/paste it.

    So, if you would like to see my source so far, feel free to ask, but I don't feel that the actual code is relevant.

    edit: I'm also not usually one to ask for help like this. I got flak from a veteran coder for simply asking him a specific question as if I didn't research the problem myself. All I can find is accessing variables from within one method to the class above it, but not a method inside of a method. Or, as I said, I'm simply told to make the variables public. Neither is a solution to my problem, as stated.
     
    Last edited: May 6, 2010
  2. LtKen
    Offline

    LtKen Silver Member

    Joined:
    Jan 27, 2010
    Messages:
    2,628
    Likes Received:
    1
    Trophy Points:
    103
    Ratings:
    +1
    Post the code, dont worry about the flak. As long as you're not doing a school project, I'd be more than happy to help.
     
  3. Jett
    Offline

    Jett New Member

    Joined:
    Apr 30, 2010
    Messages:
    15
    Likes Received:
    0
    Trophy Points:
    1
    Ratings:
    +0
    Haha, I'm happy I'm out of school. First drink I ever had was with the network administrator at my college.

    Code:
    package com.android.test;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;
    
    public class HelloWorld extends Activity {
        /** Called when the activity is first created. */
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.setContentView(R.layout.main);
            Button bButton1 = (Button) findViewById(R.id.Button01);
            Button bButton2 = (Button) findViewById(R.id.Button02);
            
            bButton1.setOnClickListener(new  OnClickListener() {
                public void onClick(View v) {
                    HelloWorld hello = new HelloWorld();
                    bButton2.setClickable(!bButton2.isClickable());
                    //i've removed all of my previous attemps, and it's obvious that this
                    //code won't do anything since it can't access bButton2
                }
            });
            
            bButton2.setOnClickListener(new  OnClickListener() {
                public void onClick(View v) {
                    Toast.makeText(HelloWorld.this, "...", Toast.LENGTH_SHORT).show();
                }
            });
            
        }
    }
    edit: Accidentally left the created instance of HelloWorld in there. Clearly unused.
     
    Last edited: May 6, 2010
  4. LtKen
    Offline

    LtKen Silver Member

    Joined:
    Jan 27, 2010
    Messages:
    2,628
    Likes Received:
    1
    Trophy Points:
    103
    Ratings:
    +1
    This will build? Because I'm seeing some really screwy things with parenthesis balance. Not sure if this is an Android thing, but any Java compiler I use would puke on this. Like:

    bButton1.setOnClickListener(new OnClickListener() { public void onClick(View v) {

    Should read more like:


    bButton1.setOnClickListener(new OnClickListener() click);

    Where you're naming the new OnClickListener object that you'll use for the rest of the program. You might run into scoping issues, so you may need to define the OnClickListener above this line, and then initialize it as new inside that function.

    Does this help?
     
  5. Jett
    Offline

    Jett New Member

    Joined:
    Apr 30, 2010
    Messages:
    15
    Likes Received:
    0
    Trophy Points:
    1
    Ratings:
    +0
    I followed the tutorial over at Hello World - Your First Android Application | Android Code Monkey to get the base code done, but removed and added bits and pieces. It is a bit screwy, I'll admit, but this guy seems to know what he's talking about.

    The code builds if I remove the line above my comments.

    It actually makes more sense to do what you mentioned. Well, makes it easier for me to code. I hadn't thought to do that. I now have this code and I verified that it compiles and runs correctly. I still cannot access bButton2 within bButton1's listener, however. I commented out that line, either way.

    Code:
    package com.android.test;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;
    
    public class HelloWorld extends Activity {
        /** Called when the activity is first created. */
        public boolean boolClickable = true;
    
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.setContentView(R.layout.main);
            Button bButton1 = (Button) findViewById(R.id.Button01);
            Button bButton2 = (Button) findViewById(R.id.Button02);
            
            OnClickListener lButton1 = new OnClickListener() {
                public void onClick(View v) {
                    //bButton2.setClickable(!bButton2.isClickable());
                    Toast.makeText(HelloWorld.this, "...", Toast.LENGTH_SHORT).show();
                }
            };
            
            bButton1.setOnClickListener(lButton1);
            
            bButton2.setOnClickListener(new  OnClickListener() {
                public void onClick(View v) {
                    Toast.makeText(HelloWorld.this, "...", Toast.LENGTH_SHORT).show();
                }
            });
            
        }
    }
     
  6. LtKen
    Offline

    LtKen Silver Member

    Joined:
    Jan 27, 2010
    Messages:
    2,628
    Likes Received:
    1
    Trophy Points:
    103
    Ratings:
    +1
    It's a scoping problem, follow the comments:

    public class HelloWorld extends Activity {
    /** Called when the activity is first created. */
    public boolean boolClickable = true;

    \\Declare the buttons HERE if you want to use them where the ****** are

    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.main);
    Button bButton1 = (Button) findViewById(R.id.Button01);
    Button bButton2 = (Button) findViewById(R.id.Button02);

    OnClickListener lButton1 = new OnClickListener() {
    public void onClick(View v) {
    //bButton2.setClickable(!bButton2.isClickable());
    Toast.makeText(HelloWorld.this, "...", Toast.LENGTH_SHORT).show();
    }

    //You can access bButton2 Here because it's declared within this method

    };

    bButton1.setOnClickListener(lButton1);


    //You cannot access bButton2 here, because it is no longer in scope, it
    dissapears when you leave the method above.
    //*****
    bButton2.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
    Toast.makeText(HelloWorld.this, "...", Toast.LENGTH_SHORT).show();
    }
    });

    }
    }
     
  7. Jett
    Offline

    Jett New Member

    Joined:
    Apr 30, 2010
    Messages:
    15
    Likes Received:
    0
    Trophy Points:
    1
    Ratings:
    +0
    Indeed. That was my first guess as I was trying to debug this problem on my own.

    Sadly, for no particular reason, my Droid crashes whenever I declare buttons where you posted that. Now I don't feel so dumb for asking for help. I'm truly clueless as to why it crashes or how to get around it. I debugged very carefully and I'm positive that it's crashing because I'm declaring the buttons up there.

    edit: I'm going to try something really quickly. Posted this before I thought of it.
     
  8. LtKen
    Offline

    LtKen Silver Member

    Joined:
    Jan 27, 2010
    Messages:
    2,628
    Likes Received:
    1
    Trophy Points:
    103
    Ratings:
    +1
    Dont declare them as public, declare them as private and make sure they're initialized, otherwise Java will garbage collect and optimize them away.
     
  9. Jett
    Offline

    Jett New Member

    Joined:
    Apr 30, 2010
    Messages:
    15
    Likes Received:
    0
    Trophy Points:
    1
    Ratings:
    +0
    I figured out the problem. I didn't realize until now that while I was declaring the buttons, I was also running code (findViewById()), which you obviously can't do up there. Removed that and moved it into the method, declared the button up there, and voila.

    But, basically what you're saying is that I should be able to access in those methods anyways, and that my code will run faster (not that that's too imperative) if I declare it as private rather than public?
     
  10. LtKen
    Offline

    LtKen Silver Member

    Joined:
    Jan 27, 2010
    Messages:
    2,628
    Likes Received:
    1
    Trophy Points:
    103
    Ratings:
    +1
    Public versus private is a security thing and good programming practice, it has nothing to do with speed. Dont worry about it for now.

    Also, I'll throw in a simple scoping lesson. Please forgive me if you already know this, I certainly dont mean to insult your intelligence.


    Main{
    variable A:

    Method 1{

    variable B;
    \\variables A and B are accessible here

    }

    Method 2{

    variable C;
    \\variables A and C are accessible here

    }

    \\Only variable A is accessible here

    }

    Have fun.
     
  11. Jett
    Offline

    Jett New Member

    Joined:
    Apr 30, 2010
    Messages:
    15
    Likes Received:
    0
    Trophy Points:
    1
    Ratings:
    +0
    I understood it from the beginning (though, I'll admit, Visual Basic 6 was my first language. I began learning it around age 12 and actually established a bit of a name for myself on the AIM scene in the years following.) but my main problem was that the app on the Droid would simply crash. It would compile just fine and attempt to run before saying "the app has encountered a problem" and my only response was "...you're not going to tell me what the problem is, are you?"
     
  12. LtKen
    Offline

    LtKen Silver Member

    Joined:
    Jan 27, 2010
    Messages:
    2,628
    Likes Received:
    1
    Trophy Points:
    103
    Ratings:
    +1
    That's so frustrating.... glad you got it worked out.
     
Search tags for this page

android setclickable not working

,
android setonclicklistener scope
,
find view by id crashing
,
visual basic for android