Здравствуйте, TheBeatlemaniac!
Я, честно говоря, не знаю, выполнимо ли то, что вы ищете (EDIT: в том виде, в каком вы его реализуете, как подменю), но я бы сделалэто так:
Создайте действие, которое выглядит как подменю, которое вы хотите отобразить.
Это может показаться немного более сложным, но это прямое итаким образом, он не исчезнет, если вы выберете / отмените выбор элемента, и вы сможете реализовать гораздо больше функций.
Вот как я бы лично это сделал:
- Создать класс для представления элемента подменю.Он должен содержать строку (описание) и логическое значение (для хранения, если оно проверено или нет).
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;
}
}
Как видите, класс реализует Serializable, так что объекты этого классаможет быть передан из действия в другое с помощью намерений / пакетов.
- Добавьте следующее в текущее действие (я предположил, что оно называется MainActivity , поэтому при попытке его заменить MainActivity по названию вашей деятельности).
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 );
}
Список (ArrayList) используется для размещения всех ваших пунктов подменю настроек с флажками.Как видите, каждый объект SettingCheckBox имеет описание и состояние (отмечено или не отмечено).По умолчанию после создания состояние объекта не проверено .Вы должны инициализировать список внутри метода onCreate .
Статическая и конечная переменная SETTING_CHECK_BOX используется в качестве ключа для сохранения / восстановления содержимого этого списка до / послевоссоздание активности (например, поворот экрана), а также для передачи списка настроек из одного действия в другое.(поясняется позже)
- Удалите ваше подменю, чтобы xml-файл меню выглядел следующим образом:
<?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>
Больше не нужно подменю, так как выбудет осуществлять деятельность, которая действует как один.Теперь, чтобы связать пункт меню с действием, которое будет отображать настройки, вы должны использовать метод onOptionsItemSelected внутри вашего текущего действия, например:
@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 );
}
}
Операция настройки запущена длярезультат.Это означает, что он ведет себя как дочернее действие, и может вернуть результат его родительскому действию.
Список настроек передается действию настроек через намерение.
Если дочернее действие заканчивается и возвращает данные родительскому действию, вызывается следующий метод:
protected void onActivityResult ( int requestCode , int resultCode , Intent data ) {
if ( resultCode != RESULT_OK || data == null )
return;
settingList = (ArrayList < SettingCheckBox >) data.getSerializableExtra ( SETTING_CHECK_BOX );
}
Вы должны заставить дочернее действие / настройки вернуть список (новых / измененных) параметров и какКак показано выше, новый список установлен.
- Создайте следующий XML-файл макета с именем 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>
Это макет действия, который будет действовать какваше подменю.На самом деле это действие списка и может содержать столько параметров, сколько вы хотите (вы просто добавляете их в список массивов, объявленный в вашем действии выше).
- Создайте следующий XML-файл макета с именем 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>
Это расположение каждой строки в списке, есть текстовое представление и флажок (точно так же, как подменю, которое вы уже использовали).
- Создайте новый класс под названием MyActivity_Settings, который должен содержать следующее:
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
}
Этот класс представляет действие, которое будет действовать как ваше подменю.Как я уже говорил ранее, это List Activity (и, следовательно, должен расширять ListActivity).Чтобы отобразить различные параметры в списке, вам нужен адаптер (для этого достаточно адаптера массива), это роль класса MyActivity_Settings_Adapter (который расширяет ArrayAdapter).
Если действие списка заканчивается (пользователь нажимает кнопку «Назад» или в любом месте за пределами действия, которое отображается в виде диалога), оно (действие) возвращает родительскому действию новый список параметров с новыми отмеченными значениями.
Адаптер создаст каждую строку для отображения списка.Кроме того, адаптер будет назначать прослушиватель щелчков для каждого флажка, так что если флажок установлен (или не отмечен), параметр будет соответствующим образом изменен.
И если вы щелкнете где-нибудь за пределами подменю (или просто нажмите накнопка «Назад»), подменю исчезнет, а выбранные пользователем параметры будут сохранены в логическом массиве в вашем основном действии.
Если вы не знакомы с ListActivity и ArrayAdapter, это руководство очень помогло бы!
- Не забудьте добавить это в свой XML-файл манифеста Android (в теге приложения):
<activity android:name=".MyActivity_Settings"
android:theme="@android:style/Theme.Dialog" />
Примененная тема (@android: style / Theme.Dialog) сделает действие похожим на подменю.
Надеюсь, это поможет!Я попробовал, и это работает отлично!Попробуйте и дайте мне знать, что происходит.