2011-08-16 9 views
7

Mam menu opcji z opcją "Dodaj/Usuń", która po kliknięciu pokazuje listę do sprawdzenia. Problem z aktualnie posiadanym kodem polega na tym, że możesz wybrać tylko jeden przedmiot na raz, a menu zniknie. Chcę mieć możliwość jednoczesnego sprawdzania wielu pozycji na liście i nie znikania, dopóki użytkownik nie dotknie miejsca w innym miejscu na ekranie. Jak mogę to zrobić? Oto ogólny pomysł co mam:Jak wybrać wiele pól wyboru w podmenu na urządzeniu z systemem Android?

<?xml version="1.0" encoding="UTF-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:id="@+id/select_options" 
      android:title="Add/Remove"> 
     <menu> 
      <group android:checkableBehavior="all"> 
       <item android:id="@+id/A" 
         android:checked="true" 
         android:title="Option One" /> 
       <item android:id="@+id/B" 
         android:checked="true" 
         android:title="Option Two" /> 
      </group> 
     </menu> 
    </item> 
</menu> 

i

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    MenuInflater inflater = getMenuInflater(); 
    inflater.inflate(R.menu.selection_menu, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item){ 
    switch (item.getItemId()){ 
    case R.id.A: 
     item.setChecked(!item.isChecked()); 
     return true; 
    case R.id.B: 
     item.setChecked(!item.isChecked()); 
     return true; 
    default: 
     return super.onOptionsItemSelected(item); 
    } 
} 
+0

przez przypadek to rozgryzłeś? Szukam tej samej – Waqas

Odpowiedz

6

Witam TheBeatlemaniac!

Szczerze mówiąc, nie wiem, czy to, czego szukają, jest wykonalne czy nie (EDIT: w sposób wdrażają go jako podmenu), ale chciałbym zrobić to w ten sposób:

Utwórz działanie, które wygląda jak podmenu, które chcesz wyświetlić.

Może wydawać się nieco bardziej skomplikowany, ale jest prosty i dzięki temu nie zniknie, jeśli wybierzesz/odznaczysz element i możesz wdrożyć znacznie więcej funkcji.

Oto jak bym osobiście zrobił:


  • Tworzenie klasy do reprezentowania element podmenu. Powinien zawierać ciąg (opis) i wartość logiczną (do zapisania, jeśli jest zaznaczona lub nie).
public class SettingCheckBox implements Serializable { 

    private static final long serialVersionUID = 1L; 

    private static final String DEFAULT_DESCRIPTION = "N/A"; 

    private final String description; 

    private boolean checked; 

    public String getDescription() { 
     return description == null ? DEFAULT_DESCRIPTION : description; 
    } 

    public void setChecked (final boolean checked) { 
     this.checked = checked; 
    } 

    public boolean getChecked() { 
     return checked; 
    } 

    public SettingCheckBox (final String description) { 
     this.description = description; 
    } 

} 

Jak widać, klasa implementuje Serializable tak, że obiekty tej klasy mogą być przekazywane z działalności do innego korzystających zamiarów/wiązkach.

  • Dodaj poniższe linie do swojej bieżącej działalności (Przypuszczałem nazywa główną działalność, więc podczas spróbować go wymienić główną działalność po imieniu aktywności).
public static final String SETTING_CHECK_BOX = "SETTING_CHECK_BOX"; 

private ArrayList <SettingCheckBox> settingList; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    // ... 
    settingList = new ArrayList <SettingCheckBox>(); 
    settingList.add (new SettingCheckBox ("Option A")); 
    settingList.add (new SettingCheckBox ("Option B")); 
    // ... add more items 
    // restore any previously saved list 
    if (savedInstanceState != null) { 
     settingList = (ArrayList <SettingCheckBox>) savedInstanceState.getSerializable (SETTING_CHECK_BOX); 
    } 
    // ... 
} 

protected void onSaveInstanceState (Bundle outState) { 
    super.onSaveInstanceState (outState); 
    outState.putSerializable (SETTING_CHECK_BOX , settingList); 
} 

listy (ArrayList) służy do obsługi wszystkich nastaw pomocniczych elementów menu z pól wyboru. Jak widać, każdy obiekt ma opis i stan (zaznaczone lub niezaznaczone). Domyślnie po utworzeniu stan obiektu to niezaznaczony. Powinieneś zainicjować listę wewnątrz metody onCreate.

