├── .gitignore ├── README.md ├── app ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── codepath │ │ └── example │ │ └── menuspopupsdialogsdemo │ │ ├── CustomAlertDialogFragment.java │ │ ├── EditNameDialog.java │ │ └── MainActivity.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── drawable │ └── popup_bg.9.png │ ├── layout │ ├── activity_main.xml │ ├── fragment_edit_name.xml │ └── popup_window.xml │ ├── menu │ ├── main.xml │ ├── menu_item.xml │ └── popup_menu.xml │ ├── values-v11 │ └── styles.xml │ ├── values-v14 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Source: https://gist.github.com/nesquena/5617544/raw/53710b374e7df3302df43b552488d876040ada3d/.gitignore 2 | 3 | # built application files 4 | *.apk 5 | *.ap_ 6 | 7 | # files for the dex VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # generated files 14 | bin/ 15 | gen/ 16 | 17 | # Local configuration file (sdk path, etc) 18 | local.properties 19 | 20 | # Eclipse project files 21 | .classpath 22 | .project 23 | 24 | # Proguard folder generated by Eclipse 25 | proguard/ 26 | proguard-project.txt 27 | 28 | # Intellij project files 29 | *.iml 30 | *.ipr 31 | *.iws 32 | .idea/ 33 | 34 | *.pydevproject 35 | .project 36 | .metadata 37 | bin/** 38 | tmp/** 39 | tmp/**/* 40 | *.tmp 41 | *.bak 42 | *.swp 43 | *~.nib 44 | local.properties 45 | .classpath 46 | .settings/ 47 | .loadpath 48 | 49 | # External tool builders 50 | .externalToolBuilders/ 51 | 52 | # Locally stored "Eclipse launch configurations" 53 | *.launch 54 | 55 | # CDT-specific 56 | .cproject 57 | 58 | # PDT-specific 59 | .buildpath 60 | 61 | # Android Studio project files 62 | *.iml 63 | .gradle 64 | .idea 65 | build 66 | import-summary.txt 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Menus + Popups + Dialogs Demo 2 | 3 | Android demo of menus, popups and dialogs. See the [Menus and Popups](http://guides.thecodepath.com/android/Menus-and-Popups) cliffnotes for more details. 4 | 5 | Features: 6 | 7 | * Displaying a custom dialog with layout content 8 | * Displaying a custom dialog with alert builder 9 | * Displaying a popup menu to show secondary actions 10 | * Displaying a popup window for a tooltip 11 | * Enabling contextual action modes for list items 12 | 13 | Screens: 14 | 15 |   16 |   17 |   18 |   19 |   20 |   21 | 22 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 19 5 | buildToolsVersion "21.1.2" 6 | 7 | defaultConfig { 8 | applicationId "com.codepath.example.menuspopupsdialogsdemo" 9 | minSdkVersion 14 10 | targetSdkVersion 19 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile 'com.android.support:support-v4:19.1.0' 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/example/menuspopupsdialogsdemo/CustomAlertDialogFragment.java: -------------------------------------------------------------------------------- 1 | package com.codepath.example.menuspopupsdialogsdemo; 2 | 3 | import android.app.AlertDialog; 4 | import android.app.Dialog; 5 | import android.content.DialogInterface; 6 | import android.os.Bundle; 7 | import android.support.v4.app.DialogFragment; 8 | 9 | public class CustomAlertDialogFragment extends DialogFragment { 10 | public interface CustomAlertListener { 11 | void onOKButton(); 12 | void onCancelButton(); 13 | } 14 | 15 | private CustomAlertListener listener; 16 | 17 | public CustomAlertDialogFragment() { 18 | // Empty constructor required for DialogFragment 19 | } 20 | 21 | public static CustomAlertDialogFragment newInstance(String title) { 22 | CustomAlertDialogFragment frag = new CustomAlertDialogFragment(); 23 | Bundle args = new Bundle(); 24 | args.putString("title", title); 25 | frag.setArguments(args); 26 | return frag; 27 | } 28 | 29 | @Override 30 | public Dialog onCreateDialog(Bundle savedInstanceState) { 31 | String title = getArguments().getString("title"); 32 | AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity()); 33 | alertDialogBuilder.setTitle(title); 34 | alertDialogBuilder.setMessage("Are you sure?"); 35 | listener = (CustomAlertListener) getActivity(); 36 | alertDialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() { 37 | @Override 38 | public void onClick(DialogInterface dialog, int which) { 39 | listener.onOKButton(); 40 | dialog.dismiss(); 41 | } 42 | }); 43 | alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 44 | @Override 45 | public void onClick(DialogInterface dialog, int which) { 46 | listener.onCancelButton(); 47 | dialog.dismiss(); 48 | } 49 | }); 50 | return alertDialogBuilder.create(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/example/menuspopupsdialogsdemo/EditNameDialog.java: -------------------------------------------------------------------------------- 1 | package com.codepath.example.menuspopupsdialogsdemo; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.DialogFragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.View.OnClickListener; 8 | import android.view.ViewGroup; 9 | import android.view.WindowManager; 10 | import android.widget.Button; 11 | import android.widget.EditText; 12 | 13 | public class EditNameDialog extends DialogFragment { 14 | private Button btnSubmit; 15 | private EditText mEditText; 16 | 17 | public interface EditNameDialogListener { 18 | void onFinishEditDialog(String inputText); 19 | } 20 | 21 | public EditNameDialog() { 22 | // Empty constructor required for DialogFragment 23 | } 24 | 25 | public static EditNameDialog newInstance(String title) { 26 | EditNameDialog frag = new EditNameDialog(); 27 | Bundle args = new Bundle(); 28 | args.putString("title", title); 29 | frag.setArguments(args); 30 | return frag; 31 | } 32 | 33 | @Override 34 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 35 | Bundle savedInstanceState) { 36 | View view = inflater.inflate(R.layout.fragment_edit_name, container); 37 | mEditText = (EditText) view.findViewById(R.id.txt_your_name); 38 | btnSubmit = (Button) view.findViewById(R.id.btnSubmit); 39 | btnSubmit.setOnClickListener(new OnClickListener() { 40 | @Override 41 | public void onClick(View v) { 42 | EditNameDialogListener listener = (EditNameDialogListener) getActivity(); 43 | listener.onFinishEditDialog(mEditText.getText().toString()); 44 | dismiss(); 45 | } 46 | }); 47 | String title = getArguments().getString("title", "Enter Name"); 48 | getDialog().setTitle(title); 49 | // Show soft keyboard automatically 50 | mEditText.requestFocus(); 51 | getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); 52 | return view; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/example/menuspopupsdialogsdemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.codepath.example.menuspopupsdialogsdemo; 2 | 3 | import java.util.ArrayList; 4 | 5 | import android.graphics.drawable.BitmapDrawable; 6 | import android.os.Bundle; 7 | import android.support.v4.app.FragmentActivity; 8 | import android.support.v4.app.FragmentManager; 9 | import android.view.ActionMode; 10 | import android.view.Menu; 11 | import android.view.MenuItem; 12 | import android.view.View; 13 | import android.view.WindowManager; 14 | import android.widget.AdapterView; 15 | import android.widget.ArrayAdapter; 16 | import android.widget.ListView; 17 | import android.widget.PopupMenu; 18 | import android.widget.PopupWindow; 19 | import android.widget.Toast; 20 | 21 | import com.codepath.example.menuspopupsdialogsdemo.CustomAlertDialogFragment.CustomAlertListener; 22 | import com.codepath.example.menuspopupsdialogsdemo.EditNameDialog.EditNameDialogListener; 23 | 24 | public class MainActivity extends FragmentActivity implements EditNameDialogListener, 25 | CustomAlertListener { 26 | 27 | private ArrayList items; 28 | private ArrayAdapter adapterItems; 29 | 30 | @Override 31 | protected void onCreate(Bundle savedInstanceState) { 32 | super.onCreate(savedInstanceState); 33 | setContentView(R.layout.activity_main); 34 | populateListView(); 35 | } 36 | 37 | public void populateListView() { 38 | items = new ArrayList(); 39 | items.add("First"); 40 | items.add("Second"); 41 | items.add("Third"); 42 | items.add("Fourth"); 43 | items.add("Fifth"); 44 | adapterItems = new ArrayAdapter(this, 45 | android.R.layout.simple_list_item_1, items); 46 | ListView lvItems = (ListView) findViewById(R.id.lvItems); 47 | lvItems.setAdapter(adapterItems); 48 | // Setup contextual action mode when item is clicked 49 | lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() { 50 | public void onItemClick(AdapterView parent, View view, int position, long id) { 51 | if (currentActionMode != null) { return; } 52 | currentListItemIndex = position; 53 | currentActionMode = startActionMode(modeCallBack); 54 | view.setSelected(true); 55 | } 56 | }); 57 | } 58 | 59 | public void onShowDialogWindow(View v) { 60 | FragmentManager fm = getSupportFragmentManager(); 61 | EditNameDialog editNameDialog = EditNameDialog.newInstance("Type your name"); 62 | editNameDialog.show(fm, "fragment_edit_name"); 63 | } 64 | 65 | public void onShowAlertDialog(View v) { 66 | FragmentManager fm = getSupportFragmentManager(); 67 | CustomAlertDialogFragment alertDialog = CustomAlertDialogFragment.newInstance("Some title"); 68 | alertDialog.show(fm, "fragment_alert"); 69 | } 70 | 71 | public void onShowPopupWindow(View v) { 72 | PopupWindow popup = new PopupWindow(MainActivity.this); 73 | View layout = getLayoutInflater().inflate(R.layout.popup_window, null); 74 | popup.setContentView(layout); 75 | // Set content width and height 76 | popup.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); 77 | popup.setWidth(WindowManager.LayoutParams.WRAP_CONTENT); 78 | // Closes the popup window when touch outside of it - when looses focus 79 | popup.setOutsideTouchable(true); 80 | popup.setFocusable(true); 81 | // Show anchored to button 82 | popup.setBackgroundDrawable(new BitmapDrawable()); 83 | popup.showAsDropDown(v); 84 | } 85 | 86 | public void onShowPopupMenu(View v) { 87 | PopupMenu popup = new PopupMenu(this, v); 88 | // Inflate the menu from xml 89 | popup.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu()); 90 | // Setup menu item selection 91 | popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { 92 | public boolean onMenuItemClick(MenuItem item) { 93 | switch (item.getItemId()) { 94 | case R.id.menu_more: 95 | Toast.makeText(MainActivity.this, "More!", Toast.LENGTH_SHORT).show(); 96 | return true; 97 | case R.id.menu_hide: 98 | Toast.makeText(MainActivity.this, "Hide!", Toast.LENGTH_SHORT).show(); 99 | return true; 100 | default: 101 | return false; 102 | } 103 | } 104 | }); 105 | // Show the menu 106 | popup.show(); 107 | } 108 | 109 | @Override 110 | public boolean onCreateOptionsMenu(Menu menu) { 111 | // Inflate the menu; this adds items to the action bar if it is present. 112 | getMenuInflater().inflate(R.menu.main, menu); 113 | return true; 114 | } 115 | 116 | @Override 117 | public boolean onOptionsItemSelected(MenuItem item) { 118 | int id = item.getItemId(); 119 | if (id == R.id.action_settings) { 120 | return true; 121 | } 122 | return super.onOptionsItemSelected(item); 123 | } 124 | 125 | @Override 126 | public void onFinishEditDialog(String inputText) { 127 | Toast.makeText(this, "Your name is: " + inputText, Toast.LENGTH_SHORT).show(); 128 | } 129 | 130 | @Override 131 | public void onOKButton() { 132 | Toast.makeText(this, "Pressed OK!", Toast.LENGTH_SHORT).show(); 133 | } 134 | 135 | @Override 136 | public void onCancelButton() { 137 | Toast.makeText(this, "Pressed Cancel!", Toast.LENGTH_SHORT).show(); 138 | } 139 | 140 | // Tracks current contextual action mode 141 | private ActionMode currentActionMode; 142 | // Tracks current menu item 143 | private int currentListItemIndex; 144 | // Define the callback when ActionMode is activated 145 | private ActionMode.Callback modeCallBack = new ActionMode.Callback() { 146 | // Called when the action mode is created; startActionMode() was called 147 | @Override 148 | public boolean onCreateActionMode(ActionMode mode, Menu menu) { 149 | mode.setTitle("Remove Item"); 150 | mode.getMenuInflater().inflate(R.menu.menu_item, menu); 151 | return true; 152 | } 153 | 154 | // Called each time the action mode is shown. 155 | @Override 156 | public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 157 | return false; // Return false if nothing is done 158 | } 159 | 160 | // Called when the user selects a contextual menu item 161 | @Override 162 | public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 163 | switch (item.getItemId()) { 164 | case R.id.menu_delete: 165 | items.remove(currentListItemIndex); 166 | adapterItems.notifyDataSetChanged(); 167 | mode.finish(); // Action picked, so close the contextual menu 168 | return true; 169 | default: 170 | return false; 171 | } 172 | } 173 | 174 | // Called when the user exits the action mode 175 | @Override 176 | public void onDestroyActionMode(ActionMode mode) { 177 | currentActionMode = null; // Clear current action mode 178 | } 179 | }; 180 | 181 | } 182 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-menus-popups-dialogs-demo/8bb98776ec186641d0e38f0239a580ec88002b99/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-menus-popups-dialogs-demo/8bb98776ec186641d0e38f0239a580ec88002b99/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-menus-popups-dialogs-demo/8bb98776ec186641d0e38f0239a580ec88002b99/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-menus-popups-dialogs-demo/8bb98776ec186641d0e38f0239a580ec88002b99/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/popup_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-menus-popups-dialogs-demo/8bb98776ec186641d0e38f0239a580ec88002b99/app/src/main/res/drawable/popup_bg.9.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 |