2014-03-28 8 views

Antwort

1

sollte es möglich sein, dass die Verwendung Stile zu tun:

ActionBarSherlock:

<style name="MyTheme" parent="Theme.Sherlock.Light"> 
    <item name="actionOverflowButtonStyle">@style/MyTheme.OverFlow</item> 
</style> 

<style name="MyTheme.OverFlow" parent="Widget.Sherlock.ActionButton.Overflow"> 
    <item name="android:src">@drawable/YOUR_ICON_GOES_HERE</item> 
</style> 

ActioBar:

<style name="MyTheme" parent="@android:style/Theme.Holo"> 
    <item name="android:actionOverflowButtonStyle">@style/MyTheme.OverFlow</item> 
</style> 

<style name="MyTheme.OverFlow" parent="@android:style/Widget.Holo.ActionButton.Overflow"> 
    <item name="android:src">@drawable/YOUR_ICON_GOES_HERE</item> 
</style> 

Stellen Sie sicher, MyTheme im Manifest zu setzen.

+1

Ja, ich habe das für die ActionBar getan, aber ich brauche Holo.Dunkles Symbol für die ActionBar und das Holo.Light-Symbol für den ActionMode. – TeKo

3

ImageButton ist das Widget, mit dem der Menüüberlauf angezeigt wird. actionOverflowButtonStyle wird für das Styling der ImageButton verwendet. Dieses Styling wird in ActionMenuPresenter angewendet.

private class OverflowMenuButton extends ImageButton implements ActionMenuChildView { 
    public OverflowMenuButton(Context context) { 
     super(context, null, com.android.internal.R.attr.actionOverflowButtonStyle); 
     ... 
    } 
} 

ActionMenuPresenter Klasse wird für den Aufbau von Aktionsmenüs sowohl in action bar und action modes verwendet. Durch das Überschreiben des Themas werden die Dateien in beiden Modi gleich angewendet. Der einzige Weg, um dies zu erreichen, ist es programmatisch, wie es here für die action bar getan wird.

Hier ist der Code, wie es für action mode Überlauf-Symbol getan werden kann. Sie können die drawable der ImageButton in ActionMode.Callback.onPrepareActionMode Methode zuweisen.

public class MainActivity extends Activity { 
    ViewGroup mDecorView; 

    public void onCreate(Bundle savedInstanceState) { 
     // Assign mDecorView to later use in action mode callback 
     mDecorView = (ViewGroup) getWindow().getDecorView(); 
    } 

    private ActionMode.Callback mCallback = new ActionMode.Callback() 
    { 
     @Override 
     public boolean onPrepareActionMode(ActionMode mode, Menu menu) 
     { 
      // We have to update the icon after it is displayed, 
      // hence this postDelayed variant. 
      // This is what I don't like, but it is the only way to move forward. 

      mDecorView.postDelayed(new Runnable() { 

       @Override 
       public void run() { 
        ArrayList<View> outViews = new ArrayList<View>(); 
        // The content description of overflow button is "More options". 
        // If you want, you can override the style and assign custom content 
        // description and use it here. 
        mDecorView.findViewsWithText(outViews, "More Options", View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION); 
        if(!outViews.isEmpty()) { 
         View v = outViews.get(0); 
         if(v instanceof ImageButton) { 
          ImageButton btn = (ImageButton) v; 
          // Update the image here. 
          btn.setImageResource(R.drawable.custom); 
         }      
        } 
       }    
      }, 500); 

      return true; 
     } 

    } 
} 
+0

Danke! Ich habe diese Art der Implementierung bereits gesehen, dachte aber, dass es eine Möglichkeit geben muss, dies in XML zu tun. Aber deine Erklärung ist sehr gut und ich denke jetzt, dass die Art, wie du vorschlägst, der einzige Weg ist, dies zu tun ... Viel Spaß mit dem Kopfgeld (in 14 Stunden ...) – Frame91

+0

