Hi TheBeatlemaniac!
I honestly donโt know if what you are looking for is feasible or not (EDIT: how you implement it, as a submenu), but I would do it like this:
Create an action that looks like a submenu that you want to display.
It may seem a little more complicated, but it is straightforward, and thus it will not disappear if you select / deselect an item and you can implement much more functionality.
Here is how I personally would do it:
- Create a class to represent the submenu item. It should contain a string (description) and a logical value (to save if it is checked or not).
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; } }
As you can see, the class implements Serializable so that objects of this class can be transferred from one operation to another using intentions / packages.
- Add the following to your current action: I assumed it was called MainActivity , so when you try it, replace MainActivity with the name of your activity).
public static final String SETTING_CHECK_BOX = "SETTING_CHECK_BOX"; private ArrayList < SettingCheckBox > settingList; @Override public void onCreate(Bundle savedInstanceState) {
The list (ArrayList) is used to place all the elements of the parameter submenu using flags. As you can see, each SettingCheckBox object has a description and status (checked or not checked). By default, after creation, the state of the object is not marked. You must initialize the list inside the onCreate method.
The static and final variable SETTING_CHECK_BOX is used as a key to save / restore the contents of this list before / after recreating the activity (for example, to rotate the screen), and also to transfer the list of settings from activity to another. (explained later)
- Delete the submenu so that the menu xml file looks like this:
<?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>
There is no need for an additional menu, as you will perform an action that acts as one. Now, to associate a menu item with an activity that will display settings, you must use the onOptionsItemSelected method inside your current action, for example:
@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 ); } }
Settings activity is triggered for the result. This means that it behaves as a child activity and can return the result to its parent activity.
The list of settings is transferred to the settings using intent.
If the child activity completes and returns the parent activity data, the following method is called:
protected void onActivityResult ( int requestCode , int resultCode , Intent data ) { if ( resultCode != RESULT_OK || data == null ) return; settingList = (ArrayList < SettingCheckBox >) data.getSerializableExtra ( SETTING_CHECK_BOX ); }
You must make the child / settings action return a (new / changed) list of settings, and as shown above, the new list is set.
- Create the following XML layout file called 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>
This is a mock activity that will act as your submenu. This is actually an activity of the list and can contain as many parameters as possible (you simply add them to the list of arrays specified in your activity above).
- Create the following XML layout file called 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>
This is the layout of each line in the list, there is a text view and a checkbox (as in the submenu that you already used).
- Create a new class called MyActivity_Settings, which should contain the following:
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;
This class represents an action that will act as your submenu. As I said, this is list activity (and therefore should extend ListActivity). To display various parameters inside the list, you need an adapter (for this case, an array adapter is enough), which is the role of the MyActivity_Settings_Adapter class (which extends ArrayAdapter).
If the action of the list ends (the user presses the "Back" button or somewhere outside the operation, which is displayed as a dialog), it (action) returns to the parent action a new list of parameters with the new values โโmarked.
The adapter will build each line to display a list. In addition, the adapter will assign a click listener for each flag, so if it is installed (or not installed), the option will be changed accordingly.
And if you click anywhere outside the submenu (or just click the "Back" button), the submenu will disappear, and the user's selection will be saved in a boolean array in your main action.
If you are not familiar with ListActivity and ArrayAdapter, this tutorial will help a lot!
- Remember to add this to your Android manifest XML file (in the application tag):
<activity android:name=".MyActivity_Settings" android:theme="@android:style/Theme.Dialog" />
The applicable theme (@android: style / Theme.Dialog) will make the activity look like a submenu.
Hope this helps! I tried and it works great! Try it and let me know what will happen.