Please refer to the textbook to fully understand and complete the section of this chapter ...
In this chapter, we will implement the ability to delete crime records long by list items for the application. Deleting a crime record is a contextual action (contextual action), which is associated with a particular screen view (a single list item) rather than the entire screen.
On honeycomb Previous versions of the device, context operations were rendered in a floating context menu. On the subsequent version of the device, the context operation is mainly rendered through the context Action bar. Located above the activity's action bar, the context Action Bar provides the user with a variety of actions, as shown in 18-1.
Figure 18-1 Long Press the list item to delete a crime record
In the 16th chapter, we have seen that for the Options menu, dealing with compatibility issues at different API levels is simple: Simply define a menu resource and implement a set of menu-related callback methods, and the operating system on different devices will determine how the menu items are displayed.
And for context operations, things are not that simple. Although we still define a menu resource, we must implement two different sets of callback methods, one for the context Action Bar and one for the floating context menu.
In this chapter, we will implement a context operation on devices running API level 11 and above, and then implement a floating context menu on the Froyo and gingerbread devices.
(We may have seen an app with a contextual action bar running on an old device.) Typically, these applications were developed based on a third-party library called Actionbarsherlock. The library implements the function of the context action bar for the legacy system device by imitating replication. We will discuss the use of the Actionbarsherlock Library in detail at the end of this chapter. ) 18.1 Define context Menu Resources
In the res/menu/directory, create a new menu resource file named Crime_list_item_context.xml with menu as the root element. Then, refer to listing 18-1 to add the required menu items.
Code Listing 18-1 above menu for crime list (crime_list_item_context.xml)
The menu resources defined above will be used for the implementation of the context action bar and the floating context menu. 18.2 Implementing a floating context menu
First, let's create a floating context menu. Fragment
The callback method is similar to the callback method used in the 16th chapter for the Options menu. To instantiate a context menu, you can use the following methods:
public void Oncreatecontextmenu (ContextMenu menu, View V, Contextmenu.contextmenuinfo menuinfo)
To respond to a user's context menu selection, the following methods can be implemented Fragment
:
public boolean oncontextitemselected (MenuItem Item)
18.2.1
Create a context menu
In Crimelistfragment.java, implement onCreateContextMenu(...)
the method, instantiate the menu resource, and populate the context menu with it, as shown in Listing 18-2.
Code Listing 18-2 Creating a context menu (Crimelistfragment.java)
Unlike onCreateOptionsMenu(...)
methods, the above menu callback methods do not accept MenuInflater
instance parameters, so we should first get the CrimeListActivity
associated MenuInflater
. It then invokes the MenuInflater.inflate(...)
method, passes in the menu resource ID and ContextMenu
instance, populates the menu instance with the menu item defined in the menu resource file, and completes the creation of the context menu.
Currently we have only defined a context menu resource, so the menu is generated from the resource instantiation, regardless of which view the user has long pressed. If more than one context menu resource is defined, by examining onCreateContextMenu(...)
The view ID of the incoming method View
, we are free to decide which resource to use to generate the context menu. 18.2.2 register a view for a context menu
By default, the long-press view does not trigger the creation of a context menu. To trigger the creation of a menu, you must call the following Fragment
method to register a view for the floating context menu:
public void Registerforcontextmenu (view view)
The method needs to pass in the view that triggers the context menu.
In the Criminalintent app, we want to click on any list item to bring up the context menu. Does this mean that you need to register the list item view individually? Without the hassle, register the ListView
view directly, and it will automatically enlist the individual list item views.
In the CrimeListFragment.onCreateView(...)
method, reference and Enlist ListView
, as shown in Listing 18-3.
Code Listing 18-3 Register for context menu ListView
(Crimelistfragment.java)
In the onCreateView(...)
method, use the android.R.id.list
resource ID to get ListFragment
the managed ListView
. ListFragment
There is also a getListView()
method, but it is onCreateView(...)
not available in the method. This is because the onCreateView()
method always returns a null value before the method completes the call and returns getListView()
the view.
Run the Criminalintent app and press and hold any list item to eject the floating menu with the Delete menu item, as shown in 18-2.
Figure 18-2 Long Press the list item popup context menu item 18.2.3 Response menu item Selection
The Delete menu item is available and requires a way to delete the crime data from the model layer. In Crimelab.java, the new deleteCrime(Crime)
method, as shown in Listing 18-4.
Code Listing 18-4 New ways to delete crime (Crimelab.java)
Then, the onContextItemSelected(MenuItem)
menu item selection event is processed in the method. MenuItem
there is a resource ID that can be used to identify the selected menu item. In addition, it is necessary to specify the crime object to be deleted in order to determine the intent of the user to delete the crime data.
A callable MenuItem
getMenuInfo()
method that gets the information for the crime object to be deleted. The method returns an ContextMenu.ContextMenuInfo
instance of the class that implements the interface.
In CrimeListFragment
, add the onContextItemSelected(MenuItem)
implementation method, use the menu information and adapter, identify the object that was long pressed, Crime
and then remove it from the model layer data, as shown in Listing 18-5. ( Note:import android.widget.AdapterView.AdapterContextMenuInfo; )
Code Listing 18-5 Listener Context menu item selection event (Crimelistfragment.java)
In the above code, because ListView
it is a AdapterView
subclass, the getMenuInfo()
method returns an AdapterView.AdapterContextMenuInfo
instance. Then, getMenuInfo()
type-Convert the returned result of the method to get the location information of the selected list item in the dataset. Finally, use the position of the list item to get the crime object you want to delete.
Run the Criminalintent app, add a crime record, and then long press to delete it. (to simulate a long-press action on the simulator, you can press the left mouse button until the menu pops up.) ) 18.3 Implementation Context operation mode
Remove the implementation code for the crime record from the floating context menu, which can be run on any Android device. For example, figure 18-2 is a floating menu that pops up on a jelly bean system device.
However, on new system devices, the long-press view into context mode of Operation is the main way to provide contextual operations . When the screen enters context operation mode, the menu items defined in the context menu appear on the context action bar that covers the action bar, as shown in 18-3. The contextual Action Bar does not obscure the screen compared to a floating menu, so it is a better way to display the menu.
Figure 18-3 Long Press the list item to appear context Operation Bar
The implementation code of the context action Bar differs from the floating context menu. In addition, the classes and methods used by the context action Bar Implementation code do not support older systems such as Froyo or gingerbread, so it is important to ensure that only the code that supports the new system will not be called on the old system. 18.3.1 to implement a multi-select operation for a list view
When a list view enters context mode of operation, it can turn on its multi-select mode. In multi-select mode, any action on the context Action Bar will be applied to all selected views at the same time.
In the CrimeListFragment.onCreateView(...)
method, set the selection mode for the list view to Choice_mode_multiple_modal, as shown in Listing 18-6. Finally, to deal with compatibility issues, remember to use the compiled version constants to separate the enlisted code from the ListView
code that sets the selection pattern.
Code Listing 18-6 Setting the selection mode of the list view (Crimelistfragment.java)
18.3.2 operation mode callback method in List view
Next, ListView
set up a listener to implement AbsListView.MultiChoiceModeListener
the interface. The interface contains the following callback methods, which are triggered when the view is checked or revoked:
public abstract void Onitemcheckedstatechanged (actionmode mode, int position, long ID, Boolean checked)
MultiChoiceModeListener
Implements the other interface, i.e. ActionMode.Callback
. A class instance is created when the user screen enters context mode of Operation ActionMode
. The ActionMode.Callback
callback method of the interface is then invoked at different points in its life cycle. The following are the ActionMode.Callback
four methods that must be implemented in an interface:
Public abstract Boolean Oncreateactionmode (Actionmode mode, menu menu)
ActionMode
called after the object is created. The context menu resource is also instantiated and displayed where the task is completed on the context Action bar.
Public abstract Boolean Onprepareactionmode (Actionmode mode, menu menu)
onCreateActionMode(...)
called after the method, and when the current context action bar needs to be refreshed to display new data.
Public abstract Boolean onactionitemclicked (Actionmode mode, MenuItem Item)
Called when the user selects a menu item action. is where the context menu item action responds.
public abstract void Ondestroyactionmode (Actionmode mode)
Called when the user exits the context operation mode or the selected menu item operation has been responded to, causing the object to be ActionMode
destroyed. The default implementation causes the selected view to be reversed. Here, you can also complete the corresponding fragment update that is raised in the context operation mode, which responds to menu item actions.
In the CrimeListFragment.onCreateView()
method, set MultiChoiceModeListener
the listener that implements the interface for the list view. Here, you just need onCreateActionMode()
to implement and onActionItemClicked(ActionMode, MenuItem)
method, as shown in Listing 18-7. ( note : import android.view.ActionMode;)
Code Listing 18-7 Setup MultiChoiceModeListener
Listener (Crimelistfragment.java)
Note that if you create an interface with code auto MultiChoiceModeListener
-completion, the system automatically generates a onCreateActionMode(...)
stub method that returns a value of false. Remember to change it to return a true value, because returning a false value causes the operation mode creation to fail.
It is also important to note that in the onCreateActionMode(...)
method, we get from the operation mode, not the activity MenuInflater
. The operation mode is responsible for configuring the context Action Bar. For example, the callable ActionMode.setTitle(...)
method sets a caption for the context Action bar, and the activity MenuInflater
does not do that.
Next, in the onActionItemClicked(...)
method, respond to the menu item delete operation, CrimeLab
delete one or more Crime
objects from, and then reload the display list. Finally, the method is called to ActionMode.finish()
prepare the destroy operation mode.
Run the Criminalintent app. Long press to select any list item and enter context mode. At this point, you also want to select other list items, you can click directly. Click the selected list item again to undo the selection. Clicking the delete icon will end the operation mode and return to the refreshed list item interface. You can also click the Cancel icon at the far left of the context Action bar, which cancels the operation mode and returns to the list item interface without any changes.
18-4, although there is no problem with feature usage, the user experience is bad because it is difficult to see which list items are selected. However, the problem can be resolved by changing the background of the selected list item.
Figure 18-4 Second Crime record has been selected 18.3.3 Changing the display background of an activated view
Depending on their state , sometimes a view needs to be displayed differently. In the Criminalintent app, we want to be able to change the display background when the list item is active. The view is active, meaning that the view has been marked by the user as the object of concern.
Based on the status of the view, you can use the state list drawable resource to change its display background. The state list drawable is a resource defined in XML. In this resource definition, we specify a drawable (bitmap or color map) and list the drawable corresponding state. (see StateListDrawable
the Reference manual page for more view-related status.) )
Right-click the res\drawable directory, select new-> drawable resource file, and create a resource file named background_activated. Refer to listing 18-8 to complete the content additions.
Code Listing 18-8 Simple State List drawable resource (res/drawable/background_activated.xml)
The XML file above tells us that when the view referencing the drawable resource is active, the android:drawable
resource specified by the property value is used, and otherwise no action is taken. If android:state_activated
the property value is set to False, the android:drawable
specified resource will be used as long as the view is not in the active state.
Modify the Res/layout/list_item_crime.xml file to refer to the resource defined background_activated.xml the drawable directory, as shown in Listing 18-9.
Code Listing 18-9 Changing the display background of a list item (res/layout/list_item_crime.xml)
Re-run the Criminalintent app. This time, the selected list item can be seen at one glance, as shown in 18-5.
Figure 18-5 Eye-catching second list item 18.3.4 Implementing a context mode of operation for other views
The context menu bar implemented in this chapter can be applied perfectly to the ListView and GridView. (The GridView is a subclass of Adapterview, which is used in the 26th chapter.) But what if the view is not, and ListView
is not, what to do GridView
with the contextual action bar?
First, set up a View.OnLongClickListener
listener that implements the interface. Then, in the listener implementation body, invoke the Activity.startActionMode(...)
method to create an ActionMode
instance. (As seen earlier, if you are using an MultiChoiceModeListener
interface, the ActionMode
instance is created automatically.) )
startActionMode(...)
Method requires an ActionMode.Callback
object that implements an interface as a parameter. Therefore, the implementation of an interface is created ActionMode.Callback
, and the interface implementation naturally includes the four ActionMode
life cycle methods previously used:
Public abstract Boolean Oncreateactionmode (Actionmode mode, menu menu)
Public abstract Boolean Onprepareactionmode (Actionmode mode, menu menu)
Public abstract Boolean onactionitemclicked (Actionmode mode, MenuItem Item)
public abstract void Ondestroyactionmode (Actionmode mode)
When implemented, you can first create an ActionMode.Callback
object that implements the interface, and then startActionMode(...)
pass in when the method is called, or call the startActionMode(...)
method directly and pass in an anonymous implementation parameter.
The 18th Chapter context menu and Context operation mode