@ Frame91 Nur ein Vorschlag..make complete use of dein Kopfgeldangebot. Sie können diese Antwort in einem nicht akzeptierten Zustand halten, so dass andere versuchen werden, (möglicherweise) eine bessere Lösung dafür bereitzustellen. Wenn sich das Kopfgeld der Ablaufzeit nähert, können Sie das Kopfgeld manuell zuweisen. –

+0

Ja, du hast recht - aber wie du erklärst, wird niemand eine einfache xml-Lösung einreichen;) – Frame91

6

Ich muß noch herausfinden, wie nur den Überlauf-Icon ändern innerhalb der ActionMode-ActionBar als ich meinen Überlaufes-Icon in der Standard-ActionBar geändert, die nicht sichtbar in der ActionMode-ActionBar ist (und nein, ich möchte den Hintergrund meiner ActionMode-Aktionsleiste nicht ändern!)

Okay.

Beginnen wir mit der Definition einiger Stile. Ich werde versuchen und erklären, warum wir sie auf diese Weise definieren:

// This is just your base theme. It will probably include a lot more stuff. 
// We are going to define the style 'OverflowActionBar' next. 

<style name="BaseTheme" parent="android:Theme.Holo.Light"> 
    .... 
    .... 
    .... 
    <item name="android:actionOverflowButtonStyle">@style/OverflowActionBar</item> 
</style> 

// Assigning a parent to this style is important - we will inherit two attributes - 
// the background (state-selector) and the content description 

<style name="OverflowActionBar" parent="@android:style/Widget.Holo.ActionButton.Overflow"> 
    <item name="android:src">@drawable/overflow_menu_light</item> 
</style> 

// Next up is an extension to our 'BaseTheme'. Notice the parent here. 

<style name="ChangeOverflowToDark" parent="@style/BaseTheme"> 
    <item name="android:actionOverflowButtonStyle">@style/OverflowActionMode</item> 
</style> 

// One last thing is to define 'OverflowActionMode'. Again, we inherit useful 
// attributes by assigning 'Widget.Holo.ActionButton.Overflow' as the parent. 

<style name="OverflowActionMode" parent="@android:style/Widget.Holo.ActionButton.Overflow"> 
    <item name="android:src">@drawable/overflow_menu_dark</item> 
</style> 

Alle unsere Arbeit mit styles.xml erfolgt. Das allerletzte Bit passiert zur Laufzeit. Ich nehme an, Sie haben bereits eine Implementierung von ActionMode.Callback.

In Ihrer Tätigkeit definieren, eine Methode - changeOverflowIcon():

public void changeOverflowIcon() { 
    getTheme().applyStyle(R.style.ChangeOverflowToDark, true); 
} 

Sie diese Methode von onCreateActionMode(...) Ihrer ActionMode.Callback Implementierung anrufen:

public class CustomActionModeCallback implements ActionMode.Callback { 

    @Override 
    public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
     changeOverflowIcon() 

     // other initialization 

     return true; 
    } 

    @Override 
    public boolean onPrepareActionMode(final ActionMode mode, Menu menu) { 
     return true; 
    } 

    @Override 
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 
     return false; 
    } 

    @Override 
    public void onDestroyActionMode(ActionMode mode) {} 
} 

Ein bisschen Erklärung:

Die Zuordnung in 'BaseTheme' ist für die ActionBar. Es wird das Zeichen overflow_menu_light auswählen, da wir es im Basisthema Ihrer App zuweisen.

getTheme().applyStyle(R.style.ChangeOverflowToDark, true) 

Das zweite Argument true zwingt das aktuelle Thema die alten Attribute mit den neuen zu überschreiben. Da wir nur ein Attribut in ChangeOverflowToDark definieren, wird dessen Wert überschrieben. Die ActionBar ist nicht betroffen, da das alte Attribut bereits verwendet wurde. Aber der Aktionsmodus muss noch erstellt werden (er wird erstellt, wenn wir true von onCreateActionMode(...) zurückgeben). Wenn der Aktionsmodus nach diesem Attributwert sucht, erhält er den neuen Wert.

