2013-04-24 13 views
10

Ich habe etwas seltsames Verhalten in der kontextabhängigen Aktionsleiste.Contextual Action Bar seltsames Verhalten für den Menüpunkt

Erstens:

Clicking behavior overflow button of CAB

Zweitens/drittens:

Gibt es eine Möglichkeit, dass die Symbole

Ein Menüpunkt wird nur jedes zweite Mal, dass ich auf der Überlauf-Taste klicken gezeigt nutze nicht so viel Platz?

Wenn ich hinzufügen Eigenschaft ändern android:showAsAction="always" auf alle Elemente gibt tatsächlich genügend Platz ist, alle Symbole zeigen - aber meinen Anteil Symbol ist anklickbar nicht mehr:

All Items with showAsAction always

reinigen Projekt nicht Hilfe.

Ich verwende Android 4.2.2 auf meinem Testgerät (Galaxy S3).

Ich versuchte sogar völlig neues ROM auf meinem XXX GS3 zu blinken (CyanogenMod 10.1 jetzt, bevor SlimBean, auch die navigationbar bei am Boden entfernt) - half nicht.

Ich habe es auch auf einer Nexus 4 versucht. Da mehr Platz vorhanden ist, sind die Schaltfläche "Teilen" und die Schaltfläche "Löschen" sichtbar. Die Share-Taste ist nicht anklickbar, wenn ich den Action-Modus starte, aber wenn ich das Gerät in den Querformat-Modus drehe, funktioniert es, und wenn ich es ins Hochformat zurückstelle, funktioniert es immer noch. So grundlegend auf dem Nexus 4, funktioniert der Share-Button nicht vor dem Drehen.


Manifest:

<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" /> 

Kompilieren gegen minSdkVersion=17 macht keinen Unterschied.

ich das Action-Modus aus einem Fragment wie folgt beginnen:

mActionMode = activity.startActionMode(mMultipleCallback); 

Im ActionMode.Callback besiedeln ich das Menü:

@Override 
public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
    MenuInflater inflater = mode.getMenuInflater(); 
    inflater.inflate(R.menu.management_cab, menu); 
    MenuItem item = menu.findItem(R.id.managementCABShare); 
    mShareActionProvider = (ShareActionProvider) item.getActionProvider(); 
    //...other stuff 
    return true; 
} 

Und hier ist der XML:

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android" > 
    <item 
     android:title="@string/checkAll" 
     android:id="@+id/managementCABCheckAll" 
     android:icon="@android:drawable/checkbox_on_background"> 
    </item> 
    <item 
     android:title="@string/enable" 
     android:id="@+id/managementCABEnable" 
     android:icon="@drawable/sphere_green"> 
    </item> 
    <item 
     android:title="@string/disable" 
     android:id="@+id/managementCABDisable" 
     android:icon="@drawable/sphere_red"> 
    </item> 
    <item 
     android:title="@string/delete" 
     android:id="@+id/managementCABDelete" 
     android:icon="@android:drawable/ic_menu_close_clear_cancel"> 
    </item> 
    <item 
     android:title="@string/share" 
     android:id="@+id/managementCABShare" 
     android:actionProviderClass="android.widget.ShareActionProvider" 
     android:icon="@android:drawable/ic_menu_share"> 
    </item> 
    <item 
     android:title="@string/export" 
     android:id="@+id/managementCABExport" 
     android:icon="@drawable/explorer"> 
    </item> 
</menu> 

Der Vollständigkeit halber ist das ganze callback:

protected ActionMode.Callback mMultipleCallback = new ActionMode.Callback() { 

    private ShareActionProvider mShareActionProvider; 

    @Override 
    public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
     MenuInflater inflater = mode.getMenuInflater(); 
     inflater.inflate(R.menu.management_cab, menu); 
     MenuItem item = menu.findItem(R.id.managementCABShare); 
     mShareActionProvider = (ShareActionProvider) item.getActionProvider(); 
     hideUnwantedCABItems(menu); 
     return true; 
    } 

    @Override 
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 
     List<Integer> checkedPositions = getAllCheckedPositions(); 
     switch (item.getItemId()) { 
     case R.id.managementCABCheckAll: 
      changeCheckedOfAllItems(true); 
      return true; 
     case R.id.managementCABEnable: 
      changeEnabled(checkedPositions, true); 
      return true; 
     case R.id.managementCABDisable: 
      changeEnabled(checkedPositions, false); 
      return true; 
     case R.id.managementCABDelete: 
      if (deleteAlert == null) 
       createDeleteDialog(checkedPositions); 
      initDeleteDialog(checkedPositions); 
      return true; 
     case R.id.managementCABShare: 
      Intent shareIntent = new Intent(); 
      shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE); 
      shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, exportItemsAndGetUris(checkedPositions)); 
      shareIntent.setType("application/xml"); 
      setShareIntent(shareIntent); 
      return true; 
     case R.id.managementCABExport: 
      String message; 
      if (StorageController.copyUriListToExportFolder(exportItemsAndGetUris(checkedPositions))) 
       message = getActivity().getString(R.string.export_success); 
      else 
       message = getActivity().getString(R.string.export_fail); 

      Toast.makeText(getActivity(), message + ":\n" + StorageController.getExternalExportApplicationFolder(), Toast.LENGTH_LONG).show(); 
      return true; 
     default: 
      return false; 
     } 
    } 

    @Override 
    public void onDestroyActionMode(ActionMode mode) { 
     mActionMode = null; 
     changeCheckedOfAllItems(false); 
    } 

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

    private void setShareIntent(Intent shareIntent) { 
     if (mShareActionProvider != null) { 
      mShareActionProvider.setShareIntent(shareIntent); 
     } 
    } 
}; 
+0

Sie verwenden v14 auf Ihrem Gerät oder kompilieren Sie gegen v14 SDK? –

+0

wtf warum die down vote? Wie auch immer, ich benutze 4.2.2 auf meinem Gerät - überprüfen Sie die Bearbeitung zur Klarstellung –

+0

Das war nicht ich, wenn Sie gegen v14 kompilieren, würde ich versuchen, zuerst gegen das neueste SDK zu kompilieren. –

Antwort

9

Okay, die Lösung für das nicht klickbare Share-Symbol. Dies war ein Missverständnis von mir zur API.

Ich dachte, Sie könnten ein SharedActionProvider-Item wie jedes andere Element in Ihrer XML-Menüdatei behandeln. Aber eigentlich kannst du nicht. onActionItemClicked wird nicht einmal für dieses Symbol ausgelöst, wenn es als Aktion angezeigt wird (daher ist es nicht anklickbar, wenn Sie showAsAction=always hinzufügen).Lustigerweise wird das Klickereignis ausgelöst, wenn das Symbol nicht angezeigt wird, aber im Überlaufmenü sichtbar ist. Dies kann ein tatsächlicher Fehler in der kontextabhängigen Aktionsleiste sein!

Nun endlich habe ich herausgefunden, wie man sollte ein auslösen SharedActionProvider-Item:

Sie haben setzen, um eine Intent im onCreateActionMode Verfahren (!):

public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
    MenuInflater inflater = mode.getMenuInflater(); 
    inflater.inflate(R.menu.management_cab, menu); 
    MenuItem item = menu.findItem(R.id.managementCABShare); 
    initSharedActionProvider(item); //Check out this method in the next code fragment 
    return false; 
} 

Jetzt können Sie sagen: „Du Idiot , das war offensichtlich, und es ist noch besser, die Absicht immer dort statt wie in der onActionItemClicked Methode wie zuvor zu setzen.

Sorry, aber ich stimme nicht zu: Es macht keinen Sinn, es hier zu setzen. Der Grund ist: Für mich ändert sich die Absicht mit jedem weiteren Gegenstand, den du kontrollierst. Es erstellt eine Export-XML-Datei für jedes von Ihnen geprüfte Element, und ich möchte wirklich nicht jedes Mal, wenn auf ein Symbol geklickt wird, eine XML-Datei erstellen. Dies macht keinen Sinn, und ich möchte, dass alle XML-Dateien nur erstellt werden, wenn ein Benutzer wirklich die Elemente exportieren möchte.