Zmienna statyczna i końcowy SETTING_CHECK_BOX służy jako klucz do zapisu/przed odtworzeniem zawartości tej listy/po rekonstrukcje działalności (takich jak obrót ekranu), a także przekazać listę ustawień z działalności do innego.(Wyjaśnione później)

  • Usuń swoje podmenu, tak, że plik menu xml wygląda następująco:
<?xml version="1.0" encoding="UTF-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:id="@+id/select_options" 
     android:title="Add/Remove"> 
    </item> 
</menu> 

Nie potrzeba podmenu już od będzie wdrożenie działań, które zachowuje się jak jeden. Teraz, aby połączyć element menu do aktywności, która będzie wyświetlać ustawienia, należy użyć onOptionsItemSelected metodę wewnątrz swojej bieżącej działalności tak:

@Override 
public boolean onOptionsItemSelected (MenuItem menuItem) { 
    if (menuItem.getItemId() == R.id.select_options) { 
     Intent intent = new Intent (this , MyActivity_Settings.class); 
     intent.putExtra (SETTING_CHECK_BOX , settingList); 
     startActivityForResult (intent , 0); 
    } 
} 

Aktywność ustawień jest uruchamiany dla wyniku. Oznacza to, że zachowuje się jak aktywność podrzędna, a może zwrócić wynik do swojej macierzystej aktywności.

Lista ustawień jest przekazywana do działania ustawień za pomocą intencji.

Jeżeli działalność dziecko kończy i zwraca dane z działalnością dominującą, poniższa metoda nazywa się:

protected void onActivityResult (int requestCode , int resultCode , Intent data) { 
    if (resultCode != RESULT_OK || data == null) 
     return; 
    settingList = (ArrayList <SettingCheckBox>) data.getSerializableExtra (SETTING_CHECK_BOX); 
} 

Należy dokonać aktywność dziecka/ustawienia zwrotu (nowy/zmodyfikowany) listę ustawień, a jak wykazano powyżej, nowa lista jest ustawiona.

  • Tworzenie następujący układ pliku xml nazwie sub_menu:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

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

</LinearLayout> 

Jest to układ z działalności, który będzie działał jako podmenu. W rzeczywistości jest to działanie na liście i może zawierać dowolną liczbę opcji (wystarczy dodać je do listy tablic zadeklarowanej w powyższym działaniu).

  • Tworzenie następujący układ plik xml o nazwie sub_menu_item:
<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:gravity="center_vertical" > 

    <TextView 
     android:id="@+id/option_title" 
     android:layout_width="0dip" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" 
     android:textAppearance="@android:style/TextAppearance.Medium" /> 

    <CheckBox 
     android:id="@+id/option_checkbox" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 

</LinearLayout> 

Jest to układ z każdego wiersza w liście, istnieje pogląd tekst i pole wyboru (tak jak sub menu, z którego już korzystałeś).

  • utworzyć nową klasę uprawnione MyActivity_Settings który powinien zawierać następujące elementy:
public class MyActivity_Settings extends ListActivity { 

    private ArrayList <SettingCheckBox> settingList; 

    @Override 
    public void onCreate (Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView (R.layout.sub_menu); 
     setTitle ("Add/Remove"); 
     settingList = getIntent().getSerializableExtra (MainActivity.SETTING_CHECK_BOX); 
     if (savedInstanceState != null) { 
      settingList = (ArrayList <SettingCheckBox>) savedInstanceState.getSerializable (MainActivity.SETTING_CHECK_BOX); 
     } 
     setListAdapter (new MyActivity_Settings_Adapter (this , R.layout.item_layout , settingList)); 
    } 

    protected void onSaveInstanceState (Bundle outState) { 
     super.onSaveInstanceState (outState); 
     outState.putSerializable (MainActivity.SETTING_CHECK_BOX , settingList); 
    } 

    @Override 
    public void finish() { 
     setResult (RESULT_OK , new Intent().putExtra (MainActivity.SETTING_CHECK_BOX , settingList)); 
     super.finish(); 
    } 

} 

class MyActivity_Settings_Adapter extends ArrayAdapter <SettingCheckBox> { 

    private final LayoutInflater layoutInflater; 
    private final int itemResourceId; 

