Devrath
Devrath

Reputation: 42854

Keeping the pressed state of ActionBar Icons in android

States of actionBar


pressed state::

enter image description here

Default state::

enter image description here


What i am doing ::


What i want::


Code that i use::

@Override
    public boolean onOptionsItemSelected(MenuItem item) {

         if(item.getItemId()==R.id.searchID){
            //SEARCH Button Handling
            //((View) item).setBackgroundResource(R.color.actionBarIconPressed);
            //item.setIcon(R.color.actionBarIconPressed);
            item.setEnabled(true);
            ft1=getSupportFragmentManager().beginTransaction();
            ft1.hide(fragment1);
            //Condition to check whether the fragment is already in container & based on that do appropriate actions
            if (getSupportFragmentManager().findFragmentByTag("SearchFragmentTag")==null){             
                ft1.add(R.id.content_frame, fragSearch, "SearchFragmentTag");
                ft1.addToBackStack(null);
                ft1.commit();
            }else{
                ft1.remove(fragSearch);
                ft1.add(R.id.content_frame, fragSearch, "SearchFragmentTag");
                ft1.commit();
            }
            return true;
        }
        return super.onOptionsItemSelected(item);
    }    



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getSupportMenuInflater();
        menuInflater.inflate(R.menu.actionbar_sort_menu, menu);

        return super.onCreateOptionsMenu(menu);
    }

My Questions::

  1. How to modify my code to achieve this feature ?
  2. Is it possible ?
  3. What are the possible ways ?

Upvotes: 2

Views: 781

Answers (3)

Blo
Blo

Reputation: 11988

In onOptionsItemSelected, you can cast the MenuItem into a View and then, change its background. I got a start answer however I think you can improve it and change it according to your needs:

Init your ids in an array:

int[] listItemId = { R.id.searchID, R.id.ratindID, R.id.likeID, R.id.shareID };

Call your options item selected method:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()) {
         case R.id.searchID:
             // call private method with int 1
             onItemChangeBackground(1);
             ... // do some stuff
             return true;
         case R.id.ratindID:
             onItemChangeBackground(2);
             ... // do some stuff
             return true;
         case R.id.likeID:
             onItemChangeBackground(3);
             ...
             return true;
         case R.id.shareID:
             onItemChangeBackground(4);
             ...
             return true;
    }
    return super.onOptionsItemSelected(item);
}

Change the background item by switching an int value:

private void onItemChangeBackground(int i) {
    // Loop to reinit the background items
    for(int ii = 0; ii < listItemId.length; ii++) { 
        // Cast the MenuItem into a View
        ( (View) findViewById(listItemId[ii]) )
                 // And set the default background (for example dark)
                 .setBackgroundColor(getResources().getColor(R.color.dark));
    }
    // Selected background
    switch(i) {
        case 1: ( (View) findViewById(R.id.searchID) )
                 .setBackgroundColor(getResources().getColor(R.color.blue));
            break;
        case 2: ( (View) findViewById(R.id.ratindID) )
                 .setBackgroundColor(getResources().getColor(R.color.blue));
            break;
        case 3: ( (View) findViewById(R.id.likeID) )
                 .setBackgroundColor(getResources().getColor(R.color.blue));
            break;
        case 4: ( (View) findViewById(R.id.shareID) )
                 .setBackgroundColor(getResources().getColor(R.color.blue));
            break;
    }
}  

You can also set a drawable with a selector by using setBackgroundDrawable() when you want to reinitialize the background items (as you do in the styles.xml). Tested, it works!

Another solution might be to use invalidateOptionsMenu(). This will clear and redraw the menu by recalling onCreateOptionsMenu() again. Keep in mind without call invalidateOptionsMenu() the last method will never be recalled, it's only called at the first rime of the activity's creation. That's why we need to invalidate its content:

Update an integer for each item selected:

@Override
public boolean onOptionsItemSelected(MenuItem item) {  
    if(item.getItemId()==R.id.searchID){
        nbItemSelected = 1;
        invalidateOptionsMenu();
        ...
    } else if(...) {
        nbItemSelected = 2;
        invalidateOptionsMenu();
    } ...
} 

Then, change the background while you create the options:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_layout, menu);
    if(nItemSelected != 0) {
         // Find item, cast the selected item to a view
         ( (View) menu.findItem(listItemId[nItemSelected]) )
              // Change its background
              .setBackgroundColor(getResources().getColor(R.color.blue));
    } 
    ...
    return true;
}

I guess it is possible in this way too, it might work.

Upvotes: 2

100rabh
100rabh

Reputation: 6186

@Casper did you tried setting custom selector for your ActionBar?
Refer one below

drawable/tab_bg_selector.xml
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- Active tab -->
        <item android:drawable="@drawable/tab_selected_customtabs" android:state_focused="false" android:state_pressed="false" android:state_selected="true"/>
        <!-- Inactive tab -->
        <item android:drawable="@drawable/ab_transparent_customtabs" android:state_focused="false" android:state_pressed="false" android:state_selected="false"/>
        <!-- Pressed tab -->
        <item android:drawable="@drawable/tab_selected_pressed_customtabs" android:state_pressed="true"/>
        <!-- Selected tab -->
        <item android:drawable="@drawable/tab_selected_focused_customtabs" android:state_focused="true" android:state_pressed="false" android:state_selected="true"/>
    </selector>

Upvotes: 0

Aldo Borrero
Aldo Borrero

Reputation: 547

Are you creating a TabBarView like for example those you can find in iOs?

If so, an split actionbar is not the best component, it is better to use a ViewPagerIndicator with a ViewPager component. In there you can create your custom icons with your custom icons states and backgrounds.

I have an spare snippet of code I created long time ago for an application that required that component. Maybe you can look it around and take what you need (but I advice you that the code is not the best you can find as I was in a hurry, things can be done better, much better):

https://gist.github.com/aldoborrero/70fbeb062fab0ccc7d87

Upvotes: 0

Related Questions