简体   繁体   中英

Android Development - Create a menu with 3 imageButtons

First of all english is not my first language but i will try my best.

Also... i am pretty sure my title choice was not the best so sorry for that.

Basically what i wanted to do is a menu with three ImageButtons but there is a tricky part (tricky for me at least) since every time i press one button that same button changes image (to a colored version instead of a grayed out image) and the other two change as well from colored version of their respective images to grayed out ones, actually only one of the other two will change since the purpose of this is to be able to activate only one at a time so it would not be possible to have the other two active at the same time.

Notice that this is not a menu on the top right corner but just a set of three ImageButtons on a activity or Fragment.

I already tried a lot of stuff to make that happen but so far no luck but i think i know why though i can't find a workaround for this since i am actually new in android dev.

what i tried was inside the setOnClickListener of any of those buttons such as:

eventsButton.setOnClickListener(
   new View.OnClickListener() {
      public void onClick(View view) {
         ImageButton eventsButton = (ImageButton) view.findViewById(R.id.eventsButton);
         eventsButton.setBackgroundResource(R.drawable.events_icon_active);
         eventsButton.setClickable(false);
      }
   }
);

i tried to add the functions to change the other imageButtons as well like:

eventsButton.setOnClickListener(
   new View.OnClickListener() {
      public void onClick(View view) {
         ImageButton eventsButton = (ImageButton) view.findViewById(R.id.eventsButton);
         eventsButton.setBackgroundResource(R.drawable.events_icon_inactive);
         eventsButton.setClickable(false);

         ImageButton contactsButton = (ImageButton) view.findViewById(R.id.contactsButton);
         contactsButton.setBackgroundResource(R.drawable.contacts_icon_inactive);
         contactsButton.setClickable(true);

         ImageButton interestsButton = (ImageButton) view.findViewById(R.id.interestsButton);
         interestsButton.setBackgroundResource(R.drawable.interests_icon_inactive);
         interestsButton.setClickable(true);
      }
   }
);

and i repeated that three time, always setting the other buttons clickable and setting their images to the inactive one (the grayed out one), also setting the button i click as no longer clickable.

But from what i gather i cant do any references to any other buttons inside the eventsButton.setOnClickListener like the buttons interestsButton or contactsButton, it will crash the app as soon as i touch any of those three buttons with the following error message:

Attempt to invoke virtual method 'void android.widget.ImageButton.setBackgroundResource(int)' on a null object reference

And it always point to the first line where i make a reference to another button other then the one used to start the setOnClickListener.

If you can just point me in the right direction i would be tremendously grateful.

All the best

eventsButton.setOnClickListener(
   new View.OnClickListener() {
      public void onClick(View view) {

         ImageButton contactsButton = (ImageButton) view.findViewById(R.id.contactsButton);
         contactsButton.setBackgroundResource(R.drawable.contacts_icon_inactive);
         contactsButton.setClickable(true);
      }
   }
);

Your problem is in view.findViewById(R.id.contactsButton) : view here is the button being clicked (the events one), and by calling view.findViewById(contactsButton) you are implicitly saying that the contact button is a child of view , which is not.

Just use findViewById() (from Activity), getActivity().findViewById() (from Fragments), or better container.findViewById() (if you have a reference to the layout containing the three buttons).

I'm not saying that yours is the most efficient way to deal with a menu, just pointing out your error.

You can declare your ImageViews as final outside the scope of the listener and when the onClickListener(View v) is called you can then just call setBackground because they are final and you can reference them from inside the listener.

Something like this:

final ImageView view1 = (ImageView) findViewById(R.id.view1id);
final ImageView view2 = (ImageView) findViewById(R.id.view2id);

view1.setOnClickListener(
   new View.OnClickListener() {
      public void onClick(View view) {
          // do whatever you want to the ImageViews
          // view1.setBackground...
      }
   }
);

You can first make things simple; I suggest:

  • you add 3 array ( Arraylist might be better) fields in your activity class, one for the buttons, one for the active resources and one for the inactive resources
  • initialize those arrays in the onCreate method;
  • define a single onClickListener object and use it for all the buttons; Use a loop in the onClick method, see bellow.

In terms of code, it looks like this:

ImageButton[] buttons;
int[] activeResources;
int[] inactiveResources;

protected void onCreate2(Bundle savedInstanceState) {

    View.OnClickListener onClickListener = new View.OnClickListener(){
        public void onClick(View view) {
            ImageButton clickedButton = (ImageButton) view;
            for(int i = 0; i<buttons.length; i++){
                ImageButton bt = buttons[i];
                if(clickedButton==bt){
                    bt.setBackgroundResource(inactiveResources[i]);
                    bt.setClickable(false);
                }else{
                    bt.setBackgroundResource(activeResources[i]);
                    bt.setClickable(true);
                }
            }
        }
    };

    buttons = new ImageButton[3];
    activeResources = new int[3];
    inactiveResources = new int[3];

    int idx = 0;
    buttons[idx] = (ImageButton) findViewById(R.id.eventsButton);
    inactiveResources[idx] = R.drawable.events_icon_inactive;
    activeResources[idx] = R.drawable.events_icon_active;

    idx = 1;
    buttons[idx] = (ImageButton) findViewById(R.id.contactsButton);
    inactiveResources[idx] = R.drawable.contacts_icon_inactive;
    activeResources[idx] = R.drawable.contacts_icon_active;

    idx = 3;
    buttons[idx] = (ImageButton) findViewById(R.id.interestsButton);
    inactiveResources[idx] = R.drawable.interests_icon_inactive;
    activeResources[idx] = R.drawable.interests_icon_active;

    for(int i =0; i<buttons.length; i++){
        buttons[i].setBackgroundResource(activeResources[i]);
        buttons[i].setOnClickListener(onClickListener);
    }
}

Do not expect it to run right the way, I am giving only ideas, you have to look and see if it fit for you are looking for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM