2011-08-16 40 views
7

Tôi có một menu tùy chọn với tùy chọn "Thêm/Loại bỏ", khi được nhấp, hiển thị danh sách có thể kiểm tra. Vấn đề với mã mà tôi hiện có là bạn chỉ có thể chọn một mục tại một thời điểm và menu sẽ biến mất. Tôi muốn có thể kiểm tra nhiều mục trong danh sách cùng một lúc và để nó không biến mất cho đến khi người dùng chạm vào vị trí khác trên màn hình. Tôi có thể làm cái này như thế nào? Dưới đây là hướng dẫn chung về những gì tôi có:Cách chọn nhiều hộp kiểm trong menu phụ trên 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> 

@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

bởi bất kỳ cơ hội nào bạn đã tìm ra? Tôi đang tìm kiếm cùng một – Waqas

Trả lời

6

Xin chào TheBeatlemaniac!

Thực sự tôi không biết nếu những gì bạn đang tìm kiếm là doable hay không (EDIT: theo cách bạn đang thực hiện nó, như một trình đơn phụ), nhưng tôi đã có thể làm nó theo cách này:

Tạo hoạt động giống như menu phụ bạn muốn hiển thị.

Nó có vẻ phức tạp hơn một chút nhưng nó thẳng về phía trước và theo cách này, nó sẽ không biến mất nếu bạn chọn/bỏ chọn một mục và bạn có thể thực hiện nhiều chức năng hơn.

Đây là cách tôi sẽ có cá nhân thực hiện nó:


  • Tạo một lớp học để đại diện cho một mục trình đơn phụ. Nó sẽ chứa một chuỗi (mô tả), và một boolean (để lưu trữ nếu nó được kiểm tra hay không).
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; 
    } 

} 

Như bạn có thể thấy, lớp thực hiện Serializable để các đối tượng của lớp đó có thể được truyền từ một hoạt động khác ý đồ sử dụng/bó.

  • Thêm dòng sau vào hoạt động hiện tại của bạn (tôi cho rằng nó được gọi là MainActivity, vì vậy khi bạn thử nó, thay thế MainActivity theo tên hoạt động của bạn).
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); 
} 

Danh sách (ArrayList) được sử dụng để lưu trữ tất cả các mục menu cài đặt phụ của bạn với các hộp kiểm. Như bạn thấy, mỗi đối tượng SettingCheckBox có mô tả và trạng thái (được chọn hoặc bỏ chọn). Theo mặc định, khi tạo, trạng thái đối tượng là không được chọn. Bạn nên khởi tạo danh sách bên trong phương thức onCreate.

Biến tĩnh và cuối SETTING_CHECK_BOX được sử dụng làm chìa khóa để lưu/khôi phục nội dung của danh sách đó trước/sau hoạt động tái tạo (như xoay màn hình) và chuyển danh sách cài đặt từ hoạt động này sang hoạt động khác.(Giải thích sau này)

  • Di menu phụ của bạn, do đó các tập tin trình đơn xml trông như thế này:
<?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> 

Không cần vào menu phụ nữa vì bạn sẽ được thực hiện một hoạt động mà hành động như một. Bây giờ, để liên kết các mục trình đơn để hoạt động mà sẽ hiển thị các cài đặt, bạn nên sử dụng onOptionsItemSelected phương pháp trong hoạt động hiện tại của bạn như thế này:

@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); 
    } 
} 

Các hoạt động cài đặt được bắt đầu cho một kết quả. Nó có nghĩa là nó hoạt động như một hoạt động trẻ em, và có thể trả lại kết quả cho hoạt động gốc của nó.

Danh sách cài đặt được chuyển đến hoạt động cài đặt thông qua mục đích.

Nếu hoạt động con kết thúc và trả về dữ liệu đến các hoạt động phụ huynh, các phương pháp sau đây được gọi là:

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

Bạn nên thực hiện các hoạt động con/cài đặt trả lại (mới/sửa đổi) danh sách các thiết lập, và như đã trình bày ở trên, danh sách mới được thiết lập.

  • Tạo file xml bố trí sau đây gọi là 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> 

Đây là cách bố trí của các hoạt động mà sẽ hoạt động như trình đơn phụ của bạn. Nó thực sự là một hoạt động danh sách, và có thể chứa nhiều tùy chọn như bạn muốn (bạn chỉ cần thêm chúng vào danh sách mảng được khai báo trong hoạt động của bạn ở trên).

  • Tạo file xml bố trí sau đây gọi là 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> 

Đây là cách bố trí của mỗi hàng trong danh sách, có một quan điểm văn bản và hộp kiểm tra (giống như các tiểu menu bạn đã sử dụng).

  • Tạo một MyActivity_Settings hưởng lớp mới mà nên chứa những điều sau đây:
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 

} 

Lớp này đại diện cho hoạt động mà sẽ hoạt động như trình đơn phụ của bạn. Như tôi đã nói, đây là một hoạt động List (và do đó nên mở rộng ListActivity). Để hiển thị các tùy chọn khác nhau bên trong danh sách, bạn cần một bộ điều hợp (bộ điều hợp mảng là đủ cho trường hợp này), đó là vai trò của lớp MyActivity_Settings_Adapter (mở rộng ArrayAdapter).

Nếu hoạt động danh sách kết thúc (người dùng nhấp vào nút quay lại hoặc bất kỳ nơi nào bên ngoài hoạt động được hiển thị dưới dạng hộp thoại), nó (hoạt động) trả về hoạt động gốc danh sách tùy chọn mới với kiểm tra mới giá trị.

Bộ điều hợp sẽ tạo mỗi hàng để danh sách hiển thị. Ngoài ra, bộ điều hợp sẽ chỉ định trình nghe nhấp chuột cho mỗi hộp kiểm, để nếu được chọn (hoặc bỏ chọn), tùy chọn sẽ được sửa đổi cho phù hợp.

Và nếu bạn nhấp vào bất kỳ nơi nào bên ngoài menu phụ (hoặc chỉ cần nhấn vào nút quay lại), menu phụ sẽ biến mất và lựa chọn người dùng được lưu giữ trong mảng boolean trong hoạt động chính của bạn.

Nếu bạn không quen thuộc với ListActivity và ArrayAdapter, điều này tutorial sẽ giúp ích rất nhiều!

  • Đừng quên để thêm video này trong file xml manifest Android của bạn (trong thẻ ứng dụng):
<activity android:name=".MyActivity_Settings" 
     android:theme="@android:style/Theme.Dialog" /> 

Chủ đề áp dụng (@android: phong cách/Theme.Dialog) sẽ làm cho hoạt động trông giống như một menu phụ.

Hy vọng điều đó sẽ hữu ích! Tôi đã thử nó và nó hoạt động hoàn hảo! Hãy thử nó và cho tôi biết những gì sẽ xảy ra.

+0

Câu trả lời tuyệt vời .. –

+0

Người đàn ông tuyệt vời !!!! – ngoa

+0

Tuyệt vời! Tôi đang sử dụng mã ở trên nhưng làm cách nào tôi có thể nhận danh sách các mục đã được kiểm tra khi nhấn nút quay lại hoặc khi tôi trở lại hoạt động gốc? – choman

Các vấn đề liên quan