    // Holder pattern (used instead of findViewById for better performance) 
    static class ViewHolder { 
     public TextView title; 
     public CheckBox checkBox; 
    } 

    // Constructor 
    public MyActivity_Settings_Adapter (ListActivity context, int itemResourceId , List <SettingCheckBox> options) { 
     super (context , itemResourceId , options); 
     layoutInflater = context.getLayoutInflater(); 
     this.itemResourceId = itemResourceId; 
    } 

    // Method called by the list view every time to display a row 
    @Override 
    public View getView (int position , View convertView , ViewGroup parent) { 
     // Declare and initialize the row view 
     View rowView = convertView; 
     // Declare the row view holder 
     ViewHolder viewHolder; 
     // Check if an inflated view is provided 
     if (rowView == null) { 
      // A new view must be inflated 
      rowView = layoutInflater.inflate (itemResourceId , null); 
      // Declare and initialize a view holder 
      viewHolder = new ViewHolder(); 
      // Retrieve a reference to the row title 
      viewHolder.title = (TextView) rowView.findViewById (R.id.option_title); 
      // Retrieve a reference to the row check box 
      viewHolder.checkBox = (CheckBox) rowView.findViewById (R.id.option_checkbox); 
      // Store the view holder as tag 
      rowView.setTag (viewHolder); 
     } // End if 
     else 
     // An inflated view is already provided, retrieve the stored view holder 
     viewHolder = (ViewHolder) rowView.getTag(); 

     // Set the option title 
     viewHolder.title.setText (getItem (position).getDescription()); 
     // Set the option check box state 
     viewHolder.checkBox.setChecked (getItem (position).getChecked()); 
     // Assign a click listener to the checkbox 
     viewHolder.checkBox.setOnClickListener(new OnClickListener() { 

      public void onClick (View checkBox) { 
       // Retrieve the stored view holder 
       ViewHolder viewHolder = (ViewHolder) ((View) checkBox.getParent()).getTag(); 
       // Update the option state 
       getItem (position).setChecked (! getItem (position).getChecked()); 
       // Display the new option state 
       viewHolder.checkBox.setChecked (getItem (position).getChecked()); 
      } 
     }); 

     // Return the row view for display 
     return rowView; 
    } // End of getView 

} 

Klasa ta reprezentuje aktywność, która będzie działać jako podmenu. Jak już wcześniej wspomniałem, jest to działanie z listą (i dlatego powinno rozszerzyć ListActivity). Aby wyświetlić różne opcje na liście, potrzebny jest adapter (adapter karty jest wystarczający dla tego przypadku), to jest rola klasy MyActivity_Settings_Adapter (która rozszerza ArrayAdapter).

Jeśli działanie listy zostanie zakończone (użytkownik kliknie przycisk Wstecz lub gdziekolwiek poza działaniem, które jest wyświetlane jako okno dialogowe), to (działanie) wraca do działania nadrzędnego nową listę opcji z nową zaznaczoną wartości.

Adapter zbuduje każdy wiersz dla wyświetlanej listy. Ponadto adapter przypisze odbiornik kliknięć dla każdego pola wyboru, tak aby po zaznaczeniu (lub niezaznaczeniu) opcja ta została odpowiednio zmieniona.

A jeśli klikniesz w dowolnym miejscu poza podmenu (lub po prostu naciśnij przycisk Wstecz), podmenu zniknie, a wybory użytkownika zostaną zachowane w tablicy boolowskiej w głównej aktywności.

Jeśli nie znasz się na ListActivity i ArrayAdapter, ta tutorial bardzo by pomogła!

  • Nie zapomnij dodać to w android pliku manifestu XML (w tagu aplikacji):
<activity android:name=".MyActivity_Settings" 
     android:theme="@android:style/Theme.Dialog" /> 

Tematem stosowana (@android: styl/Theme.Dialog) sprawi, że aktywność wygląda jak podmenu.

Mam nadzieję, że pomoże! Wypróbowałem to i działa idealnie! Spróbuj i daj mi znać, co się stanie.

+0

Doskonała odpowiedź .. –

+0

Awesome Man !!!! – ngoa

+0

Świetnie! Używam powyższego kodu, ale jak mogę uzyskać listę elementów, które zostały sprawdzone po naciśnięciu przycisku Wstecz lub po powrocie do działania nadrzędnego? – choman

Powiązane problemy