Android-Long Press the ListView to use the context menu (Actionmode) for bulk event processing

Source: Internet
Author: User

Long time no blog to write "" "

In the near future, a little idle.

Get bored with your phone and clean up text messages. Find the processing of batch events is still a good thing ""

Then you also come to the cottage a look at the effect bar ""


Gossip less, first of all, we look at the mobile phone comes with the message function in the run batch delete effect:



Then there is the effect of our own simple cottage:


The operation of the simulation is very easy, but also very representative.

We assume that we are in a situation where the. Enter an interface to hold the contact list.


So, first we define a progress box that simulates the download of data from the network.

Then. When the network data is successfully downloaded to the mobile device, the data binding is displayed in the appropriate listview.

And that's what we're talking about in this blog: Long press the ListView trigger event for that contact list.

Pop Up the context menu using Actionmode. And let the list items in the ListView Support replication, Implementing bulk operations.

At last. is when the user chooses a certain number of options. After you click item in the menu to perform a bulk operation, run the appropriate action and refresh the ListView.


To sort out what we want to achieve, and then what we're going to do

is to tidy up the idea, and then gradually to write code, completed the implementation of the work. Let's do it!


First, we already know that we want to use a contact list as a scene.

Well, naturally we will need a ListView to bind and store these contact data.

So, let's start with a layout file that stores the details of the ListView and the item that defines the ListView, respectively:


Context_menu_action_mode.xml

<?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=" match_parent "    android:o rientation= "vertical" >    <listview        android:id= "@+id/context_menu_listview"        android:layout_ Width= "Match_parent"        android:layout_height= "Match_parent"/></linearlayout>

Context_menu_action_mode_item.xml
<?

XML version= "1.0" encoding= "Utf-8"?

><relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "Match_ Parent "android:layout_height=" match_parent "android:paddingbottom=" @dimen/activity_vertical_margin "Android:padd ingleft= "@dimen/activity_horizontal_margin" android:paddingright= "@dimen/activity_horizontal_margin" Android: paddingtop= "@dimen/activity_vertical_margin" > <imageview android:id= "@+id/user_head" android:layou T_width= "55DP" android:layout_height= "55DP" android:contentdescription= "@string/user_head_description" android:src= "@drawable/headimage_default"/> <textview android:id= "@+id/user_name" android:layout _width= "Wrap_content" android:layout_height= "wrap_content" android:layout_marginleft= "20DP" android:l Ayout_marginstart= "20DP" android:layout_toendof= "@id/user_head" android:layout_torightof= "@id/user_head" Android:textsize= "25sp"/> < TextView android:id= "@+id/phone_number" android:layout_width= "wrap_content" android:layout_height= "WR Ap_content "android:layout_alignbottom=" @id/user_head "android:layout_marginleft=" 20DP "android:layou T_marginstart= "20DP" android:layout_toendof= "@id/user_head" android:layout_torightof= "@id/user_head"/> <checkbox android:id= "@+id/contact_selected_checkbox" android:layout_width= "Wrap_content" Androi d:layout_height= "Wrap_content" android:layout_alignparentend= "true" android:layout_alignparentright= "true" Android:layout_centervertical= "true" android:clickable= "false" android:focusable= "false"/></rel Ativelayout>


About the definition of the layout. And there is no difficulty.

The only thing to note is that we have a more friendly interaction experience, so after the user presses the ListView into the check mode,

A checkbox is added to the right side of each list to indicate whether the user has successfully selected the list item that you want to manipulate.

The checkbox is only displayed when the user enters the check mode, so we need to be careful to control its display dynamically in the code later.

And! It's more important to remember to set the value of the checkbox's clickable and focusable two properties to false!

The reason for this is that the checkbox (defined in the item file as the ListView) itself responds with focus and the Click event takes precedence over the ListView itself.

So. If you forget to set it, the focus and response events will be intercepted in the checkbox, unable to reach the ListView.


The second step, when we have defined the ListView related program, naturally forget its good base friend: Adapter Adapter

Mycontactadapter.java:

Package Com.example.android_menu_test_demo.adapter;import Java.util.arraylist;import Com.example.android_menu_ Test_demo. R;import Com.example.android_menu_test_demo.domain.contact;import Android.content.context;import Android.view.layoutinflater;import Android.view.view;import Android.view.viewgroup;import Android.widget.baseadapter;import Android.widget.checkbox;import Android.widget.imageview;import Android.widget.textview;public class Mycontactadapter extends Baseadapter {private Context mcontext;private ArrayList <Contact> contacts;private viewholder mviewholder;private arraylist<contact> selected_contacts = new Arraylist<contact> ();p rivate boolean itemmulticheckable;public mycontactadapter (Context mcontext, ArrayList <Contact> contacts) {This.mcontext = Mcontext;this.contacts = Contacts;} @Overridepublic int GetCount () {return contacts.size ();} @Overridepublic Object getItem (int position) {return contacts.get (position);} @Overridepublic long getitemid (int positioN) {return position;} @Overridepublic view GetView (int position, view Convertview, ViewGroup parent) {if (Convertview = = null) {Convertview = La Youtinflater.from (Mcontext). Inflate (R.layout.contact_listview_item, null); Mviewholder = new Viewholder (); Mviewholder.user_head = (ImageView) Convertview.findviewbyid (r.id.user_head); mviewholder.user_name_text = (TextView ) Convertview.findviewbyid (r.id.user_name); mviewholder.phone_number_text = (TextView) Convertview.findviewbyid ( R.id.phone_number); mviewholder.item_seleted = (CheckBox) Convertview.findviewbyid (R.id.contact_selected_checkbox) ; Convertview.settag (Mviewholder);} else {Mviewholder = (Viewholder) Convertview.gettag ();} For detailed handling of the control ****************//set whether the checkbox is visible if (itemmulticheckable) {mviewholder.item_ Seleted.setvisibility (view.visible);//Assume the checkbox is visible. If you are currently in a multi-select operation, the checkbox is selected according to user selection if (selected_contacts.contains (contacts.get (position))) {Mviewholder.item _seleted.setchecked (TRUE);} else {Mviewholder.item_seleted.sEtchecked (FALSE);}} else {mViewHolder.item_seleted.setVisibility (view.gone);} Control Assignment Contact Contact = contacts.get (position); MViewHolder.user_name_text.setText (Contact.getusername ()); MViewHolder.phone_number_text.setText (Contact.getphonenumber ()); return Convertview;} public void Setitemmulticheckable (Boolean flag) {itemmulticheckable = flag;} public void addselectedcontact (int position) {Selected_contacts.add (Contacts.get (position));} public void cancelseletedcontact (int position) {Selected_contacts.remove (Contacts.get (position));} public void Clearseletedcontacts () {selected_contacts = new arraylist<contact> ();} public void Deleteseletedcontacts () {to (contact contact:selected_contacts) {contacts.remove (contact);}} Static class Viewholder {ImageView user_head; TextView User_name_text, Phone_number_text; CheckBox item_seleted;}}

The definition of the adapter class is not much different from the most common definition of our development.

Notable code is nothing more than the previous one, do a good job of dynamic control checkbox display state.

In addition, we are in the definition of the adapter, in order to let the ListView to display the data, more convenient for loading and delivery.

The entity class that encapsulates the data is typically defined, as in the contact class above. Just this is too simple, there is no need to put the code.


Next. Is the focus of the functionality we want to achieve,

We talked about the desire to trigger a context menu for event handling via the ListView's long Click event.

After Android 3.0, add the Actionmode relative to the previous normal context menu.

Obviously more suitable for batch event processing. Have a better interaction experience.


So. Now that you're going to use the context menu,. Say less nonsense.

First define a simple menu file that we need:

Multi_acitonmode_menu.xml:

<?xml version= "1.0" encoding= "Utf-8"?

><menu xmlns:android= "Http://schemas.android.com/apk/res/android" > <item android:id= "@+id/ Menu_cancle " android:showasaction=" always " android:title=" @string/item_cancle "/> <item Android:id= "@+id/menu_delete" android:showasaction= "always" android:title= "@string/item_delete"/> </menu>


Immediately after that, we were all ready to work,

So the next thing to do. Nature is the work of coding the activity.

Contextmenuactionmodeactivity.java

Package Com.example.android_menu_test_demo;import Android.view.actionmode;import Android.view.LayoutInflater; Import Android.view.menu;import android.view.menuitem;import android.view.view;import Android.widget.ListView; Import Android.widget.textview;import Android.widget.abslistview.multichoicemodelistener;import Java.util.arraylist;import Com.example.android_menu_test_demo.adapter.mycontactadapter;import Com.example.android_menu_test_demo.domain.contact;import Android.annotation.targetapi;import Android.app.activity;import Android.app.progressdialog;import Android.os.asynctask;import Android.os.Build;import Android.os.Bundle; the @TargetApi (build.version_codes. Honeycomb) public class Contextmenuactionmodeactivity extends Activity {private ListView contact_list_view;private ProgressDialog mdialog;private mycontactadapter madpater;private multimodecallback mCallback;//analog Data Private ArrayList <Contact> contacts;private string[] userNames = new string[] {"Jack", "Rose", "Matt", "Adam", "XtIna "," Blake "," Tupac "," Biggie "," T.i "," Eminem "};p rivate string[] phonenumbers = new string[] {" 138-0000-0001 "," 138-00 00-0002 "," 138-0000-0003 "," 138-0000-0004 "," 138-0000-0005 "," 138-0000-0006 "," 138-0000-0007 "," 138-0000-0008 "," 138-0000-0009 "," 138-0000-0010 "}; @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate ( Savedinstancestate); Setcontentview (R.layout.context_menu_action_mode); Initview (); new Contactsdownloadtask (). Execute ();} private void Initview () {Contact_list_view = (ListView) This.findviewbyid (r.id.context_menu_listview); mdialog = new ProgressDialog (this); Mdialog.settitle ("Prompt Message"), Mdialog.setmessage ("Download contact list ..."); Mdialog.setprogressstyle ( Progressdialog.style_horizontal); mcallback = new Multimodecallback (); Contact_list_view.setchoicemode ( Listview.choice_mode_multiple_modal); Contact_list_view.setmultichoicemodelistener (mCallback);} private void Downloadcontactsfromserver () {if (contacts = = null) {contacts = new arraylist<contact> ();} for (int i = 0; i < usernames.length; i++) {Contacts.add (new contact (Usernames[i], phonenumbers[i]);}} Private class Contactsdownloadtask extends Asynctask<void, Integer, void> {private int currentlyprogressvalue;@ overrideprotected void OnPreExecute () {mdialog.show (); Super.onpreexecute ();} @Overrideprotected void Doinbackground (void ... params) {while (Currentlyprogressvalue <) {Publishprogress (+ +) Currentlyprogressvalue); try {thread.sleep;} catch (Interruptedexception e) {e.printstacktrace ()}} Download data from Serverdownloadcontactsfromserver (); return null;} @Overrideprotected void Onprogressupdate (Integer ... values) {super.onprogressupdate (values); Mdialog.setprogress ( Values[0]);} @Overrideprotected void OnPostExecute (void result) {Super.onpostexecute (result); madpater = new Mycontactadapter ( Contextmenuactionmodeactivity.this, Contacts); Contact_list_view.setadapter (Madpater); Mdialog.dismiss ();}} Private class Multimodecallback implements Multichoicemodelistener {private View MmulTiselectactionbarview;private TextView Mselectedcount; @Overridepublic boolean oncreateactionmode (Actionmode mode, Menu menu) {mode.getmenuinflater (). Inflate (R.menu.multi_acitonmode_menu, menu); Madpater.setitemmulticheckable ( true); madpater.notifydatasetchanged (); if (Mmultiselectactionbarview = = null) {Mmultiselectactionbarview = Layoutinflater.from (Contextmenuactionmodeactivity.this). Inflate (R.layout.list_multi_select_actionbar, NULL); Mselectedcount = (TextView) Mmultiselectactionbarview.findviewbyid (r.id.selected_conv_count);} Mode.setcustomview (Mmultiselectactionbarview);((TextView) Mmultiselectactionbarview.findviewbyid (R.id.title)). SetText (R.string.select_item); return true;} @Overridepublic boolean Onprepareactionmode (Actionmode mode, menu menu) {//TODO auto-generated method Stubreturn false;} @Overridepublic boolean onactionitemclicked (actionmode mode, MenuItem Item) {switch (Item.getitemid ()) {case R.id.menu_ Cancle:mAdpater.setItemMultiCheckable (false); Madpater.clearseletedcontacts (); madpater.notifydatasetchanged (); Mode.finish (); break;case r.id.menu_delete:madpater.deleteseletedcontacts (); Madpater.notifydatasetchanged (); Mode.invalidate (); Mode.finish (); break;default:break;} return false;} @Overridepublic void Ondestroyactionmode (Actionmode mode) {madpater.setitemmulticheckable (false); Madpater.clearseletedcontacts (); madpater.notifydatasetchanged ();} @Overridepublic void onitemcheckedstatechanged (actionmode mode, int position, long ID, Boolean checked) {if (checked) {MAd Pater.addselectedcontact (position);} else {madpater.cancelseletedcontact (position);} Madpater.notifydatasetchanged (); Updateseletedcount (); Mode.invalidate ();} public void Updateseletedcount () {Mselectedcount.settext (integer.tostring (Contact_list_view.getcheckeditemcount () ) + "Bar");}}}

For the rookie of us, the above activity code may be notable:

1, basically, we will first define an asynchronous task class. Simulates the process of downloading data from the network. Helps to master the use of adapter APIs.

2, we defined in the code above the implementation of the Multichoicemodelistener interface of the inner class, Multimodecallback is to help us to implement long press the ListView (also tried for the GridView). And listening to the key to handling Multichoice events.

-Simply speaking, you can see. In the callback method Oncreateactionmode of the inner class, we handle the Actionmode menu-related creation work after long pressing the ListView. And in this control the checkbox in the ListView displays, informing the user that we have entered into a mode capable of bulk operation.

The-onactionitemclicked method is used to listen to and respond to the click events of the corresponding options on the menu, where you can write response codes for the corresponding menu options based on your needs.

The-ondestroyactionmode method is used to handle the action to be run when the menu is destroyed.

-The onitemcheckedstatechanged rule is used to listen for callbacks when the selected state of each list item in the ListView is changed. We will be here according to the need to complete the corresponding coding work.

3, to here, we want to the realization of the function, can say that has been basically done. However, you may have noticed some of the code in the Multimodecallback class above:

For a more friendly interactive feel, we can also be in the form of Actionbar. On the menu bar, add a section of content. As used in the text messaging feature, the user is prompted with a message similar to "You have selected XX content now". So we'll also define a layout file similar to Actionbar. For example, the following:

List_multi_select_actionbar.xml:

<linearlayout    xmlns:android= "http://schemas.android.com/apk/res/android"    android:id= "@+id/custom_ Title_root "    android:layout_width=" match_parent "    android:layout_height=" match_parent "    android:o rientation= "Horizontal" >    <textview        android:id= "@+id/title" android:layout_gravity= "Center_        Vertical "        android:layout_height=" wrap_content "        android:layout_width=" Wrap_content "        android: Textcolor= "#ffffff"/>    <textview        android:id= "@+id/selected_conv_count"        android:layout_ Gravity= "center_vertical"        android:layout_width= "wrap_content"        android:layout_height= "Wrap_content"         android:textcolor= "#ffffff"/></linearlayout>

In the above code, you can see that we are the same at the same time that we finished loading the Actionmode context menu in the Oncreateactionmode method, as well as the load and display control work for the view that is used as the Actionbar.

After the view loading and display work is finished, we have to do is very easy, just need to listen in onitemcheckedstatechanged, when the user selects a list item, the display of the TextView to display the prompt information is updated, It's OK.


Go to this step, we can say is already cottage completed, the next thing to do is to be able to compile the demo to the simulator or mobile phone, see the effect ~


Android-Long Press the ListView to use the context menu (Actionmode) for bulk event processing

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.