Also im Grunde habe ich einen Workaround dafür gemacht. Zu Beginn mache ich einen Intent und füge einen leeren List<Uri> hinzu. Diese Liste wird als Elementvariable in meiner Klasse gespeichert. Wenn ich also Elemente hinzufüge, werden die Elemente ebenfalls in der Absicht angezeigt. Wenn der Benutzer dann auf das Freigabeelement klickt, wird die Liste mit allen ausgewählten Elementen gefüllt. Um dies zu erreichen, überging ich die OnShareTargetSelectedListener. Diese Methode wird ausgelöst, wenn ein Benutzer auf ein konkretes Freigabeziel (wie E-Mail, Dropbox usw.) klickt.

Jetzt ist hier der gesamte Code für das (die Methode nur einmal von onCreateActionMode genannt wird):

private void initSharedActionProvider(MenuItem item) { 
    mShareActionProvider = (ShareActionProvider) item.getActionProvider(); 
    mShareActionProvider.setOnShareTargetSelectedListener(new OnShareTargetSelectedListener() { 
     @Override 
     public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) { 

      //Here is the exportedFiles list populated 
      exportItemsAndSetList(getAllCheckedPositions()); 
      return true; 
     } 
    }); 

    Intent shareIntent = new Intent(); 
    shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE); 

    //exportedFiles is a member Variable which I populate with the selected items, with the exportItemsAndSetList method 
    shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, exportedFiles); 
    shareIntent.setType("application/xml"); 
    mShareActionProvider.setShareIntent(shareIntent); 
} 

Ich hoffe, Sie verstehen, was ich da tat. Wenn nicht, zögern Sie nicht zu fragen.

Mit all dem oben genannten ist eines meiner Probleme gelöst (das Share-Icon ist nicht anklickbar, wenn es als Icon angezeigt wird) - aber die anderen beiden bleiben offen (Icons sollten nicht so viel Platz und das erste Problem verwenden) .


Problem 2 Art gelöst:

Scheint, wie Android auf die Symbole, die in den höheren Auflösung Ordner (hdpi, xhdpi) sind wirklich braucht, in einer höheren Auflösung zu sein - mein aktivieren/deaktivieren Symbol hatte nur eine Größe von 32x32 Pixel (und ich habe sie einfach in alle Ordner gelegt) und deshalb hat Android irgendwie ein großes Durcheinander gemacht, so dass nur drei Icons auf die Aktionsleiste passten. Ich habe nur alle Icons entfernt, aber die ursprünglichen 32x32 Pixel in mdpi. Jetzt skaliert Android die 32x32-Pixel-Symbole und kann fünf Elemente in der Aktionsleiste anzeigen. Es ist irgendwie komisch.


Problem 1 Art gelöst:

wie folgt aussieht wurde direkt sobald ich gelöstes Problem 2, das Löschsymbol platziert wurde direkt auf der Aktionsleiste zu Problem 2, bezogen.

Auch mit einigen Tests habe ich gesehen, dass der Text immer da war, wenn ich showAsAction=never zum Löschen-Symbol hinzugefügt habe. Ich denke wirklich, dass es etwas mit Problem 2 zu tun hat (die Icons haben wirklich schlechte Sachen gemacht).


Meine Probleme sind fast gelöst.

Ich glaube, ich habe einen (neuen) echten Fehler jetzt: die zuletzt verwendete Freigabe Aktion schwebt über das Überlaufsymbol. Wenn klicken, öffnet sich das Überlaufmenü noch, aber es sieht ziemlich beschissen:

Most recent share icon above overflow icon

Wie habe ich dieses Problem beheben?

Nun, ich bin fertig damit herumspielen mit diesem ****, also habe ich nur das showAsAction=never zum share icon hinzugefügt. (Und ja ich sah this, aber ich erhalte eine Ausnahme, wenn ich das tue, auch es ist eine andere Veränderung des normalen Lebenszyklus ...)

Fühlen Sie sich frei zu äußern, wenn Sie eine bessere Lösung wissen als früher:>