Es gibt mehr ...

Die Antwort von Manish gegeben ist ziemlich genial. Ich hätte nie gedacht, die Inhaltsbeschreibung zu verwenden, um die genaue ImageButton zu finden. Aber was, wenn Sie die ImageButton mit einem einfachen findViewById() finden könnten?

Hier ist, wie Sie können:

Zunächst werden wir eindeutige IDs müssen. Wenn Ihr Projekt derzeit keine res/values/ids.xml Datei hat, erstellen Sie eine. Fügen Sie eine neue ID hinzu:

<item type="id" name="my_custom_id" /> 

Das Setup, das ich oben besprochen habe, wird gleich bleiben. Der einzige Unterschied wird in OverflowActionMode Stil sein:

<style name="OverflowActionMode" parent="@android:style/Widget.Holo.ActionButton.Overflow"> 
    <item name="android:src">@drawable/overflow_menu_dark</item> 
    <item name="android:id">@id/my_custom_id</item> 
</style> 

Die id wir oben definiert wird dem ImageButton zugewiesen werden, wenn wir getTheme().applyStyle(R.style.ChangeOverflowToDark, true);

nennen Ich werde den Code-Schnipsel aus Manish Antwort borgen hier:

private ActionMode.Callback mCallback = new ActionMode.Callback() 
{ 
    @Override 
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) 
    { 

     mDecorView.postDelayed(new Runnable() { 

      @Override 
      public void run() { 
       ImageButton btn = (ImageButton) mDecorView.findViewById(R.id.my_custom_id); 
       // Update the image here. 
       btn.setImageResource(R.drawable.custom); 
      }   
     }, 500); // 500 ms is quite generous // I would say that 50 will work just fine 

     return true; 
    } 
} 

Das Beste aus beiden Welten?

Lassen Sie uns sagen, dass wir R.drawable.overflow_menu_light für ActionBar und R.drawable.overflow_menu_dark für ActionMode benötigen.

Styles:

<style name="BaseTheme" parent="android:Theme.Holo.Light"> 
    .... 
    .... 
    .... 
    <item name="android:actionOverflowButtonStyle">@style/OverflowActionMode</item> 
</style> 

<style name="OverflowActionMode" parent="@android:style/Widget.Holo.ActionButton.Overflow"> 
    <item name="android:src">@drawable/overflow_menu_dark</item> 
    <item name="android:id">@id/my_custom_id</item> 
</style> 

Wie in unserem Stil definiert, wird die ActionBarR.drawable.overflow_menu_dark holen - aber wir brauchen nicht die Licht Version für die ActionBar? Ja - wir werden das onPrepareOptionsMenu(Menu) Rückruf der in der Aktivität zuordnen:

@Override 
public boolean onPrepareOptionsMenu(Menu menu) { 

    new Handler().postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      ImageButton ib = (ImageButton) 
           getWindow().getDecorView() 
           .findViewById(R.id.my_custom_id); 
      if (ib != null) 
       ib.setImageResource(R.drawable.overflow_menu_light); 
     } 
    }, 50L); 
    return super.onPrepareOptionsMenu(menu); 
} 

Wir können das hier tun, weil vor onPrepareOptionsMenu(Menu) würde die ImageButton nicht erstellt worden sind.

Nun wir nicht Notwendigkeit, mit ActionMode beschäftigen tun - weil es die dark ziehbar aus dem Thema wählen.

Ich entschuldige mich für diesen gigantischen Beitrag. I wirklich hoffe, es hilft.

+2

Das ist nur eine erstaunliche Erklärung! Dein erstes Tutorial hat ganz gut geklappt! Meiner Meinung nach ist das viel schöner, als mit Handlern und Runnables zu arbeiten ... Danke dafür! :)) – Frame91

+1

Versuchte die erste Lösung mit Stilen, funktioniert für mich vor Android 5.0, funktioniert aber nicht mit Android Lollipop 5.0. Irgendwelche Updates dazu? –