cevap

41

İşte yaptığım şey.

Düzenleme: Önceki cevabı kullanışsız koda (woops) ve daha az çaba ve daha temiz bir kod ile elde edilebilir CAB şey bir sürü buldum, bu yüzden biraz zaman aldı bu yana geçen ve güncellenmiş bir yıl boyunca o

LibraryFragment ListView liste öğesi otomatik list.setItemChecked vurgulanan yarı şeffaf bindirmeyi çizmek üzere bir? özn/activatedBackgroundIndicator ön plan olmalıdır

<ListView 
    android:id="@android:id/list" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:choiceMode="none"/> 

seçim modu "none" ile tanımlanmalıdır

(poz ,

list_item_library.xml) gerçek

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:foreground="?attr/activatedBackgroundIndicator" 
    android:paddingBottom="5dp" 
    android:paddingTop="5dp" > 

.... 

ListFragment

import android.support.v4.app.DialogFragment; 
import com.actionbarsherlock.app.SherlockListFragment; 
import com.actionbarsherlock.view.ActionMode; 
import com.actionbarsherlock.view.Menu; 

public final class LibraryFragment 
     extends SherlockListFragment 
{ 

    private MyListAdapter adapter; 
    private ListView list; 

    // if ActoinMode is null - assume we are in normal mode 
    private ActionMode actionMode; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) 
    { 
     View v = inflater.inflate(R.layout.fragment_library, null); 
     this.list = (ListView) v.findViewById(android.R.id.list); 
     this.initListView(); 
     return v; 
    } 

    @Override 
    public void onPause() 
    { 
     super.onPause(); 
     if (this.actionMode != null) { 
      this.actionMode.finish(); 
     } 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     updateData(); 
    } 

    // update ListView 
    protected void updateData() 
    { 
     if (adapter == null) { 
      return; 
     } 
     adapter.clear(); 
     // my kinda stuff :) 
     File[] items = scan(); 
     if (items != null) { 
      adapter.updateData(items); 
      if (actionMode != null) { 
       actionMode.invalidate(); 
      } 
     } 
     // if empty - finish action mode. 
     if (actionMode != null && (files == null || files.length == 0)) { 
      actionMode.finish(); 
     } 
    } 

    private void initListView() 
    { 
     this.adapter = new MyAdapter(getActivity()); 
     this.list.setAdapter(adapter); 
     this.list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() 
     { 

      @Override 
      public boolean onItemLongClick(AdapterView<?> arg0, 
        View arg1, int arg2, long arg3) 
      { 
       if (actionMode != null) { 
        // if already in action mode - do nothing 
        return false; 
       } 
       // set checked selected item and enter multi selection mode 
       list.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE); 
       list.setItemChecked(arg2, true); 

       getSherlockActivity().startActionMode(
         new ActionModeCallback()); 
       return true; 
      } 
     }); 
     this.list.setOnItemClickListener(new AdapterView.OnItemClickListener() 
     { 
      @Override 
      public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, 
        long arg3) 
      { 
       if (actionMode != null) { 
        // the items are auomatically "checked" becaise we've set AbsListView.CHOICE_MODE_MULTIPLE before 
        // starting action mode, so the only thing we have to care about is invalidating the actionmode 
        actionMode.invalidate(); //invalidate title and menus. 
       } else { 
        // do whatever you should on item click 
       } 
      } 
     }); 
    } 


    // all our ActionMode stuff here :) 
    private final class ActionModeCallback 
      implements ActionMode.Callback 
    { 

     // " selected" string resource to update ActionBar text 
     private String selected = getActivity().getString(
       R.string.library_selected); 

     @Override 
     public boolean onCreateActionMode(ActionMode mode, Menu menu) 
     { 
      actionMode = mode; 
      return true; 
     } 

     @Override 
     public boolean onPrepareActionMode(ActionMode mode, Menu menu) 
     { 
      // remove previous items 
      menu.clear(); 
      final int checked = list.getCheckedItemCount(); 
      // update title with number of checked items 
      mode.setTitle(checked + this.selected); 
      switch (checked) { 
      case 0: 
       // if nothing checked - exit action mode 
       mode.finish(); 
       return true; 
      case 1: 
       // all items - rename + delete 
       getSherlockActivity().getSupportMenuInflater().inflate(
         R.menu.library_context, menu); 
       return true; 
      default: 
       getSherlockActivity().getSupportMenuInflater().inflate(
         R.menu.library_context, menu); 
       // remove rename option - because we have more than one selected 
       menu.removeItem(R.id.library_context_rename); 
       return true; 
      } 
     } 

     @Override 
     public boolean onActionItemClicked(ActionMode mode, 
       com.actionbarsherlock.view.MenuItem item) 
     { 
      SparseBooleanArray checked; 
      switch (item.getItemId()) { 
      case R.id.library_context_rename: 
       // the rename action is present only when only one item is selected. 
       // so when the first checked item found, show the dialog and break 
       checked = list.getCheckedItemPositions(); 
       for (int i = 0; i < checked.size(); i++) { 
        final int index = checked.keyAt(i); 
        if (checked.get(index)) { 
         final DialogFragment d = RenameDialog.instantiate(adapter.getItem(index).getFile(), LibraryFragment.this); 
         d.show(getActivity().getSupportFragmentManager(), "dialog"); 
         break; 
        } 
       } 
       return true; 

      case R.id.library_context_delete: 
       // delete every checked item 
       checked = list.getCheckedItemPositions(); 
       for (int i = 0; i < checked.size(); i++) { 
        final int index = checked.keyAt(i); 
        if (checked.get(index)) { 
         adapter.getItem(index).getFile().delete(); 
        } 
       } 
       updateData(); 
       return true; 
      default: 
       return false; 
      } 
     } 

     @Override 
     public void onDestroyActionMode(ActionMode mode) 
     { 
      list.clearChoices(); 

      //workaround for some items not being unchecked. 
      //see http://stackoverflow.com/a/10542628/1366471 
      for (int i = 0; i < list.getChildCount(); i++) { 
       (list.getChildAt(i).getBackground()).setState(new int[] { 0 }); 
      } 

      list.setChoiceMode(AbsListView.CHOICE_MODE_NONE); 
      actionMode = null; 
     } 

    } 
+0

Paylaştığınız için teşekkürler. Tam olarak bunu arıyordum! – h4ck3d

+0

Bu harika gönderi için teşekkürler, ancak yönelim değişikliği konusunda bir sorunum var. Diyelim ki, actionmode üzerinde birkaç öğe seçtikten sonra cihazı döndürdüm, actionbar'ı geri yükleyebildim ve seçili öğeleri ayarlayabiliyorum. Ancak, vurguyu ekrandan ve geri listeden kaydırıncaya kadar gösterilmez. Herhangi bir fikrin var mı? – triston

+0

@triston Durumu nasıl geri yüklersiniz? Bağdaştırıcıdaki setChecked() öğesini çağırdığınızdan emin olun. Bu durumda çalışması gerekir. Ama yaptıklarınız buysa ve işe yaramazsa, korkarım ki bu şeyleri test etmek için yeterli boş zamanım olmadığından sana yardım edemem. –

0

çözüm bu iş parçacığı için en iyi ve en kolay çözümdür. Ancak getView() 'da küçük bir sorun var - yukarıdaki yorumlarıma geri dönün.

int version = android.os.Build.VERSION.SDK_INT;  
if(version < 11){ 
    if (checkedItems.contains(Integer.valueOf(position))) { 
     convertView.getBackground().setState(
       new int[] { android.R.attr.state_checked }); 
    } else { 
     convertView.getBackground().setState(
       new int[] { -android.R.attr.state_checked }); 
    } 
}else{ 

    if (checkedItems.contains(Integer.valueOf(position))) { 
     convertView.setActivated(true); 
    } else { 
     convertView.setActivated(false);   
    } 
} 

Bu sizi bunun için komple bir çözüm yoktur

+0

setActivated yalnızca API level 11'den itibaren kullanılabilir. API 11'i kullanırsanız ActionBarSherlock'a gerek yoktur ve bu API 11 başlatma işlemini gerçekleştirmenin daha kolay bir yolu olduğundan çözümüm kötüdür. Http://developer.android.com/ guide/topics/ui/menus.html # CAB –

+0

Projem minimum bir API8 olarak ayarlandı, bu yüzden ikisini de kullanmam gerekiyor. Benim önerimi de değiştireceğim. Teşekkürler. – triston