سؤال

States of actionBar


pressed state::

enter image description here

Default state::

enter image description here


What i am doing ::

  • I am using the splitted actionbar
  • On click of icon in bottom, I am changing the fragment
  • Functionality is working fine

What i want::

  • Is it possible to keep the pressed state of the actionbar item until i click the next actionbar icon
  • Then when i say click the star in figure, i want to keep the star in pressed state as blue color and search icon to return to normal state

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 ?
هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

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

@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>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top