From 4ee94ba0f17d60fd0bc7470cea9c26e27d71f803 Mon Sep 17 00:00:00 2001 From: Bartek Przybylski Date: Wed, 24 Oct 2012 00:06:38 +0200 Subject: [PATCH] revert of 5ffdcdd25ebc2d08dc48b0d62ff906fbf16fdc59 --- .gitmodules | 3 + actionbarsherlock | 1 + actionbarsherlock/.classpath | 8 - actionbarsherlock/AndroidManifest.xml | 6 - actionbarsherlock/README.md | 15 - actionbarsherlock/build.xml | 92 - actionbarsherlock/libs/android-support-v4.jar | Bin 271754 -> 0 bytes actionbarsherlock/pom.xml | 148 -- actionbarsherlock/proguard-project.txt | 20 - actionbarsherlock/project.properties | 12 - .../abs__primary_text_disable_only_holo_dark.xml | 20 - .../abs__primary_text_disable_only_holo_light.xml | 21 - .../res/color/abs__primary_text_holo_dark.xml | 24 - .../res/color/abs__primary_text_holo_light.xml | 26 - .../abs__ab_bottom_solid_dark_holo.9.png | Bin 144 -> 0 bytes .../abs__ab_bottom_solid_inverse_holo.9.png | Bin 138 -> 0 bytes .../abs__ab_bottom_solid_light_holo.9.png | Bin 144 -> 0 bytes .../abs__ab_bottom_transparent_dark_holo.9.png | Bin 135 -> 0 bytes .../abs__ab_bottom_transparent_light_holo.9.png | Bin 134 -> 0 bytes .../abs__ab_share_pack_holo_dark.9.png | Bin 2863 -> 0 bytes .../abs__ab_share_pack_holo_light.9.png | Bin 2859 -> 0 bytes .../drawable-hdpi/abs__ab_solid_dark_holo.9.png | Bin 146 -> 0 bytes .../drawable-hdpi/abs__ab_solid_light_holo.9.png | Bin 145 -> 0 bytes .../drawable-hdpi/abs__ab_solid_shadow_holo.9.png | Bin 192 -> 0 bytes .../abs__ab_stacked_solid_dark_holo.9.png | Bin 146 -> 0 bytes .../abs__ab_stacked_solid_light_holo.9.png | Bin 146 -> 0 bytes .../abs__ab_stacked_transparent_dark_holo.9.png | Bin 139 -> 0 bytes .../abs__ab_stacked_transparent_light_holo.9.png | Bin 133 -> 0 bytes .../abs__ab_transparent_dark_holo.9.png | Bin 155 -> 0 bytes .../abs__ab_transparent_light_holo.9.png | Bin 145 -> 0 bytes .../abs__btn_cab_done_default_holo_dark.9.png | Bin 104 -> 0 bytes .../abs__btn_cab_done_default_holo_light.9.png | Bin 102 -> 0 bytes .../abs__btn_cab_done_focused_holo_dark.9.png | Bin 112 -> 0 bytes .../abs__btn_cab_done_focused_holo_light.9.png | Bin 108 -> 0 bytes .../abs__btn_cab_done_pressed_holo_dark.9.png | Bin 110 -> 0 bytes .../abs__btn_cab_done_pressed_holo_light.9.png | Bin 108 -> 0 bytes .../abs__cab_background_bottom_holo_dark.9.png | Bin 149 -> 0 bytes .../abs__cab_background_bottom_holo_light.9.png | Bin 145 -> 0 bytes .../abs__cab_background_top_holo_dark.9.png | Bin 147 -> 0 bytes .../abs__cab_background_top_holo_light.9.png | Bin 147 -> 0 bytes .../drawable-hdpi/abs__dialog_full_holo_dark.9.png | Bin 1414 -> 0 bytes .../abs__dialog_full_holo_light.9.png | Bin 1537 -> 0 bytes .../drawable-hdpi/abs__ic_ab_back_holo_dark.png | Bin 602 -> 0 bytes .../drawable-hdpi/abs__ic_ab_back_holo_light.png | Bin 546 -> 0 bytes .../drawable-hdpi/abs__ic_cab_done_holo_dark.png | Bin 713 -> 0 bytes .../drawable-hdpi/abs__ic_cab_done_holo_light.png | Bin 737 -> 0 bytes .../res/drawable-hdpi/abs__ic_clear_disabled.png | Bin 1774 -> 0 bytes .../res/drawable-hdpi/abs__ic_clear_normal.png | Bin 1945 -> 0 bytes ...bs__ic_clear_search_api_disabled_holo_light.png | Bin 1504 -> 0 bytes .../abs__ic_clear_search_api_holo_light.png | Bin 1540 -> 0 bytes actionbarsherlock/res/drawable-hdpi/abs__ic_go.png | Bin 1415 -> 0 bytes .../abs__ic_go_search_api_holo_light.png | Bin 1252 -> 0 bytes .../abs__ic_menu_moreoverflow_normal_holo_dark.png | Bin 144 -> 0 bytes ...abs__ic_menu_moreoverflow_normal_holo_light.png | Bin 148 -> 0 bytes .../drawable-hdpi/abs__ic_menu_share_holo_dark.png | Bin 467 -> 0 bytes .../abs__ic_menu_share_holo_light.png | Bin 505 -> 0 bytes .../res/drawable-hdpi/abs__ic_search.png | Bin 2280 -> 0 bytes .../abs__ic_search_api_holo_light.png | Bin 2271 -> 0 bytes .../res/drawable-hdpi/abs__ic_voice_search.png | Bin 2070 -> 0 bytes .../abs__ic_voice_search_api_holo_light.png | Bin 1833 -> 0 bytes .../drawable-hdpi/abs__list_activated_holo.9.png | Bin 154 -> 0 bytes .../abs__list_divider_holo_dark.9.png | Bin 78 -> 0 bytes .../abs__list_divider_holo_light.9.png | Bin 76 -> 0 bytes .../res/drawable-hdpi/abs__list_focused_holo.9.png | Bin 159 -> 0 bytes .../drawable-hdpi/abs__list_longpressed_holo.9.png | Bin 154 -> 0 bytes .../abs__list_pressed_holo_dark.9.png | Bin 159 -> 0 bytes .../abs__list_pressed_holo_light.9.png | Bin 159 -> 0 bytes .../abs__list_selector_disabled_holo_dark.9.png | Bin 189 -> 0 bytes .../abs__list_selector_disabled_holo_light.9.png | Bin 189 -> 0 bytes .../abs__menu_dropdown_panel_holo_dark.9.png | Bin 922 -> 0 bytes .../abs__menu_dropdown_panel_holo_light.9.png | Bin 1061 -> 0 bytes .../drawable-hdpi/abs__progress_bg_holo_dark.9.png | Bin 178 -> 0 bytes .../abs__progress_bg_holo_light.9.png | Bin 174 -> 0 bytes .../abs__progress_primary_holo_dark.9.png | Bin 917 -> 0 bytes .../abs__progress_primary_holo_light.9.png | Bin 917 -> 0 bytes .../abs__progress_secondary_holo_dark.9.png | Bin 188 -> 0 bytes .../abs__progress_secondary_holo_light.9.png | Bin 188 -> 0 bytes .../drawable-hdpi/abs__spinner_48_inner_holo.png | Bin 2081 -> 0 bytes .../drawable-hdpi/abs__spinner_48_outer_holo.png | Bin 1811 -> 0 bytes .../abs__spinner_ab_default_holo_dark.9.png | Bin 311 -> 0 bytes .../abs__spinner_ab_default_holo_light.9.png | Bin 312 -> 0 bytes .../abs__spinner_ab_disabled_holo_dark.9.png | Bin 306 -> 0 bytes .../abs__spinner_ab_disabled_holo_light.9.png | Bin 306 -> 0 bytes .../abs__spinner_ab_focused_holo_dark.9.png | Bin 524 -> 0 bytes .../abs__spinner_ab_focused_holo_light.9.png | Bin 523 -> 0 bytes .../abs__spinner_ab_pressed_holo_dark.9.png | Bin 464 -> 0 bytes .../abs__spinner_ab_pressed_holo_light.9.png | Bin 458 -> 0 bytes .../abs__tab_selected_focused_holo.9.png | Bin 147 -> 0 bytes .../res/drawable-hdpi/abs__tab_selected_holo.9.png | Bin 148 -> 0 bytes .../abs__tab_selected_pressed_holo.9.png | Bin 147 -> 0 bytes .../abs__tab_unselected_pressed_holo.9.png | Bin 145 -> 0 bytes .../abs__textfield_search_default_holo_dark.9.png | Bin 110 -> 0 bytes .../abs__textfield_search_default_holo_light.9.png | Bin 105 -> 0 bytes ..._textfield_search_right_default_holo_dark.9.png | Bin 108 -> 0 bytes ...textfield_search_right_default_holo_light.9.png | Bin 103 -> 0 bytes ...textfield_search_right_selected_holo_dark.9.png | Bin 114 -> 0 bytes ...extfield_search_right_selected_holo_light.9.png | Bin 111 -> 0 bytes .../abs__textfield_search_selected_holo_dark.9.png | Bin 114 -> 0 bytes ...abs__textfield_search_selected_holo_light.9.png | Bin 112 -> 0 bytes .../abs__ab_bottom_solid_dark_holo.9.png | Bin 134 -> 0 bytes .../abs__ab_bottom_solid_inverse_holo.9.png | Bin 129 -> 0 bytes .../abs__ab_bottom_solid_light_holo.9.png | Bin 134 -> 0 bytes .../abs__ab_bottom_transparent_dark_holo.9.png | Bin 123 -> 0 bytes .../abs__ab_bottom_transparent_light_holo.9.png | Bin 123 -> 0 bytes .../abs__ab_share_pack_holo_dark.9.png | Bin 2849 -> 0 bytes .../abs__ab_share_pack_holo_light.9.png | Bin 191 -> 0 bytes .../drawable-mdpi/abs__ab_solid_dark_holo.9.png | Bin 133 -> 0 bytes .../drawable-mdpi/abs__ab_solid_light_holo.9.png | Bin 133 -> 0 bytes .../drawable-mdpi/abs__ab_solid_shadow_holo.9.png | Bin 168 -> 0 bytes .../abs__ab_stacked_solid_dark_holo.9.png | Bin 134 -> 0 bytes .../abs__ab_stacked_solid_light_holo.9.png | Bin 133 -> 0 bytes .../abs__ab_stacked_transparent_dark_holo.9.png | Bin 127 -> 0 bytes .../abs__ab_stacked_transparent_light_holo.9.png | Bin 123 -> 0 bytes .../abs__ab_transparent_dark_holo.9.png | Bin 139 -> 0 bytes .../abs__ab_transparent_light_holo.9.png | Bin 133 -> 0 bytes .../abs__btn_cab_done_default_holo_dark.9.png | Bin 101 -> 0 bytes .../abs__btn_cab_done_default_holo_light.9.png | Bin 99 -> 0 bytes .../abs__btn_cab_done_focused_holo_dark.9.png | Bin 109 -> 0 bytes .../abs__btn_cab_done_focused_holo_light.9.png | Bin 105 -> 0 bytes .../abs__btn_cab_done_pressed_holo_dark.9.png | Bin 107 -> 0 bytes .../abs__btn_cab_done_pressed_holo_light.9.png | Bin 105 -> 0 bytes .../abs__cab_background_bottom_holo_dark.9.png | Bin 127 -> 0 bytes .../abs__cab_background_bottom_holo_light.9.png | Bin 124 -> 0 bytes .../abs__cab_background_top_holo_dark.9.png | Bin 130 -> 0 bytes .../abs__cab_background_top_holo_light.9.png | Bin 128 -> 0 bytes .../drawable-mdpi/abs__dialog_full_holo_dark.9.png | Bin 882 -> 0 bytes .../abs__dialog_full_holo_light.9.png | Bin 1003 -> 0 bytes .../drawable-mdpi/abs__ic_ab_back_holo_dark.png | Bin 466 -> 0 bytes .../drawable-mdpi/abs__ic_ab_back_holo_light.png | Bin 438 -> 0 bytes .../drawable-mdpi/abs__ic_cab_done_holo_dark.png | Bin 566 -> 0 bytes .../drawable-mdpi/abs__ic_cab_done_holo_light.png | Bin 552 -> 0 bytes .../res/drawable-mdpi/abs__ic_clear_disabled.png | Bin 1775 -> 0 bytes .../res/drawable-mdpi/abs__ic_clear_normal.png | Bin 1869 -> 0 bytes ...bs__ic_clear_search_api_disabled_holo_light.png | Bin 740 -> 0 bytes .../abs__ic_clear_search_api_holo_light.png | Bin 743 -> 0 bytes actionbarsherlock/res/drawable-mdpi/abs__ic_go.png | Bin 1538 -> 0 bytes .../abs__ic_go_search_api_holo_light.png | Bin 570 -> 0 bytes .../abs__ic_menu_moreoverflow_normal_holo_dark.png | Bin 122 -> 0 bytes ...abs__ic_menu_moreoverflow_normal_holo_light.png | Bin 131 -> 0 bytes .../drawable-mdpi/abs__ic_menu_share_holo_dark.png | Bin 332 -> 0 bytes .../abs__ic_menu_share_holo_light.png | Bin 355 -> 0 bytes .../res/drawable-mdpi/abs__ic_search.png | Bin 2280 -> 0 bytes .../abs__ic_search_api_holo_light.png | Bin 1541 -> 0 bytes .../res/drawable-mdpi/abs__ic_voice_search.png | Bin 1937 -> 0 bytes .../abs__ic_voice_search_api_holo_light.png | Bin 794 -> 0 bytes .../drawable-mdpi/abs__list_activated_holo.9.png | Bin 151 -> 0 bytes .../abs__list_divider_holo_dark.9.png | Bin 78 -> 0 bytes .../abs__list_divider_holo_light.9.png | Bin 76 -> 0 bytes .../res/drawable-mdpi/abs__list_focused_holo.9.png | Bin 158 -> 0 bytes .../drawable-mdpi/abs__list_longpressed_holo.9.png | Bin 151 -> 0 bytes .../abs__list_pressed_holo_dark.9.png | Bin 158 -> 0 bytes .../abs__list_pressed_holo_light.9.png | Bin 158 -> 0 bytes .../abs__list_selector_disabled_holo_dark.9.png | Bin 172 -> 0 bytes .../abs__list_selector_disabled_holo_light.9.png | Bin 171 -> 0 bytes .../abs__menu_dropdown_panel_holo_dark.9.png | Bin 651 -> 0 bytes .../abs__menu_dropdown_panel_holo_light.9.png | Bin 720 -> 0 bytes .../drawable-mdpi/abs__progress_bg_holo_dark.9.png | Bin 165 -> 0 bytes .../abs__progress_bg_holo_light.9.png | Bin 159 -> 0 bytes .../abs__progress_primary_holo_dark.9.png | Bin 572 -> 0 bytes .../abs__progress_primary_holo_light.9.png | Bin 572 -> 0 bytes .../abs__progress_secondary_holo_dark.9.png | Bin 170 -> 0 bytes .../abs__progress_secondary_holo_light.9.png | Bin 170 -> 0 bytes .../drawable-mdpi/abs__spinner_48_inner_holo.png | Bin 1336 -> 0 bytes .../drawable-mdpi/abs__spinner_48_outer_holo.png | Bin 1165 -> 0 bytes .../abs__spinner_ab_default_holo_dark.9.png | Bin 254 -> 0 bytes .../abs__spinner_ab_default_holo_light.9.png | Bin 255 -> 0 bytes .../abs__spinner_ab_disabled_holo_dark.9.png | Bin 249 -> 0 bytes .../abs__spinner_ab_disabled_holo_light.9.png | Bin 249 -> 0 bytes .../abs__spinner_ab_focused_holo_dark.9.png | Bin 417 -> 0 bytes .../abs__spinner_ab_focused_holo_light.9.png | Bin 424 -> 0 bytes .../abs__spinner_ab_pressed_holo_dark.9.png | Bin 370 -> 0 bytes .../abs__spinner_ab_pressed_holo_light.9.png | Bin 370 -> 0 bytes .../abs__tab_selected_focused_holo.9.png | Bin 148 -> 0 bytes .../res/drawable-mdpi/abs__tab_selected_holo.9.png | Bin 151 -> 0 bytes .../abs__tab_selected_pressed_holo.9.png | Bin 150 -> 0 bytes .../abs__tab_unselected_pressed_holo.9.png | Bin 155 -> 0 bytes .../abs__textfield_search_default_holo_dark.9.png | Bin 106 -> 0 bytes .../abs__textfield_search_default_holo_light.9.png | Bin 100 -> 0 bytes ..._textfield_search_right_default_holo_dark.9.png | Bin 105 -> 0 bytes ...textfield_search_right_default_holo_light.9.png | Bin 98 -> 0 bytes ...textfield_search_right_selected_holo_dark.9.png | Bin 107 -> 0 bytes ...extfield_search_right_selected_holo_light.9.png | Bin 107 -> 0 bytes .../abs__textfield_search_selected_holo_dark.9.png | Bin 109 -> 0 bytes ...abs__textfield_search_selected_holo_light.9.png | Bin 109 -> 0 bytes .../res/drawable-v11/abs__progress_medium_holo.xml | 34 - .../abs__ab_bottom_solid_dark_holo.9.png | Bin 165 -> 0 bytes .../abs__ab_bottom_solid_inverse_holo.9.png | Bin 157 -> 0 bytes .../abs__ab_bottom_solid_light_holo.9.png | Bin 166 -> 0 bytes .../abs__ab_bottom_transparent_dark_holo.9.png | Bin 153 -> 0 bytes .../abs__ab_bottom_transparent_light_holo.9.png | Bin 152 -> 0 bytes .../abs__ab_share_pack_holo_dark.9.png | Bin 2878 -> 0 bytes .../abs__ab_share_pack_holo_light.9.png | Bin 2873 -> 0 bytes .../drawable-xhdpi/abs__ab_solid_dark_holo.9.png | Bin 163 -> 0 bytes .../drawable-xhdpi/abs__ab_solid_light_holo.9.png | Bin 163 -> 0 bytes .../drawable-xhdpi/abs__ab_solid_shadow_holo.9.png | Bin 290 -> 0 bytes .../abs__ab_stacked_solid_dark_holo.9.png | Bin 163 -> 0 bytes .../abs__ab_stacked_solid_light_holo.9.png | Bin 163 -> 0 bytes .../abs__ab_stacked_transparent_dark_holo.9.png | Bin 158 -> 0 bytes .../abs__ab_stacked_transparent_light_holo.9.png | Bin 152 -> 0 bytes .../abs__ab_transparent_dark_holo.9.png | Bin 171 -> 0 bytes .../abs__ab_transparent_light_holo.9.png | Bin 160 -> 0 bytes .../abs__btn_cab_done_default_holo_dark.9.png | Bin 109 -> 0 bytes .../abs__btn_cab_done_default_holo_light.9.png | Bin 108 -> 0 bytes .../abs__btn_cab_done_focused_holo_dark.9.png | Bin 112 -> 0 bytes .../abs__btn_cab_done_focused_holo_light.9.png | Bin 113 -> 0 bytes .../abs__btn_cab_done_pressed_holo_dark.9.png | Bin 115 -> 0 bytes .../abs__btn_cab_done_pressed_holo_light.9.png | Bin 113 -> 0 bytes .../abs__cab_background_bottom_holo_dark.9.png | Bin 166 -> 0 bytes .../abs__cab_background_bottom_holo_light.9.png | Bin 161 -> 0 bytes .../abs__cab_background_top_holo_dark.9.png | Bin 174 -> 0 bytes .../abs__cab_background_top_holo_light.9.png | Bin 161 -> 0 bytes .../abs__dialog_full_holo_dark.9.png | Bin 2159 -> 0 bytes .../abs__dialog_full_holo_light.9.png | Bin 2302 -> 0 bytes .../drawable-xhdpi/abs__ic_ab_back_holo_dark.png | Bin 741 -> 0 bytes .../drawable-xhdpi/abs__ic_ab_back_holo_light.png | Bin 661 -> 0 bytes .../drawable-xhdpi/abs__ic_cab_done_holo_dark.png | Bin 970 -> 0 bytes .../drawable-xhdpi/abs__ic_cab_done_holo_light.png | Bin 915 -> 0 bytes .../res/drawable-xhdpi/abs__ic_clear_disabled.png | Bin 2531 -> 0 bytes ...bs__ic_clear_search_api_disabled_holo_light.png | Bin 1315 -> 0 bytes .../abs__ic_clear_search_api_holo_light.png | Bin 1447 -> 0 bytes .../res/drawable-xhdpi/abs__ic_go.png | Bin 1983 -> 0 bytes .../abs__ic_go_search_api_holo_light.png | Bin 836 -> 0 bytes .../abs__ic_menu_moreoverflow_normal_holo_dark.png | Bin 167 -> 0 bytes ...abs__ic_menu_moreoverflow_normal_holo_light.png | Bin 184 -> 0 bytes .../abs__ic_menu_share_holo_dark.png | Bin 699 -> 0 bytes .../abs__ic_menu_share_holo_light.png | Bin 935 -> 0 bytes .../res/drawable-xhdpi/abs__ic_search.png | Bin 3784 -> 0 bytes .../abs__ic_search_api_holo_light.png | Bin 3037 -> 0 bytes .../res/drawable-xhdpi/abs__ic_voice_search.png | Bin 3053 -> 0 bytes .../abs__ic_voice_search_api_holo_light.png | Bin 1414 -> 0 bytes .../drawable-xhdpi/abs__list_activated_holo.9.png | Bin 158 -> 0 bytes .../abs__list_divider_holo_dark.9.png | Bin 83 -> 0 bytes .../abs__list_divider_holo_light.9.png | Bin 83 -> 0 bytes .../drawable-xhdpi/abs__list_focused_holo.9.png | Bin 163 -> 0 bytes .../abs__list_longpressed_holo.9.png | Bin 158 -> 0 bytes .../abs__list_pressed_holo_dark.9.png | Bin 163 -> 0 bytes .../abs__list_pressed_holo_light.9.png | Bin 163 -> 0 bytes .../abs__list_selector_disabled_holo_dark.9.png | Bin 190 -> 0 bytes .../abs__list_selector_disabled_holo_light.9.png | Bin 188 -> 0 bytes .../abs__menu_dropdown_panel_holo_dark.9.png | Bin 1362 -> 0 bytes .../abs__menu_dropdown_panel_holo_light.9.png | Bin 1551 -> 0 bytes .../abs__progress_bg_holo_dark.9.png | Bin 174 -> 0 bytes .../abs__progress_bg_holo_light.9.png | Bin 172 -> 0 bytes .../abs__progress_primary_holo_dark.9.png | Bin 1309 -> 0 bytes .../abs__progress_primary_holo_light.9.png | Bin 1309 -> 0 bytes .../abs__progress_secondary_holo_dark.9.png | Bin 184 -> 0 bytes .../abs__progress_secondary_holo_light.9.png | Bin 184 -> 0 bytes .../drawable-xhdpi/abs__spinner_48_inner_holo.png | Bin 2769 -> 0 bytes .../drawable-xhdpi/abs__spinner_48_outer_holo.png | Bin 2432 -> 0 bytes .../abs__spinner_ab_default_holo_dark.9.png | Bin 395 -> 0 bytes .../abs__spinner_ab_default_holo_light.9.png | Bin 394 -> 0 bytes .../abs__spinner_ab_disabled_holo_dark.9.png | Bin 381 -> 0 bytes .../abs__spinner_ab_disabled_holo_light.9.png | Bin 381 -> 0 bytes .../abs__spinner_ab_focused_holo_dark.9.png | Bin 680 -> 0 bytes .../abs__spinner_ab_focused_holo_light.9.png | Bin 671 -> 0 bytes .../abs__spinner_ab_pressed_holo_dark.9.png | Bin 609 -> 0 bytes .../abs__spinner_ab_pressed_holo_light.9.png | Bin 602 -> 0 bytes .../abs__tab_selected_focused_holo.9.png | Bin 147 -> 0 bytes .../drawable-xhdpi/abs__tab_selected_holo.9.png | Bin 153 -> 0 bytes .../abs__tab_selected_pressed_holo.9.png | Bin 147 -> 0 bytes .../abs__tab_unselected_pressed_holo.9.png | Bin 149 -> 0 bytes .../abs__textfield_search_default_holo_dark.9.png | Bin 126 -> 0 bytes .../abs__textfield_search_default_holo_light.9.png | Bin 126 -> 0 bytes ..._textfield_search_right_default_holo_dark.9.png | Bin 125 -> 0 bytes ...textfield_search_right_default_holo_light.9.png | Bin 127 -> 0 bytes ...textfield_search_right_selected_holo_dark.9.png | Bin 128 -> 0 bytes ...extfield_search_right_selected_holo_light.9.png | Bin 128 -> 0 bytes .../abs__textfield_search_selected_holo_dark.9.png | Bin 114 -> 0 bytes ...abs__textfield_search_selected_holo_light.9.png | Bin 126 -> 0 bytes .../abs__activated_background_holo_dark.xml | 20 - .../abs__activated_background_holo_light.xml | 20 - .../res/drawable/abs__btn_cab_done_holo_dark.xml | 24 - .../res/drawable/abs__btn_cab_done_holo_light.xml | 24 - actionbarsherlock/res/drawable/abs__ic_clear.xml | 22 - .../res/drawable/abs__ic_clear_holo_light.xml | 22 - .../abs__ic_menu_moreoverflow_holo_dark.xml | 18 - .../abs__ic_menu_moreoverflow_holo_light.xml | 18 - .../drawable/abs__item_background_holo_dark.xml | 26 - .../drawable/abs__item_background_holo_light.xml | 26 - ...st_selector_background_transition_holo_dark.xml | 20 - ...t_selector_background_transition_holo_light.xml | 20 - .../res/drawable/abs__list_selector_holo_dark.xml | 27 - .../res/drawable/abs__list_selector_holo_light.xml | 28 - .../abs__progress_horizontal_holo_dark.xml | 32 - .../abs__progress_horizontal_holo_light.xml | 32 - .../res/drawable/abs__progress_medium_holo.xml | 34 - .../res/drawable/abs__search_dropdown_dark.xml | 22 - .../res/drawable/abs__search_dropdown_light.xml | 22 - .../res/drawable/abs__spinner_ab_holo_dark.xml | 25 - .../res/drawable/abs__spinner_ab_holo_light.xml | 25 - .../res/drawable/abs__tab_indicator_ab_holo.xml | 34 - .../abs__textfield_searchview_holo_dark.xml | 22 - .../abs__textfield_searchview_holo_light.xml | 22 - .../abs__textfield_searchview_right_holo_dark.xml | 22 - .../abs__textfield_searchview_right_holo_light.xml | 22 - .../layout-large/abs__action_mode_close_item.xml | 40 - .../layout-v14/sherlock_spinner_dropdown_item.xml | 26 - .../res/layout-v14/sherlock_spinner_item.xml | 26 - .../res/layout-xlarge/abs__screen_action_bar.xml | 50 - .../abs__screen_action_bar_overlay.xml | 49 - .../res/layout/abs__action_bar_home.xml | 38 - .../res/layout/abs__action_bar_tab.xml | 7 - .../res/layout/abs__action_bar_tab_bar_view.xml | 6 - .../res/layout/abs__action_bar_title_item.xml | 50 - .../res/layout/abs__action_menu_item_layout.xml | 56 - .../res/layout/abs__action_menu_layout.xml | 23 - .../res/layout/abs__action_mode_bar.xml | 24 - .../res/layout/abs__action_mode_close_item.xml | 31 - .../res/layout/abs__activity_chooser_view.xml | 70 - .../abs__activity_chooser_view_list_item.xml | 53 - .../res/layout/abs__dialog_title_holo.xml | 46 - .../res/layout/abs__list_menu_item_checkbox.xml | 26 - .../res/layout/abs__list_menu_item_icon.xml | 28 - .../res/layout/abs__list_menu_item_layout.xml | 59 - .../res/layout/abs__list_menu_item_radio.xml | 24 - .../res/layout/abs__popup_menu_item_layout.xml | 60 - .../res/layout/abs__screen_action_bar.xml | 57 - .../res/layout/abs__screen_action_bar_overlay.xml | 59 - .../res/layout/abs__screen_simple.xml | 38 - .../abs__screen_simple_overlay_action_mode.xml | 38 - .../abs__search_dropdown_item_icons_2line.xml | 89 - actionbarsherlock/res/layout/abs__search_view.xml | 159 -- .../res/layout/abs__simple_dropdown_hint.xml | 29 - .../res/layout/sherlock_spinner_dropdown_item.xml | 26 - .../res/layout/sherlock_spinner_item.xml | 26 - actionbarsherlock/res/values-land/abs__dimens.xml | 33 - .../res/values-large-hdpi-1024x600/abs__dimens.xml | 33 - .../abs__dimens.xml | 33 - .../abs__dimens.xml | 33 - .../res/values-large-mdpi-1024x600/abs__dimens.xml | 36 - actionbarsherlock/res/values-large/abs__dimens.xml | 29 - .../res/values-sw600dp/abs__bools.xml | 19 - .../res/values-sw600dp/abs__dimens.xml | 38 - actionbarsherlock/res/values-v11/abs__themes.xml | 12 - actionbarsherlock/res/values-v14/abs__styles.xml | 123 -- actionbarsherlock/res/values-v14/abs__themes.xml | 34 - .../res/values-w360dp/abs__dimens.xml | 22 - actionbarsherlock/res/values-w480dp/abs__bools.xml | 22 - .../res/values-w480dp/abs__config.xml | 29 - .../res/values-w500dp/abs__dimens.xml | 22 - .../res/values-w600dp/abs__dimens.xml | 22 - .../res/values-xlarge/abs__dimens.xml | 45 - actionbarsherlock/res/values/abs__attrs.xml | 432 ----- actionbarsherlock/res/values/abs__bools.xml | 22 - actionbarsherlock/res/values/abs__colors.xml | 27 - actionbarsherlock/res/values/abs__config.xml | 43 - actionbarsherlock/res/values/abs__dimens.xml | 67 - actionbarsherlock/res/values/abs__ids.xml | 26 - actionbarsherlock/res/values/abs__strings.xml | 53 - actionbarsherlock/res/values/abs__styles.xml | 412 ----- actionbarsherlock/res/values/abs__themes.xml | 239 --- .../src/android/support/v4/app/Watson.java | 144 -- .../com/actionbarsherlock/ActionBarSherlock.java | 794 --------- .../src/com/actionbarsherlock/app/ActionBar.java | 956 ----------- .../actionbarsherlock/app/SherlockActivity.java | 270 --- .../app/SherlockDialogFragment.java | 68 - .../app/SherlockExpandableListActivity.java | 259 --- .../actionbarsherlock/app/SherlockFragment.java | 68 - .../app/SherlockFragmentActivity.java | 303 ---- .../app/SherlockListActivity.java | 270 --- .../app/SherlockListFragment.java | 68 - .../app/SherlockPreferenceActivity.java | 270 --- .../internal/ActionBarSherlockCompat.java | 1203 ------------- .../internal/ActionBarSherlockNative.java | 336 ---- .../internal/ResourcesCompat.java | 95 - .../internal/app/ActionBarImpl.java | 1026 ----------- .../internal/app/ActionBarWrapper.java | 468 ----- .../nineoldandroids/animation/Animator.java | 278 --- .../animation/AnimatorListenerAdapter.java | 54 - .../nineoldandroids/animation/AnimatorSet.java | 1111 ------------ .../nineoldandroids/animation/FloatEvaluator.java | 42 - .../animation/FloatKeyframeSet.java | 136 -- .../nineoldandroids/animation/IntEvaluator.java | 42 - .../nineoldandroids/animation/IntKeyframeSet.java | 135 -- .../nineoldandroids/animation/Keyframe.java | 361 ---- .../nineoldandroids/animation/KeyframeSet.java | 227 --- .../nineoldandroids/animation/ObjectAnimator.java | 491 ------ .../animation/PropertyValuesHolder.java | 1012 ----------- .../nineoldandroids/animation/TypeEvaluator.java | 44 - .../nineoldandroids/animation/ValueAnimator.java | 1265 -------------- .../nineoldandroids/view/NineViewGroup.java | 79 - .../view/animation/AnimatorProxy.java | 212 --- .../nineoldandroids/widget/NineFrameLayout.java | 57 - .../widget/NineHorizontalScrollView.java | 41 - .../nineoldandroids/widget/NineLinearLayout.java | 57 - .../internal/view/ActionProviderWrapper.java | 40 - .../internal/view/StandaloneActionMode.java | 148 -- .../view/View_HasStateListenerSupport.java | 6 - .../view/View_OnAttachStateChangeListener.java | 8 - .../internal/view/menu/ActionMenu.java | 264 --- .../internal/view/menu/ActionMenuItem.java | 278 --- .../internal/view/menu/ActionMenuItemView.java | 295 ---- .../internal/view/menu/ActionMenuPresenter.java | 714 -------- .../internal/view/menu/ActionMenuView.java | 575 ------- .../internal/view/menu/BaseMenuPresenter.java | 231 --- .../internal/view/menu/ListMenuItemView.java | 278 --- .../internal/view/menu/MenuBuilder.java | 1335 --------------- .../internal/view/menu/MenuItemImpl.java | 647 ------- .../internal/view/menu/MenuItemWrapper.java | 310 ---- .../internal/view/menu/MenuPopupHelper.java | 376 ---- .../internal/view/menu/MenuPresenter.java | 148 -- .../internal/view/menu/MenuView.java | 120 -- .../internal/view/menu/MenuWrapper.java | 185 -- .../internal/view/menu/SubMenuBuilder.java | 134 -- .../internal/view/menu/SubMenuWrapper.java | 72 - .../internal/widget/AbsActionBarView.java | 291 ---- .../internal/widget/ActionBarContainer.java | 258 --- .../internal/widget/ActionBarContextView.java | 518 ------ .../internal/widget/ActionBarView.java | 1548 ----------------- .../internal/widget/CapitalizingButton.java | 40 - .../internal/widget/CapitalizingTextView.java | 50 - .../widget/CollapsibleActionViewWrapper.java | 30 - .../internal/widget/FakeDialogPhoneWindow.java | 64 - .../internal/widget/IcsAbsSpinner.java | 479 ------ .../internal/widget/IcsAdapterView.java | 1160 ------------- .../internal/widget/IcsColorDrawable.java | 41 - .../internal/widget/IcsLinearLayout.java | 410 ----- .../internal/widget/IcsListPopupWindow.java | 644 ------- .../internal/widget/IcsProgressBar.java | 1193 ------------- .../internal/widget/IcsSpinner.java | 703 -------- .../actionbarsherlock/internal/widget/IcsView.java | 21 - .../internal/widget/ScrollingTabContainerView.java | 546 ------ .../src/com/actionbarsherlock/view/ActionMode.java | 224 --- .../com/actionbarsherlock/view/ActionProvider.java | 170 -- .../view/CollapsibleActionView.java | 39 - .../src/com/actionbarsherlock/view/Menu.java | 447 ----- .../com/actionbarsherlock/view/MenuInflater.java | 495 ------ .../src/com/actionbarsherlock/view/MenuItem.java | 598 ------- .../src/com/actionbarsherlock/view/SubMenu.java | 110 -- .../src/com/actionbarsherlock/view/Window.java | 65 - .../widget/ActivityChooserModel.java | 1104 ------------ .../widget/ActivityChooserView.java | 827 --------- .../com/actionbarsherlock/widget/SearchView.java | 1811 -------------------- .../widget/ShareActionProvider.java | 316 ---- .../widget/SuggestionsAdapter.java | 733 -------- .../internal/ManifestParsingTest.java | 37 - project.properties | 2 +- setup_env.sh | 5 +- 438 files changed, 9 insertions(+), 37654 deletions(-) create mode 100644 .gitmodules create mode 160000 actionbarsherlock delete mode 100644 actionbarsherlock/.classpath delete mode 100644 actionbarsherlock/AndroidManifest.xml delete mode 100644 actionbarsherlock/README.md delete mode 100644 actionbarsherlock/build.xml delete mode 100644 actionbarsherlock/libs/android-support-v4.jar delete mode 100644 actionbarsherlock/pom.xml delete mode 100644 actionbarsherlock/proguard-project.txt delete mode 100644 actionbarsherlock/project.properties delete mode 100644 actionbarsherlock/res/color/abs__primary_text_disable_only_holo_dark.xml delete mode 100644 actionbarsherlock/res/color/abs__primary_text_disable_only_holo_light.xml delete mode 100644 actionbarsherlock/res/color/abs__primary_text_holo_dark.xml delete mode 100644 actionbarsherlock/res/color/abs__primary_text_holo_light.xml delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_solid_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_solid_inverse_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_solid_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_transparent_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_transparent_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_share_pack_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_share_pack_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_solid_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_solid_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_solid_shadow_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_stacked_solid_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_stacked_solid_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_stacked_transparent_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_stacked_transparent_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_transparent_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ab_transparent_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__btn_cab_done_default_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__btn_cab_done_default_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__btn_cab_done_focused_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__btn_cab_done_focused_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__btn_cab_done_pressed_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__btn_cab_done_pressed_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__cab_background_bottom_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__cab_background_bottom_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__cab_background_top_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__cab_background_top_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__dialog_full_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__dialog_full_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_ab_back_holo_dark.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_ab_back_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_cab_done_holo_dark.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_cab_done_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_clear_disabled.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_clear_normal.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_clear_search_api_disabled_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_clear_search_api_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_go.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_go_search_api_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_menu_share_holo_dark.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_menu_share_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_search.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_search_api_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_voice_search.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__ic_voice_search_api_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__list_activated_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__list_divider_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__list_divider_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__list_focused_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__list_longpressed_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__list_pressed_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__list_pressed_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__list_selector_disabled_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__list_selector_disabled_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__menu_dropdown_panel_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__menu_dropdown_panel_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__progress_bg_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__progress_bg_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__progress_primary_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__progress_primary_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__progress_secondary_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__progress_secondary_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__spinner_48_inner_holo.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__spinner_48_outer_holo.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_default_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_default_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_disabled_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_disabled_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_focused_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_focused_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_pressed_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_pressed_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__tab_selected_focused_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__tab_selected_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__tab_selected_pressed_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__tab_unselected_pressed_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__textfield_search_default_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__textfield_search_default_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__textfield_search_right_default_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__textfield_search_right_default_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__textfield_search_right_selected_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__textfield_search_right_selected_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__textfield_search_selected_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-hdpi/abs__textfield_search_selected_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_bottom_solid_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_bottom_solid_inverse_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_bottom_solid_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_bottom_transparent_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_bottom_transparent_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_share_pack_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_share_pack_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_solid_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_solid_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_solid_shadow_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_stacked_solid_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_stacked_solid_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_stacked_transparent_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_stacked_transparent_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_transparent_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ab_transparent_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_default_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_default_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_focused_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_focused_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__cab_background_bottom_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__cab_background_bottom_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__cab_background_top_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__cab_background_top_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__dialog_full_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__dialog_full_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_ab_back_holo_dark.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_ab_back_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_cab_done_holo_dark.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_cab_done_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_clear_disabled.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_clear_normal.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_clear_search_api_disabled_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_clear_search_api_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_go.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_go_search_api_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_menu_moreoverflow_normal_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_menu_share_holo_dark.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_menu_share_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_search.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_search_api_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_voice_search.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__ic_voice_search_api_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__list_activated_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__list_divider_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__list_divider_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__list_focused_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__list_longpressed_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__list_pressed_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__list_pressed_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__list_selector_disabled_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__list_selector_disabled_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__menu_dropdown_panel_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__menu_dropdown_panel_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__progress_bg_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__progress_bg_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__progress_primary_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__progress_primary_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__progress_secondary_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__progress_secondary_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__spinner_48_inner_holo.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__spinner_48_outer_holo.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_default_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_default_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_disabled_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_disabled_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_focused_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_focused_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_pressed_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_pressed_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__tab_selected_focused_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__tab_selected_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__tab_selected_pressed_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__tab_unselected_pressed_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__textfield_search_default_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__textfield_search_default_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__textfield_search_right_default_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__textfield_search_right_default_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__textfield_search_right_selected_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__textfield_search_right_selected_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__textfield_search_selected_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-mdpi/abs__textfield_search_selected_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-v11/abs__progress_medium_holo.xml delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_bottom_solid_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_bottom_solid_inverse_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_bottom_solid_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_bottom_transparent_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_bottom_transparent_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_share_pack_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_share_pack_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_solid_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_solid_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_solid_shadow_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_stacked_solid_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_stacked_solid_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_stacked_transparent_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_stacked_transparent_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_transparent_dark_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ab_transparent_light_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_default_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_default_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_focused_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_focused_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__cab_background_bottom_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__cab_background_bottom_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__cab_background_top_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__cab_background_top_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__dialog_full_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__dialog_full_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_ab_back_holo_dark.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_ab_back_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_cab_done_holo_dark.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_cab_done_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_clear_disabled.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_clear_search_api_disabled_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_clear_search_api_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_go.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_go_search_api_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_menu_share_holo_dark.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_menu_share_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_search.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_search_api_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_voice_search.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__ic_voice_search_api_holo_light.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__list_activated_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__list_divider_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__list_divider_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__list_focused_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__list_longpressed_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__list_pressed_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__list_pressed_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__list_selector_disabled_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__list_selector_disabled_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__menu_dropdown_panel_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__menu_dropdown_panel_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__progress_bg_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__progress_bg_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__progress_primary_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__progress_primary_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__progress_secondary_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__progress_secondary_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__spinner_48_inner_holo.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__spinner_48_outer_holo.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_default_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_default_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_focused_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_focused_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__tab_selected_focused_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__tab_selected_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__tab_selected_pressed_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__tab_unselected_pressed_holo.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_default_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_default_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_right_default_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_right_default_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_right_selected_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_right_selected_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_selected_holo_dark.9.png delete mode 100644 actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_selected_holo_light.9.png delete mode 100644 actionbarsherlock/res/drawable/abs__activated_background_holo_dark.xml delete mode 100644 actionbarsherlock/res/drawable/abs__activated_background_holo_light.xml delete mode 100644 actionbarsherlock/res/drawable/abs__btn_cab_done_holo_dark.xml delete mode 100644 actionbarsherlock/res/drawable/abs__btn_cab_done_holo_light.xml delete mode 100644 actionbarsherlock/res/drawable/abs__ic_clear.xml delete mode 100644 actionbarsherlock/res/drawable/abs__ic_clear_holo_light.xml delete mode 100644 actionbarsherlock/res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml delete mode 100644 actionbarsherlock/res/drawable/abs__ic_menu_moreoverflow_holo_light.xml delete mode 100644 actionbarsherlock/res/drawable/abs__item_background_holo_dark.xml delete mode 100644 actionbarsherlock/res/drawable/abs__item_background_holo_light.xml delete mode 100644 actionbarsherlock/res/drawable/abs__list_selector_background_transition_holo_dark.xml delete mode 100644 actionbarsherlock/res/drawable/abs__list_selector_background_transition_holo_light.xml delete mode 100644 actionbarsherlock/res/drawable/abs__list_selector_holo_dark.xml delete mode 100644 actionbarsherlock/res/drawable/abs__list_selector_holo_light.xml delete mode 100644 actionbarsherlock/res/drawable/abs__progress_horizontal_holo_dark.xml delete mode 100644 actionbarsherlock/res/drawable/abs__progress_horizontal_holo_light.xml delete mode 100644 actionbarsherlock/res/drawable/abs__progress_medium_holo.xml delete mode 100644 actionbarsherlock/res/drawable/abs__search_dropdown_dark.xml delete mode 100644 actionbarsherlock/res/drawable/abs__search_dropdown_light.xml delete mode 100644 actionbarsherlock/res/drawable/abs__spinner_ab_holo_dark.xml delete mode 100644 actionbarsherlock/res/drawable/abs__spinner_ab_holo_light.xml delete mode 100644 actionbarsherlock/res/drawable/abs__tab_indicator_ab_holo.xml delete mode 100644 actionbarsherlock/res/drawable/abs__textfield_searchview_holo_dark.xml delete mode 100644 actionbarsherlock/res/drawable/abs__textfield_searchview_holo_light.xml delete mode 100644 actionbarsherlock/res/drawable/abs__textfield_searchview_right_holo_dark.xml delete mode 100644 actionbarsherlock/res/drawable/abs__textfield_searchview_right_holo_light.xml delete mode 100644 actionbarsherlock/res/layout-large/abs__action_mode_close_item.xml delete mode 100644 actionbarsherlock/res/layout-v14/sherlock_spinner_dropdown_item.xml delete mode 100644 actionbarsherlock/res/layout-v14/sherlock_spinner_item.xml delete mode 100644 actionbarsherlock/res/layout-xlarge/abs__screen_action_bar.xml delete mode 100644 actionbarsherlock/res/layout-xlarge/abs__screen_action_bar_overlay.xml delete mode 100644 actionbarsherlock/res/layout/abs__action_bar_home.xml delete mode 100644 actionbarsherlock/res/layout/abs__action_bar_tab.xml delete mode 100644 actionbarsherlock/res/layout/abs__action_bar_tab_bar_view.xml delete mode 100644 actionbarsherlock/res/layout/abs__action_bar_title_item.xml delete mode 100644 actionbarsherlock/res/layout/abs__action_menu_item_layout.xml delete mode 100644 actionbarsherlock/res/layout/abs__action_menu_layout.xml delete mode 100644 actionbarsherlock/res/layout/abs__action_mode_bar.xml delete mode 100644 actionbarsherlock/res/layout/abs__action_mode_close_item.xml delete mode 100644 actionbarsherlock/res/layout/abs__activity_chooser_view.xml delete mode 100644 actionbarsherlock/res/layout/abs__activity_chooser_view_list_item.xml delete mode 100644 actionbarsherlock/res/layout/abs__dialog_title_holo.xml delete mode 100644 actionbarsherlock/res/layout/abs__list_menu_item_checkbox.xml delete mode 100644 actionbarsherlock/res/layout/abs__list_menu_item_icon.xml delete mode 100644 actionbarsherlock/res/layout/abs__list_menu_item_layout.xml delete mode 100644 actionbarsherlock/res/layout/abs__list_menu_item_radio.xml delete mode 100644 actionbarsherlock/res/layout/abs__popup_menu_item_layout.xml delete mode 100644 actionbarsherlock/res/layout/abs__screen_action_bar.xml delete mode 100644 actionbarsherlock/res/layout/abs__screen_action_bar_overlay.xml delete mode 100644 actionbarsherlock/res/layout/abs__screen_simple.xml delete mode 100644 actionbarsherlock/res/layout/abs__screen_simple_overlay_action_mode.xml delete mode 100644 actionbarsherlock/res/layout/abs__search_dropdown_item_icons_2line.xml delete mode 100644 actionbarsherlock/res/layout/abs__search_view.xml delete mode 100644 actionbarsherlock/res/layout/abs__simple_dropdown_hint.xml delete mode 100644 actionbarsherlock/res/layout/sherlock_spinner_dropdown_item.xml delete mode 100644 actionbarsherlock/res/layout/sherlock_spinner_item.xml delete mode 100644 actionbarsherlock/res/values-land/abs__dimens.xml delete mode 100644 actionbarsherlock/res/values-large-hdpi-1024x600/abs__dimens.xml delete mode 100644 actionbarsherlock/res/values-large-land-hdpi-1024x600/abs__dimens.xml delete mode 100644 actionbarsherlock/res/values-large-land-mdpi-1024x600/abs__dimens.xml delete mode 100644 actionbarsherlock/res/values-large-mdpi-1024x600/abs__dimens.xml delete mode 100644 actionbarsherlock/res/values-large/abs__dimens.xml delete mode 100644 actionbarsherlock/res/values-sw600dp/abs__bools.xml delete mode 100644 actionbarsherlock/res/values-sw600dp/abs__dimens.xml delete mode 100644 actionbarsherlock/res/values-v11/abs__themes.xml delete mode 100644 actionbarsherlock/res/values-v14/abs__styles.xml delete mode 100644 actionbarsherlock/res/values-v14/abs__themes.xml delete mode 100644 actionbarsherlock/res/values-w360dp/abs__dimens.xml delete mode 100644 actionbarsherlock/res/values-w480dp/abs__bools.xml delete mode 100644 actionbarsherlock/res/values-w480dp/abs__config.xml delete mode 100644 actionbarsherlock/res/values-w500dp/abs__dimens.xml delete mode 100644 actionbarsherlock/res/values-w600dp/abs__dimens.xml delete mode 100644 actionbarsherlock/res/values-xlarge/abs__dimens.xml delete mode 100644 actionbarsherlock/res/values/abs__attrs.xml delete mode 100644 actionbarsherlock/res/values/abs__bools.xml delete mode 100644 actionbarsherlock/res/values/abs__colors.xml delete mode 100644 actionbarsherlock/res/values/abs__config.xml delete mode 100644 actionbarsherlock/res/values/abs__dimens.xml delete mode 100644 actionbarsherlock/res/values/abs__ids.xml delete mode 100644 actionbarsherlock/res/values/abs__strings.xml delete mode 100644 actionbarsherlock/res/values/abs__styles.xml delete mode 100644 actionbarsherlock/res/values/abs__themes.xml delete mode 100644 actionbarsherlock/src/android/support/v4/app/Watson.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/ActionBarSherlock.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/app/ActionBar.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/app/SherlockActivity.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/app/SherlockDialogFragment.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/app/SherlockExpandableListActivity.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/app/SherlockFragment.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/app/SherlockFragmentActivity.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/app/SherlockListActivity.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/app/SherlockListFragment.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/app/SherlockPreferenceActivity.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/ActionBarSherlockCompat.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/ActionBarSherlockNative.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/ResourcesCompat.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/app/ActionBarWrapper.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Animator.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorListenerAdapter.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorSet.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatEvaluator.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatKeyframeSet.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntEvaluator.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntKeyframeSet.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Keyframe.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/KeyframeSet.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ObjectAnimator.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/TypeEvaluator.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ValueAnimator.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/NineViewGroup.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/animation/AnimatorProxy.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineFrameLayout.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineHorizontalScrollView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineLinearLayout.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/ActionProviderWrapper.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/StandaloneActionMode.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/View_HasStateListenerSupport.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/View_OnAttachStateChangeListener.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenu.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItem.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItemView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/BaseMenuPresenter.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ListMenuItemView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuBuilder.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemImpl.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemWrapper.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuPopupHelper.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuPresenter.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuWrapper.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuBuilder.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuWrapper.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/AbsActionBarView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/ActionBarContextView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/ActionBarView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/CapitalizingTextView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/CollapsibleActionViewWrapper.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsAbsSpinner.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsAdapterView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsColorDrawable.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsSpinner.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/view/ActionMode.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/view/ActionProvider.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/view/CollapsibleActionView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/view/Menu.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/view/MenuInflater.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/view/MenuItem.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/view/SubMenu.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/view/Window.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/widget/ActivityChooserModel.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/widget/ActivityChooserView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/widget/SearchView.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/widget/ShareActionProvider.java delete mode 100644 actionbarsherlock/src/com/actionbarsherlock/widget/SuggestionsAdapter.java delete mode 100644 actionbarsherlock/test/com/actionbarsherlock/internal/ManifestParsingTest.java diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..b41da321 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "actionbarsherlock"] + path = actionbarsherlock + url = git://github.com/JakeWharton/ActionBarSherlock.git diff --git a/actionbarsherlock b/actionbarsherlock new file mode 160000 index 00000000..9598f2bb --- /dev/null +++ b/actionbarsherlock @@ -0,0 +1 @@ +Subproject commit 9598f2bb2ceed4a834cd5586a903f270ca4c0ccc diff --git a/actionbarsherlock/.classpath b/actionbarsherlock/.classpath deleted file mode 100644 index 3f9691c5..00000000 --- a/actionbarsherlock/.classpath +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/actionbarsherlock/AndroidManifest.xml b/actionbarsherlock/AndroidManifest.xml deleted file mode 100644 index 7b8a8482..00000000 --- a/actionbarsherlock/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/actionbarsherlock/README.md b/actionbarsherlock/README.md deleted file mode 100644 index e8a2c080..00000000 --- a/actionbarsherlock/README.md +++ /dev/null @@ -1,15 +0,0 @@ -ActionBarSherlock Library -========================= - -This folder contains the main library which should be linked against as an -Android library project in your application. - -For more information see the "Including In Your Project" section of the -[usage page][1]. - - - - - - - [1]: http://actionbarsherlock.com/usage.html diff --git a/actionbarsherlock/build.xml b/actionbarsherlock/build.xml deleted file mode 100644 index 2af40096..00000000 --- a/actionbarsherlock/build.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/libs/android-support-v4.jar b/actionbarsherlock/libs/android-support-v4.jar deleted file mode 100644 index 99e063b33a53c8ba7980a5b5244ce0e0da46ae54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 271754 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

Helper for implementing the action bar design pattern across all versions - * of Android.

- * - *

This class will manage interaction with a custom action bar based on the - * Android 4.0 source code. The exposed API mirrors that of its native - * counterpart and you should refer to its documentation for instruction.

- * - * @author Jake Wharton - */ -public abstract class ActionBarSherlock { - protected static final String TAG = "ActionBarSherlock"; - protected static final boolean DEBUG = false; - - private static final Class[] CONSTRUCTOR_ARGS = new Class[] { Activity.class, int.class }; - private static final HashMap> IMPLEMENTATIONS = - new HashMap>(); - - static { - //Register our two built-in implementations - registerImplementation(ActionBarSherlockCompat.class); - registerImplementation(ActionBarSherlockNative.class); - } - - - /** - *

Denotes an implementation of ActionBarSherlock which provides an - * action bar-enhanced experience.

- */ - @Target(ElementType.TYPE) - @Retention(RetentionPolicy.RUNTIME) - public @interface Implementation { - static final int DEFAULT_API = -1; - static final int DEFAULT_DPI = -1; - - int api() default DEFAULT_API; - int dpi() default DEFAULT_DPI; - } - - - /** Activity interface for menu creation callback. */ - public interface OnCreatePanelMenuListener { - public boolean onCreatePanelMenu(int featureId, Menu menu); - } - /** Activity interface for menu creation callback. */ - public interface OnCreateOptionsMenuListener { - public boolean onCreateOptionsMenu(Menu menu); - } - /** Activity interface for menu item selection callback. */ - public interface OnMenuItemSelectedListener { - public boolean onMenuItemSelected(int featureId, MenuItem item); - } - /** Activity interface for menu item selection callback. */ - public interface OnOptionsItemSelectedListener { - public boolean onOptionsItemSelected(MenuItem item); - } - /** Activity interface for menu preparation callback. */ - public interface OnPreparePanelListener { - public boolean onPreparePanel(int featureId, View view, Menu menu); - } - /** Activity interface for menu preparation callback. */ - public interface OnPrepareOptionsMenuListener { - public boolean onPrepareOptionsMenu(Menu menu); - } - /** Activity interface for action mode finished callback. */ - public interface OnActionModeFinishedListener { - public void onActionModeFinished(ActionMode mode); - } - /** Activity interface for action mode started callback. */ - public interface OnActionModeStartedListener { - public void onActionModeStarted(ActionMode mode); - } - - - /** - * If set, the logic in these classes will assume that an {@link Activity} - * is dispatching all of the required events to the class. This flag should - * only be used internally or if you are creating your own base activity - * modeled after one of the included types (e.g., {@code SherlockActivity}). - */ - public static final int FLAG_DELEGATE = 1; - - - /** - * Register an ActionBarSherlock implementation. - * - * @param implementationClass Target implementation class which extends - * {@link ActionBarSherlock}. This class must also be annotated with - * {@link Implementation}. - */ - public static void registerImplementation(Class implementationClass) { - if (!implementationClass.isAnnotationPresent(Implementation.class)) { - throw new IllegalArgumentException("Class " + implementationClass.getSimpleName() + " is not annotated with @Implementation"); - } else if (IMPLEMENTATIONS.containsValue(implementationClass)) { - if (DEBUG) Log.w(TAG, "Class " + implementationClass.getSimpleName() + " already registered"); - return; - } - - Implementation impl = implementationClass.getAnnotation(Implementation.class); - if (DEBUG) Log.i(TAG, "Registering " + implementationClass.getSimpleName() + " with qualifier " + impl); - IMPLEMENTATIONS.put(impl, implementationClass); - } - - /** - * Unregister an ActionBarSherlock implementation. This should be - * considered very volatile and you should only use it if you know what - * you are doing. You have been warned. - * - * @param implementationClass Target implementation class. - * @return Boolean indicating whether the class was removed. - */ - public static boolean unregisterImplementation(Class implementationClass) { - return IMPLEMENTATIONS.values().remove(implementationClass); - } - - /** - * Wrap an activity with an action bar abstraction which will enable the - * use of a custom implementation on platforms where a native version does - * not exist. - * - * @param activity Activity to wrap. - * @return Instance to interact with the action bar. - */ - public static ActionBarSherlock wrap(Activity activity) { - return wrap(activity, 0); - } - - /** - * Wrap an activity with an action bar abstraction which will enable the - * use of a custom implementation on platforms where a native version does - * not exist. - * - * @param activity Owning activity. - * @param flags Option flags to control behavior. - * @return Instance to interact with the action bar. - */ - public static ActionBarSherlock wrap(Activity activity, int flags) { - //Create a local implementation map we can modify - HashMap> impls = - new HashMap>(IMPLEMENTATIONS); - boolean hasQualfier; - - /* DPI FILTERING */ - hasQualfier = false; - for (Implementation key : impls.keySet()) { - //Only honor TVDPI as a specific qualifier - if (key.dpi() == DisplayMetrics.DENSITY_TV) { - hasQualfier = true; - break; - } - } - if (hasQualfier) { - final boolean isTvDpi = activity.getResources().getDisplayMetrics().densityDpi == DisplayMetrics.DENSITY_TV; - for (Iterator keys = impls.keySet().iterator(); keys.hasNext(); ) { - int keyDpi = keys.next().dpi(); - if ((isTvDpi && keyDpi != DisplayMetrics.DENSITY_TV) - || (!isTvDpi && keyDpi == DisplayMetrics.DENSITY_TV)) { - keys.remove(); - } - } - } - - /* API FILTERING */ - hasQualfier = false; - for (Implementation key : impls.keySet()) { - if (key.api() != Implementation.DEFAULT_API) { - hasQualfier = true; - break; - } - } - if (hasQualfier) { - final int runtimeApi = Build.VERSION.SDK_INT; - int bestApi = 0; - for (Iterator keys = impls.keySet().iterator(); keys.hasNext(); ) { - int keyApi = keys.next().api(); - if (keyApi > runtimeApi) { - keys.remove(); - } else if (keyApi > bestApi) { - bestApi = keyApi; - } - } - for (Iterator keys = impls.keySet().iterator(); keys.hasNext(); ) { - if (keys.next().api() != bestApi) { - keys.remove(); - } - } - } - - if (impls.size() > 1) { - throw new IllegalStateException("More than one implementation matches configuration."); - } - if (impls.isEmpty()) { - throw new IllegalStateException("No implementations match configuration."); - } - Class impl = impls.values().iterator().next(); - if (DEBUG) Log.i(TAG, "Using implementation: " + impl.getSimpleName()); - - try { - Constructor ctor = impl.getConstructor(CONSTRUCTOR_ARGS); - return ctor.newInstance(activity, flags); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - - /** Activity which is displaying the action bar. Also used for context. */ - protected final Activity mActivity; - /** Whether delegating actions for the activity or managing ourselves. */ - protected final boolean mIsDelegate; - - /** Reference to our custom menu inflater which supports action items. */ - protected MenuInflater mMenuInflater; - - - - protected ActionBarSherlock(Activity activity, int flags) { - if (DEBUG) Log.d(TAG, "[] activity: " + activity + ", flags: " + flags); - - mActivity = activity; - mIsDelegate = (flags & FLAG_DELEGATE) != 0; - } - - - /** - * Get the current action bar instance. - * - * @return Action bar instance. - */ - public abstract ActionBar getActionBar(); - - - /////////////////////////////////////////////////////////////////////////// - // Lifecycle and interaction callbacks when delegating - /////////////////////////////////////////////////////////////////////////// - - /** - * Notify action bar of a configuration change event. Should be dispatched - * after the call to the superclass implementation. - * - *
-     * @Override
-     * public void onConfigurationChanged(Configuration newConfig) {
-     *     super.onConfigurationChanged(newConfig);
-     *     mSherlock.dispatchConfigurationChanged(newConfig);
-     * }
-     * 
- * - * @param newConfig The new device configuration. - */ - public void dispatchConfigurationChanged(Configuration newConfig) {} - - /** - * Notify the action bar that the activity has finished its resuming. This - * should be dispatched after the call to the superclass implementation. - * - *
-     * @Override
-     * protected void onPostResume() {
-     *     super.onPostResume();
-     *     mSherlock.dispatchPostResume();
-     * }
-     * 
- */ - public void dispatchPostResume() {} - - /** - * Notify the action bar that the activity is pausing. This should be - * dispatched before the call to the superclass implementation. - * - *
-     * @Override
-     * protected void onPause() {
-     *     mSherlock.dispatchPause();
-     *     super.onPause();
-     * }
-     * 
- */ - public void dispatchPause() {} - - /** - * Notify the action bar that the activity is stopping. This should be - * called before the superclass implementation. - * - *

- * @Override - * protected void onStop() { - * mSherlock.dispatchStop(); - * super.onStop(); - * } - *

- */ - public void dispatchStop() {} - - /** - * Indicate that the menu should be recreated by calling - * {@link OnCreateOptionsMenuListener#onCreateOptionsMenu(com.actionbarsherlock.view.Menu)}. - */ - public abstract void dispatchInvalidateOptionsMenu(); - - /** - * Notify the action bar that it should display its overflow menu if it is - * appropriate for the device. The implementation should conditionally - * call the superclass method only if this method returns {@code false}. - * - *

- * @Override - * public void openOptionsMenu() { - * if (!mSherlock.dispatchOpenOptionsMenu()) { - * super.openOptionsMenu(); - * } - * } - *

- * - * @return {@code true} if the opening of the menu was handled internally. - */ - public boolean dispatchOpenOptionsMenu() { - return false; - } - - /** - * Notify the action bar that it should close its overflow menu if it is - * appropriate for the device. This implementation should conditionally - * call the superclass method only if this method returns {@code false}. - * - *
-     * @Override
-     * public void closeOptionsMenu() {
-     *     if (!mSherlock.dispatchCloseOptionsMenu()) {
-     *         super.closeOptionsMenu();
-     *     }
-     * }
-     * 
- * - * @return {@code true} if the closing of the menu was handled internally. - */ - public boolean dispatchCloseOptionsMenu() { - return false; - } - - /** - * Notify the class that the activity has finished its creation. This - * should be called after the superclass implementation. - * - *
-     * @Override
-     * protected void onPostCreate(Bundle savedInstanceState) {
-     *     mSherlock.dispatchPostCreate(savedInstanceState);
-     *     super.onPostCreate(savedInstanceState);
-     * }
-     * 
- * - * @param savedInstanceState If the activity is being re-initialized after - * previously being shut down then this Bundle - * contains the data it most recently supplied in - * {@link Activity#}onSaveInstanceState(Bundle)}. - * Note: Otherwise it is null. - */ - public void dispatchPostCreate(Bundle savedInstanceState) {} - - /** - * Notify the action bar that the title has changed and the action bar - * should be updated to reflect the change. This should be called before - * the superclass implementation. - * - *
-     *  @Override
-     *  protected void onTitleChanged(CharSequence title, int color) {
-     *      mSherlock.dispatchTitleChanged(title, color);
-     *      super.onTitleChanged(title, color);
-     *  }
-     * 
- * - * @param title New activity title. - * @param color New activity color. - */ - public void dispatchTitleChanged(CharSequence title, int color) {} - - /** - * Notify the action bar the user has created a key event. This is used to - * toggle the display of the overflow action item with the menu key and to - * close the action mode or expanded action item with the back key. - * - *
-     * @Override
-     * public boolean dispatchKeyEvent(KeyEvent event) {
-     *     if (mSherlock.dispatchKeyEvent(event)) {
-     *         return true;
-     *     }
-     *     return super.dispatchKeyEvent(event);
-     * }
-     * 
- * - * @param event Description of the key event. - * @return {@code true} if the event was handled. - */ - public boolean dispatchKeyEvent(KeyEvent event) { - return false; - } - - /** - * Notify the action bar that the Activity has triggered a menu creation - * which should happen on the conclusion of {@link Activity#onCreate}. This - * will be used to gain a reference to the native menu for native and - * overflow binding as well as to indicate when compatibility create should - * occur for the first time. - * - * @param menu Activity native menu. - * @return {@code true} since we always want to say that we have a native - */ - public abstract boolean dispatchCreateOptionsMenu(android.view.Menu menu); - - /** - * Notify the action bar that the Activity has triggered a menu preparation - * which usually means that the user has requested the overflow menu via a - * hardware menu key. You should return the result of this method call and - * not call the superclass implementation. - * - *

- * @Override - * public final boolean onPrepareOptionsMenu(android.view.Menu menu) { - * return mSherlock.dispatchPrepareOptionsMenu(menu); - * } - *

- * - * @param menu Activity native menu. - * @return {@code true} if menu display should proceed. - */ - public abstract boolean dispatchPrepareOptionsMenu(android.view.Menu menu); - - /** - * Notify the action bar that a native options menu item has been selected. - * The implementation should return the result of this method call. - * - *

- * @Override - * public final boolean onOptionsItemSelected(android.view.MenuItem item) { - * return mSherlock.dispatchOptionsItemSelected(item); - * } - *

- * - * @param item Options menu item. - * @return @{code true} if the selection was handled. - */ - public abstract boolean dispatchOptionsItemSelected(android.view.MenuItem item); - - /** - * Notify the action bar that the overflow menu has been opened. The - * implementation should conditionally return {@code true} if this method - * returns {@code true}, otherwise return the result of the superclass - * method. - * - *

- * @Override - * public final boolean onMenuOpened(int featureId, android.view.Menu menu) { - * if (mSherlock.dispatchMenuOpened(featureId, menu)) { - * return true; - * } - * return super.onMenuOpened(featureId, menu); - * } - *

- * - * @param featureId Window feature which triggered the event. - * @param menu Activity native menu. - * @return {@code true} if the event was handled by this method. - */ - public boolean dispatchMenuOpened(int featureId, android.view.Menu menu) { - return false; - } - - /** - * Notify the action bar that the overflow menu has been closed. This - * method should be called before the superclass implementation. - * - *

- * @Override - * public void onPanelClosed(int featureId, android.view.Menu menu) { - * mSherlock.dispatchPanelClosed(featureId, menu); - * super.onPanelClosed(featureId, menu); - * } - *

- * - * @param featureId - * @param menu - */ - public void dispatchPanelClosed(int featureId, android.view.Menu menu) {} - - /** - * Notify the action bar that the activity has been destroyed. This method - * should be called before the superclass implementation. - * - *

- * @Override - * public void onDestroy() { - * mSherlock.dispatchDestroy(); - * super.onDestroy(); - * } - *

- */ - public void dispatchDestroy() {} - - public void dispatchSaveInstanceState(Bundle outState) {} - - public void dispatchRestoreInstanceState(Bundle savedInstanceState) {} - - /////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////// - - - /** - * Internal method to trigger the menu creation process. - * - * @return {@code true} if menu creation should proceed. - */ - protected final boolean callbackCreateOptionsMenu(Menu menu) { - if (DEBUG) Log.d(TAG, "[callbackCreateOptionsMenu] menu: " + menu); - - boolean result = true; - if (mActivity instanceof OnCreatePanelMenuListener) { - OnCreatePanelMenuListener listener = (OnCreatePanelMenuListener)mActivity; - result = listener.onCreatePanelMenu(Window.FEATURE_OPTIONS_PANEL, menu); - } else if (mActivity instanceof OnCreateOptionsMenuListener) { - OnCreateOptionsMenuListener listener = (OnCreateOptionsMenuListener)mActivity; - result = listener.onCreateOptionsMenu(menu); - } - - if (DEBUG) Log.d(TAG, "[callbackCreateOptionsMenu] returning " + result); - return result; - } - - /** - * Internal method to trigger the menu preparation process. - * - * @return {@code true} if menu preparation should proceed. - */ - protected final boolean callbackPrepareOptionsMenu(Menu menu) { - if (DEBUG) Log.d(TAG, "[callbackPrepareOptionsMenu] menu: " + menu); - - boolean result = true; - if (mActivity instanceof OnPreparePanelListener) { - OnPreparePanelListener listener = (OnPreparePanelListener)mActivity; - result = listener.onPreparePanel(Window.FEATURE_OPTIONS_PANEL, null, menu); - } else if (mActivity instanceof OnPrepareOptionsMenuListener) { - OnPrepareOptionsMenuListener listener = (OnPrepareOptionsMenuListener)mActivity; - result = listener.onPrepareOptionsMenu(menu); - } - - if (DEBUG) Log.d(TAG, "[callbackPrepareOptionsMenu] returning " + result); - return result; - } - - /** - * Internal method for dispatching options menu selection to the owning - * activity callback. - * - * @param item Selected options menu item. - * @return {@code true} if the item selection was handled in the callback. - */ - protected final boolean callbackOptionsItemSelected(MenuItem item) { - if (DEBUG) Log.d(TAG, "[callbackOptionsItemSelected] item: " + item.getTitleCondensed()); - - boolean result = false; - if (mActivity instanceof OnMenuItemSelectedListener) { - OnMenuItemSelectedListener listener = (OnMenuItemSelectedListener)mActivity; - result = listener.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item); - } else if (mActivity instanceof OnOptionsItemSelectedListener) { - OnOptionsItemSelectedListener listener = (OnOptionsItemSelectedListener)mActivity; - result = listener.onOptionsItemSelected(item); - } - - if (DEBUG) Log.d(TAG, "[callbackOptionsItemSelected] returning " + result); - return result; - } - - - /////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////// - - - /** - * Query for the availability of a certain feature. - * - * @param featureId The feature ID to check. - * @return {@code true} if feature is enabled, {@code false} otherwise. - */ - public abstract boolean hasFeature(int featureId); - - /** - * Enable extended screen features. This must be called before - * {@code setContentView()}. May be called as many times as desired as long - * as it is before {@code setContentView()}. If not called, no extended - * features will be available. You can not turn off a feature once it is - * requested. - * - * @param featureId The desired features, defined as constants by Window. - * @return Returns true if the requested feature is supported and now - * enabled. - */ - public abstract boolean requestFeature(int featureId); - - /** - * Set extra options that will influence the UI for this window. - * - * @param uiOptions Flags specifying extra options for this window. - */ - public abstract void setUiOptions(int uiOptions); - - /** - * Set extra options that will influence the UI for this window. Only the - * bits filtered by mask will be modified. - * - * @param uiOptions Flags specifying extra options for this window. - * @param mask Flags specifying which options should be modified. Others - * will remain unchanged. - */ - public abstract void setUiOptions(int uiOptions, int mask); - - /** - * Set the content of the activity inside the action bar. - * - * @param layoutResId Layout resource ID. - */ - public abstract void setContentView(int layoutResId); - - /** - * Set the content of the activity inside the action bar. - * - * @param view The desired content to display. - */ - public void setContentView(View view) { - if (DEBUG) Log.d(TAG, "[setContentView] view: " + view); - - setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); - } - - /** - * Set the content of the activity inside the action bar. - * - * @param view The desired content to display. - * @param params Layout parameters to apply to the view. - */ - public abstract void setContentView(View view, ViewGroup.LayoutParams params); - - /** - * Variation on {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)} - * to add an additional content view to the screen. Added after any - * existing ones on the screen -- existing views are NOT removed. - * - * @param view The desired content to display. - * @param params Layout parameters for the view. - */ - public abstract void addContentView(View view, ViewGroup.LayoutParams params); - - /** - * Change the title associated with this activity. - */ - public abstract void setTitle(CharSequence title); - - /** - * Change the title associated with this activity. - */ - public void setTitle(int resId) { - if (DEBUG) Log.d(TAG, "[setTitle] resId: " + resId); - - setTitle(mActivity.getString(resId)); - } - - /** - * Sets the visibility of the progress bar in the title. - *

- * In order for the progress bar to be shown, the feature must be requested - * via {@link #requestWindowFeature(int)}. - * - * @param visible Whether to show the progress bars in the title. - */ - public abstract void setProgressBarVisibility(boolean visible); - - /** - * Sets the visibility of the indeterminate progress bar in the title. - *

- * In order for the progress bar to be shown, the feature must be requested - * via {@link #requestWindowFeature(int)}. - * - * @param visible Whether to show the progress bars in the title. - */ - public abstract void setProgressBarIndeterminateVisibility(boolean visible); - - /** - * Sets whether the horizontal progress bar in the title should be indeterminate (the circular - * is always indeterminate). - *

- * In order for the progress bar to be shown, the feature must be requested - * via {@link #requestWindowFeature(int)}. - * - * @param indeterminate Whether the horizontal progress bar should be indeterminate. - */ - public abstract void setProgressBarIndeterminate(boolean indeterminate); - - /** - * Sets the progress for the progress bars in the title. - *

- * In order for the progress bar to be shown, the feature must be requested - * via {@link #requestWindowFeature(int)}. - * - * @param progress The progress for the progress bar. Valid ranges are from - * 0 to 10000 (both inclusive). If 10000 is given, the progress - * bar will be completely filled and will fade out. - */ - public abstract void setProgress(int progress); - - /** - * Sets the secondary progress for the progress bar in the title. This - * progress is drawn between the primary progress (set via - * {@link #setProgress(int)} and the background. It can be ideal for media - * scenarios such as showing the buffering progress while the default - * progress shows the play progress. - *

- * In order for the progress bar to be shown, the feature must be requested - * via {@link #requestWindowFeature(int)}. - * - * @param secondaryProgress The secondary progress for the progress bar. Valid ranges are from - * 0 to 10000 (both inclusive). - */ - public abstract void setSecondaryProgress(int secondaryProgress); - - /** - * Get a menu inflater instance which supports the newer menu attributes. - * - * @return Menu inflater instance. - */ - public MenuInflater getMenuInflater() { - if (DEBUG) Log.d(TAG, "[getMenuInflater]"); - - // Make sure that action views can get an appropriate theme. - if (mMenuInflater == null) { - if (getActionBar() != null) { - mMenuInflater = new MenuInflater(getThemedContext(), mActivity); - } else { - mMenuInflater = new MenuInflater(mActivity); - } - } - return mMenuInflater; - } - - protected abstract Context getThemedContext(); - - /** - * Start an action mode. - * - * @param callback Callback that will manage lifecycle events for this - * context mode. - * @return The ContextMode that was started, or null if it was canceled. - * @see ActionMode - */ - public abstract ActionMode startActionMode(ActionMode.Callback callback); -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/app/ActionBar.java b/actionbarsherlock/src/com/actionbarsherlock/app/ActionBar.java deleted file mode 100644 index 03755be2..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/app/ActionBar.java +++ /dev/null @@ -1,956 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.app; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.support.v4.app.FragmentTransaction; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.view.ViewDebug; -import android.view.ViewGroup; -import android.view.ViewGroup.MarginLayoutParams; -import android.widget.SpinnerAdapter; - -/** - * A window feature at the top of the activity that may display the activity title, navigation - * modes, and other interactive items. - *

Beginning with Android 3.0 (API level 11), the action bar appears at the top of an - * activity's window when the activity uses the system's {@link - * android.R.style#Theme_Holo Holo} theme (or one of its descendant themes), which is the default. - * You may otherwise add the action bar by calling {@link - * android.view.Window#requestFeature requestFeature(FEATURE_ACTION_BAR)} or by declaring it in a - * custom theme with the {@link android.R.styleable#Theme_windowActionBar windowActionBar} property. - *

By default, the action bar shows the application icon on - * the left, followed by the activity title. If your activity has an options menu, you can make - * select items accessible directly from the action bar as "action items". You can also - * modify various characteristics of the action bar or remove it completely.

- *

From your activity, you can retrieve an instance of {@link ActionBar} by calling {@link - * android.app.Activity#getActionBar getActionBar()}.

- *

In some cases, the action bar may be overlayed by another bar that enables contextual actions, - * using an {@link android.view.ActionMode}. For example, when the user selects one or more items in - * your activity, you can enable an action mode that offers actions specific to the selected - * items, with a UI that temporarily replaces the action bar. Although the UI may occupy the - * same space, the {@link android.view.ActionMode} APIs are distinct and independent from those for - * {@link ActionBar}. - *

- */ -public abstract class ActionBar { - /** - * Standard navigation mode. Consists of either a logo or icon - * and title text with an optional subtitle. Clicking any of these elements - * will dispatch onOptionsItemSelected to the host Activity with - * a MenuItem with item ID android.R.id.home. - */ - public static final int NAVIGATION_MODE_STANDARD = android.app.ActionBar.NAVIGATION_MODE_STANDARD; - - /** - * List navigation mode. Instead of static title text this mode - * presents a list menu for navigation within the activity. - * e.g. this might be presented to the user as a dropdown list. - */ - public static final int NAVIGATION_MODE_LIST = android.app.ActionBar.NAVIGATION_MODE_LIST; - - /** - * Tab navigation mode. Instead of static title text this mode - * presents a series of tabs for navigation within the activity. - */ - public static final int NAVIGATION_MODE_TABS = android.app.ActionBar.NAVIGATION_MODE_TABS; - - /** - * Use logo instead of icon if available. This flag will cause appropriate - * navigation modes to use a wider logo in place of the standard icon. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public static final int DISPLAY_USE_LOGO = android.app.ActionBar.DISPLAY_USE_LOGO; - - /** - * Show 'home' elements in this action bar, leaving more space for other - * navigation elements. This includes logo and icon. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public static final int DISPLAY_SHOW_HOME = android.app.ActionBar.DISPLAY_SHOW_HOME; - - /** - * Display the 'home' element such that it appears as an 'up' affordance. - * e.g. show an arrow to the left indicating the action that will be taken. - * - * Set this flag if selecting the 'home' button in the action bar to return - * up by a single level in your UI rather than back to the top level or front page. - * - *

Setting this option will implicitly enable interaction with the home/up - * button. See {@link #setHomeButtonEnabled(boolean)}. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public static final int DISPLAY_HOME_AS_UP = android.app.ActionBar.DISPLAY_HOME_AS_UP; - - /** - * Show the activity title and subtitle, if present. - * - * @see #setTitle(CharSequence) - * @see #setTitle(int) - * @see #setSubtitle(CharSequence) - * @see #setSubtitle(int) - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public static final int DISPLAY_SHOW_TITLE = android.app.ActionBar.DISPLAY_SHOW_TITLE; - - /** - * Show the custom view if one has been set. - * @see #setCustomView(View) - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public static final int DISPLAY_SHOW_CUSTOM = android.app.ActionBar.DISPLAY_SHOW_CUSTOM; - - /** - * Set the action bar into custom navigation mode, supplying a view - * for custom navigation. - * - * Custom navigation views appear between the application icon and - * any action buttons and may use any space available there. Common - * use cases for custom navigation views might include an auto-suggesting - * address bar for a browser or other navigation mechanisms that do not - * translate well to provided navigation modes. - * - * @param view Custom navigation view to place in the ActionBar. - */ - public abstract void setCustomView(View view); - - /** - * Set the action bar into custom navigation mode, supplying a view - * for custom navigation. - * - *

Custom navigation views appear between the application icon and - * any action buttons and may use any space available there. Common - * use cases for custom navigation views might include an auto-suggesting - * address bar for a browser or other navigation mechanisms that do not - * translate well to provided navigation modes.

- * - *

The display option {@link #DISPLAY_SHOW_CUSTOM} must be set for - * the custom view to be displayed.

- * - * @param view Custom navigation view to place in the ActionBar. - * @param layoutParams How this custom view should layout in the bar. - * - * @see #setDisplayOptions(int, int) - */ - public abstract void setCustomView(View view, LayoutParams layoutParams); - - /** - * Set the action bar into custom navigation mode, supplying a view - * for custom navigation. - * - *

Custom navigation views appear between the application icon and - * any action buttons and may use any space available there. Common - * use cases for custom navigation views might include an auto-suggesting - * address bar for a browser or other navigation mechanisms that do not - * translate well to provided navigation modes.

- * - *

The display option {@link #DISPLAY_SHOW_CUSTOM} must be set for - * the custom view to be displayed.

- * - * @param resId Resource ID of a layout to inflate into the ActionBar. - * - * @see #setDisplayOptions(int, int) - */ - public abstract void setCustomView(int resId); - - /** - * Set the icon to display in the 'home' section of the action bar. - * The action bar will use an icon specified by its style or the - * activity icon by default. - * - * Whether the home section shows an icon or logo is controlled - * by the display option {@link #DISPLAY_USE_LOGO}. - * - * @param resId Resource ID of a drawable to show as an icon. - * - * @see #setDisplayUseLogoEnabled(boolean) - * @see #setDisplayShowHomeEnabled(boolean) - */ - public abstract void setIcon(int resId); - - /** - * Set the icon to display in the 'home' section of the action bar. - * The action bar will use an icon specified by its style or the - * activity icon by default. - * - * Whether the home section shows an icon or logo is controlled - * by the display option {@link #DISPLAY_USE_LOGO}. - * - * @param icon Drawable to show as an icon. - * - * @see #setDisplayUseLogoEnabled(boolean) - * @see #setDisplayShowHomeEnabled(boolean) - */ - public abstract void setIcon(Drawable icon); - - /** - * Set the logo to display in the 'home' section of the action bar. - * The action bar will use a logo specified by its style or the - * activity logo by default. - * - * Whether the home section shows an icon or logo is controlled - * by the display option {@link #DISPLAY_USE_LOGO}. - * - * @param resId Resource ID of a drawable to show as a logo. - * - * @see #setDisplayUseLogoEnabled(boolean) - * @see #setDisplayShowHomeEnabled(boolean) - */ - public abstract void setLogo(int resId); - - /** - * Set the logo to display in the 'home' section of the action bar. - * The action bar will use a logo specified by its style or the - * activity logo by default. - * - * Whether the home section shows an icon or logo is controlled - * by the display option {@link #DISPLAY_USE_LOGO}. - * - * @param logo Drawable to show as a logo. - * - * @see #setDisplayUseLogoEnabled(boolean) - * @see #setDisplayShowHomeEnabled(boolean) - */ - public abstract void setLogo(Drawable logo); - - /** - * Set the adapter and navigation callback for list navigation mode. - * - * The supplied adapter will provide views for the expanded list as well as - * the currently selected item. (These may be displayed differently.) - * - * The supplied OnNavigationListener will alert the application when the user - * changes the current list selection. - * - * @param adapter An adapter that will provide views both to display - * the current navigation selection and populate views - * within the dropdown navigation menu. - * @param callback An OnNavigationListener that will receive events when the user - * selects a navigation item. - */ - public abstract void setListNavigationCallbacks(SpinnerAdapter adapter, - OnNavigationListener callback); - - /** - * Set the selected navigation item in list or tabbed navigation modes. - * - * @param position Position of the item to select. - */ - public abstract void setSelectedNavigationItem(int position); - - /** - * Get the position of the selected navigation item in list or tabbed navigation modes. - * - * @return Position of the selected item. - */ - public abstract int getSelectedNavigationIndex(); - - /** - * Get the number of navigation items present in the current navigation mode. - * - * @return Number of navigation items. - */ - public abstract int getNavigationItemCount(); - - /** - * Set the action bar's title. This will only be displayed if - * {@link #DISPLAY_SHOW_TITLE} is set. - * - * @param title Title to set - * - * @see #setTitle(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setTitle(CharSequence title); - - /** - * Set the action bar's title. This will only be displayed if - * {@link #DISPLAY_SHOW_TITLE} is set. - * - * @param resId Resource ID of title string to set - * - * @see #setTitle(CharSequence) - * @see #setDisplayOptions(int, int) - */ - public abstract void setTitle(int resId); - - /** - * Set the action bar's subtitle. This will only be displayed if - * {@link #DISPLAY_SHOW_TITLE} is set. Set to null to disable the - * subtitle entirely. - * - * @param subtitle Subtitle to set - * - * @see #setSubtitle(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setSubtitle(CharSequence subtitle); - - /** - * Set the action bar's subtitle. This will only be displayed if - * {@link #DISPLAY_SHOW_TITLE} is set. - * - * @param resId Resource ID of subtitle string to set - * - * @see #setSubtitle(CharSequence) - * @see #setDisplayOptions(int, int) - */ - public abstract void setSubtitle(int resId); - - /** - * Set display options. This changes all display option bits at once. To change - * a limited subset of display options, see {@link #setDisplayOptions(int, int)}. - * - * @param options A combination of the bits defined by the DISPLAY_ constants - * defined in ActionBar. - */ - public abstract void setDisplayOptions(int options); - - /** - * Set selected display options. Only the options specified by mask will be changed. - * To change all display option bits at once, see {@link #setDisplayOptions(int)}. - * - *

Example: setDisplayOptions(0, DISPLAY_SHOW_HOME) will disable the - * {@link #DISPLAY_SHOW_HOME} option. - * setDisplayOptions(DISPLAY_SHOW_HOME, DISPLAY_SHOW_HOME | DISPLAY_USE_LOGO) - * will enable {@link #DISPLAY_SHOW_HOME} and disable {@link #DISPLAY_USE_LOGO}. - * - * @param options A combination of the bits defined by the DISPLAY_ constants - * defined in ActionBar. - * @param mask A bit mask declaring which display options should be changed. - */ - public abstract void setDisplayOptions(int options, int mask); - - /** - * Set whether to display the activity logo rather than the activity icon. - * A logo is often a wider, more detailed image. - * - *

To set several display options at once, see the setDisplayOptions methods. - * - * @param useLogo true to use the activity logo, false to use the activity icon. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setDisplayUseLogoEnabled(boolean useLogo); - - /** - * Set whether to include the application home affordance in the action bar. - * Home is presented as either an activity icon or logo. - * - *

To set several display options at once, see the setDisplayOptions methods. - * - * @param showHome true to show home, false otherwise. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setDisplayShowHomeEnabled(boolean showHome); - - /** - * Set whether home should be displayed as an "up" affordance. - * Set this to true if selecting "home" returns up by a single level in your UI - * rather than back to the top level or front page. - * - *

To set several display options at once, see the setDisplayOptions methods. - * - * @param showHomeAsUp true to show the user that selecting home will return one - * level up rather than to the top level of the app. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setDisplayHomeAsUpEnabled(boolean showHomeAsUp); - - /** - * Set whether an activity title/subtitle should be displayed. - * - *

To set several display options at once, see the setDisplayOptions methods. - * - * @param showTitle true to display a title/subtitle if present. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setDisplayShowTitleEnabled(boolean showTitle); - - /** - * Set whether a custom view should be displayed, if set. - * - *

To set several display options at once, see the setDisplayOptions methods. - * - * @param showCustom true if the currently set custom view should be displayed, false otherwise. - * - * @see #setDisplayOptions(int) - * @see #setDisplayOptions(int, int) - */ - public abstract void setDisplayShowCustomEnabled(boolean showCustom); - - /** - * Set the ActionBar's background. This will be used for the primary - * action bar. - * - * @param d Background drawable - * @see #setStackedBackgroundDrawable(Drawable) - * @see #setSplitBackgroundDrawable(Drawable) - */ - public abstract void setBackgroundDrawable(Drawable d); - - /** - * Set the ActionBar's stacked background. This will appear - * in the second row/stacked bar on some devices and configurations. - * - * @param d Background drawable for the stacked row - */ - public void setStackedBackgroundDrawable(Drawable d) { } - - /** - * Set the ActionBar's split background. This will appear in - * the split action bar containing menu-provided action buttons - * on some devices and configurations. - *

You can enable split action bar with {@link android.R.attr#uiOptions} - * - * @param d Background drawable for the split bar - */ - public void setSplitBackgroundDrawable(Drawable d) { } - - /** - * @return The current custom view. - */ - public abstract View getCustomView(); - - /** - * Returns the current ActionBar title in standard mode. - * Returns null if {@link #getNavigationMode()} would not return - * {@link #NAVIGATION_MODE_STANDARD}. - * - * @return The current ActionBar title or null. - */ - public abstract CharSequence getTitle(); - - /** - * Returns the current ActionBar subtitle in standard mode. - * Returns null if {@link #getNavigationMode()} would not return - * {@link #NAVIGATION_MODE_STANDARD}. - * - * @return The current ActionBar subtitle or null. - */ - public abstract CharSequence getSubtitle(); - - /** - * Returns the current navigation mode. The result will be one of: - *

    - *
  • {@link #NAVIGATION_MODE_STANDARD}
  • - *
  • {@link #NAVIGATION_MODE_LIST}
  • - *
  • {@link #NAVIGATION_MODE_TABS}
  • - *
- * - * @return The current navigation mode. - */ - public abstract int getNavigationMode(); - - /** - * Set the current navigation mode. - * - * @param mode The new mode to set. - * @see #NAVIGATION_MODE_STANDARD - * @see #NAVIGATION_MODE_LIST - * @see #NAVIGATION_MODE_TABS - */ - public abstract void setNavigationMode(int mode); - - /** - * @return The current set of display options. - */ - public abstract int getDisplayOptions(); - - /** - * Create and return a new {@link Tab}. - * This tab will not be included in the action bar until it is added. - * - *

Very often tabs will be used to switch between {@link Fragment} - * objects. Here is a typical implementation of such tabs:

- * - * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.java - * complete} - * - * @return A new Tab - * - * @see #addTab(Tab) - */ - public abstract Tab newTab(); - - /** - * Add a tab for use in tabbed navigation mode. The tab will be added at the end of the list. - * If this is the first tab to be added it will become the selected tab. - * - * @param tab Tab to add - */ - public abstract void addTab(Tab tab); - - /** - * Add a tab for use in tabbed navigation mode. The tab will be added at the end of the list. - * - * @param tab Tab to add - * @param setSelected True if the added tab should become the selected tab. - */ - public abstract void addTab(Tab tab, boolean setSelected); - - /** - * Add a tab for use in tabbed navigation mode. The tab will be inserted at - * position. If this is the first tab to be added it will become - * the selected tab. - * - * @param tab The tab to add - * @param position The new position of the tab - */ - public abstract void addTab(Tab tab, int position); - - /** - * Add a tab for use in tabbed navigation mode. The tab will be insterted at - * position. - * - * @param tab The tab to add - * @param position The new position of the tab - * @param setSelected True if the added tab should become the selected tab. - */ - public abstract void addTab(Tab tab, int position, boolean setSelected); - - /** - * Remove a tab from the action bar. If the removed tab was selected it will be deselected - * and another tab will be selected if present. - * - * @param tab The tab to remove - */ - public abstract void removeTab(Tab tab); - - /** - * Remove a tab from the action bar. If the removed tab was selected it will be deselected - * and another tab will be selected if present. - * - * @param position Position of the tab to remove - */ - public abstract void removeTabAt(int position); - - /** - * Remove all tabs from the action bar and deselect the current tab. - */ - public abstract void removeAllTabs(); - - /** - * Select the specified tab. If it is not a child of this action bar it will be added. - * - *

Note: If you want to select by index, use {@link #setSelectedNavigationItem(int)}.

- * - * @param tab Tab to select - */ - public abstract void selectTab(Tab tab); - - /** - * Returns the currently selected tab if in tabbed navigation mode and there is at least - * one tab present. - * - * @return The currently selected tab or null - */ - public abstract Tab getSelectedTab(); - - /** - * Returns the tab at the specified index. - * - * @param index Index value in the range 0-get - * @return - */ - public abstract Tab getTabAt(int index); - - /** - * Returns the number of tabs currently registered with the action bar. - * @return Tab count - */ - public abstract int getTabCount(); - - /** - * Retrieve the current height of the ActionBar. - * - * @return The ActionBar's height - */ - public abstract int getHeight(); - - /** - * Show the ActionBar if it is not currently showing. - * If the window hosting the ActionBar does not have the feature - * {@link Window#FEATURE_ACTION_BAR_OVERLAY} it will resize application - * content to fit the new space available. - */ - public abstract void show(); - - /** - * Hide the ActionBar if it is currently showing. - * If the window hosting the ActionBar does not have the feature - * {@link Window#FEATURE_ACTION_BAR_OVERLAY} it will resize application - * content to fit the new space available. - */ - public abstract void hide(); - - /** - * @return true if the ActionBar is showing, false otherwise. - */ - public abstract boolean isShowing(); - - /** - * Add a listener that will respond to menu visibility change events. - * - * @param listener The new listener to add - */ - public abstract void addOnMenuVisibilityListener(OnMenuVisibilityListener listener); - - /** - * Remove a menu visibility listener. This listener will no longer receive menu - * visibility change events. - * - * @param listener A listener to remove that was previously added - */ - public abstract void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener); - - /** - * Enable or disable the "home" button in the corner of the action bar. (Note that this - * is the application home/up affordance on the action bar, not the systemwide home - * button.) - * - *

This defaults to true for packages targeting < API 14. For packages targeting - * API 14 or greater, the application should call this method to enable interaction - * with the home/up affordance. - * - *

Setting the {@link #DISPLAY_HOME_AS_UP} display option will automatically enable - * the home button. - * - * @param enabled true to enable the home button, false to disable the home button. - */ - public void setHomeButtonEnabled(boolean enabled) { } - - /** - * Returns a {@link Context} with an appropriate theme for creating views that - * will appear in the action bar. If you are inflating or instantiating custom views - * that will appear in an action bar, you should use the Context returned by this method. - * (This includes adapters used for list navigation mode.) - * This will ensure that views contrast properly against the action bar. - * - * @return A themed Context for creating views - */ - public Context getThemedContext() { return null; } - - /** - * Listener interface for ActionBar navigation events. - */ - public interface OnNavigationListener { - /** - * This method is called whenever a navigation item in your action bar - * is selected. - * - * @param itemPosition Position of the item clicked. - * @param itemId ID of the item clicked. - * @return True if the event was handled, false otherwise. - */ - public boolean onNavigationItemSelected(int itemPosition, long itemId); - } - - /** - * Listener for receiving events when action bar menus are shown or hidden. - */ - public interface OnMenuVisibilityListener { - /** - * Called when an action bar menu is shown or hidden. Applications may want to use - * this to tune auto-hiding behavior for the action bar or pause/resume video playback, - * gameplay, or other activity within the main content area. - * - * @param isVisible True if an action bar menu is now visible, false if no action bar - * menus are visible. - */ - public void onMenuVisibilityChanged(boolean isVisible); - } - - /** - * A tab in the action bar. - * - *

Tabs manage the hiding and showing of {@link Fragment}s. - */ - public static abstract class Tab { - /** - * An invalid position for a tab. - * - * @see #getPosition() - */ - public static final int INVALID_POSITION = -1; - - /** - * Return the current position of this tab in the action bar. - * - * @return Current position, or {@link #INVALID_POSITION} if this tab is not currently in - * the action bar. - */ - public abstract int getPosition(); - - /** - * Return the icon associated with this tab. - * - * @return The tab's icon - */ - public abstract Drawable getIcon(); - - /** - * Return the text of this tab. - * - * @return The tab's text - */ - public abstract CharSequence getText(); - - /** - * Set the icon displayed on this tab. - * - * @param icon The drawable to use as an icon - * @return The current instance for call chaining - */ - public abstract Tab setIcon(Drawable icon); - - /** - * Set the icon displayed on this tab. - * - * @param resId Resource ID referring to the drawable to use as an icon - * @return The current instance for call chaining - */ - public abstract Tab setIcon(int resId); - - /** - * Set the text displayed on this tab. Text may be truncated if there is not - * room to display the entire string. - * - * @param text The text to display - * @return The current instance for call chaining - */ - public abstract Tab setText(CharSequence text); - - /** - * Set the text displayed on this tab. Text may be truncated if there is not - * room to display the entire string. - * - * @param resId A resource ID referring to the text that should be displayed - * @return The current instance for call chaining - */ - public abstract Tab setText(int resId); - - /** - * Set a custom view to be used for this tab. This overrides values set by - * {@link #setText(CharSequence)} and {@link #setIcon(Drawable)}. - * - * @param view Custom view to be used as a tab. - * @return The current instance for call chaining - */ - public abstract Tab setCustomView(View view); - - /** - * Set a custom view to be used for this tab. This overrides values set by - * {@link #setText(CharSequence)} and {@link #setIcon(Drawable)}. - * - * @param layoutResId A layout resource to inflate and use as a custom tab view - * @return The current instance for call chaining - */ - public abstract Tab setCustomView(int layoutResId); - - /** - * Retrieve a previously set custom view for this tab. - * - * @return The custom view set by {@link #setCustomView(View)}. - */ - public abstract View getCustomView(); - - /** - * Give this Tab an arbitrary object to hold for later use. - * - * @param obj Object to store - * @return The current instance for call chaining - */ - public abstract Tab setTag(Object obj); - - /** - * @return This Tab's tag object. - */ - public abstract Object getTag(); - - /** - * Set the {@link TabListener} that will handle switching to and from this tab. - * All tabs must have a TabListener set before being added to the ActionBar. - * - * @param listener Listener to handle tab selection events - * @return The current instance for call chaining - */ - public abstract Tab setTabListener(TabListener listener); - - /** - * Select this tab. Only valid if the tab has been added to the action bar. - */ - public abstract void select(); - - /** - * Set a description of this tab's content for use in accessibility support. - * If no content description is provided the title will be used. - * - * @param resId A resource ID referring to the description text - * @return The current instance for call chaining - * @see #setContentDescription(CharSequence) - * @see #getContentDescription() - */ - public abstract Tab setContentDescription(int resId); - - /** - * Set a description of this tab's content for use in accessibility support. - * If no content description is provided the title will be used. - * - * @param contentDesc Description of this tab's content - * @return The current instance for call chaining - * @see #setContentDescription(int) - * @see #getContentDescription() - */ - public abstract Tab setContentDescription(CharSequence contentDesc); - - /** - * Gets a brief description of this tab's content for use in accessibility support. - * - * @return Description of this tab's content - * @see #setContentDescription(CharSequence) - * @see #setContentDescription(int) - */ - public abstract CharSequence getContentDescription(); - } - - /** - * Callback interface invoked when a tab is focused, unfocused, added, or removed. - */ - public interface TabListener { - /** - * Called when a tab enters the selected state. - * - * @param tab The tab that was selected - * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute - * during a tab switch. The previous tab's unselect and this tab's select will be - * executed in a single transaction. This FragmentTransaction does not support - * being added to the back stack. - */ - public void onTabSelected(Tab tab, FragmentTransaction ft); - - /** - * Called when a tab exits the selected state. - * - * @param tab The tab that was unselected - * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute - * during a tab switch. This tab's unselect and the newly selected tab's select - * will be executed in a single transaction. This FragmentTransaction does not - * support being added to the back stack. - */ - public void onTabUnselected(Tab tab, FragmentTransaction ft); - - /** - * Called when a tab that is already selected is chosen again by the user. - * Some applications may use this action to return to the top level of a category. - * - * @param tab The tab that was reselected. - * @param ft A {@link FragmentTransaction} for queuing fragment operations to execute - * once this method returns. This FragmentTransaction does not support - * being added to the back stack. - */ - public void onTabReselected(Tab tab, FragmentTransaction ft); - } - - /** - * Per-child layout information associated with action bar custom views. - * - * @attr ref android.R.styleable#ActionBar_LayoutParams_layout_gravity - */ - public static class LayoutParams extends MarginLayoutParams { - private static final int[] ATTRS = new int[] { - android.R.attr.layout_gravity - }; - - /** - * Gravity for the view associated with these LayoutParams. - * - * @see android.view.Gravity - */ - @ViewDebug.ExportedProperty(mapping = { - @ViewDebug.IntToString(from = -1, to = "NONE"), - @ViewDebug.IntToString(from = Gravity.NO_GRAVITY, to = "NONE"), - @ViewDebug.IntToString(from = Gravity.TOP, to = "TOP"), - @ViewDebug.IntToString(from = Gravity.BOTTOM, to = "BOTTOM"), - @ViewDebug.IntToString(from = Gravity.LEFT, to = "LEFT"), - @ViewDebug.IntToString(from = Gravity.RIGHT, to = "RIGHT"), - @ViewDebug.IntToString(from = Gravity.CENTER_VERTICAL, to = "CENTER_VERTICAL"), - @ViewDebug.IntToString(from = Gravity.FILL_VERTICAL, to = "FILL_VERTICAL"), - @ViewDebug.IntToString(from = Gravity.CENTER_HORIZONTAL, to = "CENTER_HORIZONTAL"), - @ViewDebug.IntToString(from = Gravity.FILL_HORIZONTAL, to = "FILL_HORIZONTAL"), - @ViewDebug.IntToString(from = Gravity.CENTER, to = "CENTER"), - @ViewDebug.IntToString(from = Gravity.FILL, to = "FILL") - }) - public int gravity = -1; - - public LayoutParams(Context c, AttributeSet attrs) { - super(c, attrs); - - TypedArray a = c.obtainStyledAttributes(attrs, ATTRS); - gravity = a.getInt(0, -1); - a.recycle(); - } - - public LayoutParams(int width, int height) { - super(width, height); - this.gravity = Gravity.CENTER_VERTICAL | Gravity.LEFT; - } - - public LayoutParams(int width, int height, int gravity) { - super(width, height); - this.gravity = gravity; - } - - public LayoutParams(int gravity) { - this(WRAP_CONTENT, FILL_PARENT, gravity); - } - - public LayoutParams(LayoutParams source) { - super(source); - - this.gravity = source.gravity; - } - - public LayoutParams(ViewGroup.LayoutParams source) { - super(source); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockActivity.java b/actionbarsherlock/src/com/actionbarsherlock/app/SherlockActivity.java deleted file mode 100644 index 7b454364..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockActivity.java +++ /dev/null @@ -1,270 +0,0 @@ -package com.actionbarsherlock.app; - -import android.app.Activity; -import android.content.res.Configuration; -import android.os.Bundle; -import android.view.KeyEvent; -import android.view.View; -import android.view.Window; -import android.view.ViewGroup.LayoutParams; -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; -import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; -import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; -import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -public abstract class SherlockActivity extends Activity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener, OnActionModeStartedListener, OnActionModeFinishedListener { - private ActionBarSherlock mSherlock; - - protected final ActionBarSherlock getSherlock() { - if (mSherlock == null) { - mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); - } - return mSherlock; - } - - - /////////////////////////////////////////////////////////////////////////// - // Action bar and mode - /////////////////////////////////////////////////////////////////////////// - - public ActionBar getSupportActionBar() { - return getSherlock().getActionBar(); - } - - public ActionMode startActionMode(ActionMode.Callback callback) { - return getSherlock().startActionMode(callback); - } - - @Override - public void onActionModeStarted(ActionMode mode) {} - - @Override - public void onActionModeFinished(ActionMode mode) {} - - - /////////////////////////////////////////////////////////////////////////// - // General lifecycle/callback dispatching - /////////////////////////////////////////////////////////////////////////// - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - getSherlock().dispatchConfigurationChanged(newConfig); - } - - @Override - protected void onPostResume() { - super.onPostResume(); - getSherlock().dispatchPostResume(); - } - - @Override - protected void onPause() { - getSherlock().dispatchPause(); - super.onPause(); - } - - @Override - protected void onStop() { - getSherlock().dispatchStop(); - super.onStop(); - } - - @Override - protected void onDestroy() { - getSherlock().dispatchDestroy(); - super.onDestroy(); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - getSherlock().dispatchPostCreate(savedInstanceState); - super.onPostCreate(savedInstanceState); - } - - @Override - protected void onTitleChanged(CharSequence title, int color) { - getSherlock().dispatchTitleChanged(title, color); - super.onTitleChanged(title, color); - } - - @Override - public final boolean onMenuOpened(int featureId, android.view.Menu menu) { - if (getSherlock().dispatchMenuOpened(featureId, menu)) { - return true; - } - return super.onMenuOpened(featureId, menu); - } - - @Override - public void onPanelClosed(int featureId, android.view.Menu menu) { - getSherlock().dispatchPanelClosed(featureId, menu); - super.onPanelClosed(featureId, menu); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (getSherlock().dispatchKeyEvent(event)) { - return true; - } - return super.dispatchKeyEvent(event); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - getSherlock().dispatchSaveInstanceState(outState); - } - - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - getSherlock().dispatchRestoreInstanceState(savedInstanceState); - } - - /////////////////////////////////////////////////////////////////////////// - // Native menu handling - /////////////////////////////////////////////////////////////////////////// - - public MenuInflater getSupportMenuInflater() { - return getSherlock().getMenuInflater(); - } - - public void invalidateOptionsMenu() { - getSherlock().dispatchInvalidateOptionsMenu(); - } - - public void supportInvalidateOptionsMenu() { - invalidateOptionsMenu(); - } - - @Override - public final boolean onCreateOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchCreateOptionsMenu(menu); - } - - @Override - public final boolean onPrepareOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchPrepareOptionsMenu(menu); - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return getSherlock().dispatchOptionsItemSelected(item); - } - - @Override - public void openOptionsMenu() { - if (!getSherlock().dispatchOpenOptionsMenu()) { - super.openOptionsMenu(); - } - } - - @Override - public void closeOptionsMenu() { - if (!getSherlock().dispatchCloseOptionsMenu()) { - super.closeOptionsMenu(); - } - } - - - /////////////////////////////////////////////////////////////////////////// - // Sherlock menu handling - /////////////////////////////////////////////////////////////////////////// - - @Override - public boolean onCreatePanelMenu(int featureId, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onCreateOptionsMenu(menu); - } - return false; - } - - public boolean onCreateOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onPreparePanel(int featureId, View view, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onPrepareOptionsMenu(menu); - } - return false; - } - - public boolean onPrepareOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onOptionsItemSelected(item); - } - return false; - } - - public boolean onOptionsItemSelected(MenuItem item) { - return false; - } - - - /////////////////////////////////////////////////////////////////////////// - // Content - /////////////////////////////////////////////////////////////////////////// - - @Override - public void addContentView(View view, LayoutParams params) { - getSherlock().addContentView(view, params); - } - - @Override - public void setContentView(int layoutResId) { - getSherlock().setContentView(layoutResId); - } - - @Override - public void setContentView(View view, LayoutParams params) { - getSherlock().setContentView(view, params); - } - - @Override - public void setContentView(View view) { - getSherlock().setContentView(view); - } - - public void requestWindowFeature(long featureId) { - getSherlock().requestFeature((int)featureId); - } - - - /////////////////////////////////////////////////////////////////////////// - // Progress Indication - /////////////////////////////////////////////////////////////////////////// - - public void setSupportProgress(int progress) { - getSherlock().setProgress(progress); - } - - public void setSupportProgressBarIndeterminate(boolean indeterminate) { - getSherlock().setProgressBarIndeterminate(indeterminate); - } - - public void setSupportProgressBarIndeterminateVisibility(boolean visible) { - getSherlock().setProgressBarIndeterminateVisibility(visible); - } - - public void setSupportProgressBarVisibility(boolean visible) { - getSherlock().setProgressBarVisibility(visible); - } - - public void setSupportSecondaryProgress(int secondaryProgress) { - getSherlock().setSecondaryProgress(secondaryProgress); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockDialogFragment.java b/actionbarsherlock/src/com/actionbarsherlock/app/SherlockDialogFragment.java deleted file mode 100644 index a7c856bf..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockDialogFragment.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.actionbarsherlock.app; - -import android.app.Activity; -import android.support.v4.app.DialogFragment; -import com.actionbarsherlock.internal.view.menu.MenuItemWrapper; -import com.actionbarsherlock.internal.view.menu.MenuWrapper; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnCreateOptionsMenuListener; -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnOptionsItemSelectedListener; -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnPrepareOptionsMenuListener; - -public class SherlockDialogFragment extends DialogFragment implements OnCreateOptionsMenuListener, OnPrepareOptionsMenuListener, OnOptionsItemSelectedListener { - private SherlockFragmentActivity mActivity; - - public SherlockFragmentActivity getSherlockActivity() { - return mActivity; - } - - @Override - public void onAttach(Activity activity) { - if (!(activity instanceof SherlockFragmentActivity)) { - throw new IllegalStateException(getClass().getSimpleName() + " must be attached to a SherlockFragmentActivity."); - } - mActivity = (SherlockFragmentActivity)activity; - - super.onAttach(activity); - } - - @Override - public void onDetach() { - mActivity = null; - super.onDetach(); - } - - @Override - public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) { - onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater()); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - //Nothing to see here. - } - - @Override - public final void onPrepareOptionsMenu(android.view.Menu menu) { - onPrepareOptionsMenu(new MenuWrapper(menu)); - } - - @Override - public void onPrepareOptionsMenu(Menu menu) { - //Nothing to see here. - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return onOptionsItemSelected(new MenuItemWrapper(item)); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - //Nothing to see here. - return false; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockExpandableListActivity.java b/actionbarsherlock/src/com/actionbarsherlock/app/SherlockExpandableListActivity.java deleted file mode 100644 index 078f9b0c..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockExpandableListActivity.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.actionbarsherlock.app; - -import android.app.ExpandableListActivity; -import android.content.res.Configuration; -import android.os.Bundle; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.Window; -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; -import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; -import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; -import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -public abstract class SherlockExpandableListActivity extends ExpandableListActivity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener, OnActionModeStartedListener, OnActionModeFinishedListener { - private ActionBarSherlock mSherlock; - - protected final ActionBarSherlock getSherlock() { - if (mSherlock == null) { - mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); - } - return mSherlock; - } - - - /////////////////////////////////////////////////////////////////////////// - // Action bar and mode - /////////////////////////////////////////////////////////////////////////// - - public ActionBar getSupportActionBar() { - return getSherlock().getActionBar(); - } - - public ActionMode startActionMode(ActionMode.Callback callback) { - return getSherlock().startActionMode(callback); - } - - @Override - public void onActionModeStarted(ActionMode mode) {} - - @Override - public void onActionModeFinished(ActionMode mode) {} - - - /////////////////////////////////////////////////////////////////////////// - // General lifecycle/callback dispatching - /////////////////////////////////////////////////////////////////////////// - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - getSherlock().dispatchConfigurationChanged(newConfig); - } - - @Override - protected void onPostResume() { - super.onPostResume(); - getSherlock().dispatchPostResume(); - } - - @Override - protected void onPause() { - getSherlock().dispatchPause(); - super.onPause(); - } - - @Override - protected void onStop() { - getSherlock().dispatchStop(); - super.onStop(); - } - - @Override - protected void onDestroy() { - getSherlock().dispatchDestroy(); - super.onDestroy(); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - getSherlock().dispatchPostCreate(savedInstanceState); - super.onPostCreate(savedInstanceState); - } - - @Override - protected void onTitleChanged(CharSequence title, int color) { - getSherlock().dispatchTitleChanged(title, color); - super.onTitleChanged(title, color); - } - - @Override - public final boolean onMenuOpened(int featureId, android.view.Menu menu) { - if (getSherlock().dispatchMenuOpened(featureId, menu)) { - return true; - } - return super.onMenuOpened(featureId, menu); - } - - @Override - public void onPanelClosed(int featureId, android.view.Menu menu) { - getSherlock().dispatchPanelClosed(featureId, menu); - super.onPanelClosed(featureId, menu); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (getSherlock().dispatchKeyEvent(event)) { - return true; - } - return super.dispatchKeyEvent(event); - } - - - /////////////////////////////////////////////////////////////////////////// - // Native menu handling - /////////////////////////////////////////////////////////////////////////// - - public MenuInflater getSupportMenuInflater() { - return getSherlock().getMenuInflater(); - } - - public void invalidateOptionsMenu() { - getSherlock().dispatchInvalidateOptionsMenu(); - } - - public void supportInvalidateOptionsMenu() { - invalidateOptionsMenu(); - } - - @Override - public final boolean onCreateOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchCreateOptionsMenu(menu); - } - - @Override - public final boolean onPrepareOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchPrepareOptionsMenu(menu); - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return getSherlock().dispatchOptionsItemSelected(item); - } - - @Override - public void openOptionsMenu() { - if (!getSherlock().dispatchOpenOptionsMenu()) { - super.openOptionsMenu(); - } - } - - @Override - public void closeOptionsMenu() { - if (!getSherlock().dispatchCloseOptionsMenu()) { - super.closeOptionsMenu(); - } - } - - - /////////////////////////////////////////////////////////////////////////// - // Sherlock menu handling - /////////////////////////////////////////////////////////////////////////// - - @Override - public boolean onCreatePanelMenu(int featureId, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onCreateOptionsMenu(menu); - } - return false; - } - - public boolean onCreateOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onPreparePanel(int featureId, View view, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onPrepareOptionsMenu(menu); - } - return false; - } - - public boolean onPrepareOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onOptionsItemSelected(item); - } - return false; - } - - public boolean onOptionsItemSelected(MenuItem item) { - return false; - } - - - /////////////////////////////////////////////////////////////////////////// - // Content - /////////////////////////////////////////////////////////////////////////// - - @Override - public void addContentView(View view, LayoutParams params) { - getSherlock().addContentView(view, params); - } - - @Override - public void setContentView(int layoutResId) { - getSherlock().setContentView(layoutResId); - } - - @Override - public void setContentView(View view, LayoutParams params) { - getSherlock().setContentView(view, params); - } - - @Override - public void setContentView(View view) { - getSherlock().setContentView(view); - } - - public void requestWindowFeature(long featureId) { - getSherlock().requestFeature((int)featureId); - } - - - /////////////////////////////////////////////////////////////////////////// - // Progress Indication - /////////////////////////////////////////////////////////////////////////// - - public void setSupportProgress(int progress) { - getSherlock().setProgress(progress); - } - - public void setSupportProgressBarIndeterminate(boolean indeterminate) { - getSherlock().setProgressBarIndeterminate(indeterminate); - } - - public void setSupportProgressBarIndeterminateVisibility(boolean visible) { - getSherlock().setProgressBarIndeterminateVisibility(visible); - } - - public void setSupportProgressBarVisibility(boolean visible) { - getSherlock().setProgressBarVisibility(visible); - } - - public void setSupportSecondaryProgress(int secondaryProgress) { - getSherlock().setSecondaryProgress(secondaryProgress); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockFragment.java b/actionbarsherlock/src/com/actionbarsherlock/app/SherlockFragment.java deleted file mode 100644 index 0f24e9c8..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockFragment.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.actionbarsherlock.app; - -import android.app.Activity; -import android.support.v4.app.Fragment; -import com.actionbarsherlock.internal.view.menu.MenuItemWrapper; -import com.actionbarsherlock.internal.view.menu.MenuWrapper; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnCreateOptionsMenuListener; -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnOptionsItemSelectedListener; -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnPrepareOptionsMenuListener; - -public class SherlockFragment extends Fragment implements OnCreateOptionsMenuListener, OnPrepareOptionsMenuListener, OnOptionsItemSelectedListener { - private SherlockFragmentActivity mActivity; - - public SherlockFragmentActivity getSherlockActivity() { - return mActivity; - } - - @Override - public void onAttach(Activity activity) { - if (!(activity instanceof SherlockFragmentActivity)) { - throw new IllegalStateException(getClass().getSimpleName() + " must be attached to a SherlockFragmentActivity."); - } - mActivity = (SherlockFragmentActivity)activity; - - super.onAttach(activity); - } - - @Override - public void onDetach() { - mActivity = null; - super.onDetach(); - } - - @Override - public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) { - onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater()); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - //Nothing to see here. - } - - @Override - public final void onPrepareOptionsMenu(android.view.Menu menu) { - onPrepareOptionsMenu(new MenuWrapper(menu)); - } - - @Override - public void onPrepareOptionsMenu(Menu menu) { - //Nothing to see here. - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return onOptionsItemSelected(new MenuItemWrapper(item)); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - //Nothing to see here. - return false; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockFragmentActivity.java b/actionbarsherlock/src/com/actionbarsherlock/app/SherlockFragmentActivity.java deleted file mode 100644 index 3d092f03..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockFragmentActivity.java +++ /dev/null @@ -1,303 +0,0 @@ -package com.actionbarsherlock.app; - -import android.content.res.Configuration; -import android.os.Bundle; -import android.support.v4.app.Watson; -import android.util.Log; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.Window; -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -import static com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; -import static com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; - -/** @see {@link android.support.v4.app.Watson} */ -public class SherlockFragmentActivity extends Watson implements OnActionModeStartedListener, OnActionModeFinishedListener { - private static final boolean DEBUG = false; - private static final String TAG = "SherlockFragmentActivity"; - - private ActionBarSherlock mSherlock; - private boolean mIgnoreNativeCreate = false; - private boolean mIgnoreNativePrepare = false; - private boolean mIgnoreNativeSelected = false; - - protected final ActionBarSherlock getSherlock() { - if (mSherlock == null) { - mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); - } - return mSherlock; - } - - - /////////////////////////////////////////////////////////////////////////// - // Action bar and mode - /////////////////////////////////////////////////////////////////////////// - - public ActionBar getSupportActionBar() { - return getSherlock().getActionBar(); - } - - public ActionMode startActionMode(ActionMode.Callback callback) { - return getSherlock().startActionMode(callback); - } - - @Override - public void onActionModeStarted(ActionMode mode) {} - - @Override - public void onActionModeFinished(ActionMode mode) {} - - - /////////////////////////////////////////////////////////////////////////// - // General lifecycle/callback dispatching - /////////////////////////////////////////////////////////////////////////// - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - getSherlock().dispatchConfigurationChanged(newConfig); - } - - @Override - protected void onPostResume() { - super.onPostResume(); - getSherlock().dispatchPostResume(); - } - - @Override - protected void onPause() { - getSherlock().dispatchPause(); - super.onPause(); - } - - @Override - protected void onStop() { - getSherlock().dispatchStop(); - super.onStop(); - } - - @Override - protected void onDestroy() { - getSherlock().dispatchDestroy(); - super.onDestroy(); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - getSherlock().dispatchPostCreate(savedInstanceState); - super.onPostCreate(savedInstanceState); - } - - @Override - protected void onTitleChanged(CharSequence title, int color) { - getSherlock().dispatchTitleChanged(title, color); - super.onTitleChanged(title, color); - } - - @Override - public final boolean onMenuOpened(int featureId, android.view.Menu menu) { - if (getSherlock().dispatchMenuOpened(featureId, menu)) { - return true; - } - return super.onMenuOpened(featureId, menu); - } - - @Override - public void onPanelClosed(int featureId, android.view.Menu menu) { - getSherlock().dispatchPanelClosed(featureId, menu); - super.onPanelClosed(featureId, menu); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (getSherlock().dispatchKeyEvent(event)) { - return true; - } - return super.dispatchKeyEvent(event); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - getSherlock().dispatchSaveInstanceState(outState); - } - - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - getSherlock().dispatchRestoreInstanceState(savedInstanceState); - } - - /////////////////////////////////////////////////////////////////////////// - // Native menu handling - /////////////////////////////////////////////////////////////////////////// - - public MenuInflater getSupportMenuInflater() { - if (DEBUG) Log.d(TAG, "[getSupportMenuInflater]"); - - return getSherlock().getMenuInflater(); - } - - public void invalidateOptionsMenu() { - if (DEBUG) Log.d(TAG, "[invalidateOptionsMenu]"); - - getSherlock().dispatchInvalidateOptionsMenu(); - } - - public void supportInvalidateOptionsMenu() { - if (DEBUG) Log.d(TAG, "[supportInvalidateOptionsMenu]"); - - invalidateOptionsMenu(); - } - - @Override - public final boolean onCreatePanelMenu(int featureId, android.view.Menu menu) { - if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] featureId: " + featureId + ", menu: " + menu); - - if (featureId == Window.FEATURE_OPTIONS_PANEL && !mIgnoreNativeCreate) { - mIgnoreNativeCreate = true; - boolean result = getSherlock().dispatchCreateOptionsMenu(menu); - mIgnoreNativeCreate = false; - - if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] returning " + result); - return result; - } - return super.onCreatePanelMenu(featureId, menu); - } - - @Override - public final boolean onCreateOptionsMenu(android.view.Menu menu) { - return true; - } - - @Override - public final boolean onPreparePanel(int featureId, View view, android.view.Menu menu) { - if (DEBUG) Log.d(TAG, "[onPreparePanel] featureId: " + featureId + ", view: " + view + ", menu: " + menu); - - if (featureId == Window.FEATURE_OPTIONS_PANEL && !mIgnoreNativePrepare) { - mIgnoreNativePrepare = true; - boolean result = getSherlock().dispatchPrepareOptionsMenu(menu); - mIgnoreNativePrepare = false; - - if (DEBUG) Log.d(TAG, "[onPreparePanel] returning " + result); - return result; - } - return super.onPreparePanel(featureId, view, menu); - } - - @Override - public final boolean onPrepareOptionsMenu(android.view.Menu menu) { - return true; - } - - @Override - public final boolean onMenuItemSelected(int featureId, android.view.MenuItem item) { - if (DEBUG) Log.d(TAG, "[onMenuItemSelected] featureId: " + featureId + ", item: " + item); - - if (featureId == Window.FEATURE_OPTIONS_PANEL && !mIgnoreNativeSelected) { - mIgnoreNativeSelected = true; - boolean result = getSherlock().dispatchOptionsItemSelected(item); - mIgnoreNativeSelected = false; - - if (DEBUG) Log.d(TAG, "[onMenuItemSelected] returning " + result); - return result; - } - return super.onMenuItemSelected(featureId, item); - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return false; - } - - @Override - public void openOptionsMenu() { - if (!getSherlock().dispatchOpenOptionsMenu()) { - super.openOptionsMenu(); - } - } - - @Override - public void closeOptionsMenu() { - if (!getSherlock().dispatchCloseOptionsMenu()) { - super.closeOptionsMenu(); - } - } - - - /////////////////////////////////////////////////////////////////////////// - // Sherlock menu handling - /////////////////////////////////////////////////////////////////////////// - - public boolean onCreateOptionsMenu(Menu menu) { - return true; - } - - public boolean onPrepareOptionsMenu(Menu menu) { - return true; - } - - public boolean onOptionsItemSelected(MenuItem item) { - return false; - } - - - /////////////////////////////////////////////////////////////////////////// - // Content - /////////////////////////////////////////////////////////////////////////// - - @Override - public void addContentView(View view, LayoutParams params) { - getSherlock().addContentView(view, params); - } - - @Override - public void setContentView(int layoutResId) { - getSherlock().setContentView(layoutResId); - } - - @Override - public void setContentView(View view, LayoutParams params) { - getSherlock().setContentView(view, params); - } - - @Override - public void setContentView(View view) { - getSherlock().setContentView(view); - } - - public void requestWindowFeature(long featureId) { - getSherlock().requestFeature((int)featureId); - } - - - /////////////////////////////////////////////////////////////////////////// - // Progress Indication - /////////////////////////////////////////////////////////////////////////// - - public void setSupportProgress(int progress) { - getSherlock().setProgress(progress); - } - - public void setSupportProgressBarIndeterminate(boolean indeterminate) { - getSherlock().setProgressBarIndeterminate(indeterminate); - } - - public void setSupportProgressBarIndeterminateVisibility(boolean visible) { - getSherlock().setProgressBarIndeterminateVisibility(visible); - } - - public void setSupportProgressBarVisibility(boolean visible) { - getSherlock().setProgressBarVisibility(visible); - } - - public void setSupportSecondaryProgress(int secondaryProgress) { - getSherlock().setSecondaryProgress(secondaryProgress); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockListActivity.java b/actionbarsherlock/src/com/actionbarsherlock/app/SherlockListActivity.java deleted file mode 100644 index aba6d85e..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockListActivity.java +++ /dev/null @@ -1,270 +0,0 @@ -package com.actionbarsherlock.app; - -import android.app.ListActivity; -import android.content.res.Configuration; -import android.os.Bundle; -import android.view.KeyEvent; -import android.view.View; -import android.view.Window; -import android.view.ViewGroup.LayoutParams; -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; -import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; -import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; -import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -public abstract class SherlockListActivity extends ListActivity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener, OnActionModeStartedListener, OnActionModeFinishedListener { - private ActionBarSherlock mSherlock; - - protected final ActionBarSherlock getSherlock() { - if (mSherlock == null) { - mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); - } - return mSherlock; - } - - - /////////////////////////////////////////////////////////////////////////// - // Action bar and mode - /////////////////////////////////////////////////////////////////////////// - - public ActionBar getSupportActionBar() { - return getSherlock().getActionBar(); - } - - public ActionMode startActionMode(ActionMode.Callback callback) { - return getSherlock().startActionMode(callback); - } - - @Override - public void onActionModeStarted(ActionMode mode) {} - - @Override - public void onActionModeFinished(ActionMode mode) {} - - - /////////////////////////////////////////////////////////////////////////// - // General lifecycle/callback dispatching - /////////////////////////////////////////////////////////////////////////// - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - getSherlock().dispatchConfigurationChanged(newConfig); - } - - @Override - protected void onPostResume() { - super.onPostResume(); - getSherlock().dispatchPostResume(); - } - - @Override - protected void onPause() { - getSherlock().dispatchPause(); - super.onPause(); - } - - @Override - protected void onStop() { - getSherlock().dispatchStop(); - super.onStop(); - } - - @Override - protected void onDestroy() { - getSherlock().dispatchDestroy(); - super.onDestroy(); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - getSherlock().dispatchPostCreate(savedInstanceState); - super.onPostCreate(savedInstanceState); - } - - @Override - protected void onTitleChanged(CharSequence title, int color) { - getSherlock().dispatchTitleChanged(title, color); - super.onTitleChanged(title, color); - } - - @Override - public final boolean onMenuOpened(int featureId, android.view.Menu menu) { - if (getSherlock().dispatchMenuOpened(featureId, menu)) { - return true; - } - return super.onMenuOpened(featureId, menu); - } - - @Override - public void onPanelClosed(int featureId, android.view.Menu menu) { - getSherlock().dispatchPanelClosed(featureId, menu); - super.onPanelClosed(featureId, menu); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (getSherlock().dispatchKeyEvent(event)) { - return true; - } - return super.dispatchKeyEvent(event); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - getSherlock().dispatchSaveInstanceState(outState); - } - - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - getSherlock().dispatchRestoreInstanceState(savedInstanceState); - } - - /////////////////////////////////////////////////////////////////////////// - // Native menu handling - /////////////////////////////////////////////////////////////////////////// - - public MenuInflater getSupportMenuInflater() { - return getSherlock().getMenuInflater(); - } - - public void invalidateOptionsMenu() { - getSherlock().dispatchInvalidateOptionsMenu(); - } - - public void supportInvalidateOptionsMenu() { - invalidateOptionsMenu(); - } - - @Override - public final boolean onCreateOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchCreateOptionsMenu(menu); - } - - @Override - public final boolean onPrepareOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchPrepareOptionsMenu(menu); - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return getSherlock().dispatchOptionsItemSelected(item); - } - - @Override - public void openOptionsMenu() { - if (!getSherlock().dispatchOpenOptionsMenu()) { - super.openOptionsMenu(); - } - } - - @Override - public void closeOptionsMenu() { - if (!getSherlock().dispatchCloseOptionsMenu()) { - super.closeOptionsMenu(); - } - } - - - /////////////////////////////////////////////////////////////////////////// - // Sherlock menu handling - /////////////////////////////////////////////////////////////////////////// - - @Override - public boolean onCreatePanelMenu(int featureId, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onCreateOptionsMenu(menu); - } - return false; - } - - public boolean onCreateOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onPreparePanel(int featureId, View view, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onPrepareOptionsMenu(menu); - } - return false; - } - - public boolean onPrepareOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onOptionsItemSelected(item); - } - return false; - } - - public boolean onOptionsItemSelected(MenuItem item) { - return false; - } - - - /////////////////////////////////////////////////////////////////////////// - // Content - /////////////////////////////////////////////////////////////////////////// - - @Override - public void addContentView(View view, LayoutParams params) { - getSherlock().addContentView(view, params); - } - - @Override - public void setContentView(int layoutResId) { - getSherlock().setContentView(layoutResId); - } - - @Override - public void setContentView(View view, LayoutParams params) { - getSherlock().setContentView(view, params); - } - - @Override - public void setContentView(View view) { - getSherlock().setContentView(view); - } - - public void requestWindowFeature(long featureId) { - getSherlock().requestFeature((int)featureId); - } - - - /////////////////////////////////////////////////////////////////////////// - // Progress Indication - /////////////////////////////////////////////////////////////////////////// - - public void setSupportProgress(int progress) { - getSherlock().setProgress(progress); - } - - public void setSupportProgressBarIndeterminate(boolean indeterminate) { - getSherlock().setProgressBarIndeterminate(indeterminate); - } - - public void setSupportProgressBarIndeterminateVisibility(boolean visible) { - getSherlock().setProgressBarIndeterminateVisibility(visible); - } - - public void setSupportProgressBarVisibility(boolean visible) { - getSherlock().setProgressBarVisibility(visible); - } - - public void setSupportSecondaryProgress(int secondaryProgress) { - getSherlock().setSecondaryProgress(secondaryProgress); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockListFragment.java b/actionbarsherlock/src/com/actionbarsherlock/app/SherlockListFragment.java deleted file mode 100644 index 13ca3c49..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockListFragment.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.actionbarsherlock.app; - -import android.app.Activity; -import android.support.v4.app.ListFragment; -import com.actionbarsherlock.internal.view.menu.MenuItemWrapper; -import com.actionbarsherlock.internal.view.menu.MenuWrapper; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnCreateOptionsMenuListener; -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnOptionsItemSelectedListener; -import static com.actionbarsherlock.app.SherlockFragmentActivity.OnPrepareOptionsMenuListener; - -public class SherlockListFragment extends ListFragment implements OnCreateOptionsMenuListener, OnPrepareOptionsMenuListener, OnOptionsItemSelectedListener { - private SherlockFragmentActivity mActivity; - - public SherlockFragmentActivity getSherlockActivity() { - return mActivity; - } - - @Override - public void onAttach(Activity activity) { - if (!(activity instanceof SherlockFragmentActivity)) { - throw new IllegalStateException(getClass().getSimpleName() + " must be attached to a SherlockFragmentActivity."); - } - mActivity = (SherlockFragmentActivity)activity; - - super.onAttach(activity); - } - - @Override - public void onDetach() { - mActivity = null; - super.onDetach(); - } - - @Override - public final void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) { - onCreateOptionsMenu(new MenuWrapper(menu), mActivity.getSupportMenuInflater()); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - //Nothing to see here. - } - - @Override - public final void onPrepareOptionsMenu(android.view.Menu menu) { - onPrepareOptionsMenu(new MenuWrapper(menu)); - } - - @Override - public void onPrepareOptionsMenu(Menu menu) { - //Nothing to see here. - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return onOptionsItemSelected(new MenuItemWrapper(item)); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - //Nothing to see here. - return false; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockPreferenceActivity.java b/actionbarsherlock/src/com/actionbarsherlock/app/SherlockPreferenceActivity.java deleted file mode 100644 index bee72cb2..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/app/SherlockPreferenceActivity.java +++ /dev/null @@ -1,270 +0,0 @@ -package com.actionbarsherlock.app; - -import android.content.res.Configuration; -import android.os.Bundle; -import android.preference.PreferenceActivity; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.Window; -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeFinishedListener; -import com.actionbarsherlock.ActionBarSherlock.OnActionModeStartedListener; -import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; -import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; -import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -public abstract class SherlockPreferenceActivity extends PreferenceActivity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener, OnActionModeStartedListener, OnActionModeFinishedListener { - private ActionBarSherlock mSherlock; - - protected final ActionBarSherlock getSherlock() { - if (mSherlock == null) { - mSherlock = ActionBarSherlock.wrap(this, ActionBarSherlock.FLAG_DELEGATE); - } - return mSherlock; - } - - - /////////////////////////////////////////////////////////////////////////// - // Action bar and mode - /////////////////////////////////////////////////////////////////////////// - - public ActionBar getSupportActionBar() { - return getSherlock().getActionBar(); - } - - public ActionMode startActionMode(ActionMode.Callback callback) { - return getSherlock().startActionMode(callback); - } - - @Override - public void onActionModeStarted(ActionMode mode) {} - - @Override - public void onActionModeFinished(ActionMode mode) {} - - - /////////////////////////////////////////////////////////////////////////// - // General lifecycle/callback dispatching - /////////////////////////////////////////////////////////////////////////// - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - getSherlock().dispatchConfigurationChanged(newConfig); - } - - @Override - protected void onPostResume() { - super.onPostResume(); - getSherlock().dispatchPostResume(); - } - - @Override - protected void onPause() { - getSherlock().dispatchPause(); - super.onPause(); - } - - @Override - protected void onStop() { - getSherlock().dispatchStop(); - super.onStop(); - } - - @Override - protected void onDestroy() { - getSherlock().dispatchDestroy(); - super.onDestroy(); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - getSherlock().dispatchPostCreate(savedInstanceState); - super.onPostCreate(savedInstanceState); - } - - @Override - protected void onTitleChanged(CharSequence title, int color) { - getSherlock().dispatchTitleChanged(title, color); - super.onTitleChanged(title, color); - } - - @Override - public final boolean onMenuOpened(int featureId, android.view.Menu menu) { - if (getSherlock().dispatchMenuOpened(featureId, menu)) { - return true; - } - return super.onMenuOpened(featureId, menu); - } - - @Override - public void onPanelClosed(int featureId, android.view.Menu menu) { - getSherlock().dispatchPanelClosed(featureId, menu); - super.onPanelClosed(featureId, menu); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (getSherlock().dispatchKeyEvent(event)) { - return true; - } - return super.dispatchKeyEvent(event); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - getSherlock().dispatchSaveInstanceState(outState); - } - - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - getSherlock().dispatchRestoreInstanceState(savedInstanceState); - } - - /////////////////////////////////////////////////////////////////////////// - // Native menu handling - /////////////////////////////////////////////////////////////////////////// - - public MenuInflater getSupportMenuInflater() { - return getSherlock().getMenuInflater(); - } - - public void invalidateOptionsMenu() { - getSherlock().dispatchInvalidateOptionsMenu(); - } - - public void supportInvalidateOptionsMenu() { - invalidateOptionsMenu(); - } - - @Override - public final boolean onCreateOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchCreateOptionsMenu(menu); - } - - @Override - public final boolean onPrepareOptionsMenu(android.view.Menu menu) { - return getSherlock().dispatchPrepareOptionsMenu(menu); - } - - @Override - public final boolean onOptionsItemSelected(android.view.MenuItem item) { - return getSherlock().dispatchOptionsItemSelected(item); - } - - @Override - public void openOptionsMenu() { - if (!getSherlock().dispatchOpenOptionsMenu()) { - super.openOptionsMenu(); - } - } - - @Override - public void closeOptionsMenu() { - if (!getSherlock().dispatchCloseOptionsMenu()) { - super.closeOptionsMenu(); - } - } - - - /////////////////////////////////////////////////////////////////////////// - // Sherlock menu handling - /////////////////////////////////////////////////////////////////////////// - - @Override - public boolean onCreatePanelMenu(int featureId, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onCreateOptionsMenu(menu); - } - return false; - } - - public boolean onCreateOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onPreparePanel(int featureId, View view, Menu menu) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onPrepareOptionsMenu(menu); - } - return false; - } - - public boolean onPrepareOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - return onOptionsItemSelected(item); - } - return false; - } - - public boolean onOptionsItemSelected(MenuItem item) { - return false; - } - - - /////////////////////////////////////////////////////////////////////////// - // Content - /////////////////////////////////////////////////////////////////////////// - - @Override - public void addContentView(View view, LayoutParams params) { - getSherlock().addContentView(view, params); - } - - @Override - public void setContentView(int layoutResId) { - getSherlock().setContentView(layoutResId); - } - - @Override - public void setContentView(View view, LayoutParams params) { - getSherlock().setContentView(view, params); - } - - @Override - public void setContentView(View view) { - getSherlock().setContentView(view); - } - - public void requestWindowFeature(long featureId) { - getSherlock().requestFeature((int)featureId); - } - - - /////////////////////////////////////////////////////////////////////////// - // Progress Indication - /////////////////////////////////////////////////////////////////////////// - - public void setSupportProgress(int progress) { - getSherlock().setProgress(progress); - } - - public void setSupportProgressBarIndeterminate(boolean indeterminate) { - getSherlock().setProgressBarIndeterminate(indeterminate); - } - - public void setSupportProgressBarIndeterminateVisibility(boolean visible) { - getSherlock().setProgressBarIndeterminateVisibility(visible); - } - - public void setSupportProgressBarVisibility(boolean visible) { - getSherlock().setProgressBarVisibility(visible); - } - - public void setSupportSecondaryProgress(int secondaryProgress) { - getSherlock().setSecondaryProgress(secondaryProgress); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/ActionBarSherlockCompat.java b/actionbarsherlock/src/com/actionbarsherlock/internal/ActionBarSherlockCompat.java deleted file mode 100644 index 5e69275c..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/ActionBarSherlockCompat.java +++ /dev/null @@ -1,1203 +0,0 @@ -package com.actionbarsherlock.internal; - -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import org.xmlpull.v1.XmlPullParser; -import android.app.Activity; -import android.content.Context; -import android.content.pm.ActivityInfo; -import android.content.res.AssetManager; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.os.Bundle; -import android.util.AndroidRuntimeException; -import android.util.Log; -import android.util.TypedValue; -import android.view.ContextThemeWrapper; -import android.view.KeyCharacterMap; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewStub; -import android.view.Window; -import android.view.accessibility.AccessibilityEvent; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.widget.FrameLayout; -import android.widget.TextView; -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.R; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.internal.app.ActionBarImpl; -import com.actionbarsherlock.internal.view.StandaloneActionMode; -import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; -import com.actionbarsherlock.internal.view.menu.MenuBuilder; -import com.actionbarsherlock.internal.view.menu.MenuItemImpl; -import com.actionbarsherlock.internal.view.menu.MenuPresenter; -import com.actionbarsherlock.internal.widget.ActionBarContainer; -import com.actionbarsherlock.internal.widget.ActionBarContextView; -import com.actionbarsherlock.internal.widget.ActionBarView; -import com.actionbarsherlock.internal.widget.IcsProgressBar; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; - -@ActionBarSherlock.Implementation(api = 7) -public class ActionBarSherlockCompat extends ActionBarSherlock implements MenuBuilder.Callback, com.actionbarsherlock.view.Window.Callback, MenuPresenter.Callback, android.view.MenuItem.OnMenuItemClickListener { - /** Window features which are enabled by default. */ - protected static final int DEFAULT_FEATURES = 0; - - static private final String PANELS_TAG = "sherlock:Panels"; - - public ActionBarSherlockCompat(Activity activity, int flags) { - super(activity, flags); - } - - - /////////////////////////////////////////////////////////////////////////// - // Properties - /////////////////////////////////////////////////////////////////////////// - - /** Whether or not the device has a dedicated menu key button. */ - private boolean mReserveOverflow; - /** Lazy-load indicator for {@link #mReserveOverflow}. */ - private boolean mReserveOverflowSet = false; - - /** Current menu instance for managing action items. */ - private MenuBuilder mMenu; - /** Map between native options items and sherlock items. */ - protected HashMap mNativeItemMap; - - /** Parent view of the window decoration (action bar, mode, etc.). */ - private ViewGroup mDecor; - /** Parent view of the activity content. */ - private ViewGroup mContentParent; - - /** Whether or not the title is stable and can be displayed. */ - private boolean mIsTitleReady = false; - /** Whether or not the parent activity has been destroyed. */ - private boolean mIsDestroyed = false; - - /* Emulate PanelFeatureState */ - private boolean mClosingActionMenu; - private boolean mMenuIsPrepared; - private boolean mMenuRefreshContent; - private Bundle mMenuFrozenActionViewState; - - /** Implementation which backs the action bar interface API. */ - private ActionBarImpl aActionBar; - /** Main action bar view which displays the core content. */ - private ActionBarView wActionBar; - /** Relevant window and action bar features flags. */ - private int mFeatures = DEFAULT_FEATURES; - /** Relevant user interface option flags. */ - private int mUiOptions = 0; - - /** Decor indeterminate progress indicator. */ - private IcsProgressBar mCircularProgressBar; - /** Decor progress indicator. */ - private IcsProgressBar mHorizontalProgressBar; - - /** Current displayed context action bar, if any. */ - private ActionMode mActionMode; - /** Parent view in which the context action bar is displayed. */ - private ActionBarContextView mActionModeView; - - /** Title view used with dialogs. */ - private TextView mTitleView; - /** Current activity title. */ - private CharSequence mTitle = null; - /** Whether or not this "activity" is floating (i.e., a dialog) */ - private boolean mIsFloating; - - - - /////////////////////////////////////////////////////////////////////////// - // Instance methods - /////////////////////////////////////////////////////////////////////////// - - @Override - public ActionBar getActionBar() { - if (DEBUG) Log.d(TAG, "[getActionBar]"); - - initActionBar(); - return aActionBar; - } - - private void initActionBar() { - if (DEBUG) Log.d(TAG, "[initActionBar]"); - - // Initializing the window decor can change window feature flags. - // Make sure that we have the correct set before performing the test below. - if (mDecor == null) { - installDecor(); - } - - if ((aActionBar != null) || !hasFeature(Window.FEATURE_ACTION_BAR) || hasFeature(Window.FEATURE_NO_TITLE) || mActivity.isChild()) { - return; - } - - aActionBar = new ActionBarImpl(mActivity, mFeatures); - - if (!mIsDelegate) { - //We may never get another chance to set the title - wActionBar.setWindowTitle(mActivity.getTitle()); - } - } - - @Override - protected Context getThemedContext() { - return aActionBar.getThemedContext(); - } - - @Override - public void setTitle(CharSequence title) { - if (DEBUG) Log.d(TAG, "[setTitle] title: " + title); - - dispatchTitleChanged(title, 0); - } - - @Override - public ActionMode startActionMode(ActionMode.Callback callback) { - if (DEBUG) Log.d(TAG, "[startActionMode] callback: " + callback); - - if (mActionMode != null) { - mActionMode.finish(); - } - - final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback); - ActionMode mode = null; - - //Emulate Activity's onWindowStartingActionMode: - initActionBar(); - if (aActionBar != null) { - mode = aActionBar.startActionMode(wrappedCallback); - } - - if (mode != null) { - mActionMode = mode; - } else { - if (mActionModeView == null) { - ViewStub stub = (ViewStub)mDecor.findViewById(R.id.abs__action_mode_bar_stub); - if (stub != null) { - mActionModeView = (ActionBarContextView)stub.inflate(); - } - } - if (mActionModeView != null) { - mActionModeView.killMode(); - mode = new StandaloneActionMode(mActivity, mActionModeView, wrappedCallback, true); - if (callback.onCreateActionMode(mode, mode.getMenu())) { - mode.invalidate(); - mActionModeView.initForMode(mode); - mActionModeView.setVisibility(View.VISIBLE); - mActionMode = mode; - mActionModeView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - } else { - mActionMode = null; - } - } - } - if (mActionMode != null && mActivity instanceof OnActionModeStartedListener) { - ((OnActionModeStartedListener)mActivity).onActionModeStarted(mActionMode); - } - return mActionMode; - } - - - /////////////////////////////////////////////////////////////////////////// - // Lifecycle and interaction callbacks for delegation - /////////////////////////////////////////////////////////////////////////// - - @Override - public void dispatchConfigurationChanged(Configuration newConfig) { - if (DEBUG) Log.d(TAG, "[dispatchConfigurationChanged] newConfig: " + newConfig); - - if (aActionBar != null) { - aActionBar.onConfigurationChanged(newConfig); - } - } - - @Override - public void dispatchPostResume() { - if (DEBUG) Log.d(TAG, "[dispatchPostResume]"); - - if (aActionBar != null) { - aActionBar.setShowHideAnimationEnabled(true); - } - } - - @Override - public void dispatchPause() { - if (DEBUG) Log.d(TAG, "[dispatchPause]"); - - if (wActionBar != null && wActionBar.isOverflowMenuShowing()) { - wActionBar.hideOverflowMenu(); - } - } - - @Override - public void dispatchStop() { - if (DEBUG) Log.d(TAG, "[dispatchStop]"); - - if (aActionBar != null) { - aActionBar.setShowHideAnimationEnabled(false); - } - } - - @Override - public void dispatchInvalidateOptionsMenu() { - if (DEBUG) Log.d(TAG, "[dispatchInvalidateOptionsMenu]"); - - Bundle savedActionViewStates = null; - if (mMenu != null) { - savedActionViewStates = new Bundle(); - mMenu.saveActionViewStates(savedActionViewStates); - if (savedActionViewStates.size() > 0) { - mMenuFrozenActionViewState = savedActionViewStates; - } - // This will be started again when the panel is prepared. - mMenu.stopDispatchingItemsChanged(); - mMenu.clear(); - } - mMenuRefreshContent = true; - - // Prepare the options panel if we have an action bar - if (wActionBar != null) { - mMenuIsPrepared = false; - preparePanel(); - } - } - - @Override - public boolean dispatchOpenOptionsMenu() { - if (DEBUG) Log.d(TAG, "[dispatchOpenOptionsMenu]"); - - if (!isReservingOverflow()) { - return false; - } - - return wActionBar.showOverflowMenu(); - } - - @Override - public boolean dispatchCloseOptionsMenu() { - if (DEBUG) Log.d(TAG, "[dispatchCloseOptionsMenu]"); - - if (!isReservingOverflow()) { - return false; - } - - if (wActionBar != null) { - return wActionBar.hideOverflowMenu(); - } - return false; - } - - @Override - public void dispatchPostCreate(Bundle savedInstanceState) { - if (DEBUG) Log.d(TAG, "[dispatchOnPostCreate]"); - - if (mIsDelegate) { - mIsTitleReady = true; - } - - if (mDecor == null) { - initActionBar(); - } - } - - @Override - public boolean dispatchCreateOptionsMenu(android.view.Menu menu) { - if (DEBUG) { - Log.d(TAG, "[dispatchCreateOptionsMenu] android.view.Menu: " + menu); - Log.d(TAG, "[dispatchCreateOptionsMenu] returning true"); - } - return true; - } - - @Override - public boolean dispatchPrepareOptionsMenu(android.view.Menu menu) { - if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu] android.view.Menu: " + menu); - - if (mActionMode != null) { - return false; - } - - mMenuIsPrepared = false; - if (!preparePanel()) { - return false; - } - - if (isReservingOverflow()) { - return false; - } - - if (mNativeItemMap == null) { - mNativeItemMap = new HashMap(); - } else { - mNativeItemMap.clear(); - } - - if (mMenu == null) { - return false; - } - - boolean result = mMenu.bindNativeOverflow(menu, this, mNativeItemMap); - if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu] returning " + result); - return result; - } - - @Override - public boolean dispatchOptionsItemSelected(android.view.MenuItem item) { - throw new IllegalStateException("Native callback invoked. Create a test case and report!"); - } - - @Override - public boolean dispatchMenuOpened(int featureId, android.view.Menu menu) { - if (DEBUG) Log.d(TAG, "[dispatchMenuOpened] featureId: " + featureId + ", menu: " + menu); - - if (featureId == Window.FEATURE_ACTION_BAR || featureId == Window.FEATURE_OPTIONS_PANEL) { - if (aActionBar != null) { - aActionBar.dispatchMenuVisibilityChanged(true); - } - return true; - } - - return false; - } - - @Override - public void dispatchPanelClosed(int featureId, android.view.Menu menu){ - if (DEBUG) Log.d(TAG, "[dispatchPanelClosed] featureId: " + featureId + ", menu: " + menu); - - if (featureId == Window.FEATURE_ACTION_BAR || featureId == Window.FEATURE_OPTIONS_PANEL) { - if (aActionBar != null) { - aActionBar.dispatchMenuVisibilityChanged(false); - } - } - } - - @Override - public void dispatchTitleChanged(CharSequence title, int color) { - if (DEBUG) Log.d(TAG, "[dispatchTitleChanged] title: " + title + ", color: " + color); - - if (!mIsDelegate || mIsTitleReady) { - if (mTitleView != null) { - mTitleView.setText(title); - } else if (wActionBar != null) { - wActionBar.setWindowTitle(title); - } - } - - mTitle = title; - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (DEBUG) Log.d(TAG, "[dispatchKeyEvent] event: " + event); - - final int keyCode = event.getKeyCode(); - - // Not handled by the view hierarchy, does the action bar want it - // to cancel out of something special? - if (keyCode == KeyEvent.KEYCODE_BACK) { - final int action = event.getAction(); - // Back cancels action modes first. - if (mActionMode != null) { - if (action == KeyEvent.ACTION_UP) { - mActionMode.finish(); - } - if (DEBUG) Log.d(TAG, "[dispatchKeyEvent] returning true"); - return true; - } - - // Next collapse any expanded action views. - if (wActionBar != null && wActionBar.hasExpandedActionView()) { - if (action == KeyEvent.ACTION_UP) { - wActionBar.collapseActionView(); - } - if (DEBUG) Log.d(TAG, "[dispatchKeyEvent] returning true"); - return true; - } - } - - if (DEBUG) Log.d(TAG, "[dispatchKeyEvent] returning false"); - return false; - } - - @Override - public void dispatchDestroy() { - mIsDestroyed = true; - } - - @Override - public void dispatchSaveInstanceState(Bundle outState) { - if (mMenu != null) { - mMenuFrozenActionViewState = new Bundle(); - mMenu.saveActionViewStates(mMenuFrozenActionViewState); - } - outState.putParcelable(PANELS_TAG, mMenuFrozenActionViewState); - } - - @Override - public void dispatchRestoreInstanceState(Bundle savedInstanceState) { - mMenuFrozenActionViewState = savedInstanceState.getParcelable(PANELS_TAG); - } - - /////////////////////////////////////////////////////////////////////////// - // Menu callback lifecycle and creation - /////////////////////////////////////////////////////////////////////////// - - private boolean preparePanel() { - // Already prepared (isPrepared will be reset to false later) - if (mMenuIsPrepared) { - return true; - } - - // Init the panel state's menu--return false if init failed - if (mMenu == null || mMenuRefreshContent) { - if (mMenu == null) { - if (!initializePanelMenu() || (mMenu == null)) { - return false; - } - } - - if (wActionBar != null) { - wActionBar.setMenu(mMenu, this); - } - - // Call callback, and return if it doesn't want to display menu. - - // Creating the panel menu will involve a lot of manipulation; - // don't dispatch change events to presenters until we're done. - mMenu.stopDispatchingItemsChanged(); - if (!callbackCreateOptionsMenu(mMenu)) { - // Ditch the menu created above - mMenu = null; - - if (wActionBar != null) { - // Don't show it in the action bar either - wActionBar.setMenu(null, this); - } - - return false; - } - - mMenuRefreshContent = false; - } - - // Callback and return if the callback does not want to show the menu - - // Preparing the panel menu can involve a lot of manipulation; - // don't dispatch change events to presenters until we're done. - mMenu.stopDispatchingItemsChanged(); - - // Restore action view state before we prepare. This gives apps - // an opportunity to override frozen/restored state in onPrepare. - if (mMenuFrozenActionViewState != null) { - mMenu.restoreActionViewStates(mMenuFrozenActionViewState); - mMenuFrozenActionViewState = null; - } - - if (!callbackPrepareOptionsMenu(mMenu)) { - if (wActionBar != null) { - // The app didn't want to show the menu for now but it still exists. - // Clear it out of the action bar. - wActionBar.setMenu(null, this); - } - mMenu.startDispatchingItemsChanged(); - return false; - } - - // Set the proper keymap - KeyCharacterMap kmap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); - mMenu.setQwertyMode(kmap.getKeyboardType() != KeyCharacterMap.NUMERIC); - mMenu.startDispatchingItemsChanged(); - - // Set other state - mMenuIsPrepared = true; - - return true; - } - - public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { - return callbackOptionsItemSelected(item); - } - - public void onMenuModeChange(MenuBuilder menu) { - reopenMenu(true); - } - - private void reopenMenu(boolean toggleMenuMode) { - if (wActionBar != null && wActionBar.isOverflowReserved()) { - if (!wActionBar.isOverflowMenuShowing() || !toggleMenuMode) { - if (wActionBar.getVisibility() == View.VISIBLE) { - if (callbackPrepareOptionsMenu(mMenu)) { - wActionBar.showOverflowMenu(); - } - } - } else { - wActionBar.hideOverflowMenu(); - } - return; - } - } - - private boolean initializePanelMenu() { - Context context = mActivity;//getContext(); - - // If we have an action bar, initialize the menu with a context themed for it. - if (wActionBar != null) { - TypedValue outValue = new TypedValue(); - Resources.Theme currentTheme = context.getTheme(); - currentTheme.resolveAttribute(R.attr.actionBarWidgetTheme, - outValue, true); - final int targetThemeRes = outValue.resourceId; - - if (targetThemeRes != 0 /*&& context.getThemeResId() != targetThemeRes*/) { - context = new ContextThemeWrapper(context, targetThemeRes); - } - } - - mMenu = new MenuBuilder(context); - mMenu.setCallback(this); - - return true; - } - - void checkCloseActionMenu(Menu menu) { - if (mClosingActionMenu) { - return; - } - - mClosingActionMenu = true; - wActionBar.dismissPopupMenus(); - //Callback cb = getCallback(); - //if (cb != null && !isDestroyed()) { - // cb.onPanelClosed(FEATURE_ACTION_BAR, menu); - //} - mClosingActionMenu = false; - } - - @Override - public boolean onOpenSubMenu(MenuBuilder subMenu) { - return true; - } - - @Override - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - checkCloseActionMenu(menu); - } - - @Override - public boolean onMenuItemClick(android.view.MenuItem item) { - if (DEBUG) Log.d(TAG, "[mNativeItemListener.onMenuItemClick] item: " + item); - - final MenuItemImpl sherlockItem = mNativeItemMap.get(item); - if (sherlockItem != null) { - sherlockItem.invoke(); - } else { - Log.e(TAG, "Options item \"" + item + "\" not found in mapping"); - } - - return true; //Do not allow continuation of native handling - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - return callbackOptionsItemSelected(item); - } - - - /////////////////////////////////////////////////////////////////////////// - // Progress bar interaction and internal handling - /////////////////////////////////////////////////////////////////////////// - - @Override - public void setProgressBarVisibility(boolean visible) { - if (DEBUG) Log.d(TAG, "[setProgressBarVisibility] visible: " + visible); - - setFeatureInt(Window.FEATURE_PROGRESS, visible ? Window.PROGRESS_VISIBILITY_ON : - Window.PROGRESS_VISIBILITY_OFF); - } - - @Override - public void setProgressBarIndeterminateVisibility(boolean visible) { - if (DEBUG) Log.d(TAG, "[setProgressBarIndeterminateVisibility] visible: " + visible); - - setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, - visible ? Window.PROGRESS_VISIBILITY_ON : Window.PROGRESS_VISIBILITY_OFF); - } - - @Override - public void setProgressBarIndeterminate(boolean indeterminate) { - if (DEBUG) Log.d(TAG, "[setProgressBarIndeterminate] indeterminate: " + indeterminate); - - setFeatureInt(Window.FEATURE_PROGRESS, - indeterminate ? Window.PROGRESS_INDETERMINATE_ON : Window.PROGRESS_INDETERMINATE_OFF); - } - - @Override - public void setProgress(int progress) { - if (DEBUG) Log.d(TAG, "[setProgress] progress: " + progress); - - setFeatureInt(Window.FEATURE_PROGRESS, progress + Window.PROGRESS_START); - } - - @Override - public void setSecondaryProgress(int secondaryProgress) { - if (DEBUG) Log.d(TAG, "[setSecondaryProgress] secondaryProgress: " + secondaryProgress); - - setFeatureInt(Window.FEATURE_PROGRESS, - secondaryProgress + Window.PROGRESS_SECONDARY_START); - } - - private void setFeatureInt(int featureId, int value) { - updateInt(featureId, value, false); - } - - private void updateInt(int featureId, int value, boolean fromResume) { - // Do nothing if the decor is not yet installed... an update will - // need to be forced when we eventually become active. - if (mContentParent == null) { - return; - } - - final int featureMask = 1 << featureId; - - if ((getFeatures() & featureMask) == 0 && !fromResume) { - return; - } - - onIntChanged(featureId, value); - } - - private void onIntChanged(int featureId, int value) { - if (featureId == Window.FEATURE_PROGRESS || featureId == Window.FEATURE_INDETERMINATE_PROGRESS) { - updateProgressBars(value); - } - } - - private void updateProgressBars(int value) { - IcsProgressBar circularProgressBar = getCircularProgressBar(true); - IcsProgressBar horizontalProgressBar = getHorizontalProgressBar(true); - - final int features = mFeatures;//getLocalFeatures(); - if (value == Window.PROGRESS_VISIBILITY_ON) { - if ((features & (1 << Window.FEATURE_PROGRESS)) != 0) { - int level = horizontalProgressBar.getProgress(); - int visibility = (horizontalProgressBar.isIndeterminate() || level < 10000) ? - View.VISIBLE : View.INVISIBLE; - horizontalProgressBar.setVisibility(visibility); - } - if ((features & (1 << Window.FEATURE_INDETERMINATE_PROGRESS)) != 0) { - circularProgressBar.setVisibility(View.VISIBLE); - } - } else if (value == Window.PROGRESS_VISIBILITY_OFF) { - if ((features & (1 << Window.FEATURE_PROGRESS)) != 0) { - horizontalProgressBar.setVisibility(View.GONE); - } - if ((features & (1 << Window.FEATURE_INDETERMINATE_PROGRESS)) != 0) { - circularProgressBar.setVisibility(View.GONE); - } - } else if (value == Window.PROGRESS_INDETERMINATE_ON) { - horizontalProgressBar.setIndeterminate(true); - } else if (value == Window.PROGRESS_INDETERMINATE_OFF) { - horizontalProgressBar.setIndeterminate(false); - } else if (Window.PROGRESS_START <= value && value <= Window.PROGRESS_END) { - // We want to set the progress value before testing for visibility - // so that when the progress bar becomes visible again, it has the - // correct level. - horizontalProgressBar.setProgress(value - Window.PROGRESS_START); - - if (value < Window.PROGRESS_END) { - showProgressBars(horizontalProgressBar, circularProgressBar); - } else { - hideProgressBars(horizontalProgressBar, circularProgressBar); - } - } else if (Window.PROGRESS_SECONDARY_START <= value && value <= Window.PROGRESS_SECONDARY_END) { - horizontalProgressBar.setSecondaryProgress(value - Window.PROGRESS_SECONDARY_START); - - showProgressBars(horizontalProgressBar, circularProgressBar); - } - } - - private void showProgressBars(IcsProgressBar horizontalProgressBar, IcsProgressBar spinnyProgressBar) { - final int features = mFeatures;//getLocalFeatures(); - if ((features & (1 << Window.FEATURE_INDETERMINATE_PROGRESS)) != 0 && - spinnyProgressBar.getVisibility() == View.INVISIBLE) { - spinnyProgressBar.setVisibility(View.VISIBLE); - } - // Only show the progress bars if the primary progress is not complete - if ((features & (1 << Window.FEATURE_PROGRESS)) != 0 && - horizontalProgressBar.getProgress() < 10000) { - horizontalProgressBar.setVisibility(View.VISIBLE); - } - } - - private void hideProgressBars(IcsProgressBar horizontalProgressBar, IcsProgressBar spinnyProgressBar) { - final int features = mFeatures;//getLocalFeatures(); - Animation anim = AnimationUtils.loadAnimation(mActivity, android.R.anim.fade_out); - anim.setDuration(1000); - if ((features & (1 << Window.FEATURE_INDETERMINATE_PROGRESS)) != 0 && - spinnyProgressBar.getVisibility() == View.VISIBLE) { - spinnyProgressBar.startAnimation(anim); - spinnyProgressBar.setVisibility(View.INVISIBLE); - } - if ((features & (1 << Window.FEATURE_PROGRESS)) != 0 && - horizontalProgressBar.getVisibility() == View.VISIBLE) { - horizontalProgressBar.startAnimation(anim); - horizontalProgressBar.setVisibility(View.INVISIBLE); - } - } - - private IcsProgressBar getCircularProgressBar(boolean shouldInstallDecor) { - if (mCircularProgressBar != null) { - return mCircularProgressBar; - } - if (mContentParent == null && shouldInstallDecor) { - installDecor(); - } - mCircularProgressBar = (IcsProgressBar)mDecor.findViewById(R.id.abs__progress_circular); - if (mCircularProgressBar != null) { - mCircularProgressBar.setVisibility(View.INVISIBLE); - } - return mCircularProgressBar; - } - - private IcsProgressBar getHorizontalProgressBar(boolean shouldInstallDecor) { - if (mHorizontalProgressBar != null) { - return mHorizontalProgressBar; - } - if (mContentParent == null && shouldInstallDecor) { - installDecor(); - } - mHorizontalProgressBar = (IcsProgressBar)mDecor.findViewById(R.id.abs__progress_horizontal); - if (mHorizontalProgressBar != null) { - mHorizontalProgressBar.setVisibility(View.INVISIBLE); - } - return mHorizontalProgressBar; - } - - - /////////////////////////////////////////////////////////////////////////// - // Feature management and content interaction and creation - /////////////////////////////////////////////////////////////////////////// - - private int getFeatures() { - if (DEBUG) Log.d(TAG, "[getFeatures] returning " + mFeatures); - - return mFeatures; - } - - @Override - public boolean hasFeature(int featureId) { - if (DEBUG) Log.d(TAG, "[hasFeature] featureId: " + featureId); - - boolean result = (mFeatures & (1 << featureId)) != 0; - if (DEBUG) Log.d(TAG, "[hasFeature] returning " + result); - return result; - } - - @Override - public boolean requestFeature(int featureId) { - if (DEBUG) Log.d(TAG, "[requestFeature] featureId: " + featureId); - - if (mContentParent != null) { - throw new AndroidRuntimeException("requestFeature() must be called before adding content"); - } - - switch (featureId) { - case Window.FEATURE_ACTION_BAR: - case Window.FEATURE_ACTION_BAR_OVERLAY: - case Window.FEATURE_ACTION_MODE_OVERLAY: - case Window.FEATURE_INDETERMINATE_PROGRESS: - case Window.FEATURE_NO_TITLE: - case Window.FEATURE_PROGRESS: - mFeatures |= (1 << featureId); - return true; - - default: - return false; - } - } - - @Override - public void setUiOptions(int uiOptions) { - if (DEBUG) Log.d(TAG, "[setUiOptions] uiOptions: " + uiOptions); - - mUiOptions = uiOptions; - } - - @Override - public void setUiOptions(int uiOptions, int mask) { - if (DEBUG) Log.d(TAG, "[setUiOptions] uiOptions: " + uiOptions + ", mask: " + mask); - - mUiOptions = (mUiOptions & ~mask) | (uiOptions & mask); - } - - @Override - public void setContentView(int layoutResId) { - if (DEBUG) Log.d(TAG, "[setContentView] layoutResId: " + layoutResId); - - if (mContentParent == null) { - installDecor(); - } else { - mContentParent.removeAllViews(); - } - mActivity.getLayoutInflater().inflate(layoutResId, mContentParent); - - android.view.Window.Callback callback = mActivity.getWindow().getCallback(); - if (callback != null) { - callback.onContentChanged(); - } - - initActionBar(); - } - - @Override - public void setContentView(View view, ViewGroup.LayoutParams params) { - if (DEBUG) Log.d(TAG, "[setContentView] view: " + view + ", params: " + params); - - if (mContentParent == null) { - installDecor(); - } else { - mContentParent.removeAllViews(); - } - mContentParent.addView(view, params); - - android.view.Window.Callback callback = mActivity.getWindow().getCallback(); - if (callback != null) { - callback.onContentChanged(); - } - - initActionBar(); - } - - @Override - public void addContentView(View view, ViewGroup.LayoutParams params) { - if (DEBUG) Log.d(TAG, "[addContentView] view: " + view + ", params: " + params); - - if (mContentParent == null) { - installDecor(); - } - mContentParent.addView(view, params); - - initActionBar(); - } - - private void installDecor() { - if (DEBUG) Log.d(TAG, "[installDecor]"); - - if (mDecor == null) { - mDecor = (ViewGroup)mActivity.getWindow().getDecorView().findViewById(android.R.id.content); - } - if (mContentParent == null) { - //Since we are not operating at the window level we need to take - //into account the fact that the true decor may have already been - //initialized and had content attached to it. If that is the case, - //copy over its children to our new content container. - List views = null; - if (mDecor.getChildCount() > 0) { - views = new ArrayList(1); //Usually there's only one child - for (int i = 0, children = mDecor.getChildCount(); i < children; i++) { - View child = mDecor.getChildAt(0); - mDecor.removeView(child); - views.add(child); - } - } - - mContentParent = generateLayout(); - - //Copy over the old children. See above for explanation. - if (views != null) { - for (View child : views) { - mContentParent.addView(child); - } - } - - mTitleView = (TextView)mDecor.findViewById(android.R.id.title); - if (mTitleView != null) { - if (hasFeature(Window.FEATURE_NO_TITLE)) { - mTitleView.setVisibility(View.GONE); - if (mContentParent instanceof FrameLayout) { - ((FrameLayout)mContentParent).setForeground(null); - } - } else { - mTitleView.setText(mTitle); - } - } else { - wActionBar = (ActionBarView)mDecor.findViewById(R.id.abs__action_bar); - if (wActionBar != null) { - wActionBar.setWindowCallback(this); - if (wActionBar.getTitle() == null) { - wActionBar.setWindowTitle(mActivity.getTitle()); - } - if (hasFeature(Window.FEATURE_PROGRESS)) { - wActionBar.initProgress(); - } - if (hasFeature(Window.FEATURE_INDETERMINATE_PROGRESS)) { - wActionBar.initIndeterminateProgress(); - } - - //Since we don't require onCreate dispatching, parse for uiOptions here - int uiOptions = loadUiOptionsFromManifest(mActivity); - if (uiOptions != 0) { - mUiOptions = uiOptions; - } - - boolean splitActionBar = false; - final boolean splitWhenNarrow = (mUiOptions & ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW) != 0; - if (splitWhenNarrow) { - splitActionBar = getResources_getBoolean(mActivity, R.bool.abs__split_action_bar_is_narrow); - } else { - splitActionBar = mActivity.getTheme() - .obtainStyledAttributes(R.styleable.SherlockTheme) - .getBoolean(R.styleable.SherlockTheme_windowSplitActionBar, false); - } - final ActionBarContainer splitView = (ActionBarContainer)mDecor.findViewById(R.id.abs__split_action_bar); - if (splitView != null) { - wActionBar.setSplitView(splitView); - wActionBar.setSplitActionBar(splitActionBar); - wActionBar.setSplitWhenNarrow(splitWhenNarrow); - - mActionModeView = (ActionBarContextView)mDecor.findViewById(R.id.abs__action_context_bar); - mActionModeView.setSplitView(splitView); - mActionModeView.setSplitActionBar(splitActionBar); - mActionModeView.setSplitWhenNarrow(splitWhenNarrow); - } else if (splitActionBar) { - Log.e(TAG, "Requested split action bar with incompatible window decor! Ignoring request."); - } - - // Post the panel invalidate for later; avoid application onCreateOptionsMenu - // being called in the middle of onCreate or similar. - mDecor.post(new Runnable() { - @Override - public void run() { - //Invalidate if the panel menu hasn't been created before this. - if (!mIsDestroyed && !mActivity.isFinishing() && mMenu == null) { - dispatchInvalidateOptionsMenu(); - } - } - }); - } - } - } - } - - private ViewGroup generateLayout() { - if (DEBUG) Log.d(TAG, "[generateLayout]"); - - // Apply data from current theme. - - TypedArray a = mActivity.getTheme().obtainStyledAttributes(R.styleable.SherlockTheme); - - mIsFloating = a.getBoolean(R.styleable.SherlockTheme_android_windowIsFloating, false); - - if (!a.hasValue(R.styleable.SherlockTheme_windowActionBar)) { - throw new IllegalStateException("You must use Theme.Sherlock, Theme.Sherlock.Light, Theme.Sherlock.Light.DarkActionBar, or a derivative."); - } - - if (a.getBoolean(R.styleable.SherlockTheme_windowNoTitle, false)) { - requestFeature(Window.FEATURE_NO_TITLE); - } else if (a.getBoolean(R.styleable.SherlockTheme_windowActionBar, false)) { - // Don't allow an action bar if there is no title. - requestFeature(Window.FEATURE_ACTION_BAR); - } - - if (a.getBoolean(R.styleable.SherlockTheme_windowActionBarOverlay, false)) { - requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY); - } - - if (a.getBoolean(R.styleable.SherlockTheme_windowActionModeOverlay, false)) { - requestFeature(Window.FEATURE_ACTION_MODE_OVERLAY); - } - - a.recycle(); - - int layoutResource; - if (!hasFeature(Window.FEATURE_NO_TITLE)) { - if (mIsFloating) { - //Trash original dialog LinearLayout - mDecor = (ViewGroup)mDecor.getParent(); - mDecor.removeAllViews(); - - layoutResource = R.layout.abs__dialog_title_holo; - } else { - if (hasFeature(Window.FEATURE_ACTION_BAR_OVERLAY)) { - layoutResource = R.layout.abs__screen_action_bar_overlay; - } else { - layoutResource = R.layout.abs__screen_action_bar; - } - } - } else if (hasFeature(Window.FEATURE_ACTION_MODE_OVERLAY) && !hasFeature(Window.FEATURE_NO_TITLE)) { - layoutResource = R.layout.abs__screen_simple_overlay_action_mode; - } else { - layoutResource = R.layout.abs__screen_simple; - } - - if (DEBUG) Log.d(TAG, "[generateLayout] using screen XML " + mActivity.getResources().getString(layoutResource)); - View in = mActivity.getLayoutInflater().inflate(layoutResource, null); - mDecor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); - - ViewGroup contentParent = (ViewGroup)mDecor.findViewById(R.id.abs__content); - if (contentParent == null) { - throw new RuntimeException("Couldn't find content container view"); - } - - //Make our new child the true content view (for fragments). VERY VOLATILE! - mDecor.setId(View.NO_ID); - contentParent.setId(android.R.id.content); - - if (hasFeature(Window.FEATURE_INDETERMINATE_PROGRESS)) { - IcsProgressBar progress = getCircularProgressBar(false); - if (progress != null) { - progress.setIndeterminate(true); - } - } - - return contentParent; - } - - - /////////////////////////////////////////////////////////////////////////// - // Miscellaneous - /////////////////////////////////////////////////////////////////////////// - - /** - * Determine whether or not the device has a dedicated menu key. - * - * @return {@code true} if native menu key is present. - */ - private boolean isReservingOverflow() { - if (!mReserveOverflowSet) { - mReserveOverflow = ActionMenuPresenter.reserveOverflow(mActivity); - mReserveOverflowSet = true; - } - return mReserveOverflow; - } - - private static int loadUiOptionsFromManifest(Activity activity) { - int uiOptions = 0; - try { - final String thisPackage = activity.getClass().getName(); - if (DEBUG) Log.i(TAG, "Parsing AndroidManifest.xml for " + thisPackage); - - final String packageName = activity.getApplicationInfo().packageName; - final AssetManager am = activity.createPackageContext(packageName, 0).getAssets(); - final XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml"); - - int eventType = xml.getEventType(); - while (eventType != XmlPullParser.END_DOCUMENT) { - if (eventType == XmlPullParser.START_TAG) { - String name = xml.getName(); - - if ("application".equals(name)) { - //Check if the has the attribute - if (DEBUG) Log.d(TAG, "Got "); - - for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { - if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); - - if ("uiOptions".equals(xml.getAttributeName(i))) { - uiOptions = xml.getAttributeIntValue(i, 0); - break; //out of for loop - } - } - } else if ("activity".equals(name)) { - //Check if the is us and has the attribute - if (DEBUG) Log.d(TAG, "Got "); - Integer activityUiOptions = null; - String activityPackage = null; - boolean isOurActivity = false; - - for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { - if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); - - //We need both uiOptions and name attributes - String attrName = xml.getAttributeName(i); - if ("uiOptions".equals(attrName)) { - activityUiOptions = xml.getAttributeIntValue(i, 0); - } else if ("name".equals(attrName)) { - activityPackage = cleanActivityName(packageName, xml.getAttributeValue(i)); - if (!thisPackage.equals(activityPackage)) { - break; //out of for loop - } - isOurActivity = true; - } - - //Make sure we have both attributes before processing - if ((activityUiOptions != null) && (activityPackage != null)) { - //Our activity, uiOptions specified, override with our value - uiOptions = activityUiOptions.intValue(); - } - } - if (isOurActivity) { - //If we matched our activity but it had no logo don't - //do any more processing of the manifest - break; - } - } - } - eventType = xml.nextToken(); - } - } catch (Exception e) { - e.printStackTrace(); - } - if (DEBUG) Log.i(TAG, "Returning " + Integer.toHexString(uiOptions)); - return uiOptions; - } - - public static String cleanActivityName(String manifestPackage, String activityName) { - if (activityName.charAt(0) == '.') { - //Relative activity name (e.g., android:name=".ui.SomeClass") - return manifestPackage + activityName; - } - if (activityName.indexOf('.', 1) == -1) { - //Unqualified activity name (e.g., android:name="SomeClass") - return manifestPackage + "." + activityName; - } - //Fully-qualified activity name (e.g., "com.my.package.SomeClass") - return activityName; - } - - /** - * Clears out internal reference when the action mode is destroyed. - */ - private class ActionModeCallbackWrapper implements ActionMode.Callback { - private final ActionMode.Callback mWrapped; - - public ActionModeCallbackWrapper(ActionMode.Callback wrapped) { - mWrapped = wrapped; - } - - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - return mWrapped.onCreateActionMode(mode, menu); - } - - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return mWrapped.onPrepareActionMode(mode, menu); - } - - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - return mWrapped.onActionItemClicked(mode, item); - } - - public void onDestroyActionMode(ActionMode mode) { - mWrapped.onDestroyActionMode(mode); - if (mActionModeView != null) { - mActionModeView.setVisibility(View.GONE); - mActionModeView.removeAllViews(); - } - if (mActivity instanceof OnActionModeFinishedListener) { - ((OnActionModeFinishedListener)mActivity).onActionModeFinished(mActionMode); - } - mActionMode = null; - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/ActionBarSherlockNative.java b/actionbarsherlock/src/com/actionbarsherlock/internal/ActionBarSherlockNative.java deleted file mode 100644 index 0824d384..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/ActionBarSherlockNative.java +++ /dev/null @@ -1,336 +0,0 @@ -package com.actionbarsherlock.internal; - -import com.actionbarsherlock.ActionBarSherlock; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.internal.app.ActionBarWrapper; -import com.actionbarsherlock.internal.view.menu.MenuWrapper; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.MenuInflater; -import android.app.Activity; -import android.content.Context; -import android.util.Log; -import android.util.TypedValue; -import android.view.ContextThemeWrapper; -import android.view.View; -import android.view.Window; -import android.view.ViewGroup.LayoutParams; - -@ActionBarSherlock.Implementation(api = 14) -public class ActionBarSherlockNative extends ActionBarSherlock { - private ActionBarWrapper mActionBar; - private ActionModeWrapper mActionMode; - private MenuWrapper mMenu; - - public ActionBarSherlockNative(Activity activity, int flags) { - super(activity, flags); - } - - - @Override - public ActionBar getActionBar() { - if (DEBUG) Log.d(TAG, "[getActionBar]"); - - initActionBar(); - return mActionBar; - } - - private void initActionBar() { - if (mActionBar != null || mActivity.getActionBar() == null) { - return; - } - - mActionBar = new ActionBarWrapper(mActivity); - } - - @Override - public void dispatchInvalidateOptionsMenu() { - if (DEBUG) Log.d(TAG, "[dispatchInvalidateOptionsMenu]"); - - mActivity.getWindow().invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL); - } - - @Override - public boolean dispatchCreateOptionsMenu(android.view.Menu menu) { - if (DEBUG) Log.d(TAG, "[dispatchCreateOptionsMenu] menu: " + menu); - - if (mMenu == null || menu != mMenu.unwrap()) { - mMenu = new MenuWrapper(menu); - } - - final boolean result = callbackCreateOptionsMenu(mMenu); - if (DEBUG) Log.d(TAG, "[dispatchCreateOptionsMenu] returning " + result); - return result; - } - - @Override - public boolean dispatchPrepareOptionsMenu(android.view.Menu menu) { - if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu] menu: " + menu); - - final boolean result = callbackPrepareOptionsMenu(mMenu); - if (DEBUG) Log.d(TAG, "[dispatchPrepareOptionsMenu] returning " + result); - return result; - } - - @Override - public boolean dispatchOptionsItemSelected(android.view.MenuItem item) { - if (DEBUG) Log.d(TAG, "[dispatchOptionsItemSelected] item: " + item.getTitleCondensed()); - - final boolean result = callbackOptionsItemSelected(mMenu.findItem(item)); - if (DEBUG) Log.d(TAG, "[dispatchOptionsItemSelected] returning " + result); - return result; - } - - @Override - public boolean hasFeature(int feature) { - if (DEBUG) Log.d(TAG, "[hasFeature] feature: " + feature); - - final boolean result = mActivity.getWindow().hasFeature(feature); - if (DEBUG) Log.d(TAG, "[hasFeature] returning " + result); - return result; - } - - @Override - public boolean requestFeature(int featureId) { - if (DEBUG) Log.d(TAG, "[requestFeature] featureId: " + featureId); - - final boolean result = mActivity.getWindow().requestFeature(featureId); - if (DEBUG) Log.d(TAG, "[requestFeature] returning " + result); - return result; - } - - @Override - public void setUiOptions(int uiOptions) { - if (DEBUG) Log.d(TAG, "[setUiOptions] uiOptions: " + uiOptions); - - mActivity.getWindow().setUiOptions(uiOptions); - } - - @Override - public void setUiOptions(int uiOptions, int mask) { - if (DEBUG) Log.d(TAG, "[setUiOptions] uiOptions: " + uiOptions + ", mask: " + mask); - - mActivity.getWindow().setUiOptions(uiOptions, mask); - } - - @Override - public void setContentView(int layoutResId) { - if (DEBUG) Log.d(TAG, "[setContentView] layoutResId: " + layoutResId); - - mActivity.getWindow().setContentView(layoutResId); - initActionBar(); - } - - @Override - public void setContentView(View view, LayoutParams params) { - if (DEBUG) Log.d(TAG, "[setContentView] view: " + view + ", params: " + params); - - mActivity.getWindow().setContentView(view, params); - initActionBar(); - } - - @Override - public void addContentView(View view, LayoutParams params) { - if (DEBUG) Log.d(TAG, "[addContentView] view: " + view + ", params: " + params); - - mActivity.getWindow().addContentView(view, params); - initActionBar(); - } - - @Override - public void setTitle(CharSequence title) { - if (DEBUG) Log.d(TAG, "[setTitle] title: " + title); - - mActivity.getWindow().setTitle(title); - } - - @Override - public void setProgressBarVisibility(boolean visible) { - if (DEBUG) Log.d(TAG, "[setProgressBarVisibility] visible: " + visible); - - mActivity.setProgressBarVisibility(visible); - } - - @Override - public void setProgressBarIndeterminateVisibility(boolean visible) { - if (DEBUG) Log.d(TAG, "[setProgressBarIndeterminateVisibility] visible: " + visible); - - mActivity.setProgressBarIndeterminateVisibility(visible); - } - - @Override - public void setProgressBarIndeterminate(boolean indeterminate) { - if (DEBUG) Log.d(TAG, "[setProgressBarIndeterminate] indeterminate: " + indeterminate); - - mActivity.setProgressBarIndeterminate(indeterminate); - } - - @Override - public void setProgress(int progress) { - if (DEBUG) Log.d(TAG, "[setProgress] progress: " + progress); - - mActivity.setProgress(progress); - } - - @Override - public void setSecondaryProgress(int secondaryProgress) { - if (DEBUG) Log.d(TAG, "[setSecondaryProgress] secondaryProgress: " + secondaryProgress); - - mActivity.setSecondaryProgress(secondaryProgress); - } - - @Override - protected Context getThemedContext() { - Context context = mActivity; - TypedValue outValue = new TypedValue(); - mActivity.getTheme().resolveAttribute(android.R.attr.actionBarWidgetTheme, outValue, true); - if (outValue.resourceId != 0) { - //We are unable to test if this is the same as our current theme - //so we just wrap it and hope that if the attribute was specified - //then the user is intentionally specifying an alternate theme. - context = new ContextThemeWrapper(context, outValue.resourceId); - } - return context; - } - - @Override - public ActionMode startActionMode(com.actionbarsherlock.view.ActionMode.Callback callback) { - if (DEBUG) Log.d(TAG, "[startActionMode] callback: " + callback); - - if (mActionMode != null) { - mActionMode.finish(); - } - ActionModeCallbackWrapper wrapped = null; - if (callback != null) { - wrapped = new ActionModeCallbackWrapper(callback); - } - - //Calling this will trigger the callback wrapper's onCreate which - //is where we will set the new instance to mActionMode since we need - //to pass it through to the sherlock callbacks and the call below - //will not have returned yet to store its value. - if (mActivity.startActionMode(wrapped) == null) { - mActionMode = null; - } - if (mActivity instanceof OnActionModeStartedListener && mActionMode != null) { - ((OnActionModeStartedListener)mActivity).onActionModeStarted(mActionMode); - } - - return mActionMode; - } - - private class ActionModeCallbackWrapper implements android.view.ActionMode.Callback { - private final ActionMode.Callback mCallback; - - public ActionModeCallbackWrapper(ActionMode.Callback callback) { - mCallback = callback; - } - - @Override - public boolean onCreateActionMode(android.view.ActionMode mode, android.view.Menu menu) { - //See ActionBarSherlockNative#startActionMode - mActionMode = new ActionModeWrapper(mode); - - return mCallback.onCreateActionMode(mActionMode, mActionMode.getMenu()); - } - - @Override - public boolean onPrepareActionMode(android.view.ActionMode mode, android.view.Menu menu) { - return mCallback.onPrepareActionMode(mActionMode, mActionMode.getMenu()); - } - - @Override - public boolean onActionItemClicked(android.view.ActionMode mode, android.view.MenuItem item) { - return mCallback.onActionItemClicked(mActionMode, mActionMode.getMenu().findItem(item)); - } - - @Override - public void onDestroyActionMode(android.view.ActionMode mode) { - mCallback.onDestroyActionMode(mActionMode); - if (mActivity instanceof OnActionModeFinishedListener) { - ((OnActionModeFinishedListener)mActivity).onActionModeFinished(mActionMode); - } - } - } - - private class ActionModeWrapper extends ActionMode { - private final android.view.ActionMode mActionMode; - private MenuWrapper mMenu = null; - - ActionModeWrapper(android.view.ActionMode actionMode) { - mActionMode = actionMode; - } - - @Override - public void setTitle(CharSequence title) { - mActionMode.setTitle(title); - } - - @Override - public void setTitle(int resId) { - mActionMode.setTitle(resId); - } - - @Override - public void setSubtitle(CharSequence subtitle) { - mActionMode.setSubtitle(subtitle); - } - - @Override - public void setSubtitle(int resId) { - mActionMode.setSubtitle(resId); - } - - @Override - public void setCustomView(View view) { - mActionMode.setCustomView(view); - } - - @Override - public void invalidate() { - mActionMode.invalidate(); - } - - @Override - public void finish() { - mActionMode.finish(); - } - - @Override - public MenuWrapper getMenu() { - if (mMenu == null) { - mMenu = new MenuWrapper(mActionMode.getMenu()); - } - return mMenu; - } - - @Override - public CharSequence getTitle() { - return mActionMode.getTitle(); - } - - @Override - public CharSequence getSubtitle() { - return mActionMode.getSubtitle(); - } - - @Override - public View getCustomView() { - return mActionMode.getCustomView(); - } - - @Override - public MenuInflater getMenuInflater() { - return ActionBarSherlockNative.this.getMenuInflater(); - } - - @Override - public void setTag(Object tag) { - mActionMode.setTag(tag); - } - - @Override - public Object getTag() { - return mActionMode.getTag(); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/ResourcesCompat.java b/actionbarsherlock/src/com/actionbarsherlock/internal/ResourcesCompat.java deleted file mode 100644 index 8e1efe8c..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/ResourcesCompat.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.actionbarsherlock.internal; - -import android.content.Context; -import android.os.Build; -import android.util.DisplayMetrics; -import com.actionbarsherlock.R; - -public final class ResourcesCompat { - //No instances - private ResourcesCompat() {} - - - /** - * Support implementation of {@code getResources().getBoolean()} that we - * can use to simulate filtering based on width and smallest width - * qualifiers on pre-3.2. - * - * @param context Context to load booleans from on 3.2+ and to fetch the - * display metrics. - * @param id Id of boolean to load. - * @return Associated boolean value as reflected by the current display - * metrics. - */ - public static boolean getResources_getBoolean(Context context, int id) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { - return context.getResources().getBoolean(id); - } - - DisplayMetrics metrics = context.getResources().getDisplayMetrics(); - float widthDp = metrics.widthPixels / metrics.density; - float heightDp = metrics.heightPixels / metrics.density; - float smallestWidthDp = (widthDp < heightDp) ? widthDp : heightDp; - - if (id == R.bool.abs__action_bar_embed_tabs) { - if (widthDp >= 480) { - return true; //values-w480dp - } - return false; //values - } - if (id == R.bool.abs__split_action_bar_is_narrow) { - if (widthDp >= 480) { - return false; //values-w480dp - } - return true; //values - } - if (id == R.bool.abs__action_bar_expanded_action_views_exclusive) { - if (smallestWidthDp >= 600) { - return false; //values-sw600dp - } - return true; //values - } - if (id == R.bool.abs__config_allowActionMenuItemTextWithIcon) { - if (widthDp >= 480) { - return true; //values-w480dp - } - return false; //values - } - - throw new IllegalArgumentException("Unknown boolean resource ID " + id); - } - - /** - * Support implementation of {@code getResources().getInteger()} that we - * can use to simulate filtering based on width qualifiers on pre-3.2. - * - * @param context Context to load integers from on 3.2+ and to fetch the - * display metrics. - * @param id Id of integer to load. - * @return Associated integer value as reflected by the current display - * metrics. - */ - public static int getResources_getInteger(Context context, int id) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { - return context.getResources().getInteger(id); - } - - DisplayMetrics metrics = context.getResources().getDisplayMetrics(); - float widthDp = metrics.widthPixels / metrics.density; - - if (id == R.integer.abs__max_action_buttons) { - if (widthDp >= 600) { - return 5; //values-w600dp - } - if (widthDp >= 500) { - return 4; //values-w500dp - } - if (widthDp >= 360) { - return 3; //values-w360dp - } - return 2; //values - } - - throw new IllegalArgumentException("Unknown integer resource ID " + id); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java b/actionbarsherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java deleted file mode 100644 index d022a246..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java +++ /dev/null @@ -1,1026 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.app; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import android.app.Activity; -import android.app.Dialog; -import android.content.Context; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.Handler; -import android.support.v4.app.FragmentActivity; -import android.support.v4.app.FragmentTransaction; -import android.util.TypedValue; -import android.view.ContextThemeWrapper; -import android.view.LayoutInflater; -import android.view.View; -import android.view.Window; -import android.view.accessibility.AccessibilityEvent; -import android.widget.SpinnerAdapter; -import com.actionbarsherlock.R; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; -import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorListenerAdapter; -import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet; -import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; -import com.actionbarsherlock.internal.nineoldandroids.animation.Animator.AnimatorListener; -import com.actionbarsherlock.internal.nineoldandroids.widget.NineFrameLayout; -import com.actionbarsherlock.internal.view.menu.MenuBuilder; -import com.actionbarsherlock.internal.view.menu.MenuPopupHelper; -import com.actionbarsherlock.internal.view.menu.SubMenuBuilder; -import com.actionbarsherlock.internal.widget.ActionBarContainer; -import com.actionbarsherlock.internal.widget.ActionBarContextView; -import com.actionbarsherlock.internal.widget.ActionBarView; -import com.actionbarsherlock.internal.widget.ScrollingTabContainerView; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; -import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; - -/** - * ActionBarImpl is the ActionBar implementation used - * by devices of all screen sizes. If it detects a compatible decor, - * it will split contextual modes across both the ActionBarView at - * the top of the screen and a horizontal LinearLayout at the bottom - * which is normally hidden. - */ -public class ActionBarImpl extends ActionBar { - //UNUSED private static final String TAG = "ActionBarImpl"; - - private Context mContext; - private Context mThemedContext; - private Activity mActivity; - //UNUSED private Dialog mDialog; - - private ActionBarContainer mContainerView; - private ActionBarView mActionView; - private ActionBarContextView mContextView; - private ActionBarContainer mSplitView; - private NineFrameLayout mContentView; - private ScrollingTabContainerView mTabScrollView; - - private ArrayList mTabs = new ArrayList(); - - private TabImpl mSelectedTab; - private int mSavedTabPosition = INVALID_POSITION; - - ActionModeImpl mActionMode; - ActionMode mDeferredDestroyActionMode; - ActionMode.Callback mDeferredModeDestroyCallback; - - private boolean mLastMenuVisibility; - private ArrayList mMenuVisibilityListeners = - new ArrayList(); - - private static final int CONTEXT_DISPLAY_NORMAL = 0; - private static final int CONTEXT_DISPLAY_SPLIT = 1; - - private static final int INVALID_POSITION = -1; - - private int mContextDisplayMode; - private boolean mHasEmbeddedTabs; - - final Handler mHandler = new Handler(); - Runnable mTabSelector; - - private Animator mCurrentShowAnim; - private Animator mCurrentModeAnim; - private boolean mShowHideAnimationEnabled; - boolean mWasHiddenBeforeMode; - - final AnimatorListener mHideListener = new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - if (mContentView != null) { - mContentView.setTranslationY(0); - mContainerView.setTranslationY(0); - } - if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) { - mSplitView.setVisibility(View.GONE); - } - mContainerView.setVisibility(View.GONE); - mContainerView.setTransitioning(false); - mCurrentShowAnim = null; - completeDeferredDestroyActionMode(); - } - }; - - final AnimatorListener mShowListener = new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mCurrentShowAnim = null; - mContainerView.requestLayout(); - } - }; - - public ActionBarImpl(Activity activity, int features) { - mActivity = activity; - Window window = activity.getWindow(); - View decor = window.getDecorView(); - init(decor); - - //window.hasFeature() workaround for pre-3.0 - if ((features & (1 << Window.FEATURE_ACTION_BAR_OVERLAY)) == 0) { - mContentView = (NineFrameLayout)decor.findViewById(android.R.id.content); - } - } - - public ActionBarImpl(Dialog dialog) { - //UNUSED mDialog = dialog; - init(dialog.getWindow().getDecorView()); - } - - private void init(View decor) { - mContext = decor.getContext(); - mActionView = (ActionBarView) decor.findViewById(R.id.abs__action_bar); - mContextView = (ActionBarContextView) decor.findViewById( - R.id.abs__action_context_bar); - mContainerView = (ActionBarContainer) decor.findViewById( - R.id.abs__action_bar_container); - mSplitView = (ActionBarContainer) decor.findViewById( - R.id.abs__split_action_bar); - - if (mActionView == null || mContextView == null || mContainerView == null) { - throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + - "with a compatible window decor layout"); - } - - mActionView.setContextView(mContextView); - mContextDisplayMode = mActionView.isSplitActionBar() ? - CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL; - - // Older apps get the home button interaction enabled by default. - // Newer apps need to enable it explicitly. - setHomeButtonEnabled(mContext.getApplicationInfo().targetSdkVersion < 14); - - setHasEmbeddedTabs(getResources_getBoolean(mContext, - R.bool.abs__action_bar_embed_tabs)); - } - - public void onConfigurationChanged(Configuration newConfig) { - setHasEmbeddedTabs(getResources_getBoolean(mContext, - R.bool.abs__action_bar_embed_tabs)); - - //Manually dispatch a configuration change to the action bar view on pre-2.2 - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { - mActionView.onConfigurationChanged(newConfig); - if (mContextView != null) { - mContextView.onConfigurationChanged(newConfig); - } - } - } - - private void setHasEmbeddedTabs(boolean hasEmbeddedTabs) { - mHasEmbeddedTabs = hasEmbeddedTabs; - // Switch tab layout configuration if needed - if (!mHasEmbeddedTabs) { - mActionView.setEmbeddedTabView(null); - mContainerView.setTabContainer(mTabScrollView); - } else { - mContainerView.setTabContainer(null); - mActionView.setEmbeddedTabView(mTabScrollView); - } - final boolean isInTabMode = getNavigationMode() == NAVIGATION_MODE_TABS; - if (mTabScrollView != null) { - mTabScrollView.setVisibility(isInTabMode ? View.VISIBLE : View.GONE); - } - mActionView.setCollapsable(!mHasEmbeddedTabs && isInTabMode); - } - - private void ensureTabsExist() { - if (mTabScrollView != null) { - return; - } - - ScrollingTabContainerView tabScroller = new ScrollingTabContainerView(mContext); - - if (mHasEmbeddedTabs) { - tabScroller.setVisibility(View.VISIBLE); - mActionView.setEmbeddedTabView(tabScroller); - } else { - tabScroller.setVisibility(getNavigationMode() == NAVIGATION_MODE_TABS ? - View.VISIBLE : View.GONE); - mContainerView.setTabContainer(tabScroller); - } - mTabScrollView = tabScroller; - } - - void completeDeferredDestroyActionMode() { - if (mDeferredModeDestroyCallback != null) { - mDeferredModeDestroyCallback.onDestroyActionMode(mDeferredDestroyActionMode); - mDeferredDestroyActionMode = null; - mDeferredModeDestroyCallback = null; - } - } - - /** - * Enables or disables animation between show/hide states. - * If animation is disabled using this method, animations in progress - * will be finished. - * - * @param enabled true to animate, false to not animate. - */ - public void setShowHideAnimationEnabled(boolean enabled) { - mShowHideAnimationEnabled = enabled; - if (!enabled && mCurrentShowAnim != null) { - mCurrentShowAnim.end(); - } - } - - public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) { - mMenuVisibilityListeners.add(listener); - } - - public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) { - mMenuVisibilityListeners.remove(listener); - } - - public void dispatchMenuVisibilityChanged(boolean isVisible) { - if (isVisible == mLastMenuVisibility) { - return; - } - mLastMenuVisibility = isVisible; - - final int count = mMenuVisibilityListeners.size(); - for (int i = 0; i < count; i++) { - mMenuVisibilityListeners.get(i).onMenuVisibilityChanged(isVisible); - } - } - - @Override - public void setCustomView(int resId) { - setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId, mActionView, false)); - } - - @Override - public void setDisplayUseLogoEnabled(boolean useLogo) { - setDisplayOptions(useLogo ? DISPLAY_USE_LOGO : 0, DISPLAY_USE_LOGO); - } - - @Override - public void setDisplayShowHomeEnabled(boolean showHome) { - setDisplayOptions(showHome ? DISPLAY_SHOW_HOME : 0, DISPLAY_SHOW_HOME); - } - - @Override - public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) { - setDisplayOptions(showHomeAsUp ? DISPLAY_HOME_AS_UP : 0, DISPLAY_HOME_AS_UP); - } - - @Override - public void setDisplayShowTitleEnabled(boolean showTitle) { - setDisplayOptions(showTitle ? DISPLAY_SHOW_TITLE : 0, DISPLAY_SHOW_TITLE); - } - - @Override - public void setDisplayShowCustomEnabled(boolean showCustom) { - setDisplayOptions(showCustom ? DISPLAY_SHOW_CUSTOM : 0, DISPLAY_SHOW_CUSTOM); - } - - @Override - public void setHomeButtonEnabled(boolean enable) { - mActionView.setHomeButtonEnabled(enable); - } - - @Override - public void setTitle(int resId) { - setTitle(mContext.getString(resId)); - } - - @Override - public void setSubtitle(int resId) { - setSubtitle(mContext.getString(resId)); - } - - public void setSelectedNavigationItem(int position) { - switch (mActionView.getNavigationMode()) { - case NAVIGATION_MODE_TABS: - selectTab(mTabs.get(position)); - break; - case NAVIGATION_MODE_LIST: - mActionView.setDropdownSelectedPosition(position); - break; - default: - throw new IllegalStateException( - "setSelectedNavigationIndex not valid for current navigation mode"); - } - } - - public void removeAllTabs() { - cleanupTabs(); - } - - private void cleanupTabs() { - if (mSelectedTab != null) { - selectTab(null); - } - mTabs.clear(); - if (mTabScrollView != null) { - mTabScrollView.removeAllTabs(); - } - mSavedTabPosition = INVALID_POSITION; - } - - public void setTitle(CharSequence title) { - mActionView.setTitle(title); - } - - public void setSubtitle(CharSequence subtitle) { - mActionView.setSubtitle(subtitle); - } - - public void setDisplayOptions(int options) { - mActionView.setDisplayOptions(options); - } - - public void setDisplayOptions(int options, int mask) { - final int current = mActionView.getDisplayOptions(); - mActionView.setDisplayOptions((options & mask) | (current & ~mask)); - } - - public void setBackgroundDrawable(Drawable d) { - mContainerView.setPrimaryBackground(d); - } - - public void setStackedBackgroundDrawable(Drawable d) { - mContainerView.setStackedBackground(d); - } - - public void setSplitBackgroundDrawable(Drawable d) { - if (mSplitView != null) { - mSplitView.setSplitBackground(d); - } - } - - public View getCustomView() { - return mActionView.getCustomNavigationView(); - } - - public CharSequence getTitle() { - return mActionView.getTitle(); - } - - public CharSequence getSubtitle() { - return mActionView.getSubtitle(); - } - - public int getNavigationMode() { - return mActionView.getNavigationMode(); - } - - public int getDisplayOptions() { - return mActionView.getDisplayOptions(); - } - - public ActionMode startActionMode(ActionMode.Callback callback) { - boolean wasHidden = false; - if (mActionMode != null) { - wasHidden = mWasHiddenBeforeMode; - mActionMode.finish(); - } - - mContextView.killMode(); - ActionModeImpl mode = new ActionModeImpl(callback); - if (mode.dispatchOnCreate()) { - mWasHiddenBeforeMode = !isShowing() || wasHidden; - mode.invalidate(); - mContextView.initForMode(mode); - animateToMode(true); - if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) { - // TODO animate this - mSplitView.setVisibility(View.VISIBLE); - } - mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - mActionMode = mode; - return mode; - } - return null; - } - - private void configureTab(Tab tab, int position) { - final TabImpl tabi = (TabImpl) tab; - final ActionBar.TabListener callback = tabi.getCallback(); - - if (callback == null) { - throw new IllegalStateException("Action Bar Tab must have a Callback"); - } - - tabi.setPosition(position); - mTabs.add(position, tabi); - - final int count = mTabs.size(); - for (int i = position + 1; i < count; i++) { - mTabs.get(i).setPosition(i); - } - } - - @Override - public void addTab(Tab tab) { - addTab(tab, mTabs.isEmpty()); - } - - @Override - public void addTab(Tab tab, int position) { - addTab(tab, position, mTabs.isEmpty()); - } - - @Override - public void addTab(Tab tab, boolean setSelected) { - ensureTabsExist(); - mTabScrollView.addTab(tab, setSelected); - configureTab(tab, mTabs.size()); - if (setSelected) { - selectTab(tab); - } - } - - @Override - public void addTab(Tab tab, int position, boolean setSelected) { - ensureTabsExist(); - mTabScrollView.addTab(tab, position, setSelected); - configureTab(tab, position); - if (setSelected) { - selectTab(tab); - } - } - - @Override - public Tab newTab() { - return new TabImpl(); - } - - @Override - public void removeTab(Tab tab) { - removeTabAt(tab.getPosition()); - } - - @Override - public void removeTabAt(int position) { - if (mTabScrollView == null) { - // No tabs around to remove - return; - } - - int selectedTabPosition = mSelectedTab != null - ? mSelectedTab.getPosition() : mSavedTabPosition; - mTabScrollView.removeTabAt(position); - TabImpl removedTab = mTabs.remove(position); - if (removedTab != null) { - removedTab.setPosition(-1); - } - - final int newTabCount = mTabs.size(); - for (int i = position; i < newTabCount; i++) { - mTabs.get(i).setPosition(i); - } - - if (selectedTabPosition == position) { - selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1))); - } - } - - @Override - public void selectTab(Tab tab) { - if (getNavigationMode() != NAVIGATION_MODE_TABS) { - mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION; - return; - } - - FragmentTransaction trans = null; - if (mActivity instanceof FragmentActivity) { - trans = ((FragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() - .disallowAddToBackStack(); - } - - if (mSelectedTab == tab) { - if (mSelectedTab != null) { - mSelectedTab.getCallback().onTabReselected(mSelectedTab, trans); - mTabScrollView.animateToTab(tab.getPosition()); - } - } else { - mTabScrollView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION); - if (mSelectedTab != null) { - mSelectedTab.getCallback().onTabUnselected(mSelectedTab, trans); - } - mSelectedTab = (TabImpl) tab; - if (mSelectedTab != null) { - mSelectedTab.getCallback().onTabSelected(mSelectedTab, trans); - } - } - - if (trans != null && !trans.isEmpty()) { - trans.commit(); - } - } - - @Override - public Tab getSelectedTab() { - return mSelectedTab; - } - - @Override - public int getHeight() { - return mContainerView.getHeight(); - } - - @Override - public void show() { - show(true); - } - - void show(boolean markHiddenBeforeMode) { - if (mCurrentShowAnim != null) { - mCurrentShowAnim.end(); - } - if (mContainerView.getVisibility() == View.VISIBLE) { - if (markHiddenBeforeMode) mWasHiddenBeforeMode = false; - return; - } - mContainerView.setVisibility(View.VISIBLE); - - if (mShowHideAnimationEnabled) { - mContainerView.setAlpha(0); - AnimatorSet anim = new AnimatorSet(); - AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 1)); - if (mContentView != null) { - b.with(ObjectAnimator.ofFloat(mContentView, "translationY", - -mContainerView.getHeight(), 0)); - mContainerView.setTranslationY(-mContainerView.getHeight()); - b.with(ObjectAnimator.ofFloat(mContainerView, "translationY", 0)); - } - if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) { - mSplitView.setAlpha(0); - mSplitView.setVisibility(View.VISIBLE); - b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 1)); - } - anim.addListener(mShowListener); - mCurrentShowAnim = anim; - anim.start(); - } else { - mContainerView.setAlpha(1); - mContainerView.setTranslationY(0); - mShowListener.onAnimationEnd(null); - } - } - - @Override - public void hide() { - if (mCurrentShowAnim != null) { - mCurrentShowAnim.end(); - } - if (mContainerView.getVisibility() == View.GONE) { - return; - } - - if (mShowHideAnimationEnabled) { - mContainerView.setAlpha(1); - mContainerView.setTransitioning(true); - AnimatorSet anim = new AnimatorSet(); - AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 0)); - if (mContentView != null) { - b.with(ObjectAnimator.ofFloat(mContentView, "translationY", - 0, -mContainerView.getHeight())); - b.with(ObjectAnimator.ofFloat(mContainerView, "translationY", - -mContainerView.getHeight())); - } - if (mSplitView != null && mSplitView.getVisibility() == View.VISIBLE) { - mSplitView.setAlpha(1); - b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 0)); - } - anim.addListener(mHideListener); - mCurrentShowAnim = anim; - anim.start(); - } else { - mHideListener.onAnimationEnd(null); - } - } - - public boolean isShowing() { - return mContainerView.getVisibility() == View.VISIBLE; - } - - void animateToMode(boolean toActionMode) { - if (toActionMode) { - show(false); - } - if (mCurrentModeAnim != null) { - mCurrentModeAnim.end(); - } - - mActionView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE); - mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE); - if (mTabScrollView != null && !mActionView.hasEmbeddedTabs() && mActionView.isCollapsed()) { - mTabScrollView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE); - } - } - - public Context getThemedContext() { - if (mThemedContext == null) { - TypedValue outValue = new TypedValue(); - Resources.Theme currentTheme = mContext.getTheme(); - currentTheme.resolveAttribute(R.attr.actionBarWidgetTheme, - outValue, true); - final int targetThemeRes = outValue.resourceId; - - if (targetThemeRes != 0) { //XXX && mContext.getThemeResId() != targetThemeRes) { - mThemedContext = new ContextThemeWrapper(mContext, targetThemeRes); - } else { - mThemedContext = mContext; - } - } - return mThemedContext; - } - - /** - * @hide - */ - public class ActionModeImpl extends ActionMode implements MenuBuilder.Callback { - private ActionMode.Callback mCallback; - private MenuBuilder mMenu; - private WeakReference mCustomView; - - public ActionModeImpl(ActionMode.Callback callback) { - mCallback = callback; - mMenu = new MenuBuilder(getThemedContext()) - .setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - mMenu.setCallback(this); - } - - @Override - public MenuInflater getMenuInflater() { - return new MenuInflater(getThemedContext()); - } - - @Override - public Menu getMenu() { - return mMenu; - } - - @Override - public void finish() { - if (mActionMode != this) { - // Not the active action mode - no-op - return; - } - - // If we were hidden before the mode was shown, defer the onDestroy - // callback until the animation is finished and associated relayout - // is about to happen. This lets apps better anticipate visibility - // and layout behavior. - if (mWasHiddenBeforeMode) { - mDeferredDestroyActionMode = this; - mDeferredModeDestroyCallback = mCallback; - } else { - mCallback.onDestroyActionMode(this); - } - mCallback = null; - animateToMode(false); - - // Clear out the context mode views after the animation finishes - mContextView.closeMode(); - mActionView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - - mActionMode = null; - - if (mWasHiddenBeforeMode) { - hide(); - } - } - - @Override - public void invalidate() { - mMenu.stopDispatchingItemsChanged(); - try { - mCallback.onPrepareActionMode(this, mMenu); - } finally { - mMenu.startDispatchingItemsChanged(); - } - } - - public boolean dispatchOnCreate() { - mMenu.stopDispatchingItemsChanged(); - try { - return mCallback.onCreateActionMode(this, mMenu); - } finally { - mMenu.startDispatchingItemsChanged(); - } - } - - @Override - public void setCustomView(View view) { - mContextView.setCustomView(view); - mCustomView = new WeakReference(view); - } - - @Override - public void setSubtitle(CharSequence subtitle) { - mContextView.setSubtitle(subtitle); - } - - @Override - public void setTitle(CharSequence title) { - mContextView.setTitle(title); - } - - @Override - public void setTitle(int resId) { - setTitle(mContext.getResources().getString(resId)); - } - - @Override - public void setSubtitle(int resId) { - setSubtitle(mContext.getResources().getString(resId)); - } - - @Override - public CharSequence getTitle() { - return mContextView.getTitle(); - } - - @Override - public CharSequence getSubtitle() { - return mContextView.getSubtitle(); - } - - @Override - public View getCustomView() { - return mCustomView != null ? mCustomView.get() : null; - } - - public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { - if (mCallback != null) { - return mCallback.onActionItemClicked(this, item); - } else { - return false; - } - } - - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - } - - public boolean onSubMenuSelected(SubMenuBuilder subMenu) { - if (mCallback == null) { - return false; - } - - if (!subMenu.hasVisibleItems()) { - return true; - } - - new MenuPopupHelper(getThemedContext(), subMenu).show(); - return true; - } - - public void onCloseSubMenu(SubMenuBuilder menu) { - } - - public void onMenuModeChange(MenuBuilder menu) { - if (mCallback == null) { - return; - } - invalidate(); - mContextView.showOverflowMenu(); - } - } - - /** - * @hide - */ - public class TabImpl extends ActionBar.Tab { - private ActionBar.TabListener mCallback; - private Object mTag; - private Drawable mIcon; - private CharSequence mText; - private CharSequence mContentDesc; - private int mPosition = -1; - private View mCustomView; - - @Override - public Object getTag() { - return mTag; - } - - @Override - public Tab setTag(Object tag) { - mTag = tag; - return this; - } - - public ActionBar.TabListener getCallback() { - return mCallback; - } - - @Override - public Tab setTabListener(ActionBar.TabListener callback) { - mCallback = callback; - return this; - } - - @Override - public View getCustomView() { - return mCustomView; - } - - @Override - public Tab setCustomView(View view) { - mCustomView = view; - if (mPosition >= 0) { - mTabScrollView.updateTab(mPosition); - } - return this; - } - - @Override - public Tab setCustomView(int layoutResId) { - return setCustomView(LayoutInflater.from(getThemedContext()) - .inflate(layoutResId, null)); - } - - @Override - public Drawable getIcon() { - return mIcon; - } - - @Override - public int getPosition() { - return mPosition; - } - - public void setPosition(int position) { - mPosition = position; - } - - @Override - public CharSequence getText() { - return mText; - } - - @Override - public Tab setIcon(Drawable icon) { - mIcon = icon; - if (mPosition >= 0) { - mTabScrollView.updateTab(mPosition); - } - return this; - } - - @Override - public Tab setIcon(int resId) { - return setIcon(mContext.getResources().getDrawable(resId)); - } - - @Override - public Tab setText(CharSequence text) { - mText = text; - if (mPosition >= 0) { - mTabScrollView.updateTab(mPosition); - } - return this; - } - - @Override - public Tab setText(int resId) { - return setText(mContext.getResources().getText(resId)); - } - - @Override - public void select() { - selectTab(this); - } - - @Override - public Tab setContentDescription(int resId) { - return setContentDescription(mContext.getResources().getText(resId)); - } - - @Override - public Tab setContentDescription(CharSequence contentDesc) { - mContentDesc = contentDesc; - if (mPosition >= 0) { - mTabScrollView.updateTab(mPosition); - } - return this; - } - - @Override - public CharSequence getContentDescription() { - return mContentDesc; - } - } - - @Override - public void setCustomView(View view) { - mActionView.setCustomNavigationView(view); - } - - @Override - public void setCustomView(View view, LayoutParams layoutParams) { - view.setLayoutParams(layoutParams); - mActionView.setCustomNavigationView(view); - } - - @Override - public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) { - mActionView.setDropdownAdapter(adapter); - mActionView.setCallback(callback); - } - - @Override - public int getSelectedNavigationIndex() { - switch (mActionView.getNavigationMode()) { - case NAVIGATION_MODE_TABS: - return mSelectedTab != null ? mSelectedTab.getPosition() : -1; - case NAVIGATION_MODE_LIST: - return mActionView.getDropdownSelectedPosition(); - default: - return -1; - } - } - - @Override - public int getNavigationItemCount() { - switch (mActionView.getNavigationMode()) { - case NAVIGATION_MODE_TABS: - return mTabs.size(); - case NAVIGATION_MODE_LIST: - SpinnerAdapter adapter = mActionView.getDropdownAdapter(); - return adapter != null ? adapter.getCount() : 0; - default: - return 0; - } - } - - @Override - public int getTabCount() { - return mTabs.size(); - } - - @Override - public void setNavigationMode(int mode) { - final int oldMode = mActionView.getNavigationMode(); - switch (oldMode) { - case NAVIGATION_MODE_TABS: - mSavedTabPosition = getSelectedNavigationIndex(); - selectTab(null); - mTabScrollView.setVisibility(View.GONE); - break; - } - mActionView.setNavigationMode(mode); - switch (mode) { - case NAVIGATION_MODE_TABS: - ensureTabsExist(); - mTabScrollView.setVisibility(View.VISIBLE); - if (mSavedTabPosition != INVALID_POSITION) { - setSelectedNavigationItem(mSavedTabPosition); - mSavedTabPosition = INVALID_POSITION; - } - break; - } - mActionView.setCollapsable(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs); - } - - @Override - public Tab getTabAt(int index) { - return mTabs.get(index); - } - - - @Override - public void setIcon(int resId) { - mActionView.setIcon(resId); - } - - @Override - public void setIcon(Drawable icon) { - mActionView.setIcon(icon); - } - - @Override - public void setLogo(int resId) { - mActionView.setLogo(resId); - } - - @Override - public void setLogo(Drawable logo) { - mActionView.setLogo(logo); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/app/ActionBarWrapper.java b/actionbarsherlock/src/com/actionbarsherlock/internal/app/ActionBarWrapper.java deleted file mode 100644 index 840cb3d2..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/app/ActionBarWrapper.java +++ /dev/null @@ -1,468 +0,0 @@ -package com.actionbarsherlock.internal.app; - -import java.util.HashSet; -import java.util.Set; - -import android.app.Activity; -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.support.v4.app.FragmentActivity; -import android.support.v4.app.FragmentTransaction; -import android.view.View; -import android.widget.SpinnerAdapter; - -import com.actionbarsherlock.app.ActionBar; - -public class ActionBarWrapper extends ActionBar implements android.app.ActionBar.OnNavigationListener, android.app.ActionBar.OnMenuVisibilityListener { - private final Activity mActivity; - private final android.app.ActionBar mActionBar; - private ActionBar.OnNavigationListener mNavigationListener; - private Set mMenuVisibilityListeners = new HashSet(1); - private FragmentTransaction mFragmentTransaction; - - - public ActionBarWrapper(Activity activity) { - mActivity = activity; - mActionBar = activity.getActionBar(); - if (mActionBar != null) { - mActionBar.addOnMenuVisibilityListener(this); - } - } - - - @Override - public void setHomeButtonEnabled(boolean enabled) { - mActionBar.setHomeButtonEnabled(enabled); - } - - @Override - public Context getThemedContext() { - return mActionBar.getThemedContext(); - } - - @Override - public void setCustomView(View view) { - mActionBar.setCustomView(view); - } - - @Override - public void setCustomView(View view, LayoutParams layoutParams) { - android.app.ActionBar.LayoutParams lp = new android.app.ActionBar.LayoutParams(layoutParams); - lp.gravity = layoutParams.gravity; - lp.bottomMargin = layoutParams.bottomMargin; - lp.topMargin = layoutParams.topMargin; - lp.leftMargin = layoutParams.leftMargin; - lp.rightMargin = layoutParams.rightMargin; - mActionBar.setCustomView(view, lp); - } - - @Override - public void setCustomView(int resId) { - mActionBar.setCustomView(resId); - } - - @Override - public void setIcon(int resId) { - mActionBar.setIcon(resId); - } - - @Override - public void setIcon(Drawable icon) { - mActionBar.setIcon(icon); - } - - @Override - public void setLogo(int resId) { - mActionBar.setLogo(resId); - } - - @Override - public void setLogo(Drawable logo) { - mActionBar.setLogo(logo); - } - - @Override - public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) { - mNavigationListener = callback; - mActionBar.setListNavigationCallbacks(adapter, (callback != null) ? this : null); - } - - @Override - public boolean onNavigationItemSelected(int itemPosition, long itemId) { - //This should never be a NullPointerException since we only set - //ourselves as the listener when the callback is not null. - return mNavigationListener.onNavigationItemSelected(itemPosition, itemId); - } - - @Override - public void setSelectedNavigationItem(int position) { - mActionBar.setSelectedNavigationItem(position); - } - - @Override - public int getSelectedNavigationIndex() { - return mActionBar.getSelectedNavigationIndex(); - } - - @Override - public int getNavigationItemCount() { - return mActionBar.getNavigationItemCount(); - } - - @Override - public void setTitle(CharSequence title) { - mActionBar.setTitle(title); - } - - @Override - public void setTitle(int resId) { - mActionBar.setTitle(resId); - } - - @Override - public void setSubtitle(CharSequence subtitle) { - mActionBar.setSubtitle(subtitle); - } - - @Override - public void setSubtitle(int resId) { - mActionBar.setSubtitle(resId); - } - - @Override - public void setDisplayOptions(int options) { - mActionBar.setDisplayOptions(options); - } - - @Override - public void setDisplayOptions(int options, int mask) { - mActionBar.setDisplayOptions(options, mask); - } - - @Override - public void setDisplayUseLogoEnabled(boolean useLogo) { - mActionBar.setDisplayUseLogoEnabled(useLogo); - } - - @Override - public void setDisplayShowHomeEnabled(boolean showHome) { - mActionBar.setDisplayShowHomeEnabled(showHome); - } - - @Override - public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) { - mActionBar.setDisplayHomeAsUpEnabled(showHomeAsUp); - } - - @Override - public void setDisplayShowTitleEnabled(boolean showTitle) { - mActionBar.setDisplayShowTitleEnabled(showTitle); - } - - @Override - public void setDisplayShowCustomEnabled(boolean showCustom) { - mActionBar.setDisplayShowCustomEnabled(showCustom); - } - - @Override - public void setBackgroundDrawable(Drawable d) { - mActionBar.setBackgroundDrawable(d); - } - - @Override - public void setStackedBackgroundDrawable(Drawable d) { - mActionBar.setStackedBackgroundDrawable(d); - } - - @Override - public void setSplitBackgroundDrawable(Drawable d) { - mActionBar.setSplitBackgroundDrawable(d); - } - - @Override - public View getCustomView() { - return mActionBar.getCustomView(); - } - - @Override - public CharSequence getTitle() { - return mActionBar.getTitle(); - } - - @Override - public CharSequence getSubtitle() { - return mActionBar.getSubtitle(); - } - - @Override - public int getNavigationMode() { - return mActionBar.getNavigationMode(); - } - - @Override - public void setNavigationMode(int mode) { - mActionBar.setNavigationMode(mode); - } - - @Override - public int getDisplayOptions() { - return mActionBar.getDisplayOptions(); - } - - public class TabWrapper extends ActionBar.Tab implements android.app.ActionBar.TabListener { - final android.app.ActionBar.Tab mNativeTab; - private Object mTag; - private TabListener mListener; - - public TabWrapper(android.app.ActionBar.Tab nativeTab) { - mNativeTab = nativeTab; - mNativeTab.setTag(this); - } - - @Override - public int getPosition() { - return mNativeTab.getPosition(); - } - - @Override - public Drawable getIcon() { - return mNativeTab.getIcon(); - } - - @Override - public CharSequence getText() { - return mNativeTab.getText(); - } - - @Override - public Tab setIcon(Drawable icon) { - mNativeTab.setIcon(icon); - return this; - } - - @Override - public Tab setIcon(int resId) { - mNativeTab.setIcon(resId); - return this; - } - - @Override - public Tab setText(CharSequence text) { - mNativeTab.setText(text); - return this; - } - - @Override - public Tab setText(int resId) { - mNativeTab.setText(resId); - return this; - } - - @Override - public Tab setCustomView(View view) { - mNativeTab.setCustomView(view); - return this; - } - - @Override - public Tab setCustomView(int layoutResId) { - mNativeTab.setCustomView(layoutResId); - return this; - } - - @Override - public View getCustomView() { - return mNativeTab.getCustomView(); - } - - @Override - public Tab setTag(Object obj) { - mTag = obj; - return this; - } - - @Override - public Object getTag() { - return mTag; - } - - @Override - public Tab setTabListener(TabListener listener) { - mNativeTab.setTabListener(listener != null ? this : null); - mListener = listener; - return this; - } - - @Override - public void select() { - mNativeTab.select(); - } - - @Override - public Tab setContentDescription(int resId) { - mNativeTab.setContentDescription(resId); - return this; - } - - @Override - public Tab setContentDescription(CharSequence contentDesc) { - mNativeTab.setContentDescription(contentDesc); - return this; - } - - @Override - public CharSequence getContentDescription() { - return mNativeTab.getContentDescription(); - } - - @Override - public void onTabReselected(android.app.ActionBar.Tab tab, android.app.FragmentTransaction ft) { - if (mListener != null) { - FragmentTransaction trans = null; - if (mActivity instanceof FragmentActivity) { - trans = ((FragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() - .disallowAddToBackStack(); - } - - mListener.onTabReselected(this, trans); - - if (trans != null && !trans.isEmpty()) { - trans.commit(); - } - } - } - - @Override - public void onTabSelected(android.app.ActionBar.Tab tab, android.app.FragmentTransaction ft) { - if (mListener != null) { - - if (mFragmentTransaction == null && mActivity instanceof FragmentActivity) { - mFragmentTransaction = ((FragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() - .disallowAddToBackStack(); - } - - mListener.onTabSelected(this, mFragmentTransaction); - - if (mFragmentTransaction != null) { - if (!mFragmentTransaction.isEmpty()) { - mFragmentTransaction.commit(); - } - mFragmentTransaction = null; - } - } - } - - @Override - public void onTabUnselected(android.app.ActionBar.Tab tab, android.app.FragmentTransaction ft) { - if (mListener != null) { - FragmentTransaction trans = null; - if (mActivity instanceof FragmentActivity) { - trans = ((FragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() - .disallowAddToBackStack(); - mFragmentTransaction = trans; - } - - mListener.onTabUnselected(this, trans); - } - } - } - - @Override - public Tab newTab() { - return new TabWrapper(mActionBar.newTab()); - } - - @Override - public void addTab(Tab tab) { - mActionBar.addTab(((TabWrapper)tab).mNativeTab); - } - - @Override - public void addTab(Tab tab, boolean setSelected) { - mActionBar.addTab(((TabWrapper)tab).mNativeTab, setSelected); - } - - @Override - public void addTab(Tab tab, int position) { - mActionBar.addTab(((TabWrapper)tab).mNativeTab, position); - } - - @Override - public void addTab(Tab tab, int position, boolean setSelected) { - mActionBar.addTab(((TabWrapper)tab).mNativeTab, position, setSelected); - } - - @Override - public void removeTab(Tab tab) { - mActionBar.removeTab(((TabWrapper)tab).mNativeTab); - } - - @Override - public void removeTabAt(int position) { - mActionBar.removeTabAt(position); - } - - @Override - public void removeAllTabs() { - mActionBar.removeAllTabs(); - } - - @Override - public void selectTab(Tab tab) { - mActionBar.selectTab(((TabWrapper)tab).mNativeTab); - } - - @Override - public Tab getSelectedTab() { - android.app.ActionBar.Tab selected = mActionBar.getSelectedTab(); - return (selected != null) ? (Tab)selected.getTag() : null; - } - - @Override - public Tab getTabAt(int index) { - android.app.ActionBar.Tab selected = mActionBar.getTabAt(index); - return (selected != null) ? (Tab)selected.getTag() : null; - } - - @Override - public int getTabCount() { - return mActionBar.getTabCount(); - } - - @Override - public int getHeight() { - return mActionBar.getHeight(); - } - - @Override - public void show() { - mActionBar.show(); - } - - @Override - public void hide() { - mActionBar.hide(); - } - - @Override - public boolean isShowing() { - return mActionBar.isShowing(); - } - - @Override - public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) { - mMenuVisibilityListeners.add(listener); - } - - @Override - public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) { - mMenuVisibilityListeners.remove(listener); - } - - @Override - public void onMenuVisibilityChanged(boolean isVisible) { - for (OnMenuVisibilityListener listener : mMenuVisibilityListeners) { - listener.onMenuVisibilityChanged(isVisible); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Animator.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Animator.java deleted file mode 100644 index 2caf5b4a..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Animator.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import java.util.ArrayList; - -import android.view.animation.Interpolator; - -/** - * This is the superclass for classes which provide basic support for animations which can be - * started, ended, and have AnimatorListeners added to them. - */ -public abstract class Animator implements Cloneable { - - - /** - * The set of listeners to be sent events through the life of an animation. - */ - ArrayList mListeners = null; - - /** - * Starts this animation. If the animation has a nonzero startDelay, the animation will start - * running after that delay elapses. A non-delayed animation will have its initial - * value(s) set immediately, followed by calls to - * {@link AnimatorListener#onAnimationStart(Animator)} for any listeners of this animator. - * - *

The animation started by calling this method will be run on the thread that called - * this method. This thread should have a Looper on it (a runtime exception will be thrown if - * this is not the case). Also, if the animation will animate - * properties of objects in the view hierarchy, then the calling thread should be the UI - * thread for that view hierarchy.

- * - */ - public void start() { - } - - /** - * Cancels the animation. Unlike {@link #end()}, cancel() causes the animation to - * stop in its tracks, sending an - * {@link android.animation.Animator.AnimatorListener#onAnimationCancel(Animator)} to - * its listeners, followed by an - * {@link android.animation.Animator.AnimatorListener#onAnimationEnd(Animator)} message. - * - *

This method must be called on the thread that is running the animation.

- */ - public void cancel() { - } - - /** - * Ends the animation. This causes the animation to assign the end value of the property being - * animated, then calling the - * {@link android.animation.Animator.AnimatorListener#onAnimationEnd(Animator)} method on - * its listeners. - * - *

This method must be called on the thread that is running the animation.

- */ - public void end() { - } - - /** - * The amount of time, in milliseconds, to delay starting the animation after - * {@link #start()} is called. - * - * @return the number of milliseconds to delay running the animation - */ - public abstract long getStartDelay(); - - /** - * The amount of time, in milliseconds, to delay starting the animation after - * {@link #start()} is called. - - * @param startDelay The amount of the delay, in milliseconds - */ - public abstract void setStartDelay(long startDelay); - - - /** - * Sets the length of the animation. - * - * @param duration The length of the animation, in milliseconds. - */ - public abstract Animator setDuration(long duration); - - /** - * Gets the length of the animation. - * - * @return The length of the animation, in milliseconds. - */ - public abstract long getDuration(); - - /** - * The time interpolator used in calculating the elapsed fraction of this animation. The - * interpolator determines whether the animation runs with linear or non-linear motion, - * such as acceleration and deceleration. The default value is - * {@link android.view.animation.AccelerateDecelerateInterpolator} - * - * @param value the interpolator to be used by this animation - */ - public abstract void setInterpolator(/*Time*/Interpolator value); - - /** - * Returns whether this Animator is currently running (having been started and gone past any - * initial startDelay period and not yet ended). - * - * @return Whether the Animator is running. - */ - public abstract boolean isRunning(); - - /** - * Returns whether this Animator has been started and not yet ended. This state is a superset - * of the state of {@link #isRunning()}, because an Animator with a nonzero - * {@link #getStartDelay() startDelay} will return true for {@link #isStarted()} during the - * delay phase, whereas {@link #isRunning()} will return true only after the delay phase - * is complete. - * - * @return Whether the Animator has been started and not yet ended. - */ - public boolean isStarted() { - // Default method returns value for isRunning(). Subclasses should override to return a - // real value. - return isRunning(); - } - - /** - * Adds a listener to the set of listeners that are sent events through the life of an - * animation, such as start, repeat, and end. - * - * @param listener the listener to be added to the current set of listeners for this animation. - */ - public void addListener(AnimatorListener listener) { - if (mListeners == null) { - mListeners = new ArrayList(); - } - mListeners.add(listener); - } - - /** - * Removes a listener from the set listening to this animation. - * - * @param listener the listener to be removed from the current set of listeners for this - * animation. - */ - public void removeListener(AnimatorListener listener) { - if (mListeners == null) { - return; - } - mListeners.remove(listener); - if (mListeners.size() == 0) { - mListeners = null; - } - } - - /** - * Gets the set of {@link android.animation.Animator.AnimatorListener} objects that are currently - * listening for events on this Animator object. - * - * @return ArrayList The set of listeners. - */ - public ArrayList getListeners() { - return mListeners; - } - - /** - * Removes all listeners from this object. This is equivalent to calling - * getListeners() followed by calling clear() on the - * returned list of listeners. - */ - public void removeAllListeners() { - if (mListeners != null) { - mListeners.clear(); - mListeners = null; - } - } - - @Override - public Animator clone() { - try { - final Animator anim = (Animator) super.clone(); - if (mListeners != null) { - ArrayList oldListeners = mListeners; - anim.mListeners = new ArrayList(); - int numListeners = oldListeners.size(); - for (int i = 0; i < numListeners; ++i) { - anim.mListeners.add(oldListeners.get(i)); - } - } - return anim; - } catch (CloneNotSupportedException e) { - throw new AssertionError(); - } - } - - /** - * This method tells the object to use appropriate information to extract - * starting values for the animation. For example, a AnimatorSet object will pass - * this call to its child objects to tell them to set up the values. A - * ObjectAnimator object will use the information it has about its target object - * and PropertyValuesHolder objects to get the start values for its properties. - * An ValueAnimator object will ignore the request since it does not have enough - * information (such as a target object) to gather these values. - */ - public void setupStartValues() { - } - - /** - * This method tells the object to use appropriate information to extract - * ending values for the animation. For example, a AnimatorSet object will pass - * this call to its child objects to tell them to set up the values. A - * ObjectAnimator object will use the information it has about its target object - * and PropertyValuesHolder objects to get the start values for its properties. - * An ValueAnimator object will ignore the request since it does not have enough - * information (such as a target object) to gather these values. - */ - public void setupEndValues() { - } - - /** - * Sets the target object whose property will be animated by this animation. Not all subclasses - * operate on target objects (for example, {@link ValueAnimator}, but this method - * is on the superclass for the convenience of dealing generically with those subclasses - * that do handle targets. - * - * @param target The object being animated - */ - public void setTarget(Object target) { - } - - /** - *

An animation listener receives notifications from an animation. - * Notifications indicate animation related events, such as the end or the - * repetition of the animation.

- */ - public static interface AnimatorListener { - /** - *

Notifies the start of the animation.

- * - * @param animation The started animation. - */ - void onAnimationStart(Animator animation); - - /** - *

Notifies the end of the animation. This callback is not invoked - * for animations with repeat count set to INFINITE.

- * - * @param animation The animation which reached its end. - */ - void onAnimationEnd(Animator animation); - - /** - *

Notifies the cancellation of the animation. This callback is not invoked - * for animations with repeat count set to INFINITE.

- * - * @param animation The animation which was canceled. - */ - void onAnimationCancel(Animator animation); - - /** - *

Notifies the repetition of the animation.

- * - * @param animation The animation which was repeated. - */ - void onAnimationRepeat(Animator animation); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorListenerAdapter.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorListenerAdapter.java deleted file mode 100644 index 02ddff48..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorListenerAdapter.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -/** - * This adapter class provides empty implementations of the methods from {@link android.animation.Animator.AnimatorListener}. - * Any custom listener that cares only about a subset of the methods of this listener can - * simply subclass this adapter class instead of implementing the interface directly. - */ -public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener { - - /** - * {@inheritDoc} - */ - @Override - public void onAnimationCancel(Animator animation) { - } - - /** - * {@inheritDoc} - */ - @Override - public void onAnimationEnd(Animator animation) { - } - - /** - * {@inheritDoc} - */ - @Override - public void onAnimationRepeat(Animator animation) { - } - - /** - * {@inheritDoc} - */ - @Override - public void onAnimationStart(Animator animation) { - } - -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorSet.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorSet.java deleted file mode 100644 index 3231080c..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/AnimatorSet.java +++ /dev/null @@ -1,1111 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; - -import android.view.animation.Interpolator; - -/** - * This class plays a set of {@link Animator} objects in the specified order. Animations - * can be set up to play together, in sequence, or after a specified delay. - * - *

There are two different approaches to adding animations to a AnimatorSet: - * either the {@link AnimatorSet#playTogether(Animator[]) playTogether()} or - * {@link AnimatorSet#playSequentially(Animator[]) playSequentially()} methods can be called to add - * a set of animations all at once, or the {@link AnimatorSet#play(Animator)} can be - * used in conjunction with methods in the {@link AnimatorSet.Builder Builder} - * class to add animations - * one by one.

- * - *

It is possible to set up a AnimatorSet with circular dependencies between - * its animations. For example, an animation a1 could be set up to start before animation a2, a2 - * before a3, and a3 before a1. The results of this configuration are undefined, but will typically - * result in none of the affected animations being played. Because of this (and because - * circular dependencies do not make logical sense anyway), circular dependencies - * should be avoided, and the dependency flow of animations should only be in one direction. - */ -@SuppressWarnings("unchecked") -public final class AnimatorSet extends Animator { - - /** - * Internal variables - * NOTE: This object implements the clone() method, making a deep copy of any referenced - * objects. As other non-trivial fields are added to this class, make sure to add logic - * to clone() to make deep copies of them. - */ - - /** - * Tracks animations currently being played, so that we know what to - * cancel or end when cancel() or end() is called on this AnimatorSet - */ - private ArrayList mPlayingSet = new ArrayList(); - - /** - * Contains all nodes, mapped to their respective Animators. When new - * dependency information is added for an Animator, we want to add it - * to a single node representing that Animator, not create a new Node - * if one already exists. - */ - private HashMap mNodeMap = new HashMap(); - - /** - * Set of all nodes created for this AnimatorSet. This list is used upon - * starting the set, and the nodes are placed in sorted order into the - * sortedNodes collection. - */ - private ArrayList mNodes = new ArrayList(); - - /** - * The sorted list of nodes. This is the order in which the animations will - * be played. The details about when exactly they will be played depend - * on the dependency relationships of the nodes. - */ - private ArrayList mSortedNodes = new ArrayList(); - - /** - * Flag indicating whether the nodes should be sorted prior to playing. This - * flag allows us to cache the previous sorted nodes so that if the sequence - * is replayed with no changes, it does not have to re-sort the nodes again. - */ - private boolean mNeedsSort = true; - - private AnimatorSetListener mSetListener = null; - - /** - * Flag indicating that the AnimatorSet has been manually - * terminated (by calling cancel() or end()). - * This flag is used to avoid starting other animations when currently-playing - * child animations of this AnimatorSet end. It also determines whether cancel/end - * notifications are sent out via the normal AnimatorSetListener mechanism. - */ - boolean mTerminated = false; - - /** - * Indicates whether an AnimatorSet has been start()'d, whether or - * not there is a nonzero startDelay. - */ - private boolean mStarted = false; - - // The amount of time in ms to delay starting the animation after start() is called - private long mStartDelay = 0; - - // Animator used for a nonzero startDelay - private ValueAnimator mDelayAnim = null; - - - // How long the child animations should last in ms. The default value is negative, which - // simply means that there is no duration set on the AnimatorSet. When a real duration is - // set, it is passed along to the child animations. - private long mDuration = -1; - - - /** - * Sets up this AnimatorSet to play all of the supplied animations at the same time. - * - * @param items The animations that will be started simultaneously. - */ - public void playTogether(Animator... items) { - if (items != null) { - mNeedsSort = true; - Builder builder = play(items[0]); - for (int i = 1; i < items.length; ++i) { - builder.with(items[i]); - } - } - } - - /** - * Sets up this AnimatorSet to play all of the supplied animations at the same time. - * - * @param items The animations that will be started simultaneously. - */ - public void playTogether(Collection items) { - if (items != null && items.size() > 0) { - mNeedsSort = true; - Builder builder = null; - for (Animator anim : items) { - if (builder == null) { - builder = play(anim); - } else { - builder.with(anim); - } - } - } - } - - /** - * Sets up this AnimatorSet to play each of the supplied animations when the - * previous animation ends. - * - * @param items The animations that will be started one after another. - */ - public void playSequentially(Animator... items) { - if (items != null) { - mNeedsSort = true; - if (items.length == 1) { - play(items[0]); - } else { - for (int i = 0; i < items.length - 1; ++i) { - play(items[i]).before(items[i+1]); - } - } - } - } - - /** - * Sets up this AnimatorSet to play each of the supplied animations when the - * previous animation ends. - * - * @param items The animations that will be started one after another. - */ - public void playSequentially(List items) { - if (items != null && items.size() > 0) { - mNeedsSort = true; - if (items.size() == 1) { - play(items.get(0)); - } else { - for (int i = 0; i < items.size() - 1; ++i) { - play(items.get(i)).before(items.get(i+1)); - } - } - } - } - - /** - * Returns the current list of child Animator objects controlled by this - * AnimatorSet. This is a copy of the internal list; modifications to the returned list - * will not affect the AnimatorSet, although changes to the underlying Animator objects - * will affect those objects being managed by the AnimatorSet. - * - * @return ArrayList The list of child animations of this AnimatorSet. - */ - public ArrayList getChildAnimations() { - ArrayList childList = new ArrayList(); - for (Node node : mNodes) { - childList.add(node.animation); - } - return childList; - } - - /** - * Sets the target object for all current {@link #getChildAnimations() child animations} - * of this AnimatorSet that take targets ({@link ObjectAnimator} and - * AnimatorSet). - * - * @param target The object being animated - */ - @Override - public void setTarget(Object target) { - for (Node node : mNodes) { - Animator animation = node.animation; - if (animation instanceof AnimatorSet) { - ((AnimatorSet)animation).setTarget(target); - } else if (animation instanceof ObjectAnimator) { - ((ObjectAnimator)animation).setTarget(target); - } - } - } - - /** - * Sets the TimeInterpolator for all current {@link #getChildAnimations() child animations} - * of this AnimatorSet. - * - * @param interpolator the interpolator to be used by each child animation of this AnimatorSet - */ - @Override - public void setInterpolator(/*Time*/Interpolator interpolator) { - for (Node node : mNodes) { - node.animation.setInterpolator(interpolator); - } - } - - /** - * This method creates a Builder object, which is used to - * set up playing constraints. This initial play() method - * tells the Builder the animation that is the dependency for - * the succeeding commands to the Builder. For example, - * calling play(a1).with(a2) sets up the AnimatorSet to play - * a1 and a2 at the same time, - * play(a1).before(a2) sets up the AnimatorSet to play - * a1 first, followed by a2, and - * play(a1).after(a2) sets up the AnimatorSet to play - * a2 first, followed by a1. - * - *

Note that play() is the only way to tell the - * Builder the animation upon which the dependency is created, - * so successive calls to the various functions in Builder - * will all refer to the initial parameter supplied in play() - * as the dependency of the other animations. For example, calling - * play(a1).before(a2).before(a3) will play both a2 - * and a3 when a1 ends; it does not set up a dependency between - * a2 and a3.

- * - * @param anim The animation that is the dependency used in later calls to the - * methods in the returned Builder object. A null parameter will result - * in a null Builder return value. - * @return Builder The object that constructs the AnimatorSet based on the dependencies - * outlined in the calls to play and the other methods in the - * BuilderNote that canceling a AnimatorSet also cancels all of the animations that it - * is responsible for.

- */ - @Override - public void cancel() { - mTerminated = true; - if (isStarted()) { - ArrayList tmpListeners = null; - if (mListeners != null) { - tmpListeners = (ArrayList) mListeners.clone(); - for (AnimatorListener listener : tmpListeners) { - listener.onAnimationCancel(this); - } - } - if (mDelayAnim != null && mDelayAnim.isRunning()) { - // If we're currently in the startDelay period, just cancel that animator and - // send out the end event to all listeners - mDelayAnim.cancel(); - } else if (mSortedNodes.size() > 0) { - for (Node node : mSortedNodes) { - node.animation.cancel(); - } - } - if (tmpListeners != null) { - for (AnimatorListener listener : tmpListeners) { - listener.onAnimationEnd(this); - } - } - mStarted = false; - } - } - - /** - * {@inheritDoc} - * - *

Note that ending a AnimatorSet also ends all of the animations that it is - * responsible for.

- */ - @Override - public void end() { - mTerminated = true; - if (isStarted()) { - if (mSortedNodes.size() != mNodes.size()) { - // hasn't been started yet - sort the nodes now, then end them - sortNodes(); - for (Node node : mSortedNodes) { - if (mSetListener == null) { - mSetListener = new AnimatorSetListener(this); - } - node.animation.addListener(mSetListener); - } - } - if (mDelayAnim != null) { - mDelayAnim.cancel(); - } - if (mSortedNodes.size() > 0) { - for (Node node : mSortedNodes) { - node.animation.end(); - } - } - if (mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - for (AnimatorListener listener : tmpListeners) { - listener.onAnimationEnd(this); - } - } - mStarted = false; - } - } - - /** - * Returns true if any of the child animations of this AnimatorSet have been started and have - * not yet ended. - * @return Whether this AnimatorSet has been started and has not yet ended. - */ - @Override - public boolean isRunning() { - for (Node node : mNodes) { - if (node.animation.isRunning()) { - return true; - } - } - return false; - } - - @Override - public boolean isStarted() { - return mStarted; - } - - /** - * The amount of time, in milliseconds, to delay starting the animation after - * {@link #start()} is called. - * - * @return the number of milliseconds to delay running the animation - */ - @Override - public long getStartDelay() { - return mStartDelay; - } - - /** - * The amount of time, in milliseconds, to delay starting the animation after - * {@link #start()} is called. - - * @param startDelay The amount of the delay, in milliseconds - */ - @Override - public void setStartDelay(long startDelay) { - mStartDelay = startDelay; - } - - /** - * Gets the length of each of the child animations of this AnimatorSet. This value may - * be less than 0, which indicates that no duration has been set on this AnimatorSet - * and each of the child animations will use their own duration. - * - * @return The length of the animation, in milliseconds, of each of the child - * animations of this AnimatorSet. - */ - @Override - public long getDuration() { - return mDuration; - } - - /** - * Sets the length of each of the current child animations of this AnimatorSet. By default, - * each child animation will use its own duration. If the duration is set on the AnimatorSet, - * then each child animation inherits this duration. - * - * @param duration The length of the animation, in milliseconds, of each of the child - * animations of this AnimatorSet. - */ - @Override - public AnimatorSet setDuration(long duration) { - if (duration < 0) { - throw new IllegalArgumentException("duration must be a value of zero or greater"); - } - for (Node node : mNodes) { - // TODO: don't set the duration of the timing-only nodes created by AnimatorSet to - // insert "play-after" delays - node.animation.setDuration(duration); - } - mDuration = duration; - return this; - } - - @Override - public void setupStartValues() { - for (Node node : mNodes) { - node.animation.setupStartValues(); - } - } - - @Override - public void setupEndValues() { - for (Node node : mNodes) { - node.animation.setupEndValues(); - } - } - - /** - * {@inheritDoc} - * - *

Starting this AnimatorSet will, in turn, start the animations for which - * it is responsible. The details of when exactly those animations are started depends on - * the dependency relationships that have been set up between the animations. - */ - @Override - public void start() { - mTerminated = false; - mStarted = true; - - // First, sort the nodes (if necessary). This will ensure that sortedNodes - // contains the animation nodes in the correct order. - sortNodes(); - - int numSortedNodes = mSortedNodes.size(); - for (int i = 0; i < numSortedNodes; ++i) { - Node node = mSortedNodes.get(i); - // First, clear out the old listeners - ArrayList oldListeners = node.animation.getListeners(); - if (oldListeners != null && oldListeners.size() > 0) { - final ArrayList clonedListeners = new - ArrayList(oldListeners); - - for (AnimatorListener listener : clonedListeners) { - if (listener instanceof DependencyListener || - listener instanceof AnimatorSetListener) { - node.animation.removeListener(listener); - } - } - } - } - - // nodesToStart holds the list of nodes to be started immediately. We don't want to - // start the animations in the loop directly because we first need to set up - // dependencies on all of the nodes. For example, we don't want to start an animation - // when some other animation also wants to start when the first animation begins. - final ArrayList nodesToStart = new ArrayList(); - for (int i = 0; i < numSortedNodes; ++i) { - Node node = mSortedNodes.get(i); - if (mSetListener == null) { - mSetListener = new AnimatorSetListener(this); - } - if (node.dependencies == null || node.dependencies.size() == 0) { - nodesToStart.add(node); - } else { - int numDependencies = node.dependencies.size(); - for (int j = 0; j < numDependencies; ++j) { - Dependency dependency = node.dependencies.get(j); - dependency.node.animation.addListener( - new DependencyListener(this, node, dependency.rule)); - } - node.tmpDependencies = (ArrayList) node.dependencies.clone(); - } - node.animation.addListener(mSetListener); - } - // Now that all dependencies are set up, start the animations that should be started. - if (mStartDelay <= 0) { - for (Node node : nodesToStart) { - node.animation.start(); - mPlayingSet.add(node.animation); - } - } else { - mDelayAnim = ValueAnimator.ofFloat(0f, 1f); - mDelayAnim.setDuration(mStartDelay); - mDelayAnim.addListener(new AnimatorListenerAdapter() { - boolean canceled = false; - public void onAnimationCancel(Animator anim) { - canceled = true; - } - public void onAnimationEnd(Animator anim) { - if (!canceled) { - int numNodes = nodesToStart.size(); - for (int i = 0; i < numNodes; ++i) { - Node node = nodesToStart.get(i); - node.animation.start(); - mPlayingSet.add(node.animation); - } - } - } - }); - mDelayAnim.start(); - } - if (mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationStart(this); - } - } - if (mNodes.size() == 0 && mStartDelay == 0) { - // Handle unusual case where empty AnimatorSet is started - should send out - // end event immediately since the event will not be sent out at all otherwise - mStarted = false; - if (mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationEnd(this); - } - } - } - } - - @Override - public AnimatorSet clone() { - final AnimatorSet anim = (AnimatorSet) super.clone(); - /* - * The basic clone() operation copies all items. This doesn't work very well for - * AnimatorSet, because it will copy references that need to be recreated and state - * that may not apply. What we need to do now is put the clone in an uninitialized - * state, with fresh, empty data structures. Then we will build up the nodes list - * manually, as we clone each Node (and its animation). The clone will then be sorted, - * and will populate any appropriate lists, when it is started. - */ - anim.mNeedsSort = true; - anim.mTerminated = false; - anim.mStarted = false; - anim.mPlayingSet = new ArrayList(); - anim.mNodeMap = new HashMap(); - anim.mNodes = new ArrayList(); - anim.mSortedNodes = new ArrayList(); - - // Walk through the old nodes list, cloning each node and adding it to the new nodemap. - // One problem is that the old node dependencies point to nodes in the old AnimatorSet. - // We need to track the old/new nodes in order to reconstruct the dependencies in the clone. - HashMap nodeCloneMap = new HashMap(); // - for (Node node : mNodes) { - Node nodeClone = node.clone(); - nodeCloneMap.put(node, nodeClone); - anim.mNodes.add(nodeClone); - anim.mNodeMap.put(nodeClone.animation, nodeClone); - // Clear out the dependencies in the clone; we'll set these up manually later - nodeClone.dependencies = null; - nodeClone.tmpDependencies = null; - nodeClone.nodeDependents = null; - nodeClone.nodeDependencies = null; - // clear out any listeners that were set up by the AnimatorSet; these will - // be set up when the clone's nodes are sorted - ArrayList cloneListeners = nodeClone.animation.getListeners(); - if (cloneListeners != null) { - ArrayList listenersToRemove = null; - for (AnimatorListener listener : cloneListeners) { - if (listener instanceof AnimatorSetListener) { - if (listenersToRemove == null) { - listenersToRemove = new ArrayList(); - } - listenersToRemove.add(listener); - } - } - if (listenersToRemove != null) { - for (AnimatorListener listener : listenersToRemove) { - cloneListeners.remove(listener); - } - } - } - } - // Now that we've cloned all of the nodes, we're ready to walk through their - // dependencies, mapping the old dependencies to the new nodes - for (Node node : mNodes) { - Node nodeClone = nodeCloneMap.get(node); - if (node.dependencies != null) { - for (Dependency dependency : node.dependencies) { - Node clonedDependencyNode = nodeCloneMap.get(dependency.node); - Dependency cloneDependency = new Dependency(clonedDependencyNode, - dependency.rule); - nodeClone.addDependency(cloneDependency); - } - } - } - - return anim; - } - - /** - * This class is the mechanism by which animations are started based on events in other - * animations. If an animation has multiple dependencies on other animations, then - * all dependencies must be satisfied before the animation is started. - */ - private static class DependencyListener implements AnimatorListener { - - private AnimatorSet mAnimatorSet; - - // The node upon which the dependency is based. - private Node mNode; - - // The Dependency rule (WITH or AFTER) that the listener should wait for on - // the node - private int mRule; - - public DependencyListener(AnimatorSet animatorSet, Node node, int rule) { - this.mAnimatorSet = animatorSet; - this.mNode = node; - this.mRule = rule; - } - - /** - * Ignore cancel events for now. We may want to handle this eventually, - * to prevent follow-on animations from running when some dependency - * animation is canceled. - */ - public void onAnimationCancel(Animator animation) { - } - - /** - * An end event is received - see if this is an event we are listening for - */ - public void onAnimationEnd(Animator animation) { - if (mRule == Dependency.AFTER) { - startIfReady(animation); - } - } - - /** - * Ignore repeat events for now - */ - public void onAnimationRepeat(Animator animation) { - } - - /** - * A start event is received - see if this is an event we are listening for - */ - public void onAnimationStart(Animator animation) { - if (mRule == Dependency.WITH) { - startIfReady(animation); - } - } - - /** - * Check whether the event received is one that the node was waiting for. - * If so, mark it as complete and see whether it's time to start - * the animation. - * @param dependencyAnimation the animation that sent the event. - */ - private void startIfReady(Animator dependencyAnimation) { - if (mAnimatorSet.mTerminated) { - // if the parent AnimatorSet was canceled, then don't start any dependent anims - return; - } - Dependency dependencyToRemove = null; - int numDependencies = mNode.tmpDependencies.size(); - for (int i = 0; i < numDependencies; ++i) { - Dependency dependency = mNode.tmpDependencies.get(i); - if (dependency.rule == mRule && - dependency.node.animation == dependencyAnimation) { - // rule fired - remove the dependency and listener and check to - // see whether it's time to start the animation - dependencyToRemove = dependency; - dependencyAnimation.removeListener(this); - break; - } - } - mNode.tmpDependencies.remove(dependencyToRemove); - if (mNode.tmpDependencies.size() == 0) { - // all dependencies satisfied: start the animation - mNode.animation.start(); - mAnimatorSet.mPlayingSet.add(mNode.animation); - } - } - - } - - private class AnimatorSetListener implements AnimatorListener { - - private AnimatorSet mAnimatorSet; - - AnimatorSetListener(AnimatorSet animatorSet) { - mAnimatorSet = animatorSet; - } - - public void onAnimationCancel(Animator animation) { - if (!mTerminated) { - // Listeners are already notified of the AnimatorSet canceling in cancel(). - // The logic below only kicks in when animations end normally - if (mPlayingSet.size() == 0) { - if (mListeners != null) { - int numListeners = mListeners.size(); - for (int i = 0; i < numListeners; ++i) { - mListeners.get(i).onAnimationCancel(mAnimatorSet); - } - } - } - } - } - - public void onAnimationEnd(Animator animation) { - animation.removeListener(this); - mPlayingSet.remove(animation); - Node animNode = mAnimatorSet.mNodeMap.get(animation); - animNode.done = true; - if (!mTerminated) { - // Listeners are already notified of the AnimatorSet ending in cancel() or - // end(); the logic below only kicks in when animations end normally - ArrayList sortedNodes = mAnimatorSet.mSortedNodes; - boolean allDone = true; - int numSortedNodes = sortedNodes.size(); - for (int i = 0; i < numSortedNodes; ++i) { - if (!sortedNodes.get(i).done) { - allDone = false; - break; - } - } - if (allDone) { - // If this was the last child animation to end, then notify listeners that this - // AnimatorSet has ended - if (mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationEnd(mAnimatorSet); - } - } - mAnimatorSet.mStarted = false; - } - } - } - - // Nothing to do - public void onAnimationRepeat(Animator animation) { - } - - // Nothing to do - public void onAnimationStart(Animator animation) { - } - - } - - /** - * This method sorts the current set of nodes, if needed. The sort is a simple - * DependencyGraph sort, which goes like this: - * - All nodes without dependencies become 'roots' - * - while roots list is not null - * - for each root r - * - add r to sorted list - * - remove r as a dependency from any other node - * - any nodes with no dependencies are added to the roots list - */ - private void sortNodes() { - if (mNeedsSort) { - mSortedNodes.clear(); - ArrayList roots = new ArrayList(); - int numNodes = mNodes.size(); - for (int i = 0; i < numNodes; ++i) { - Node node = mNodes.get(i); - if (node.dependencies == null || node.dependencies.size() == 0) { - roots.add(node); - } - } - ArrayList tmpRoots = new ArrayList(); - while (roots.size() > 0) { - int numRoots = roots.size(); - for (int i = 0; i < numRoots; ++i) { - Node root = roots.get(i); - mSortedNodes.add(root); - if (root.nodeDependents != null) { - int numDependents = root.nodeDependents.size(); - for (int j = 0; j < numDependents; ++j) { - Node node = root.nodeDependents.get(j); - node.nodeDependencies.remove(root); - if (node.nodeDependencies.size() == 0) { - tmpRoots.add(node); - } - } - } - } - roots.clear(); - roots.addAll(tmpRoots); - tmpRoots.clear(); - } - mNeedsSort = false; - if (mSortedNodes.size() != mNodes.size()) { - throw new IllegalStateException("Circular dependencies cannot exist" - + " in AnimatorSet"); - } - } else { - // Doesn't need sorting, but still need to add in the nodeDependencies list - // because these get removed as the event listeners fire and the dependencies - // are satisfied - int numNodes = mNodes.size(); - for (int i = 0; i < numNodes; ++i) { - Node node = mNodes.get(i); - if (node.dependencies != null && node.dependencies.size() > 0) { - int numDependencies = node.dependencies.size(); - for (int j = 0; j < numDependencies; ++j) { - Dependency dependency = node.dependencies.get(j); - if (node.nodeDependencies == null) { - node.nodeDependencies = new ArrayList(); - } - if (!node.nodeDependencies.contains(dependency.node)) { - node.nodeDependencies.add(dependency.node); - } - } - } - // nodes are 'done' by default; they become un-done when started, and done - // again when ended - node.done = false; - } - } - } - - /** - * Dependency holds information about the node that some other node is - * dependent upon and the nature of that dependency. - * - */ - private static class Dependency { - static final int WITH = 0; // dependent node must start with this dependency node - static final int AFTER = 1; // dependent node must start when this dependency node finishes - - // The node that the other node with this Dependency is dependent upon - public Node node; - - // The nature of the dependency (WITH or AFTER) - public int rule; - - public Dependency(Node node, int rule) { - this.node = node; - this.rule = rule; - } - } - - /** - * A Node is an embodiment of both the Animator that it wraps as well as - * any dependencies that are associated with that Animation. This includes - * both dependencies upon other nodes (in the dependencies list) as - * well as dependencies of other nodes upon this (in the nodeDependents list). - */ - private static class Node implements Cloneable { - public Animator animation; - - /** - * These are the dependencies that this node's animation has on other - * nodes. For example, if this node's animation should begin with some - * other animation ends, then there will be an item in this node's - * dependencies list for that other animation's node. - */ - public ArrayList dependencies = null; - - /** - * tmpDependencies is a runtime detail. We use the dependencies list for sorting. - * But we also use the list to keep track of when multiple dependencies are satisfied, - * but removing each dependency as it is satisfied. We do not want to remove - * the dependency itself from the list, because we need to retain that information - * if the AnimatorSet is launched in the future. So we create a copy of the dependency - * list when the AnimatorSet starts and use this tmpDependencies list to track the - * list of satisfied dependencies. - */ - public ArrayList tmpDependencies = null; - - /** - * nodeDependencies is just a list of the nodes that this Node is dependent upon. - * This information is used in sortNodes(), to determine when a node is a root. - */ - public ArrayList nodeDependencies = null; - - /** - * nodeDepdendents is the list of nodes that have this node as a dependency. This - * is a utility field used in sortNodes to facilitate removing this node as a - * dependency when it is a root node. - */ - public ArrayList nodeDependents = null; - - /** - * Flag indicating whether the animation in this node is finished. This flag - * is used by AnimatorSet to check, as each animation ends, whether all child animations - * are done and it's time to send out an end event for the entire AnimatorSet. - */ - public boolean done = false; - - /** - * Constructs the Node with the animation that it encapsulates. A Node has no - * dependencies by default; dependencies are added via the addDependency() - * method. - * - * @param animation The animation that the Node encapsulates. - */ - public Node(Animator animation) { - this.animation = animation; - } - - /** - * Add a dependency to this Node. The dependency includes information about the - * node that this node is dependency upon and the nature of the dependency. - * @param dependency - */ - public void addDependency(Dependency dependency) { - if (dependencies == null) { - dependencies = new ArrayList(); - nodeDependencies = new ArrayList(); - } - dependencies.add(dependency); - if (!nodeDependencies.contains(dependency.node)) { - nodeDependencies.add(dependency.node); - } - Node dependencyNode = dependency.node; - if (dependencyNode.nodeDependents == null) { - dependencyNode.nodeDependents = new ArrayList(); - } - dependencyNode.nodeDependents.add(this); - } - - @Override - public Node clone() { - try { - Node node = (Node) super.clone(); - node.animation = animation.clone(); - return node; - } catch (CloneNotSupportedException e) { - throw new AssertionError(); - } - } - } - - /** - * The Builder object is a utility class to facilitate adding animations to a - * AnimatorSet along with the relationships between the various animations. The - * intention of the Builder methods, along with the {@link - * AnimatorSet#play(Animator) play()} method of AnimatorSet is to make it possible - * to express the dependency relationships of animations in a natural way. Developers can also - * use the {@link AnimatorSet#playTogether(Animator[]) playTogether()} and {@link - * AnimatorSet#playSequentially(Animator[]) playSequentially()} methods if these suit the need, - * but it might be easier in some situations to express the AnimatorSet of animations in pairs. - *

- *

The Builder object cannot be constructed directly, but is rather constructed - * internally via a call to {@link AnimatorSet#play(Animator)}.

- *

- *

For example, this sets up a AnimatorSet to play anim1 and anim2 at the same time, anim3 to - * play when anim2 finishes, and anim4 to play when anim3 finishes:

- *
-     *     AnimatorSet s = new AnimatorSet();
-     *     s.play(anim1).with(anim2);
-     *     s.play(anim2).before(anim3);
-     *     s.play(anim4).after(anim3);
-     * 
- *

- *

Note in the example that both {@link Builder#before(Animator)} and {@link - * Builder#after(Animator)} are used. These are just different ways of expressing the same - * relationship and are provided to make it easier to say things in a way that is more natural, - * depending on the situation.

- *

- *

It is possible to make several calls into the same Builder object to express - * multiple relationships. However, note that it is only the animation passed into the initial - * {@link AnimatorSet#play(Animator)} method that is the dependency in any of the successive - * calls to the Builder object. For example, the following code starts both anim2 - * and anim3 when anim1 ends; there is no direct dependency relationship between anim2 and - * anim3: - *

-     *   AnimatorSet s = new AnimatorSet();
-     *   s.play(anim1).before(anim2).before(anim3);
-     * 
- * If the desired result is to play anim1 then anim2 then anim3, this code expresses the - * relationship correctly:

- *
-     *   AnimatorSet s = new AnimatorSet();
-     *   s.play(anim1).before(anim2);
-     *   s.play(anim2).before(anim3);
-     * 
- *

- *

Note that it is possible to express relationships that cannot be resolved and will not - * result in sensible results. For example, play(anim1).after(anim1) makes no - * sense. In general, circular dependencies like this one (or more indirect ones where a depends - * on b, which depends on c, which depends on a) should be avoided. Only create AnimatorSets - * that can boil down to a simple, one-way relationship of animations starting with, before, and - * after other, different, animations.

- */ - public class Builder { - - /** - * This tracks the current node being processed. It is supplied to the play() method - * of AnimatorSet and passed into the constructor of Builder. - */ - private Node mCurrentNode; - - /** - * package-private constructor. Builders are only constructed by AnimatorSet, when the - * play() method is called. - * - * @param anim The animation that is the dependency for the other animations passed into - * the other methods of this Builder object. - */ - Builder(Animator anim) { - mCurrentNode = mNodeMap.get(anim); - if (mCurrentNode == null) { - mCurrentNode = new Node(anim); - mNodeMap.put(anim, mCurrentNode); - mNodes.add(mCurrentNode); - } - } - - /** - * Sets up the given animation to play at the same time as the animation supplied in the - * {@link AnimatorSet#play(Animator)} call that created this Builder object. - * - * @param anim The animation that will play when the animation supplied to the - * {@link AnimatorSet#play(Animator)} method starts. - */ - public Builder with(Animator anim) { - Node node = mNodeMap.get(anim); - if (node == null) { - node = new Node(anim); - mNodeMap.put(anim, node); - mNodes.add(node); - } - Dependency dependency = new Dependency(mCurrentNode, Dependency.WITH); - node.addDependency(dependency); - return this; - } - - /** - * Sets up the given animation to play when the animation supplied in the - * {@link AnimatorSet#play(Animator)} call that created this Builder object - * ends. - * - * @param anim The animation that will play when the animation supplied to the - * {@link AnimatorSet#play(Animator)} method ends. - */ - public Builder before(Animator anim) { - Node node = mNodeMap.get(anim); - if (node == null) { - node = new Node(anim); - mNodeMap.put(anim, node); - mNodes.add(node); - } - Dependency dependency = new Dependency(mCurrentNode, Dependency.AFTER); - node.addDependency(dependency); - return this; - } - - /** - * Sets up the given animation to play when the animation supplied in the - * {@link AnimatorSet#play(Animator)} call that created this Builder object - * to start when the animation supplied in this method call ends. - * - * @param anim The animation whose end will cause the animation supplied to the - * {@link AnimatorSet#play(Animator)} method to play. - */ - public Builder after(Animator anim) { - Node node = mNodeMap.get(anim); - if (node == null) { - node = new Node(anim); - mNodeMap.put(anim, node); - mNodes.add(node); - } - Dependency dependency = new Dependency(node, Dependency.AFTER); - mCurrentNode.addDependency(dependency); - return this; - } - - /** - * Sets up the animation supplied in the - * {@link AnimatorSet#play(Animator)} call that created this Builder object - * to play when the given amount of time elapses. - * - * @param delay The number of milliseconds that should elapse before the - * animation starts. - */ - public Builder after(long delay) { - // setup dummy ValueAnimator just to run the clock - ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); - anim.setDuration(delay); - after(anim); - return this; - } - - } - -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatEvaluator.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatEvaluator.java deleted file mode 100644 index e4101936..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatEvaluator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -/** - * This evaluator can be used to perform type interpolation between float values. - */ -public class FloatEvaluator implements TypeEvaluator { - - /** - * This function returns the result of linearly interpolating the start and end values, with - * fraction representing the proportion between the start and end values. The - * calculation is a simple parametric calculation: result = x0 + t * (v1 - v0), - * where x0 is startValue, x1 is endValue, - * and t is fraction. - * - * @param fraction The fraction from the starting to the ending values - * @param startValue The start value; should be of type float or - * Float - * @param endValue The end value; should be of type float or Float - * @return A linear interpolation between the start and end values, given the - * fraction parameter. - */ - public Float evaluate(float fraction, Number startValue, Number endValue) { - float startFloat = startValue.floatValue(); - return startFloat + fraction * (endValue.floatValue() - startFloat); - } -} \ No newline at end of file diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatKeyframeSet.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatKeyframeSet.java deleted file mode 100644 index 6d9dafa7..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/FloatKeyframeSet.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import java.util.ArrayList; -import android.view.animation.Interpolator; - -import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.FloatKeyframe; - -/** - * This class holds a collection of FloatKeyframe objects and is called by ValueAnimator to calculate - * values between those keyframes for a given animation. The class internal to the animation - * package because it is an implementation detail of how Keyframes are stored and used. - * - *

This type-specific subclass of KeyframeSet, along with the other type-specific subclass for - * int, exists to speed up the getValue() method when there is no custom - * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the - * Object equivalents of these primitive types.

- */ -@SuppressWarnings("unchecked") -class FloatKeyframeSet extends KeyframeSet { - private float firstValue; - private float lastValue; - private float deltaValue; - private boolean firstTime = true; - - public FloatKeyframeSet(FloatKeyframe... keyframes) { - super(keyframes); - } - - @Override - public Object getValue(float fraction) { - return getFloatValue(fraction); - } - - @Override - public FloatKeyframeSet clone() { - ArrayList keyframes = mKeyframes; - int numKeyframes = mKeyframes.size(); - FloatKeyframe[] newKeyframes = new FloatKeyframe[numKeyframes]; - for (int i = 0; i < numKeyframes; ++i) { - newKeyframes[i] = (FloatKeyframe) keyframes.get(i).clone(); - } - FloatKeyframeSet newSet = new FloatKeyframeSet(newKeyframes); - return newSet; - } - - public float getFloatValue(float fraction) { - if (mNumKeyframes == 2) { - if (firstTime) { - firstTime = false; - firstValue = ((FloatKeyframe) mKeyframes.get(0)).getFloatValue(); - lastValue = ((FloatKeyframe) mKeyframes.get(1)).getFloatValue(); - deltaValue = lastValue - firstValue; - } - if (mInterpolator != null) { - fraction = mInterpolator.getInterpolation(fraction); - } - if (mEvaluator == null) { - return firstValue + fraction * deltaValue; - } else { - return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).floatValue(); - } - } - if (fraction <= 0f) { - final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0); - final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(1); - float prevValue = prevKeyframe.getFloatValue(); - float nextValue = nextKeyframe.getFloatValue(); - float prevFraction = prevKeyframe.getFraction(); - float nextFraction = nextKeyframe.getFraction(); - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); - return mEvaluator == null ? - prevValue + intervalFraction * (nextValue - prevValue) : - ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). - floatValue(); - } else if (fraction >= 1f) { - final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 2); - final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 1); - float prevValue = prevKeyframe.getFloatValue(); - float nextValue = nextKeyframe.getFloatValue(); - float prevFraction = prevKeyframe.getFraction(); - float nextFraction = nextKeyframe.getFraction(); - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); - return mEvaluator == null ? - prevValue + intervalFraction * (nextValue - prevValue) : - ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). - floatValue(); - } - FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0); - for (int i = 1; i < mNumKeyframes; ++i) { - FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(i); - if (fraction < nextKeyframe.getFraction()) { - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - float intervalFraction = (fraction - prevKeyframe.getFraction()) / - (nextKeyframe.getFraction() - prevKeyframe.getFraction()); - float prevValue = prevKeyframe.getFloatValue(); - float nextValue = nextKeyframe.getFloatValue(); - return mEvaluator == null ? - prevValue + intervalFraction * (nextValue - prevValue) : - ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). - floatValue(); - } - prevKeyframe = nextKeyframe; - } - // shouldn't get here - return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue(); - } - -} - diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntEvaluator.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntEvaluator.java deleted file mode 100644 index ed5e79ec..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntEvaluator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -/** - * This evaluator can be used to perform type interpolation between int values. - */ -public class IntEvaluator implements TypeEvaluator { - - /** - * This function returns the result of linearly interpolating the start and end values, with - * fraction representing the proportion between the start and end values. The - * calculation is a simple parametric calculation: result = x0 + t * (v1 - v0), - * where x0 is startValue, x1 is endValue, - * and t is fraction. - * - * @param fraction The fraction from the starting to the ending values - * @param startValue The start value; should be of type int or - * Integer - * @param endValue The end value; should be of type int or Integer - * @return A linear interpolation between the start and end values, given the - * fraction parameter. - */ - public Integer evaluate(float fraction, Integer startValue, Integer endValue) { - int startInt = startValue; - return (int)(startInt + fraction * (endValue - startInt)); - } -} \ No newline at end of file diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntKeyframeSet.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntKeyframeSet.java deleted file mode 100644 index e9215e7f..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/IntKeyframeSet.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import java.util.ArrayList; -import android.view.animation.Interpolator; - -import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.IntKeyframe; - -/** - * This class holds a collection of IntKeyframe objects and is called by ValueAnimator to calculate - * values between those keyframes for a given animation. The class internal to the animation - * package because it is an implementation detail of how Keyframes are stored and used. - * - *

This type-specific subclass of KeyframeSet, along with the other type-specific subclass for - * float, exists to speed up the getValue() method when there is no custom - * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the - * Object equivalents of these primitive types.

- */ -@SuppressWarnings("unchecked") -class IntKeyframeSet extends KeyframeSet { - private int firstValue; - private int lastValue; - private int deltaValue; - private boolean firstTime = true; - - public IntKeyframeSet(IntKeyframe... keyframes) { - super(keyframes); - } - - @Override - public Object getValue(float fraction) { - return getIntValue(fraction); - } - - @Override - public IntKeyframeSet clone() { - ArrayList keyframes = mKeyframes; - int numKeyframes = mKeyframes.size(); - IntKeyframe[] newKeyframes = new IntKeyframe[numKeyframes]; - for (int i = 0; i < numKeyframes; ++i) { - newKeyframes[i] = (IntKeyframe) keyframes.get(i).clone(); - } - IntKeyframeSet newSet = new IntKeyframeSet(newKeyframes); - return newSet; - } - - public int getIntValue(float fraction) { - if (mNumKeyframes == 2) { - if (firstTime) { - firstTime = false; - firstValue = ((IntKeyframe) mKeyframes.get(0)).getIntValue(); - lastValue = ((IntKeyframe) mKeyframes.get(1)).getIntValue(); - deltaValue = lastValue - firstValue; - } - if (mInterpolator != null) { - fraction = mInterpolator.getInterpolation(fraction); - } - if (mEvaluator == null) { - return firstValue + (int)(fraction * deltaValue); - } else { - return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).intValue(); - } - } - if (fraction <= 0f) { - final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0); - final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(1); - int prevValue = prevKeyframe.getIntValue(); - int nextValue = nextKeyframe.getIntValue(); - float prevFraction = prevKeyframe.getFraction(); - float nextFraction = nextKeyframe.getFraction(); - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); - return mEvaluator == null ? - prevValue + (int)(intervalFraction * (nextValue - prevValue)) : - ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). - intValue(); - } else if (fraction >= 1f) { - final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 2); - final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 1); - int prevValue = prevKeyframe.getIntValue(); - int nextValue = nextKeyframe.getIntValue(); - float prevFraction = prevKeyframe.getFraction(); - float nextFraction = nextKeyframe.getFraction(); - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); - return mEvaluator == null ? - prevValue + (int)(intervalFraction * (nextValue - prevValue)) : - ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).intValue(); - } - IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0); - for (int i = 1; i < mNumKeyframes; ++i) { - IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(i); - if (fraction < nextKeyframe.getFraction()) { - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - float intervalFraction = (fraction - prevKeyframe.getFraction()) / - (nextKeyframe.getFraction() - prevKeyframe.getFraction()); - int prevValue = prevKeyframe.getIntValue(); - int nextValue = nextKeyframe.getIntValue(); - return mEvaluator == null ? - prevValue + (int)(intervalFraction * (nextValue - prevValue)) : - ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). - intValue(); - } - prevKeyframe = nextKeyframe; - } - // shouldn't get here - return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).intValue(); - } - -} - diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Keyframe.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Keyframe.java deleted file mode 100644 index ab76fa7f..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/Keyframe.java +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import android.view.animation.Interpolator; - -/** - * This class holds a time/value pair for an animation. The Keyframe class is used - * by {@link ValueAnimator} to define the values that the animation target will have over the course - * of the animation. As the time proceeds from one keyframe to the other, the value of the - * target object will animate between the value at the previous keyframe and the value at the - * next keyframe. Each keyframe also holds an optional {@link TimeInterpolator} - * object, which defines the time interpolation over the intervalue preceding the keyframe. - * - *

The Keyframe class itself is abstract. The type-specific factory methods will return - * a subclass of Keyframe specific to the type of value being stored. This is done to improve - * performance when dealing with the most common cases (e.g., float and - * int values). Other types will fall into a more general Keyframe class that - * treats its values as Objects. Unless your animation requires dealing with a custom type - * or a data structure that needs to be animated directly (and evaluated using an implementation - * of {@link TypeEvaluator}), you should stick to using float and int as animations using those - * types have lower runtime overhead than other types.

- */ -@SuppressWarnings("rawtypes") -public abstract class Keyframe implements Cloneable { - /** - * The time at which mValue will hold true. - */ - float mFraction; - - /** - * The type of the value in this Keyframe. This type is determined at construction time, - * based on the type of the value object passed into the constructor. - */ - Class mValueType; - - /** - * The optional time interpolator for the interval preceding this keyframe. A null interpolator - * (the default) results in linear interpolation over the interval. - */ - private /*Time*/Interpolator mInterpolator = null; - - /** - * Flag to indicate whether this keyframe has a valid value. This flag is used when an - * animation first starts, to populate placeholder keyframes with real values derived - * from the target object. - */ - boolean mHasValue = false; - - /** - * Constructs a Keyframe object with the given time and value. The time defines the - * time, as a proportion of an overall animation's duration, at which the value will hold true - * for the animation. The value for the animation between keyframes will be calculated as - * an interpolation between the values at those keyframes. - * - * @param fraction The time, expressed as a value between 0 and 1, representing the fraction - * of time elapsed of the overall animation duration. - * @param value The value that the object will animate to as the animation time approaches - * the time in this keyframe, and the the value animated from as the time passes the time in - * this keyframe. - */ - public static Keyframe ofInt(float fraction, int value) { - return new IntKeyframe(fraction, value); - } - - /** - * Constructs a Keyframe object with the given time. The value at this time will be derived - * from the target object when the animation first starts (note that this implies that keyframes - * with no initial value must be used as part of an {@link ObjectAnimator}). - * The time defines the - * time, as a proportion of an overall animation's duration, at which the value will hold true - * for the animation. The value for the animation between keyframes will be calculated as - * an interpolation between the values at those keyframes. - * - * @param fraction The time, expressed as a value between 0 and 1, representing the fraction - * of time elapsed of the overall animation duration. - */ - public static Keyframe ofInt(float fraction) { - return new IntKeyframe(fraction); - } - - /** - * Constructs a Keyframe object with the given time and value. The time defines the - * time, as a proportion of an overall animation's duration, at which the value will hold true - * for the animation. The value for the animation between keyframes will be calculated as - * an interpolation between the values at those keyframes. - * - * @param fraction The time, expressed as a value between 0 and 1, representing the fraction - * of time elapsed of the overall animation duration. - * @param value The value that the object will animate to as the animation time approaches - * the time in this keyframe, and the the value animated from as the time passes the time in - * this keyframe. - */ - public static Keyframe ofFloat(float fraction, float value) { - return new FloatKeyframe(fraction, value); - } - - /** - * Constructs a Keyframe object with the given time. The value at this time will be derived - * from the target object when the animation first starts (note that this implies that keyframes - * with no initial value must be used as part of an {@link ObjectAnimator}). - * The time defines the - * time, as a proportion of an overall animation's duration, at which the value will hold true - * for the animation. The value for the animation between keyframes will be calculated as - * an interpolation between the values at those keyframes. - * - * @param fraction The time, expressed as a value between 0 and 1, representing the fraction - * of time elapsed of the overall animation duration. - */ - public static Keyframe ofFloat(float fraction) { - return new FloatKeyframe(fraction); - } - - /** - * Constructs a Keyframe object with the given time and value. The time defines the - * time, as a proportion of an overall animation's duration, at which the value will hold true - * for the animation. The value for the animation between keyframes will be calculated as - * an interpolation between the values at those keyframes. - * - * @param fraction The time, expressed as a value between 0 and 1, representing the fraction - * of time elapsed of the overall animation duration. - * @param value The value that the object will animate to as the animation time approaches - * the time in this keyframe, and the the value animated from as the time passes the time in - * this keyframe. - */ - public static Keyframe ofObject(float fraction, Object value) { - return new ObjectKeyframe(fraction, value); - } - - /** - * Constructs a Keyframe object with the given time. The value at this time will be derived - * from the target object when the animation first starts (note that this implies that keyframes - * with no initial value must be used as part of an {@link ObjectAnimator}). - * The time defines the - * time, as a proportion of an overall animation's duration, at which the value will hold true - * for the animation. The value for the animation between keyframes will be calculated as - * an interpolation between the values at those keyframes. - * - * @param fraction The time, expressed as a value between 0 and 1, representing the fraction - * of time elapsed of the overall animation duration. - */ - public static Keyframe ofObject(float fraction) { - return new ObjectKeyframe(fraction, null); - } - - /** - * Indicates whether this keyframe has a valid value. This method is called internally when - * an {@link ObjectAnimator} first starts; keyframes without values are assigned values at - * that time by deriving the value for the property from the target object. - * - * @return boolean Whether this object has a value assigned. - */ - public boolean hasValue() { - return mHasValue; - } - - /** - * Gets the value for this Keyframe. - * - * @return The value for this Keyframe. - */ - public abstract Object getValue(); - - /** - * Sets the value for this Keyframe. - * - * @param value value for this Keyframe. - */ - public abstract void setValue(Object value); - - /** - * Gets the time for this keyframe, as a fraction of the overall animation duration. - * - * @return The time associated with this keyframe, as a fraction of the overall animation - * duration. This should be a value between 0 and 1. - */ - public float getFraction() { - return mFraction; - } - - /** - * Sets the time for this keyframe, as a fraction of the overall animation duration. - * - * @param fraction time associated with this keyframe, as a fraction of the overall animation - * duration. This should be a value between 0 and 1. - */ - public void setFraction(float fraction) { - mFraction = fraction; - } - - /** - * Gets the optional interpolator for this Keyframe. A value of null indicates - * that there is no interpolation, which is the same as linear interpolation. - * - * @return The optional interpolator for this Keyframe. - */ - public /*Time*/Interpolator getInterpolator() { - return mInterpolator; - } - - /** - * Sets the optional interpolator for this Keyframe. A value of null indicates - * that there is no interpolation, which is the same as linear interpolation. - * - * @return The optional interpolator for this Keyframe. - */ - public void setInterpolator(/*Time*/Interpolator interpolator) { - mInterpolator = interpolator; - } - - /** - * Gets the type of keyframe. This information is used by ValueAnimator to determine the type of - * {@link TypeEvaluator} to use when calculating values between keyframes. The type is based - * on the type of Keyframe created. - * - * @return The type of the value stored in the Keyframe. - */ - public Class getType() { - return mValueType; - } - - @Override - public abstract Keyframe clone(); - - /** - * This internal subclass is used for all types which are not int or float. - */ - static class ObjectKeyframe extends Keyframe { - - /** - * The value of the animation at the time mFraction. - */ - Object mValue; - - ObjectKeyframe(float fraction, Object value) { - mFraction = fraction; - mValue = value; - mHasValue = (value != null); - mValueType = mHasValue ? value.getClass() : Object.class; - } - - public Object getValue() { - return mValue; - } - - public void setValue(Object value) { - mValue = value; - mHasValue = (value != null); - } - - @Override - public ObjectKeyframe clone() { - ObjectKeyframe kfClone = new ObjectKeyframe(getFraction(), mValue); - kfClone.setInterpolator(getInterpolator()); - return kfClone; - } - } - - /** - * Internal subclass used when the keyframe value is of type int. - */ - static class IntKeyframe extends Keyframe { - - /** - * The value of the animation at the time mFraction. - */ - int mValue; - - IntKeyframe(float fraction, int value) { - mFraction = fraction; - mValue = value; - mValueType = int.class; - mHasValue = true; - } - - IntKeyframe(float fraction) { - mFraction = fraction; - mValueType = int.class; - } - - public int getIntValue() { - return mValue; - } - - public Object getValue() { - return mValue; - } - - public void setValue(Object value) { - if (value != null && value.getClass() == Integer.class) { - mValue = ((Integer)value).intValue(); - mHasValue = true; - } - } - - @Override - public IntKeyframe clone() { - IntKeyframe kfClone = new IntKeyframe(getFraction(), mValue); - kfClone.setInterpolator(getInterpolator()); - return kfClone; - } - } - - /** - * Internal subclass used when the keyframe value is of type float. - */ - static class FloatKeyframe extends Keyframe { - /** - * The value of the animation at the time mFraction. - */ - float mValue; - - FloatKeyframe(float fraction, float value) { - mFraction = fraction; - mValue = value; - mValueType = float.class; - mHasValue = true; - } - - FloatKeyframe(float fraction) { - mFraction = fraction; - mValueType = float.class; - } - - public float getFloatValue() { - return mValue; - } - - public Object getValue() { - return mValue; - } - - public void setValue(Object value) { - if (value != null && value.getClass() == Float.class) { - mValue = ((Float)value).floatValue(); - mHasValue = true; - } - } - - @Override - public FloatKeyframe clone() { - FloatKeyframe kfClone = new FloatKeyframe(getFraction(), mValue); - kfClone.setInterpolator(getInterpolator()); - return kfClone; - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/KeyframeSet.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/KeyframeSet.java deleted file mode 100644 index a71e1ad3..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/KeyframeSet.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import java.util.ArrayList; -import java.util.Arrays; -import android.view.animation.Interpolator; - -import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.FloatKeyframe; -import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.IntKeyframe; -import com.actionbarsherlock.internal.nineoldandroids.animation.Keyframe.ObjectKeyframe; - -/** - * This class holds a collection of Keyframe objects and is called by ValueAnimator to calculate - * values between those keyframes for a given animation. The class internal to the animation - * package because it is an implementation detail of how Keyframes are stored and used. - */ -@SuppressWarnings({"rawtypes", "unchecked"}) -class KeyframeSet { - - int mNumKeyframes; - - Keyframe mFirstKeyframe; - Keyframe mLastKeyframe; - /*Time*/Interpolator mInterpolator; // only used in the 2-keyframe case - ArrayList mKeyframes; // only used when there are not 2 keyframes - TypeEvaluator mEvaluator; - - - public KeyframeSet(Keyframe... keyframes) { - mNumKeyframes = keyframes.length; - mKeyframes = new ArrayList(); - mKeyframes.addAll(Arrays.asList(keyframes)); - mFirstKeyframe = mKeyframes.get(0); - mLastKeyframe = mKeyframes.get(mNumKeyframes - 1); - mInterpolator = mLastKeyframe.getInterpolator(); - } - - public static KeyframeSet ofInt(int... values) { - int numKeyframes = values.length; - IntKeyframe keyframes[] = new IntKeyframe[Math.max(numKeyframes,2)]; - if (numKeyframes == 1) { - keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f); - keyframes[1] = (IntKeyframe) Keyframe.ofInt(1f, values[0]); - } else { - keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f, values[0]); - for (int i = 1; i < numKeyframes; ++i) { - keyframes[i] = (IntKeyframe) Keyframe.ofInt((float) i / (numKeyframes - 1), values[i]); - } - } - return new IntKeyframeSet(keyframes); - } - - public static KeyframeSet ofFloat(float... values) { - int numKeyframes = values.length; - FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)]; - if (numKeyframes == 1) { - keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f); - keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]); - } else { - keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]); - for (int i = 1; i < numKeyframes; ++i) { - keyframes[i] = (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]); - } - } - return new FloatKeyframeSet(keyframes); - } - - public static KeyframeSet ofKeyframe(Keyframe... keyframes) { - // if all keyframes of same primitive type, create the appropriate KeyframeSet - int numKeyframes = keyframes.length; - boolean hasFloat = false; - boolean hasInt = false; - boolean hasOther = false; - for (int i = 0; i < numKeyframes; ++i) { - if (keyframes[i] instanceof FloatKeyframe) { - hasFloat = true; - } else if (keyframes[i] instanceof IntKeyframe) { - hasInt = true; - } else { - hasOther = true; - } - } - if (hasFloat && !hasInt && !hasOther) { - FloatKeyframe floatKeyframes[] = new FloatKeyframe[numKeyframes]; - for (int i = 0; i < numKeyframes; ++i) { - floatKeyframes[i] = (FloatKeyframe) keyframes[i]; - } - return new FloatKeyframeSet(floatKeyframes); - } else if (hasInt && !hasFloat && !hasOther) { - IntKeyframe intKeyframes[] = new IntKeyframe[numKeyframes]; - for (int i = 0; i < numKeyframes; ++i) { - intKeyframes[i] = (IntKeyframe) keyframes[i]; - } - return new IntKeyframeSet(intKeyframes); - } else { - return new KeyframeSet(keyframes); - } - } - - public static KeyframeSet ofObject(Object... values) { - int numKeyframes = values.length; - ObjectKeyframe keyframes[] = new ObjectKeyframe[Math.max(numKeyframes,2)]; - if (numKeyframes == 1) { - keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f); - keyframes[1] = (ObjectKeyframe) Keyframe.ofObject(1f, values[0]); - } else { - keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f, values[0]); - for (int i = 1; i < numKeyframes; ++i) { - keyframes[i] = (ObjectKeyframe) Keyframe.ofObject((float) i / (numKeyframes - 1), values[i]); - } - } - return new KeyframeSet(keyframes); - } - - /** - * Sets the TypeEvaluator to be used when calculating animated values. This object - * is required only for KeyframeSets that are not either IntKeyframeSet or FloatKeyframeSet, - * both of which assume their own evaluator to speed up calculations with those primitive - * types. - * - * @param evaluator The TypeEvaluator to be used to calculate animated values. - */ - public void setEvaluator(TypeEvaluator evaluator) { - mEvaluator = evaluator; - } - - @Override - public KeyframeSet clone() { - ArrayList keyframes = mKeyframes; - int numKeyframes = mKeyframes.size(); - Keyframe[] newKeyframes = new Keyframe[numKeyframes]; - for (int i = 0; i < numKeyframes; ++i) { - newKeyframes[i] = keyframes.get(i).clone(); - } - KeyframeSet newSet = new KeyframeSet(newKeyframes); - return newSet; - } - - /** - * Gets the animated value, given the elapsed fraction of the animation (interpolated by the - * animation's interpolator) and the evaluator used to calculate in-between values. This - * function maps the input fraction to the appropriate keyframe interval and a fraction - * between them and returns the interpolated value. Note that the input fraction may fall - * outside the [0-1] bounds, if the animation's interpolator made that happen (e.g., a - * spring interpolation that might send the fraction past 1.0). We handle this situation by - * just using the two keyframes at the appropriate end when the value is outside those bounds. - * - * @param fraction The elapsed fraction of the animation - * @return The animated value. - */ - public Object getValue(float fraction) { - - // Special-case optimization for the common case of only two keyframes - if (mNumKeyframes == 2) { - if (mInterpolator != null) { - fraction = mInterpolator.getInterpolation(fraction); - } - return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(), - mLastKeyframe.getValue()); - } - if (fraction <= 0f) { - final Keyframe nextKeyframe = mKeyframes.get(1); - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - final float prevFraction = mFirstKeyframe.getFraction(); - float intervalFraction = (fraction - prevFraction) / - (nextKeyframe.getFraction() - prevFraction); - return mEvaluator.evaluate(intervalFraction, mFirstKeyframe.getValue(), - nextKeyframe.getValue()); - } else if (fraction >= 1f) { - final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2); - final /*Time*/Interpolator interpolator = mLastKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - final float prevFraction = prevKeyframe.getFraction(); - float intervalFraction = (fraction - prevFraction) / - (mLastKeyframe.getFraction() - prevFraction); - return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(), - mLastKeyframe.getValue()); - } - Keyframe prevKeyframe = mFirstKeyframe; - for (int i = 1; i < mNumKeyframes; ++i) { - Keyframe nextKeyframe = mKeyframes.get(i); - if (fraction < nextKeyframe.getFraction()) { - final /*Time*/Interpolator interpolator = nextKeyframe.getInterpolator(); - if (interpolator != null) { - fraction = interpolator.getInterpolation(fraction); - } - final float prevFraction = prevKeyframe.getFraction(); - float intervalFraction = (fraction - prevFraction) / - (nextKeyframe.getFraction() - prevFraction); - return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(), - nextKeyframe.getValue()); - } - prevKeyframe = nextKeyframe; - } - // shouldn't reach here - return mLastKeyframe.getValue(); - } - - @Override - public String toString() { - String returnVal = " "; - for (int i = 0; i < mNumKeyframes; ++i) { - returnVal += mKeyframes.get(i).getValue() + " "; - } - return returnVal; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ObjectAnimator.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ObjectAnimator.java deleted file mode 100644 index 21d15c02..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ObjectAnimator.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import android.util.Log; -//import android.util.Property; - -//import java.lang.reflect.Method; -import java.util.ArrayList; - -/** - * This subclass of {@link ValueAnimator} provides support for animating properties on target objects. - * The constructors of this class take parameters to define the target object that will be animated - * as well as the name of the property that will be animated. Appropriate set/get functions - * are then determined internally and the animation will call these functions as necessary to - * animate the property. - * - * @see #setPropertyName(String) - * - */ -@SuppressWarnings("rawtypes") -public final class ObjectAnimator extends ValueAnimator { - private static final boolean DBG = false; - - // The target object on which the property exists, set in the constructor - private Object mTarget; - - private String mPropertyName; - - //private Property mProperty; - - /** - * Sets the name of the property that will be animated. This name is used to derive - * a setter function that will be called to set animated values. - * For example, a property name of foo will result - * in a call to the function setFoo() on the target object. If either - * valueFrom or valueTo is null, then a getter function will - * also be derived and called. - * - *

For best performance of the mechanism that calls the setter function determined by the - * name of the property being animated, use float or int typed values, - * and make the setter function for those properties have a void return value. This - * will cause the code to take an optimized path for these constrained circumstances. Other - * property types and return types will work, but will have more overhead in processing - * the requests due to normal reflection mechanisms.

- * - *

Note that the setter function derived from this property name - * must take the same parameter type as the - * valueFrom and valueTo properties, otherwise the call to - * the setter function will fail.

- * - *

If this ObjectAnimator has been set up to animate several properties together, - * using more than one PropertyValuesHolder objects, then setting the propertyName simply - * sets the propertyName in the first of those PropertyValuesHolder objects.

- * - * @param propertyName The name of the property being animated. Should not be null. - */ - public void setPropertyName(String propertyName) { - // mValues could be null if this is being constructed piecemeal. Just record the - // propertyName to be used later when setValues() is called if so. - if (mValues != null) { - PropertyValuesHolder valuesHolder = mValues[0]; - String oldName = valuesHolder.getPropertyName(); - valuesHolder.setPropertyName(propertyName); - mValuesMap.remove(oldName); - mValuesMap.put(propertyName, valuesHolder); - } - mPropertyName = propertyName; - // New property/values/target should cause re-initialization prior to starting - mInitialized = false; - } - - /** - * Sets the property that will be animated. Property objects will take precedence over - * properties specified by the {@link #setPropertyName(String)} method. Animations should - * be set up to use one or the other, not both. - * - * @param property The property being animated. Should not be null. - */ - //public void setProperty(Property property) { - // // mValues could be null if this is being constructed piecemeal. Just record the - // // propertyName to be used later when setValues() is called if so. - // if (mValues != null) { - // PropertyValuesHolder valuesHolder = mValues[0]; - // String oldName = valuesHolder.getPropertyName(); - // valuesHolder.setProperty(property); - // mValuesMap.remove(oldName); - // mValuesMap.put(mPropertyName, valuesHolder); - // } - // if (mProperty != null) { - // mPropertyName = property.getName(); - // } - // mProperty = property; - // // New property/values/target should cause re-initialization prior to starting - // mInitialized = false; - //} - - /** - * Gets the name of the property that will be animated. This name will be used to derive - * a setter function that will be called to set animated values. - * For example, a property name of foo will result - * in a call to the function setFoo() on the target object. If either - * valueFrom or valueTo is null, then a getter function will - * also be derived and called. - */ - public String getPropertyName() { - return mPropertyName; - } - - /** - * Creates a new ObjectAnimator object. This default constructor is primarily for - * use internally; the other constructors which take parameters are more generally - * useful. - */ - public ObjectAnimator() { - } - - /** - * Private utility constructor that initializes the target object and name of the - * property being animated. - * - * @param target The object whose property is to be animated. This object should - * have a public method on it called setName(), where name is - * the value of the propertyName parameter. - * @param propertyName The name of the property being animated. - */ - private ObjectAnimator(Object target, String propertyName) { - mTarget = target; - setPropertyName(propertyName); - } - - /** - * Private utility constructor that initializes the target object and property being animated. - * - * @param target The object whose property is to be animated. - * @param property The property being animated. - */ - //private ObjectAnimator(T target, Property property) { - // mTarget = target; - // setProperty(property); - //} - - /** - * Constructs and returns an ObjectAnimator that animates between int values. A single - * value implies that that value is the one being animated to. Two values imply a starting - * and ending values. More than two values imply a starting value, values to animate through - * along the way, and an ending value (these values will be distributed evenly across - * the duration of the animation). - * - * @param target The object whose property is to be animated. This object should - * have a public method on it called setName(), where name is - * the value of the propertyName parameter. - * @param propertyName The name of the property being animated. - * @param values A set of values that the animation will animate between over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - public static ObjectAnimator ofInt(Object target, String propertyName, int... values) { - ObjectAnimator anim = new ObjectAnimator(target, propertyName); - anim.setIntValues(values); - return anim; - } - - /** - * Constructs and returns an ObjectAnimator that animates between int values. A single - * value implies that that value is the one being animated to. Two values imply a starting - * and ending values. More than two values imply a starting value, values to animate through - * along the way, and an ending value (these values will be distributed evenly across - * the duration of the animation). - * - * @param target The object whose property is to be animated. - * @param property The property being animated. - * @param values A set of values that the animation will animate between over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - //public static ObjectAnimator ofInt(T target, Property property, int... values) { - // ObjectAnimator anim = new ObjectAnimator(target, property); - // anim.setIntValues(values); - // return anim; - //} - - /** - * Constructs and returns an ObjectAnimator that animates between float values. A single - * value implies that that value is the one being animated to. Two values imply a starting - * and ending values. More than two values imply a starting value, values to animate through - * along the way, and an ending value (these values will be distributed evenly across - * the duration of the animation). - * - * @param target The object whose property is to be animated. This object should - * have a public method on it called setName(), where name is - * the value of the propertyName parameter. - * @param propertyName The name of the property being animated. - * @param values A set of values that the animation will animate between over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) { - ObjectAnimator anim = new ObjectAnimator(target, propertyName); - anim.setFloatValues(values); - return anim; - } - - /** - * Constructs and returns an ObjectAnimator that animates between float values. A single - * value implies that that value is the one being animated to. Two values imply a starting - * and ending values. More than two values imply a starting value, values to animate through - * along the way, and an ending value (these values will be distributed evenly across - * the duration of the animation). - * - * @param target The object whose property is to be animated. - * @param property The property being animated. - * @param values A set of values that the animation will animate between over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - //public static ObjectAnimator ofFloat(T target, Property property, - // float... values) { - // ObjectAnimator anim = new ObjectAnimator(target, property); - // anim.setFloatValues(values); - // return anim; - //} - - /** - * Constructs and returns an ObjectAnimator that animates between Object values. A single - * value implies that that value is the one being animated to. Two values imply a starting - * and ending values. More than two values imply a starting value, values to animate through - * along the way, and an ending value (these values will be distributed evenly across - * the duration of the animation). - * - * @param target The object whose property is to be animated. This object should - * have a public method on it called setName(), where name is - * the value of the propertyName parameter. - * @param propertyName The name of the property being animated. - * @param evaluator A TypeEvaluator that will be called on each animation frame to - * provide the necessary interpolation between the Object values to derive the animated - * value. - * @param values A set of values that the animation will animate between over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - public static ObjectAnimator ofObject(Object target, String propertyName, - TypeEvaluator evaluator, Object... values) { - ObjectAnimator anim = new ObjectAnimator(target, propertyName); - anim.setObjectValues(values); - anim.setEvaluator(evaluator); - return anim; - } - - /** - * Constructs and returns an ObjectAnimator that animates between Object values. A single - * value implies that that value is the one being animated to. Two values imply a starting - * and ending values. More than two values imply a starting value, values to animate through - * along the way, and an ending value (these values will be distributed evenly across - * the duration of the animation). - * - * @param target The object whose property is to be animated. - * @param property The property being animated. - * @param evaluator A TypeEvaluator that will be called on each animation frame to - * provide the necessary interpolation between the Object values to derive the animated - * value. - * @param values A set of values that the animation will animate between over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - //public static ObjectAnimator ofObject(T target, Property property, - // TypeEvaluator evaluator, V... values) { - // ObjectAnimator anim = new ObjectAnimator(target, property); - // anim.setObjectValues(values); - // anim.setEvaluator(evaluator); - // return anim; - //} - - /** - * Constructs and returns an ObjectAnimator that animates between the sets of values specified - * in PropertyValueHolder objects. This variant should be used when animating - * several properties at once with the same ObjectAnimator, since PropertyValuesHolder allows - * you to associate a set of animation values with a property name. - * - * @param target The object whose property is to be animated. Depending on how the - * PropertyValuesObjects were constructed, the target object should either have the {@link - * android.util.Property} objects used to construct the PropertyValuesHolder objects or (if the - * PropertyValuesHOlder objects were created with property names) the target object should have - * public methods on it called setName(), where name is the name of - * the property passed in as the propertyName parameter for each of the - * PropertyValuesHolder objects. - * @param values A set of PropertyValuesHolder objects whose values will be animated between - * over time. - * @return An ObjectAnimator object that is set up to animate between the given values. - */ - public static ObjectAnimator ofPropertyValuesHolder(Object target, - PropertyValuesHolder... values) { - ObjectAnimator anim = new ObjectAnimator(); - anim.mTarget = target; - anim.setValues(values); - return anim; - } - - @Override - public void setIntValues(int... values) { - if (mValues == null || mValues.length == 0) { - // No values yet - this animator is being constructed piecemeal. Init the values with - // whatever the current propertyName is - //if (mProperty != null) { - // setValues(PropertyValuesHolder.ofInt(mProperty, values)); - //} else { - setValues(PropertyValuesHolder.ofInt(mPropertyName, values)); - //} - } else { - super.setIntValues(values); - } - } - - @Override - public void setFloatValues(float... values) { - if (mValues == null || mValues.length == 0) { - // No values yet - this animator is being constructed piecemeal. Init the values with - // whatever the current propertyName is - //if (mProperty != null) { - // setValues(PropertyValuesHolder.ofFloat(mProperty, values)); - //} else { - setValues(PropertyValuesHolder.ofFloat(mPropertyName, values)); - //} - } else { - super.setFloatValues(values); - } - } - - @Override - public void setObjectValues(Object... values) { - if (mValues == null || mValues.length == 0) { - // No values yet - this animator is being constructed piecemeal. Init the values with - // whatever the current propertyName is - //if (mProperty != null) { - // setValues(PropertyValuesHolder.ofObject(mProperty, (TypeEvaluator)null, values)); - //} else { - setValues(PropertyValuesHolder.ofObject(mPropertyName, (TypeEvaluator)null, values)); - //} - } else { - super.setObjectValues(values); - } - } - - @Override - public void start() { - if (DBG) { - Log.d("ObjectAnimator", "Anim target, duration: " + mTarget + ", " + getDuration()); - for (int i = 0; i < mValues.length; ++i) { - PropertyValuesHolder pvh = mValues[i]; - ArrayList keyframes = pvh.mKeyframeSet.mKeyframes; - Log.d("ObjectAnimator", " Values[" + i + "]: " + - pvh.getPropertyName() + ", " + keyframes.get(0).getValue() + ", " + - keyframes.get(pvh.mKeyframeSet.mNumKeyframes - 1).getValue()); - } - } - super.start(); - } - - /** - * This function is called immediately before processing the first animation - * frame of an animation. If there is a nonzero startDelay, the - * function is called after that delay ends. - * It takes care of the final initialization steps for the - * animation. This includes setting mEvaluator, if the user has not yet - * set it up, and the setter/getter methods, if the user did not supply - * them. - * - *

Overriders of this method should call the superclass method to cause - * internal mechanisms to be set up correctly.

- */ - @Override - void initAnimation() { - if (!mInitialized) { - // mValueType may change due to setter/getter setup; do this before calling super.init(), - // which uses mValueType to set up the default type evaluator. - int numValues = mValues.length; - for (int i = 0; i < numValues; ++i) { - mValues[i].setupSetterAndGetter(mTarget); - } - super.initAnimation(); - } - } - - /** - * Sets the length of the animation. The default duration is 300 milliseconds. - * - * @param duration The length of the animation, in milliseconds. - * @return ObjectAnimator The object called with setDuration(). This return - * value makes it easier to compose statements together that construct and then set the - * duration, as in - * ObjectAnimator.ofInt(target, propertyName, 0, 10).setDuration(500).start(). - */ - @Override - public ObjectAnimator setDuration(long duration) { - super.setDuration(duration); - return this; - } - - - /** - * The target object whose property will be animated by this animation - * - * @return The object being animated - */ - public Object getTarget() { - return mTarget; - } - - /** - * Sets the target object whose property will be animated by this animation - * - * @param target The object being animated - */ - @Override - public void setTarget(Object target) { - if (mTarget != target) { - final Object oldTarget = mTarget; - mTarget = target; - if (oldTarget != null && target != null && oldTarget.getClass() == target.getClass()) { - return; - } - // New target type should cause re-initialization prior to starting - mInitialized = false; - } - } - - @Override - public void setupStartValues() { - initAnimation(); - int numValues = mValues.length; - for (int i = 0; i < numValues; ++i) { - mValues[i].setupStartValue(mTarget); - } - } - - @Override - public void setupEndValues() { - initAnimation(); - int numValues = mValues.length; - for (int i = 0; i < numValues; ++i) { - mValues[i].setupEndValue(mTarget); - } - } - - /** - * This method is called with the elapsed fraction of the animation during every - * animation frame. This function turns the elapsed fraction into an interpolated fraction - * and then into an animated value (from the evaluator. The function is called mostly during - * animation updates, but it is also called when the end() - * function is called, to set the final value on the property. - * - *

Overrides of this method must call the superclass to perform the calculation - * of the animated value.

- * - * @param fraction The elapsed fraction of the animation. - */ - @Override - void animateValue(float fraction) { - super.animateValue(fraction); - int numValues = mValues.length; - for (int i = 0; i < numValues; ++i) { - mValues[i].setAnimatedValue(mTarget); - } - } - - @Override - public ObjectAnimator clone() { - final ObjectAnimator anim = (ObjectAnimator) super.clone(); - return anim; - } - - @Override - public String toString() { - String returnVal = "ObjectAnimator@" + Integer.toHexString(hashCode()) + ", target " + - mTarget; - if (mValues != null) { - for (int i = 0; i < mValues.length; ++i) { - returnVal += "\n " + mValues[i].toString(); - } - } - return returnVal; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java deleted file mode 100644 index 84f7504a..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java +++ /dev/null @@ -1,1012 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -//import android.util.FloatProperty; -//import android.util.IntProperty; -import android.util.Log; -//import android.util.Property; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - * This class holds information about a property and the values that that property - * should take on during an animation. PropertyValuesHolder objects can be used to create - * animations with ValueAnimator or ObjectAnimator that operate on several different properties - * in parallel. - */ -@SuppressWarnings({"rawtypes", "unchecked"}) -public class PropertyValuesHolder implements Cloneable { - - /** - * The name of the property associated with the values. This need not be a real property, - * unless this object is being used with ObjectAnimator. But this is the name by which - * aniamted values are looked up with getAnimatedValue(String) in ValueAnimator. - */ - String mPropertyName; - - /** - * @hide - */ - //protected Property mProperty; - - /** - * The setter function, if needed. ObjectAnimator hands off this functionality to - * PropertyValuesHolder, since it holds all of the per-property information. This - * property is automatically - * derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator. - */ - Method mSetter = null; - - /** - * The getter function, if needed. ObjectAnimator hands off this functionality to - * PropertyValuesHolder, since it holds all of the per-property information. This - * property is automatically - * derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator. - * The getter is only derived and used if one of the values is null. - */ - private Method mGetter = null; - - /** - * The type of values supplied. This information is used both in deriving the setter/getter - * functions and in deriving the type of TypeEvaluator. - */ - Class mValueType; - - /** - * The set of keyframes (time/value pairs) that define this animation. - */ - KeyframeSet mKeyframeSet = null; - - - // type evaluators for the primitive types handled by this implementation - private static final TypeEvaluator sIntEvaluator = new IntEvaluator(); - private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator(); - - // We try several different types when searching for appropriate setter/getter functions. - // The caller may have supplied values in a type that does not match the setter/getter - // functions (such as the integers 0 and 1 to represent floating point values for alpha). - // Also, the use of generics in constructors means that we end up with the Object versions - // of primitive types (Float vs. float). But most likely, the setter/getter functions - // will take primitive types instead. - // So we supply an ordered array of other types to try before giving up. - private static Class[] FLOAT_VARIANTS = {float.class, Float.class, double.class, int.class, - Double.class, Integer.class}; - private static Class[] INTEGER_VARIANTS = {int.class, Integer.class, float.class, double.class, - Float.class, Double.class}; - private static Class[] DOUBLE_VARIANTS = {double.class, Double.class, float.class, int.class, - Float.class, Integer.class}; - - // These maps hold all property entries for a particular class. This map - // is used to speed up property/setter/getter lookups for a given class/property - // combination. No need to use reflection on the combination more than once. - private static final HashMap> sSetterPropertyMap = - new HashMap>(); - private static final HashMap> sGetterPropertyMap = - new HashMap>(); - - // This lock is used to ensure that only one thread is accessing the property maps - // at a time. - final ReentrantReadWriteLock mPropertyMapLock = new ReentrantReadWriteLock(); - - // Used to pass single value to varargs parameter in setter invocation - final Object[] mTmpValueArray = new Object[1]; - - /** - * The type evaluator used to calculate the animated values. This evaluator is determined - * automatically based on the type of the start/end objects passed into the constructor, - * but the system only knows about the primitive types int and float. Any other - * type will need to set the evaluator to a custom evaluator for that type. - */ - private TypeEvaluator mEvaluator; - - /** - * The value most recently calculated by calculateValue(). This is set during - * that function and might be retrieved later either by ValueAnimator.animatedValue() or - * by the property-setting logic in ObjectAnimator.animatedValue(). - */ - private Object mAnimatedValue; - - /** - * Internal utility constructor, used by the factory methods to set the property name. - * @param propertyName The name of the property for this holder. - */ - private PropertyValuesHolder(String propertyName) { - mPropertyName = propertyName; - } - - /** - * Internal utility constructor, used by the factory methods to set the property. - * @param property The property for this holder. - */ - //private PropertyValuesHolder(Property property) { - // mProperty = property; - // if (property != null) { - // mPropertyName = property.getName(); - // } - //} - - /** - * Constructs and returns a PropertyValuesHolder with a given property name and - * set of int values. - * @param propertyName The name of the property being animated. - * @param values The values that the named property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - public static PropertyValuesHolder ofInt(String propertyName, int... values) { - return new IntPropertyValuesHolder(propertyName, values); - } - - /** - * Constructs and returns a PropertyValuesHolder with a given property and - * set of int values. - * @param property The property being animated. Should not be null. - * @param values The values that the property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - //public static PropertyValuesHolder ofInt(Property property, int... values) { - // return new IntPropertyValuesHolder(property, values); - //} - - /** - * Constructs and returns a PropertyValuesHolder with a given property name and - * set of float values. - * @param propertyName The name of the property being animated. - * @param values The values that the named property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - public static PropertyValuesHolder ofFloat(String propertyName, float... values) { - return new FloatPropertyValuesHolder(propertyName, values); - } - - /** - * Constructs and returns a PropertyValuesHolder with a given property and - * set of float values. - * @param property The property being animated. Should not be null. - * @param values The values that the property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - //public static PropertyValuesHolder ofFloat(Property property, float... values) { - // return new FloatPropertyValuesHolder(property, values); - //} - - /** - * Constructs and returns a PropertyValuesHolder with a given property name and - * set of Object values. This variant also takes a TypeEvaluator because the system - * cannot automatically interpolate between objects of unknown type. - * - * @param propertyName The name of the property being animated. - * @param evaluator A TypeEvaluator that will be called on each animation frame to - * provide the necessary interpolation between the Object values to derive the animated - * value. - * @param values The values that the named property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator, - Object... values) { - PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); - pvh.setObjectValues(values); - pvh.setEvaluator(evaluator); - return pvh; - } - - /** - * Constructs and returns a PropertyValuesHolder with a given property and - * set of Object values. This variant also takes a TypeEvaluator because the system - * cannot automatically interpolate between objects of unknown type. - * - * @param property The property being animated. Should not be null. - * @param evaluator A TypeEvaluator that will be called on each animation frame to - * provide the necessary interpolation between the Object values to derive the animated - * value. - * @param values The values that the property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - //public static PropertyValuesHolder ofObject(Property property, - // TypeEvaluator evaluator, V... values) { - // PropertyValuesHolder pvh = new PropertyValuesHolder(property); - // pvh.setObjectValues(values); - // pvh.setEvaluator(evaluator); - // return pvh; - //} - - /** - * Constructs and returns a PropertyValuesHolder object with the specified property name and set - * of values. These values can be of any type, but the type should be consistent so that - * an appropriate {@link android.animation.TypeEvaluator} can be found that matches - * the common type. - *

If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling a getter function - * on the object. Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction - * {@link ObjectAnimator}, and with a getter function - * derived automatically from propertyName, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * @param propertyName The name of the property associated with this set of values. This - * can be the actual property name to be used when using a ObjectAnimator object, or - * just a name used to get animated values, such as if this object is used with an - * ValueAnimator object. - * @param values The set of values to animate between. - */ - public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values) { - KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values); - if (keyframeSet instanceof IntKeyframeSet) { - return new IntPropertyValuesHolder(propertyName, (IntKeyframeSet) keyframeSet); - } else if (keyframeSet instanceof FloatKeyframeSet) { - return new FloatPropertyValuesHolder(propertyName, (FloatKeyframeSet) keyframeSet); - } - else { - PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); - pvh.mKeyframeSet = keyframeSet; - pvh.mValueType = values[0].getType(); - return pvh; - } - } - - /** - * Constructs and returns a PropertyValuesHolder object with the specified property and set - * of values. These values can be of any type, but the type should be consistent so that - * an appropriate {@link android.animation.TypeEvaluator} can be found that matches - * the common type. - *

If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling the property's - * {@link android.util.Property#get(Object)} function. - * Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction with - * {@link ObjectAnimator}, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * @param property The property associated with this set of values. Should not be null. - * @param values The set of values to animate between. - */ - //public static PropertyValuesHolder ofKeyframe(Property property, Keyframe... values) { - // KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values); - // if (keyframeSet instanceof IntKeyframeSet) { - // return new IntPropertyValuesHolder(property, (IntKeyframeSet) keyframeSet); - // } else if (keyframeSet instanceof FloatKeyframeSet) { - // return new FloatPropertyValuesHolder(property, (FloatKeyframeSet) keyframeSet); - // } - // else { - // PropertyValuesHolder pvh = new PropertyValuesHolder(property); - // pvh.mKeyframeSet = keyframeSet; - // pvh.mValueType = ((Keyframe)values[0]).getType(); - // return pvh; - // } - //} - - /** - * Set the animated values for this object to this set of ints. - * If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling a getter function - * on the object. Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction - * {@link ObjectAnimator}, and with a getter function - * derived automatically from propertyName, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * - * @param values One or more values that the animation will animate between. - */ - public void setIntValues(int... values) { - mValueType = int.class; - mKeyframeSet = KeyframeSet.ofInt(values); - } - - /** - * Set the animated values for this object to this set of floats. - * If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling a getter function - * on the object. Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction - * {@link ObjectAnimator}, and with a getter function - * derived automatically from propertyName, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * - * @param values One or more values that the animation will animate between. - */ - public void setFloatValues(float... values) { - mValueType = float.class; - mKeyframeSet = KeyframeSet.ofFloat(values); - } - - /** - * Set the animated values for this object to this set of Keyframes. - * - * @param values One or more values that the animation will animate between. - */ - public void setKeyframes(Keyframe... values) { - int numKeyframes = values.length; - Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)]; - mValueType = values[0].getType(); - for (int i = 0; i < numKeyframes; ++i) { - keyframes[i] = values[i]; - } - mKeyframeSet = new KeyframeSet(keyframes); - } - - /** - * Set the animated values for this object to this set of Objects. - * If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling a getter function - * on the object. Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction - * {@link ObjectAnimator}, and with a getter function - * derived automatically from propertyName, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * - * @param values One or more values that the animation will animate between. - */ - public void setObjectValues(Object... values) { - mValueType = values[0].getClass(); - mKeyframeSet = KeyframeSet.ofObject(values); - } - - /** - * Determine the setter or getter function using the JavaBeans convention of setFoo or - * getFoo for a property named 'foo'. This function figures out what the name of the - * function should be and uses reflection to find the Method with that name on the - * target object. - * - * @param targetClass The class to search for the method - * @param prefix "set" or "get", depending on whether we need a setter or getter. - * @param valueType The type of the parameter (in the case of a setter). This type - * is derived from the values set on this PropertyValuesHolder. This type is used as - * a first guess at the parameter type, but we check for methods with several different - * types to avoid problems with slight mis-matches between supplied values and actual - * value types used on the setter. - * @return Method the method associated with mPropertyName. - */ - private Method getPropertyFunction(Class targetClass, String prefix, Class valueType) { - // TODO: faster implementation... - Method returnVal = null; - String methodName = getMethodName(prefix, mPropertyName); - Class args[] = null; - if (valueType == null) { - try { - returnVal = targetClass.getMethod(methodName, args); - } catch (NoSuchMethodException e) { - Log.e("PropertyValuesHolder", targetClass.getSimpleName() + " - " + - "Couldn't find no-arg method for property " + mPropertyName + ": " + e); - } - } else { - args = new Class[1]; - Class typeVariants[]; - if (mValueType.equals(Float.class)) { - typeVariants = FLOAT_VARIANTS; - } else if (mValueType.equals(Integer.class)) { - typeVariants = INTEGER_VARIANTS; - } else if (mValueType.equals(Double.class)) { - typeVariants = DOUBLE_VARIANTS; - } else { - typeVariants = new Class[1]; - typeVariants[0] = mValueType; - } - for (Class typeVariant : typeVariants) { - args[0] = typeVariant; - try { - returnVal = targetClass.getMethod(methodName, args); - // change the value type to suit - mValueType = typeVariant; - return returnVal; - } catch (NoSuchMethodException e) { - // Swallow the error and keep trying other variants - } - } - // If we got here, then no appropriate function was found - Log.e("PropertyValuesHolder", - "Couldn't find " + prefix + "ter property " + mPropertyName + - " for " + targetClass.getSimpleName() + - " with value type "+ mValueType); - } - - return returnVal; - } - - - /** - * Returns the setter or getter requested. This utility function checks whether the - * requested method exists in the propertyMapMap cache. If not, it calls another - * utility function to request the Method from the targetClass directly. - * @param targetClass The Class on which the requested method should exist. - * @param propertyMapMap The cache of setters/getters derived so far. - * @param prefix "set" or "get", for the setter or getter. - * @param valueType The type of parameter passed into the method (null for getter). - * @return Method the method associated with mPropertyName. - */ - private Method setupSetterOrGetter(Class targetClass, - HashMap> propertyMapMap, - String prefix, Class valueType) { - Method setterOrGetter = null; - try { - // Have to lock property map prior to reading it, to guard against - // another thread putting something in there after we've checked it - // but before we've added an entry to it - mPropertyMapLock.writeLock().lock(); - HashMap propertyMap = propertyMapMap.get(targetClass); - if (propertyMap != null) { - setterOrGetter = propertyMap.get(mPropertyName); - } - if (setterOrGetter == null) { - setterOrGetter = getPropertyFunction(targetClass, prefix, valueType); - if (propertyMap == null) { - propertyMap = new HashMap(); - propertyMapMap.put(targetClass, propertyMap); - } - propertyMap.put(mPropertyName, setterOrGetter); - } - } finally { - mPropertyMapLock.writeLock().unlock(); - } - return setterOrGetter; - } - - /** - * Utility function to get the setter from targetClass - * @param targetClass The Class on which the requested method should exist. - */ - void setupSetter(Class targetClass) { - mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", mValueType); - } - - /** - * Utility function to get the getter from targetClass - */ - private void setupGetter(Class targetClass) { - mGetter = setupSetterOrGetter(targetClass, sGetterPropertyMap, "get", null); - } - - /** - * Internal function (called from ObjectAnimator) to set up the setter and getter - * prior to running the animation. If the setter has not been manually set for this - * object, it will be derived automatically given the property name, target object, and - * types of values supplied. If no getter has been set, it will be supplied iff any of the - * supplied values was null. If there is a null value, then the getter (supplied or derived) - * will be called to set those null values to the current value of the property - * on the target object. - * @param target The object on which the setter (and possibly getter) exist. - */ - void setupSetterAndGetter(Object target) { - //if (mProperty != null) { - // // check to make sure that mProperty is on the class of target - // try { - // Object testValue = mProperty.get(target); - // for (Keyframe kf : mKeyframeSet.mKeyframes) { - // if (!kf.hasValue()) { - // kf.setValue(mProperty.get(target)); - // } - // } - // return; - // } catch (ClassCastException e) { - // Log.e("PropertyValuesHolder","No such property (" + mProperty.getName() + - // ") on target object " + target + ". Trying reflection instead"); - // mProperty = null; - // } - //} - Class targetClass = target.getClass(); - if (mSetter == null) { - setupSetter(targetClass); - } - for (Keyframe kf : mKeyframeSet.mKeyframes) { - if (!kf.hasValue()) { - if (mGetter == null) { - setupGetter(targetClass); - } - try { - kf.setValue(mGetter.invoke(target)); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - } - } - - /** - * Utility function to set the value stored in a particular Keyframe. The value used is - * whatever the value is for the property name specified in the keyframe on the target object. - * - * @param target The target object from which the current value should be extracted. - * @param kf The keyframe which holds the property name and value. - */ - private void setupValue(Object target, Keyframe kf) { - //if (mProperty != null) { - // kf.setValue(mProperty.get(target)); - //} - try { - if (mGetter == null) { - Class targetClass = target.getClass(); - setupGetter(targetClass); - } - kf.setValue(mGetter.invoke(target)); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - - /** - * This function is called by ObjectAnimator when setting the start values for an animation. - * The start values are set according to the current values in the target object. The - * property whose value is extracted is whatever is specified by the propertyName of this - * PropertyValuesHolder object. - * - * @param target The object which holds the start values that should be set. - */ - void setupStartValue(Object target) { - setupValue(target, mKeyframeSet.mKeyframes.get(0)); - } - - /** - * This function is called by ObjectAnimator when setting the end values for an animation. - * The end values are set according to the current values in the target object. The - * property whose value is extracted is whatever is specified by the propertyName of this - * PropertyValuesHolder object. - * - * @param target The object which holds the start values that should be set. - */ - void setupEndValue(Object target) { - setupValue(target, mKeyframeSet.mKeyframes.get(mKeyframeSet.mKeyframes.size() - 1)); - } - - @Override - public PropertyValuesHolder clone() { - try { - PropertyValuesHolder newPVH = (PropertyValuesHolder) super.clone(); - newPVH.mPropertyName = mPropertyName; - //newPVH.mProperty = mProperty; - newPVH.mKeyframeSet = mKeyframeSet.clone(); - newPVH.mEvaluator = mEvaluator; - return newPVH; - } catch (CloneNotSupportedException e) { - // won't reach here - return null; - } - } - - /** - * Internal function to set the value on the target object, using the setter set up - * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator - * to handle turning the value calculated by ValueAnimator into a value set on the object - * according to the name of the property. - * @param target The target object on which the value is set - */ - void setAnimatedValue(Object target) { - //if (mProperty != null) { - // mProperty.set(target, getAnimatedValue()); - //} - if (mSetter != null) { - try { - mTmpValueArray[0] = getAnimatedValue(); - mSetter.invoke(target, mTmpValueArray); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - } - - /** - * Internal function, called by ValueAnimator, to set up the TypeEvaluator that will be used - * to calculate animated values. - */ - void init() { - if (mEvaluator == null) { - // We already handle int and float automatically, but not their Object - // equivalents - mEvaluator = (mValueType == Integer.class) ? sIntEvaluator : - (mValueType == Float.class) ? sFloatEvaluator : - null; - } - if (mEvaluator != null) { - // KeyframeSet knows how to evaluate the common types - only give it a custom - // evaluator if one has been set on this class - mKeyframeSet.setEvaluator(mEvaluator); - } - } - - /** - * The TypeEvaluator will the automatically determined based on the type of values - * supplied to PropertyValuesHolder. The evaluator can be manually set, however, if so - * desired. This may be important in cases where either the type of the values supplied - * do not match the way that they should be interpolated between, or if the values - * are of a custom type or one not currently understood by the animation system. Currently, - * only values of type float and int (and their Object equivalents: Float - * and Integer) are correctly interpolated; all other types require setting a TypeEvaluator. - * @param evaluator - */ - public void setEvaluator(TypeEvaluator evaluator) { - mEvaluator = evaluator; - mKeyframeSet.setEvaluator(evaluator); - } - - /** - * Function used to calculate the value according to the evaluator set up for - * this PropertyValuesHolder object. This function is called by ValueAnimator.animateValue(). - * - * @param fraction The elapsed, interpolated fraction of the animation. - */ - void calculateValue(float fraction) { - mAnimatedValue = mKeyframeSet.getValue(fraction); - } - - /** - * Sets the name of the property that will be animated. This name is used to derive - * a setter function that will be called to set animated values. - * For example, a property name of foo will result - * in a call to the function setFoo() on the target object. If either - * valueFrom or valueTo is null, then a getter function will - * also be derived and called. - * - *

Note that the setter function derived from this property name - * must take the same parameter type as the - * valueFrom and valueTo properties, otherwise the call to - * the setter function will fail.

- * - * @param propertyName The name of the property being animated. - */ - public void setPropertyName(String propertyName) { - mPropertyName = propertyName; - } - - /** - * Sets the property that will be animated. - * - *

Note that if this PropertyValuesHolder object is used with ObjectAnimator, the property - * must exist on the target object specified in that ObjectAnimator.

- * - * @param property The property being animated. - */ - //public void setProperty(Property property) { - // mProperty = property; - //} - - /** - * Gets the name of the property that will be animated. This name will be used to derive - * a setter function that will be called to set animated values. - * For example, a property name of foo will result - * in a call to the function setFoo() on the target object. If either - * valueFrom or valueTo is null, then a getter function will - * also be derived and called. - */ - public String getPropertyName() { - return mPropertyName; - } - - /** - * Internal function, called by ValueAnimator and ObjectAnimator, to retrieve the value - * most recently calculated in calculateValue(). - * @return - */ - Object getAnimatedValue() { - return mAnimatedValue; - } - - @Override - public String toString() { - return mPropertyName + ": " + mKeyframeSet.toString(); - } - - /** - * Utility method to derive a setter/getter method name from a property name, where the - * prefix is typically "set" or "get" and the first letter of the property name is - * capitalized. - * - * @param prefix The precursor to the method name, before the property name begins, typically - * "set" or "get". - * @param propertyName The name of the property that represents the bulk of the method name - * after the prefix. The first letter of this word will be capitalized in the resulting - * method name. - * @return String the property name converted to a method name according to the conventions - * specified above. - */ - static String getMethodName(String prefix, String propertyName) { - if (propertyName == null || propertyName.length() == 0) { - // shouldn't get here - return prefix; - } - char firstLetter = Character.toUpperCase(propertyName.charAt(0)); - String theRest = propertyName.substring(1); - return prefix + firstLetter + theRest; - } - - static class IntPropertyValuesHolder extends PropertyValuesHolder { - - // Cache JNI functions to avoid looking them up twice - //private static final HashMap> sJNISetterPropertyMap = - // new HashMap>(); - //int mJniSetter; - //private IntProperty mIntProperty; - - IntKeyframeSet mIntKeyframeSet; - int mIntAnimatedValue; - - public IntPropertyValuesHolder(String propertyName, IntKeyframeSet keyframeSet) { - super(propertyName); - mValueType = int.class; - mKeyframeSet = keyframeSet; - mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet; - } - - //public IntPropertyValuesHolder(Property property, IntKeyframeSet keyframeSet) { - // super(property); - // mValueType = int.class; - // mKeyframeSet = keyframeSet; - // mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet; - // if (property instanceof IntProperty) { - // mIntProperty = (IntProperty) mProperty; - // } - //} - - public IntPropertyValuesHolder(String propertyName, int... values) { - super(propertyName); - setIntValues(values); - } - - //public IntPropertyValuesHolder(Property property, int... values) { - // super(property); - // setIntValues(values); - // if (property instanceof IntProperty) { - // mIntProperty = (IntProperty) mProperty; - // } - //} - - @Override - public void setIntValues(int... values) { - super.setIntValues(values); - mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet; - } - - @Override - void calculateValue(float fraction) { - mIntAnimatedValue = mIntKeyframeSet.getIntValue(fraction); - } - - @Override - Object getAnimatedValue() { - return mIntAnimatedValue; - } - - @Override - public IntPropertyValuesHolder clone() { - IntPropertyValuesHolder newPVH = (IntPropertyValuesHolder) super.clone(); - newPVH.mIntKeyframeSet = (IntKeyframeSet) newPVH.mKeyframeSet; - return newPVH; - } - - /** - * Internal function to set the value on the target object, using the setter set up - * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator - * to handle turning the value calculated by ValueAnimator into a value set on the object - * according to the name of the property. - * @param target The target object on which the value is set - */ - @Override - void setAnimatedValue(Object target) { - //if (mIntProperty != null) { - // mIntProperty.setValue(target, mIntAnimatedValue); - // return; - //} - //if (mProperty != null) { - // mProperty.set(target, mIntAnimatedValue); - // return; - //} - //if (mJniSetter != 0) { - // nCallIntMethod(target, mJniSetter, mIntAnimatedValue); - // return; - //} - if (mSetter != null) { - try { - mTmpValueArray[0] = mIntAnimatedValue; - mSetter.invoke(target, mTmpValueArray); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - } - - @Override - void setupSetter(Class targetClass) { - //if (mProperty != null) { - // return; - //} - // Check new static hashmap for setter method - //try { - // mPropertyMapLock.writeLock().lock(); - // HashMap propertyMap = sJNISetterPropertyMap.get(targetClass); - // if (propertyMap != null) { - // Integer mJniSetterInteger = propertyMap.get(mPropertyName); - // if (mJniSetterInteger != null) { - // mJniSetter = mJniSetterInteger; - // } - // } - // if (mJniSetter == 0) { - // String methodName = getMethodName("set", mPropertyName); - // mJniSetter = nGetIntMethod(targetClass, methodName); - // if (mJniSetter != 0) { - // if (propertyMap == null) { - // propertyMap = new HashMap(); - // sJNISetterPropertyMap.put(targetClass, propertyMap); - // } - // propertyMap.put(mPropertyName, mJniSetter); - // } - // } - //} catch (NoSuchMethodError e) { - // Log.d("PropertyValuesHolder", - // "Can't find native method using JNI, use reflection" + e); - //} finally { - // mPropertyMapLock.writeLock().unlock(); - //} - //if (mJniSetter == 0) { - // Couldn't find method through fast JNI approach - just use reflection - super.setupSetter(targetClass); - //} - } - } - - static class FloatPropertyValuesHolder extends PropertyValuesHolder { - - // Cache JNI functions to avoid looking them up twice - //private static final HashMap> sJNISetterPropertyMap = - // new HashMap>(); - //int mJniSetter; - //private FloatProperty mFloatProperty; - - FloatKeyframeSet mFloatKeyframeSet; - float mFloatAnimatedValue; - - public FloatPropertyValuesHolder(String propertyName, FloatKeyframeSet keyframeSet) { - super(propertyName); - mValueType = float.class; - mKeyframeSet = keyframeSet; - mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet; - } - - //public FloatPropertyValuesHolder(Property property, FloatKeyframeSet keyframeSet) { - // super(property); - // mValueType = float.class; - // mKeyframeSet = keyframeSet; - // mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet; - // if (property instanceof FloatProperty) { - // mFloatProperty = (FloatProperty) mProperty; - // } - //} - - public FloatPropertyValuesHolder(String propertyName, float... values) { - super(propertyName); - setFloatValues(values); - } - - //public FloatPropertyValuesHolder(Property property, float... values) { - // super(property); - // setFloatValues(values); - // if (property instanceof FloatProperty) { - // mFloatProperty = (FloatProperty) mProperty; - // } - //} - - @Override - public void setFloatValues(float... values) { - super.setFloatValues(values); - mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet; - } - - @Override - void calculateValue(float fraction) { - mFloatAnimatedValue = mFloatKeyframeSet.getFloatValue(fraction); - } - - @Override - Object getAnimatedValue() { - return mFloatAnimatedValue; - } - - @Override - public FloatPropertyValuesHolder clone() { - FloatPropertyValuesHolder newPVH = (FloatPropertyValuesHolder) super.clone(); - newPVH.mFloatKeyframeSet = (FloatKeyframeSet) newPVH.mKeyframeSet; - return newPVH; - } - - /** - * Internal function to set the value on the target object, using the setter set up - * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator - * to handle turning the value calculated by ValueAnimator into a value set on the object - * according to the name of the property. - * @param target The target object on which the value is set - */ - @Override - void setAnimatedValue(Object target) { - //if (mFloatProperty != null) { - // mFloatProperty.setValue(target, mFloatAnimatedValue); - // return; - //} - //if (mProperty != null) { - // mProperty.set(target, mFloatAnimatedValue); - // return; - //} - //if (mJniSetter != 0) { - // nCallFloatMethod(target, mJniSetter, mFloatAnimatedValue); - // return; - //} - if (mSetter != null) { - try { - mTmpValueArray[0] = mFloatAnimatedValue; - mSetter.invoke(target, mTmpValueArray); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - } - - @Override - void setupSetter(Class targetClass) { - //if (mProperty != null) { - // return; - //} - // Check new static hashmap for setter method - //try { - // mPropertyMapLock.writeLock().lock(); - // HashMap propertyMap = sJNISetterPropertyMap.get(targetClass); - // if (propertyMap != null) { - // Integer mJniSetterInteger = propertyMap.get(mPropertyName); - // if (mJniSetterInteger != null) { - // mJniSetter = mJniSetterInteger; - // } - // } - // if (mJniSetter == 0) { - // String methodName = getMethodName("set", mPropertyName); - // mJniSetter = nGetFloatMethod(targetClass, methodName); - // if (mJniSetter != 0) { - // if (propertyMap == null) { - // propertyMap = new HashMap(); - // sJNISetterPropertyMap.put(targetClass, propertyMap); - // } - // propertyMap.put(mPropertyName, mJniSetter); - // } - // } - //} catch (NoSuchMethodError e) { - // Log.d("PropertyValuesHolder", - // "Can't find native method using JNI, use reflection" + e); - //} finally { - // mPropertyMapLock.writeLock().unlock(); - //} - //if (mJniSetter == 0) { - // Couldn't find method through fast JNI approach - just use reflection - super.setupSetter(targetClass); - //} - } - - } - - //native static private int nGetIntMethod(Class targetClass, String methodName); - //native static private int nGetFloatMethod(Class targetClass, String methodName); - //native static private void nCallIntMethod(Object target, int methodID, int arg); - //native static private void nCallFloatMethod(Object target, int methodID, float arg); -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/TypeEvaluator.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/TypeEvaluator.java deleted file mode 100644 index 0ea31924..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/TypeEvaluator.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -/** - * Interface for use with the {@link ValueAnimator#setEvaluator(TypeEvaluator)} function. Evaluators - * allow developers to create animations on arbitrary property types, by allowing them to supply - * custom evaulators for types that are not automatically understood and used by the animation - * system. - * - * @see ValueAnimator#setEvaluator(TypeEvaluator) - */ -public interface TypeEvaluator { - - /** - * This function returns the result of linearly interpolating the start and end values, with - * fraction representing the proportion between the start and end values. The - * calculation is a simple parametric calculation: result = x0 + t * (v1 - v0), - * where x0 is startValue, x1 is endValue, - * and t is fraction. - * - * @param fraction The fraction from the starting to the ending values - * @param startValue The start value. - * @param endValue The end value. - * @return A linear interpolation between the start and end values, given the - * fraction parameter. - */ - public T evaluate(float fraction, T startValue, T endValue); - -} \ No newline at end of file diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ValueAnimator.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ValueAnimator.java deleted file mode 100644 index d8a12c68..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/ValueAnimator.java +++ /dev/null @@ -1,1265 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.nineoldandroids.animation; - -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.util.AndroidRuntimeException; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.view.animation.AnimationUtils; -import android.view.animation.Interpolator; -import android.view.animation.LinearInterpolator; - -import java.util.ArrayList; -import java.util.HashMap; - -/** - * This class provides a simple timing engine for running animations - * which calculate animated values and set them on target objects. - * - *

There is a single timing pulse that all animations use. It runs in a - * custom handler to ensure that property changes happen on the UI thread.

- * - *

By default, ValueAnimator uses non-linear time interpolation, via the - * {@link AccelerateDecelerateInterpolator} class, which accelerates into and decelerates - * out of an animation. This behavior can be changed by calling - * {@link ValueAnimator#setInterpolator(TimeInterpolator)}.

- */ -@SuppressWarnings({"rawtypes", "unchecked"}) -public class ValueAnimator extends Animator { - - /** - * Internal constants - */ - - /* - * The default amount of time in ms between animation frames - */ - private static final long DEFAULT_FRAME_DELAY = 10; - - /** - * Messages sent to timing handler: START is sent when an animation first begins, FRAME is sent - * by the handler to itself to process the next animation frame - */ - static final int ANIMATION_START = 0; - static final int ANIMATION_FRAME = 1; - - /** - * Values used with internal variable mPlayingState to indicate the current state of an - * animation. - */ - static final int STOPPED = 0; // Not yet playing - static final int RUNNING = 1; // Playing normally - static final int SEEKED = 2; // Seeked to some time value - - /** - * Internal variables - * NOTE: This object implements the clone() method, making a deep copy of any referenced - * objects. As other non-trivial fields are added to this class, make sure to add logic - * to clone() to make deep copies of them. - */ - - // The first time that the animation's animateFrame() method is called. This time is used to - // determine elapsed time (and therefore the elapsed fraction) in subsequent calls - // to animateFrame() - long mStartTime; - - /** - * Set when setCurrentPlayTime() is called. If negative, animation is not currently seeked - * to a value. - */ - long mSeekTime = -1; - - // TODO: We access the following ThreadLocal variables often, some of them on every update. - // If ThreadLocal access is significantly expensive, we may want to put all of these - // fields into a structure sot hat we just access ThreadLocal once to get the reference - // to that structure, then access the structure directly for each field. - - // The static sAnimationHandler processes the internal timing loop on which all animations - // are based - private static ThreadLocal sAnimationHandler = - new ThreadLocal(); - - // The per-thread list of all active animations - private static final ThreadLocal> sAnimations = - new ThreadLocal>() { - @Override - protected ArrayList initialValue() { - return new ArrayList(); - } - }; - - // The per-thread set of animations to be started on the next animation frame - private static final ThreadLocal> sPendingAnimations = - new ThreadLocal>() { - @Override - protected ArrayList initialValue() { - return new ArrayList(); - } - }; - - /** - * Internal per-thread collections used to avoid set collisions as animations start and end - * while being processed. - */ - private static final ThreadLocal> sDelayedAnims = - new ThreadLocal>() { - @Override - protected ArrayList initialValue() { - return new ArrayList(); - } - }; - - private static final ThreadLocal> sEndingAnims = - new ThreadLocal>() { - @Override - protected ArrayList initialValue() { - return new ArrayList(); - } - }; - - private static final ThreadLocal> sReadyAnims = - new ThreadLocal>() { - @Override - protected ArrayList initialValue() { - return new ArrayList(); - } - }; - - // The time interpolator to be used if none is set on the animation - private static final /*Time*/Interpolator sDefaultInterpolator = - new AccelerateDecelerateInterpolator(); - - // type evaluators for the primitive types handled by this implementation - //private static final TypeEvaluator sIntEvaluator = new IntEvaluator(); - //private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator(); - - /** - * Used to indicate whether the animation is currently playing in reverse. This causes the - * elapsed fraction to be inverted to calculate the appropriate values. - */ - private boolean mPlayingBackwards = false; - - /** - * This variable tracks the current iteration that is playing. When mCurrentIteration exceeds the - * repeatCount (if repeatCount!=INFINITE), the animation ends - */ - private int mCurrentIteration = 0; - - /** - * Tracks current elapsed/eased fraction, for querying in getAnimatedFraction(). - */ - private float mCurrentFraction = 0f; - - /** - * Tracks whether a startDelay'd animation has begun playing through the startDelay. - */ - private boolean mStartedDelay = false; - - /** - * Tracks the time at which the animation began playing through its startDelay. This is - * different from the mStartTime variable, which is used to track when the animation became - * active (which is when the startDelay expired and the animation was added to the active - * animations list). - */ - private long mDelayStartTime; - - /** - * Flag that represents the current state of the animation. Used to figure out when to start - * an animation (if state == STOPPED). Also used to end an animation that - * has been cancel()'d or end()'d since the last animation frame. Possible values are - * STOPPED, RUNNING, SEEKED. - */ - int mPlayingState = STOPPED; - - /** - * Additional playing state to indicate whether an animator has been start()'d. There is - * some lag between a call to start() and the first animation frame. We should still note - * that the animation has been started, even if it's first animation frame has not yet - * happened, and reflect that state in isRunning(). - * Note that delayed animations are different: they are not started until their first - * animation frame, which occurs after their delay elapses. - */ - private boolean mRunning = false; - - /** - * Additional playing state to indicate whether an animator has been start()'d, whether or - * not there is a nonzero startDelay. - */ - private boolean mStarted = false; - - /** - * Flag that denotes whether the animation is set up and ready to go. Used to - * set up animation that has not yet been started. - */ - boolean mInitialized = false; - - // - // Backing variables - // - - // How long the animation should last in ms - private long mDuration = 300; - - // The amount of time in ms to delay starting the animation after start() is called - private long mStartDelay = 0; - - // The number of milliseconds between animation frames - private static long sFrameDelay = DEFAULT_FRAME_DELAY; - - // The number of times the animation will repeat. The default is 0, which means the animation - // will play only once - private int mRepeatCount = 0; - - /** - * The type of repetition that will occur when repeatMode is nonzero. RESTART means the - * animation will start from the beginning on every new cycle. REVERSE means the animation - * will reverse directions on each iteration. - */ - private int mRepeatMode = RESTART; - - /** - * The time interpolator to be used. The elapsed fraction of the animation will be passed - * through this interpolator to calculate the interpolated fraction, which is then used to - * calculate the animated values. - */ - private /*Time*/Interpolator mInterpolator = sDefaultInterpolator; - - /** - * The set of listeners to be sent events through the life of an animation. - */ - private ArrayList mUpdateListeners = null; - - /** - * The property/value sets being animated. - */ - PropertyValuesHolder[] mValues; - - /** - * A hashmap of the PropertyValuesHolder objects. This map is used to lookup animated values - * by property name during calls to getAnimatedValue(String). - */ - HashMap mValuesMap; - - /** - * Public constants - */ - - /** - * When the animation reaches the end and repeatCount is INFINITE - * or a positive value, the animation restarts from the beginning. - */ - public static final int RESTART = 1; - /** - * When the animation reaches the end and repeatCount is INFINITE - * or a positive value, the animation reverses direction on every iteration. - */ - public static final int REVERSE = 2; - /** - * This value used used with the {@link #setRepeatCount(int)} property to repeat - * the animation indefinitely. - */ - public static final int INFINITE = -1; - - /** - * Creates a new ValueAnimator object. This default constructor is primarily for - * use internally; the factory methods which take parameters are more generally - * useful. - */ - public ValueAnimator() { - } - - /** - * Constructs and returns a ValueAnimator that animates between int values. A single - * value implies that that value is the one being animated to. However, this is not typically - * useful in a ValueAnimator object because there is no way for the object to determine the - * starting value for the animation (unlike ObjectAnimator, which can derive that value - * from the target object and property being animated). Therefore, there should typically - * be two or more values. - * - * @param values A set of values that the animation will animate between over time. - * @return A ValueAnimator object that is set up to animate between the given values. - */ - public static ValueAnimator ofInt(int... values) { - ValueAnimator anim = new ValueAnimator(); - anim.setIntValues(values); - return anim; - } - - /** - * Constructs and returns a ValueAnimator that animates between float values. A single - * value implies that that value is the one being animated to. However, this is not typically - * useful in a ValueAnimator object because there is no way for the object to determine the - * starting value for the animation (unlike ObjectAnimator, which can derive that value - * from the target object and property being animated). Therefore, there should typically - * be two or more values. - * - * @param values A set of values that the animation will animate between over time. - * @return A ValueAnimator object that is set up to animate between the given values. - */ - public static ValueAnimator ofFloat(float... values) { - ValueAnimator anim = new ValueAnimator(); - anim.setFloatValues(values); - return anim; - } - - /** - * Constructs and returns a ValueAnimator that animates between the values - * specified in the PropertyValuesHolder objects. - * - * @param values A set of PropertyValuesHolder objects whose values will be animated - * between over time. - * @return A ValueAnimator object that is set up to animate between the given values. - */ - public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values) { - ValueAnimator anim = new ValueAnimator(); - anim.setValues(values); - return anim; - } - /** - * Constructs and returns a ValueAnimator that animates between Object values. A single - * value implies that that value is the one being animated to. However, this is not typically - * useful in a ValueAnimator object because there is no way for the object to determine the - * starting value for the animation (unlike ObjectAnimator, which can derive that value - * from the target object and property being animated). Therefore, there should typically - * be two or more values. - * - *

Since ValueAnimator does not know how to animate between arbitrary Objects, this - * factory method also takes a TypeEvaluator object that the ValueAnimator will use - * to perform that interpolation. - * - * @param evaluator A TypeEvaluator that will be called on each animation frame to - * provide the ncessry interpolation between the Object values to derive the animated - * value. - * @param values A set of values that the animation will animate between over time. - * @return A ValueAnimator object that is set up to animate between the given values. - */ - public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) { - ValueAnimator anim = new ValueAnimator(); - anim.setObjectValues(values); - anim.setEvaluator(evaluator); - return anim; - } - - /** - * Sets int values that will be animated between. A single - * value implies that that value is the one being animated to. However, this is not typically - * useful in a ValueAnimator object because there is no way for the object to determine the - * starting value for the animation (unlike ObjectAnimator, which can derive that value - * from the target object and property being animated). Therefore, there should typically - * be two or more values. - * - *

If there are already multiple sets of values defined for this ValueAnimator via more - * than one PropertyValuesHolder object, this method will set the values for the first - * of those objects.

- * - * @param values A set of values that the animation will animate between over time. - */ - public void setIntValues(int... values) { - if (values == null || values.length == 0) { - return; - } - if (mValues == null || mValues.length == 0) { - setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofInt("", values)}); - } else { - PropertyValuesHolder valuesHolder = mValues[0]; - valuesHolder.setIntValues(values); - } - // New property/values/target should cause re-initialization prior to starting - mInitialized = false; - } - - /** - * Sets float values that will be animated between. A single - * value implies that that value is the one being animated to. However, this is not typically - * useful in a ValueAnimator object because there is no way for the object to determine the - * starting value for the animation (unlike ObjectAnimator, which can derive that value - * from the target object and property being animated). Therefore, there should typically - * be two or more values. - * - *

If there are already multiple sets of values defined for this ValueAnimator via more - * than one PropertyValuesHolder object, this method will set the values for the first - * of those objects.

- * - * @param values A set of values that the animation will animate between over time. - */ - public void setFloatValues(float... values) { - if (values == null || values.length == 0) { - return; - } - if (mValues == null || mValues.length == 0) { - setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofFloat("", values)}); - } else { - PropertyValuesHolder valuesHolder = mValues[0]; - valuesHolder.setFloatValues(values); - } - // New property/values/target should cause re-initialization prior to starting - mInitialized = false; - } - - /** - * Sets the values to animate between for this animation. A single - * value implies that that value is the one being animated to. However, this is not typically - * useful in a ValueAnimator object because there is no way for the object to determine the - * starting value for the animation (unlike ObjectAnimator, which can derive that value - * from the target object and property being animated). Therefore, there should typically - * be two or more values. - * - *

If there are already multiple sets of values defined for this ValueAnimator via more - * than one PropertyValuesHolder object, this method will set the values for the first - * of those objects.

- * - *

There should be a TypeEvaluator set on the ValueAnimator that knows how to interpolate - * between these value objects. ValueAnimator only knows how to interpolate between the - * primitive types specified in the other setValues() methods.

- * - * @param values The set of values to animate between. - */ - public void setObjectValues(Object... values) { - if (values == null || values.length == 0) { - return; - } - if (mValues == null || mValues.length == 0) { - setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofObject("", - (TypeEvaluator)null, values)}); - } else { - PropertyValuesHolder valuesHolder = mValues[0]; - valuesHolder.setObjectValues(values); - } - // New property/values/target should cause re-initialization prior to starting - mInitialized = false; - } - - /** - * Sets the values, per property, being animated between. This function is called internally - * by the constructors of ValueAnimator that take a list of values. But an ValueAnimator can - * be constructed without values and this method can be called to set the values manually - * instead. - * - * @param values The set of values, per property, being animated between. - */ - public void setValues(PropertyValuesHolder... values) { - int numValues = values.length; - mValues = values; - mValuesMap = new HashMap(numValues); - for (int i = 0; i < numValues; ++i) { - PropertyValuesHolder valuesHolder = values[i]; - mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder); - } - // New property/values/target should cause re-initialization prior to starting - mInitialized = false; - } - - /** - * Returns the values that this ValueAnimator animates between. These values are stored in - * PropertyValuesHolder objects, even if the ValueAnimator was created with a simple list - * of value objects instead. - * - * @return PropertyValuesHolder[] An array of PropertyValuesHolder objects which hold the - * values, per property, that define the animation. - */ - public PropertyValuesHolder[] getValues() { - return mValues; - } - - /** - * This function is called immediately before processing the first animation - * frame of an animation. If there is a nonzero startDelay, the - * function is called after that delay ends. - * It takes care of the final initialization steps for the - * animation. - * - *

Overrides of this method should call the superclass method to ensure - * that internal mechanisms for the animation are set up correctly.

- */ - void initAnimation() { - if (!mInitialized) { - int numValues = mValues.length; - for (int i = 0; i < numValues; ++i) { - mValues[i].init(); - } - mInitialized = true; - } - } - - - /** - * Sets the length of the animation. The default duration is 300 milliseconds. - * - * @param duration The length of the animation, in milliseconds. This value cannot - * be negative. - * @return ValueAnimator The object called with setDuration(). This return - * value makes it easier to compose statements together that construct and then set the - * duration, as in ValueAnimator.ofInt(0, 10).setDuration(500).start(). - */ - public ValueAnimator setDuration(long duration) { - if (duration < 0) { - throw new IllegalArgumentException("Animators cannot have negative duration: " + - duration); - } - mDuration = duration; - return this; - } - - /** - * Gets the length of the animation. The default duration is 300 milliseconds. - * - * @return The length of the animation, in milliseconds. - */ - public long getDuration() { - return mDuration; - } - - /** - * Sets the position of the animation to the specified point in time. This time should - * be between 0 and the total duration of the animation, including any repetition. If - * the animation has not yet been started, then it will not advance forward after it is - * set to this time; it will simply set the time to this value and perform any appropriate - * actions based on that time. If the animation is already running, then setCurrentPlayTime() - * will set the current playing time to this value and continue playing from that point. - * - * @param playTime The time, in milliseconds, to which the animation is advanced or rewound. - */ - public void setCurrentPlayTime(long playTime) { - initAnimation(); - long currentTime = AnimationUtils.currentAnimationTimeMillis(); - if (mPlayingState != RUNNING) { - mSeekTime = playTime; - mPlayingState = SEEKED; - } - mStartTime = currentTime - playTime; - animationFrame(currentTime); - } - - /** - * Gets the current position of the animation in time, which is equal to the current - * time minus the time that the animation started. An animation that is not yet started will - * return a value of zero. - * - * @return The current position in time of the animation. - */ - public long getCurrentPlayTime() { - if (!mInitialized || mPlayingState == STOPPED) { - return 0; - } - return AnimationUtils.currentAnimationTimeMillis() - mStartTime; - } - - /** - * This custom, static handler handles the timing pulse that is shared by - * all active animations. This approach ensures that the setting of animation - * values will happen on the UI thread and that all animations will share - * the same times for calculating their values, which makes synchronizing - * animations possible. - * - */ - private static class AnimationHandler extends Handler { - /** - * There are only two messages that we care about: ANIMATION_START and - * ANIMATION_FRAME. The START message is sent when an animation's start() - * method is called. It cannot start synchronously when start() is called - * because the call may be on the wrong thread, and it would also not be - * synchronized with other animations because it would not start on a common - * timing pulse. So each animation sends a START message to the handler, which - * causes the handler to place the animation on the active animations queue and - * start processing frames for that animation. - * The FRAME message is the one that is sent over and over while there are any - * active animations to process. - */ - @Override - public void handleMessage(Message msg) { - boolean callAgain = true; - ArrayList animations = sAnimations.get(); - ArrayList delayedAnims = sDelayedAnims.get(); - switch (msg.what) { - // TODO: should we avoid sending frame message when starting if we - // were already running? - case ANIMATION_START: - ArrayList pendingAnimations = sPendingAnimations.get(); - if (animations.size() > 0 || delayedAnims.size() > 0) { - callAgain = false; - } - // pendingAnims holds any animations that have requested to be started - // We're going to clear sPendingAnimations, but starting animation may - // cause more to be added to the pending list (for example, if one animation - // starting triggers another starting). So we loop until sPendingAnimations - // is empty. - while (pendingAnimations.size() > 0) { - ArrayList pendingCopy = - (ArrayList) pendingAnimations.clone(); - pendingAnimations.clear(); - int count = pendingCopy.size(); - for (int i = 0; i < count; ++i) { - ValueAnimator anim = pendingCopy.get(i); - // If the animation has a startDelay, place it on the delayed list - if (anim.mStartDelay == 0) { - anim.startAnimation(); - } else { - delayedAnims.add(anim); - } - } - } - // fall through to process first frame of new animations - case ANIMATION_FRAME: - // currentTime holds the common time for all animations processed - // during this frame - long currentTime = AnimationUtils.currentAnimationTimeMillis(); - ArrayList readyAnims = sReadyAnims.get(); - ArrayList endingAnims = sEndingAnims.get(); - - // First, process animations currently sitting on the delayed queue, adding - // them to the active animations if they are ready - int numDelayedAnims = delayedAnims.size(); - for (int i = 0; i < numDelayedAnims; ++i) { - ValueAnimator anim = delayedAnims.get(i); - if (anim.delayedAnimationFrame(currentTime)) { - readyAnims.add(anim); - } - } - int numReadyAnims = readyAnims.size(); - if (numReadyAnims > 0) { - for (int i = 0; i < numReadyAnims; ++i) { - ValueAnimator anim = readyAnims.get(i); - anim.startAnimation(); - anim.mRunning = true; - delayedAnims.remove(anim); - } - readyAnims.clear(); - } - - // Now process all active animations. The return value from animationFrame() - // tells the handler whether it should now be ended - int numAnims = animations.size(); - int i = 0; - while (i < numAnims) { - ValueAnimator anim = animations.get(i); - if (anim.animationFrame(currentTime)) { - endingAnims.add(anim); - } - if (animations.size() == numAnims) { - ++i; - } else { - // An animation might be canceled or ended by client code - // during the animation frame. Check to see if this happened by - // seeing whether the current index is the same as it was before - // calling animationFrame(). Another approach would be to copy - // animations to a temporary list and process that list instead, - // but that entails garbage and processing overhead that would - // be nice to avoid. - --numAnims; - endingAnims.remove(anim); - } - } - if (endingAnims.size() > 0) { - for (i = 0; i < endingAnims.size(); ++i) { - endingAnims.get(i).endAnimation(); - } - endingAnims.clear(); - } - - // If there are still active or delayed animations, call the handler again - // after the frameDelay - if (callAgain && (!animations.isEmpty() || !delayedAnims.isEmpty())) { - sendEmptyMessageDelayed(ANIMATION_FRAME, Math.max(0, sFrameDelay - - (AnimationUtils.currentAnimationTimeMillis() - currentTime))); - } - break; - } - } - } - - /** - * The amount of time, in milliseconds, to delay starting the animation after - * {@link #start()} is called. - * - * @return the number of milliseconds to delay running the animation - */ - public long getStartDelay() { - return mStartDelay; - } - - /** - * The amount of time, in milliseconds, to delay starting the animation after - * {@link #start()} is called. - - * @param startDelay The amount of the delay, in milliseconds - */ - public void setStartDelay(long startDelay) { - this.mStartDelay = startDelay; - } - - /** - * The amount of time, in milliseconds, between each frame of the animation. This is a - * requested time that the animation will attempt to honor, but the actual delay between - * frames may be different, depending on system load and capabilities. This is a static - * function because the same delay will be applied to all animations, since they are all - * run off of a single timing loop. - * - * @return the requested time between frames, in milliseconds - */ - public static long getFrameDelay() { - return sFrameDelay; - } - - /** - * The amount of time, in milliseconds, between each frame of the animation. This is a - * requested time that the animation will attempt to honor, but the actual delay between - * frames may be different, depending on system load and capabilities. This is a static - * function because the same delay will be applied to all animations, since they are all - * run off of a single timing loop. - * - * @param frameDelay the requested time between frames, in milliseconds - */ - public static void setFrameDelay(long frameDelay) { - sFrameDelay = frameDelay; - } - - /** - * The most recent value calculated by this ValueAnimator when there is just one - * property being animated. This value is only sensible while the animation is running. The main - * purpose for this read-only property is to retrieve the value from the ValueAnimator - * during a call to {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which - * is called during each animation frame, immediately after the value is calculated. - * - * @return animatedValue The value most recently calculated by this ValueAnimator for - * the single property being animated. If there are several properties being animated - * (specified by several PropertyValuesHolder objects in the constructor), this function - * returns the animated value for the first of those objects. - */ - public Object getAnimatedValue() { - if (mValues != null && mValues.length > 0) { - return mValues[0].getAnimatedValue(); - } - // Shouldn't get here; should always have values unless ValueAnimator was set up wrong - return null; - } - - /** - * The most recent value calculated by this ValueAnimator for propertyName. - * The main purpose for this read-only property is to retrieve the value from the - * ValueAnimator during a call to - * {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which - * is called during each animation frame, immediately after the value is calculated. - * - * @return animatedValue The value most recently calculated for the named property - * by this ValueAnimator. - */ - public Object getAnimatedValue(String propertyName) { - PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName); - if (valuesHolder != null) { - return valuesHolder.getAnimatedValue(); - } else { - // At least avoid crashing if called with bogus propertyName - return null; - } - } - - /** - * Sets how many times the animation should be repeated. If the repeat - * count is 0, the animation is never repeated. If the repeat count is - * greater than 0 or {@link #INFINITE}, the repeat mode will be taken - * into account. The repeat count is 0 by default. - * - * @param value the number of times the animation should be repeated - */ - public void setRepeatCount(int value) { - mRepeatCount = value; - } - /** - * Defines how many times the animation should repeat. The default value - * is 0. - * - * @return the number of times the animation should repeat, or {@link #INFINITE} - */ - public int getRepeatCount() { - return mRepeatCount; - } - - /** - * Defines what this animation should do when it reaches the end. This - * setting is applied only when the repeat count is either greater than - * 0 or {@link #INFINITE}. Defaults to {@link #RESTART}. - * - * @param value {@link #RESTART} or {@link #REVERSE} - */ - public void setRepeatMode(int value) { - mRepeatMode = value; - } - - /** - * Defines what this animation should do when it reaches the end. - * - * @return either one of {@link #REVERSE} or {@link #RESTART} - */ - public int getRepeatMode() { - return mRepeatMode; - } - - /** - * Adds a listener to the set of listeners that are sent update events through the life of - * an animation. This method is called on all listeners for every frame of the animation, - * after the values for the animation have been calculated. - * - * @param listener the listener to be added to the current set of listeners for this animation. - */ - public void addUpdateListener(AnimatorUpdateListener listener) { - if (mUpdateListeners == null) { - mUpdateListeners = new ArrayList(); - } - mUpdateListeners.add(listener); - } - - /** - * Removes all listeners from the set listening to frame updates for this animation. - */ - public void removeAllUpdateListeners() { - if (mUpdateListeners == null) { - return; - } - mUpdateListeners.clear(); - mUpdateListeners = null; - } - - /** - * Removes a listener from the set listening to frame updates for this animation. - * - * @param listener the listener to be removed from the current set of update listeners - * for this animation. - */ - public void removeUpdateListener(AnimatorUpdateListener listener) { - if (mUpdateListeners == null) { - return; - } - mUpdateListeners.remove(listener); - if (mUpdateListeners.size() == 0) { - mUpdateListeners = null; - } - } - - - /** - * The time interpolator used in calculating the elapsed fraction of this animation. The - * interpolator determines whether the animation runs with linear or non-linear motion, - * such as acceleration and deceleration. The default value is - * {@link android.view.animation.AccelerateDecelerateInterpolator} - * - * @param value the interpolator to be used by this animation. A value of null - * will result in linear interpolation. - */ - @Override - public void setInterpolator(/*Time*/Interpolator value) { - if (value != null) { - mInterpolator = value; - } else { - mInterpolator = new LinearInterpolator(); - } - } - - /** - * Returns the timing interpolator that this ValueAnimator uses. - * - * @return The timing interpolator for this ValueAnimator. - */ - public /*Time*/Interpolator getInterpolator() { - return mInterpolator; - } - - /** - * The type evaluator to be used when calculating the animated values of this animation. - * The system will automatically assign a float or int evaluator based on the type - * of startValue and endValue in the constructor. But if these values - * are not one of these primitive types, or if different evaluation is desired (such as is - * necessary with int values that represent colors), a custom evaluator needs to be assigned. - * For example, when running an animation on color values, the {@link ArgbEvaluator} - * should be used to get correct RGB color interpolation. - * - *

If this ValueAnimator has only one set of values being animated between, this evaluator - * will be used for that set. If there are several sets of values being animated, which is - * the case if PropertyValuesHOlder objects were set on the ValueAnimator, then the evaluator - * is assigned just to the first PropertyValuesHolder object.

- * - * @param value the evaluator to be used this animation - */ - public void setEvaluator(TypeEvaluator value) { - if (value != null && mValues != null && mValues.length > 0) { - mValues[0].setEvaluator(value); - } - } - - /** - * Start the animation playing. This version of start() takes a boolean flag that indicates - * whether the animation should play in reverse. The flag is usually false, but may be set - * to true if called from the reverse() method. - * - *

The animation started by calling this method will be run on the thread that called - * this method. This thread should have a Looper on it (a runtime exception will be thrown if - * this is not the case). Also, if the animation will animate - * properties of objects in the view hierarchy, then the calling thread should be the UI - * thread for that view hierarchy.

- * - * @param playBackwards Whether the ValueAnimator should start playing in reverse. - */ - private void start(boolean playBackwards) { - if (Looper.myLooper() == null) { - throw new AndroidRuntimeException("Animators may only be run on Looper threads"); - } - mPlayingBackwards = playBackwards; - mCurrentIteration = 0; - mPlayingState = STOPPED; - mStarted = true; - mStartedDelay = false; - sPendingAnimations.get().add(this); - if (mStartDelay == 0) { - // This sets the initial value of the animation, prior to actually starting it running - setCurrentPlayTime(getCurrentPlayTime()); - mPlayingState = STOPPED; - mRunning = true; - - if (mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationStart(this); - } - } - } - AnimationHandler animationHandler = sAnimationHandler.get(); - if (animationHandler == null) { - animationHandler = new AnimationHandler(); - sAnimationHandler.set(animationHandler); - } - animationHandler.sendEmptyMessage(ANIMATION_START); - } - - @Override - public void start() { - start(false); - } - - @Override - public void cancel() { - // Only cancel if the animation is actually running or has been started and is about - // to run - if (mPlayingState != STOPPED || sPendingAnimations.get().contains(this) || - sDelayedAnims.get().contains(this)) { - // Only notify listeners if the animator has actually started - if (mRunning && mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - for (AnimatorListener listener : tmpListeners) { - listener.onAnimationCancel(this); - } - } - endAnimation(); - } - } - - @Override - public void end() { - if (!sAnimations.get().contains(this) && !sPendingAnimations.get().contains(this)) { - // Special case if the animation has not yet started; get it ready for ending - mStartedDelay = false; - startAnimation(); - } else if (!mInitialized) { - initAnimation(); - } - // The final value set on the target varies, depending on whether the animation - // was supposed to repeat an odd number of times - if (mRepeatCount > 0 && (mRepeatCount & 0x01) == 1) { - animateValue(0f); - } else { - animateValue(1f); - } - endAnimation(); - } - - @Override - public boolean isRunning() { - return (mPlayingState == RUNNING || mRunning); - } - - @Override - public boolean isStarted() { - return mStarted; - } - - /** - * Plays the ValueAnimator in reverse. If the animation is already running, - * it will stop itself and play backwards from the point reached when reverse was called. - * If the animation is not currently running, then it will start from the end and - * play backwards. This behavior is only set for the current animation; future playing - * of the animation will use the default behavior of playing forward. - */ - public void reverse() { - mPlayingBackwards = !mPlayingBackwards; - if (mPlayingState == RUNNING) { - long currentTime = AnimationUtils.currentAnimationTimeMillis(); - long currentPlayTime = currentTime - mStartTime; - long timeLeft = mDuration - currentPlayTime; - mStartTime = currentTime - timeLeft; - } else { - start(true); - } - } - - /** - * Called internally to end an animation by removing it from the animations list. Must be - * called on the UI thread. - */ - private void endAnimation() { - sAnimations.get().remove(this); - sPendingAnimations.get().remove(this); - sDelayedAnims.get().remove(this); - mPlayingState = STOPPED; - if (mRunning && mListeners != null) { - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationEnd(this); - } - } - mRunning = false; - mStarted = false; - } - - /** - * Called internally to start an animation by adding it to the active animations list. Must be - * called on the UI thread. - */ - private void startAnimation() { - initAnimation(); - sAnimations.get().add(this); - if (mStartDelay > 0 && mListeners != null) { - // Listeners were already notified in start() if startDelay is 0; this is - // just for delayed animations - ArrayList tmpListeners = - (ArrayList) mListeners.clone(); - int numListeners = tmpListeners.size(); - for (int i = 0; i < numListeners; ++i) { - tmpListeners.get(i).onAnimationStart(this); - } - } - } - - /** - * Internal function called to process an animation frame on an animation that is currently - * sleeping through its startDelay phase. The return value indicates whether it - * should be woken up and put on the active animations queue. - * - * @param currentTime The current animation time, used to calculate whether the animation - * has exceeded its startDelay and should be started. - * @return True if the animation's startDelay has been exceeded and the animation - * should be added to the set of active animations. - */ - private boolean delayedAnimationFrame(long currentTime) { - if (!mStartedDelay) { - mStartedDelay = true; - mDelayStartTime = currentTime; - } else { - long deltaTime = currentTime - mDelayStartTime; - if (deltaTime > mStartDelay) { - // startDelay ended - start the anim and record the - // mStartTime appropriately - mStartTime = currentTime - (deltaTime - mStartDelay); - mPlayingState = RUNNING; - return true; - } - } - return false; - } - - /** - * This internal function processes a single animation frame for a given animation. The - * currentTime parameter is the timing pulse sent by the handler, used to calculate the - * elapsed duration, and therefore - * the elapsed fraction, of the animation. The return value indicates whether the animation - * should be ended (which happens when the elapsed time of the animation exceeds the - * animation's duration, including the repeatCount). - * - * @param currentTime The current time, as tracked by the static timing handler - * @return true if the animation's duration, including any repetitions due to - * repeatCount has been exceeded and the animation should be ended. - */ - boolean animationFrame(long currentTime) { - boolean done = false; - - if (mPlayingState == STOPPED) { - mPlayingState = RUNNING; - if (mSeekTime < 0) { - mStartTime = currentTime; - } else { - mStartTime = currentTime - mSeekTime; - // Now that we're playing, reset the seek time - mSeekTime = -1; - } - } - switch (mPlayingState) { - case RUNNING: - case SEEKED: - float fraction = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f; - if (fraction >= 1f) { - if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) { - // Time to repeat - if (mListeners != null) { - int numListeners = mListeners.size(); - for (int i = 0; i < numListeners; ++i) { - mListeners.get(i).onAnimationRepeat(this); - } - } - if (mRepeatMode == REVERSE) { - mPlayingBackwards = mPlayingBackwards ? false : true; - } - mCurrentIteration += (int)fraction; - fraction = fraction % 1f; - mStartTime += mDuration; - } else { - done = true; - fraction = Math.min(fraction, 1.0f); - } - } - if (mPlayingBackwards) { - fraction = 1f - fraction; - } - animateValue(fraction); - break; - } - - return done; - } - - /** - * Returns the current animation fraction, which is the elapsed/interpolated fraction used in - * the most recent frame update on the animation. - * - * @return Elapsed/interpolated fraction of the animation. - */ - public float getAnimatedFraction() { - return mCurrentFraction; - } - - /** - * This method is called with the elapsed fraction of the animation during every - * animation frame. This function turns the elapsed fraction into an interpolated fraction - * and then into an animated value (from the evaluator. The function is called mostly during - * animation updates, but it is also called when the end() - * function is called, to set the final value on the property. - * - *

Overrides of this method must call the superclass to perform the calculation - * of the animated value.

- * - * @param fraction The elapsed fraction of the animation. - */ - void animateValue(float fraction) { - fraction = mInterpolator.getInterpolation(fraction); - mCurrentFraction = fraction; - int numValues = mValues.length; - for (int i = 0; i < numValues; ++i) { - mValues[i].calculateValue(fraction); - } - if (mUpdateListeners != null) { - int numListeners = mUpdateListeners.size(); - for (int i = 0; i < numListeners; ++i) { - mUpdateListeners.get(i).onAnimationUpdate(this); - } - } - } - - @Override - public ValueAnimator clone() { - final ValueAnimator anim = (ValueAnimator) super.clone(); - if (mUpdateListeners != null) { - ArrayList oldListeners = mUpdateListeners; - anim.mUpdateListeners = new ArrayList(); - int numListeners = oldListeners.size(); - for (int i = 0; i < numListeners; ++i) { - anim.mUpdateListeners.add(oldListeners.get(i)); - } - } - anim.mSeekTime = -1; - anim.mPlayingBackwards = false; - anim.mCurrentIteration = 0; - anim.mInitialized = false; - anim.mPlayingState = STOPPED; - anim.mStartedDelay = false; - PropertyValuesHolder[] oldValues = mValues; - if (oldValues != null) { - int numValues = oldValues.length; - anim.mValues = new PropertyValuesHolder[numValues]; - anim.mValuesMap = new HashMap(numValues); - for (int i = 0; i < numValues; ++i) { - PropertyValuesHolder newValuesHolder = oldValues[i].clone(); - anim.mValues[i] = newValuesHolder; - anim.mValuesMap.put(newValuesHolder.getPropertyName(), newValuesHolder); - } - } - return anim; - } - - /** - * Implementors of this interface can add themselves as update listeners - * to an ValueAnimator instance to receive callbacks on every animation - * frame, after the current frame's values have been calculated for that - * ValueAnimator. - */ - public static interface AnimatorUpdateListener { - /** - *

Notifies the occurrence of another frame of the animation.

- * - * @param animation The animation which was repeated. - */ - void onAnimationUpdate(ValueAnimator animation); - - } - - /** - * Return the number of animations currently running. - * - * Used by StrictMode internally to annotate violations. Only - * called on the main thread. - * - * @hide - */ - public static int getCurrentAnimationsCount() { - return sAnimations.get().size(); - } - - /** - * Clear all animations on this thread, without canceling or ending them. - * This should be used with caution. - * - * @hide - */ - public static void clearAllAnimations() { - sAnimations.get().clear(); - sPendingAnimations.get().clear(); - sDelayedAnims.get().clear(); - } - - @Override - public String toString() { - String returnVal = "ValueAnimator@" + Integer.toHexString(hashCode()); - if (mValues != null) { - for (int i = 0; i < mValues.length; ++i) { - returnVal += "\n " + mValues[i].toString(); - } - } - return returnVal; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/NineViewGroup.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/NineViewGroup.java deleted file mode 100644 index 7b830b9c..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/NineViewGroup.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.actionbarsherlock.internal.nineoldandroids.view; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.ViewGroup; - -import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; - -public abstract class NineViewGroup extends ViewGroup { - private final AnimatorProxy mProxy; - - public NineViewGroup(Context context) { - super(context); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - public NineViewGroup(Context context, AttributeSet attrs) { - super(context, attrs); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - public NineViewGroup(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - - @Override - public void setVisibility(int visibility) { - if (mProxy != null) { - if (visibility == GONE) { - clearAnimation(); - } else if (visibility == VISIBLE) { - setAnimation(mProxy); - } - } - super.setVisibility(visibility); - } - - public float getAlpha() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getAlpha(); - } else { - return super.getAlpha(); - } - } - public void setAlpha(float alpha) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setAlpha(alpha); - } else { - super.setAlpha(alpha); - } - } - public float getTranslationX() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getTranslationX(); - } else { - return super.getTranslationX(); - } - } - public void setTranslationX(float translationX) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setTranslationX(translationX); - } else { - super.setTranslationX(translationX); - } - } - public float getTranslationY() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getTranslationY(); - } else { - return super.getTranslationY(); - } - } - public void setTranslationY(float translationY) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setTranslationY(translationY); - } else { - super.setTranslationY(translationY); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/animation/AnimatorProxy.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/animation/AnimatorProxy.java deleted file mode 100644 index 067d0494..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/view/animation/AnimatorProxy.java +++ /dev/null @@ -1,212 +0,0 @@ -package com.actionbarsherlock.internal.nineoldandroids.view.animation; - -import java.lang.ref.WeakReference; -import java.util.WeakHashMap; -import android.graphics.Matrix; -import android.graphics.RectF; -import android.os.Build; -import android.util.FloatMath; -import android.view.View; -import android.view.animation.Animation; -import android.view.animation.Transformation; - -public final class AnimatorProxy extends Animation { - public static final boolean NEEDS_PROXY = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB; - - private static final WeakHashMap PROXIES = - new WeakHashMap(); - - public static AnimatorProxy wrap(View view) { - AnimatorProxy proxy = PROXIES.get(view); - if (proxy == null) { - proxy = new AnimatorProxy(view); - PROXIES.put(view, proxy); - } - return proxy; - } - - private final WeakReference mView; - - private float mAlpha = 1; - private float mScaleX = 1; - private float mScaleY = 1; - private float mTranslationX; - private float mTranslationY; - - private final RectF mBefore = new RectF(); - private final RectF mAfter = new RectF(); - private final Matrix mTempMatrix = new Matrix(); - - private AnimatorProxy(View view) { - setDuration(0); //perform transformation immediately - setFillAfter(true); //persist transformation beyond duration - view.setAnimation(this); - mView = new WeakReference(view); - } - - public float getAlpha() { - return mAlpha; - } - public void setAlpha(float alpha) { - if (mAlpha != alpha) { - mAlpha = alpha; - View view = mView.get(); - if (view != null) { - view.invalidate(); - } - } - } - public float getScaleX() { - return mScaleX; - } - public void setScaleX(float scaleX) { - if (mScaleX != scaleX) { - prepareForUpdate(); - mScaleX = scaleX; - invalidateAfterUpdate(); - } - } - public float getScaleY() { - return mScaleY; - } - public void setScaleY(float scaleY) { - if (mScaleY != scaleY) { - prepareForUpdate(); - mScaleY = scaleY; - invalidateAfterUpdate(); - } - } - public int getScrollX() { - View view = mView.get(); - if (view == null) { - return 0; - } - return view.getScrollX(); - } - public void setScrollX(int value) { - View view = mView.get(); - if (view != null) { - view.scrollTo(value, view.getScrollY()); - } - } - public int getScrollY() { - View view = mView.get(); - if (view == null) { - return 0; - } - return view.getScrollY(); - } - public void setScrollY(int value) { - View view = mView.get(); - if (view != null) { - view.scrollTo(view.getScrollY(), value); - } - } - - public float getTranslationX() { - return mTranslationX; - } - public void setTranslationX(float translationX) { - if (mTranslationX != translationX) { - prepareForUpdate(); - mTranslationX = translationX; - invalidateAfterUpdate(); - } - } - public float getTranslationY() { - return mTranslationY; - } - public void setTranslationY(float translationY) { - if (mTranslationY != translationY) { - prepareForUpdate(); - mTranslationY = translationY; - invalidateAfterUpdate(); - } - } - - private void prepareForUpdate() { - View view = mView.get(); - if (view != null) { - computeRect(mBefore, view); - } - } - private void invalidateAfterUpdate() { - View view = mView.get(); - if (view == null) { - return; - } - View parent = (View)view.getParent(); - if (parent == null) { - return; - } - - view.setAnimation(this); - - final RectF after = mAfter; - computeRect(after, view); - after.union(mBefore); - - parent.invalidate( - (int) FloatMath.floor(after.left), - (int) FloatMath.floor(after.top), - (int) FloatMath.ceil(after.right), - (int) FloatMath.ceil(after.bottom)); - } - - private void computeRect(final RectF r, View view) { - // compute current rectangle according to matrix transformation - final float w = view.getWidth(); - final float h = view.getHeight(); - - // use a rectangle at 0,0 to make sure we don't run into issues with scaling - r.set(0, 0, w, h); - - final Matrix m = mTempMatrix; - m.reset(); - transformMatrix(m, view); - mTempMatrix.mapRect(r); - - r.offset(view.getLeft(), view.getTop()); - - // Straighten coords if rotations flipped them - if (r.right < r.left) { - final float f = r.right; - r.right = r.left; - r.left = f; - } - if (r.bottom < r.top) { - final float f = r.top; - r.top = r.bottom; - r.bottom = f; - } - } - - private void transformMatrix(Matrix m, View view) { - final float w = view.getWidth(); - final float h = view.getHeight(); - - final float sX = mScaleX; - final float sY = mScaleY; - if ((sX != 1.0f) || (sY != 1.0f)) { - final float deltaSX = ((sX * w) - w) / 2f; - final float deltaSY = ((sY * h) - h) / 2f; - m.postScale(sX, sY); - m.postTranslate(-deltaSX, -deltaSY); - } - m.postTranslate(mTranslationX, mTranslationY); - } - - @Override - protected void applyTransformation(float interpolatedTime, Transformation t) { - View view = mView.get(); - if (view != null) { - t.setAlpha(mAlpha); - transformMatrix(t.getMatrix(), view); - } - } - - @Override - public void reset() { - /* Do nothing. */ - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineFrameLayout.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineFrameLayout.java deleted file mode 100644 index 953e3e84..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineFrameLayout.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.actionbarsherlock.internal.nineoldandroids.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.FrameLayout; - -import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; - -public class NineFrameLayout extends FrameLayout { - private final AnimatorProxy mProxy; - - public NineFrameLayout(Context context, AttributeSet attrs) { - super(context, attrs); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - - @Override - public void setVisibility(int visibility) { - if (mProxy != null) { - if (visibility == GONE) { - clearAnimation(); - } else if (visibility == VISIBLE) { - setAnimation(mProxy); - } - } - super.setVisibility(visibility); - } - - public float getAlpha() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getAlpha(); - } else { - return super.getAlpha(); - } - } - public void setAlpha(float alpha) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setAlpha(alpha); - } else { - super.setAlpha(alpha); - } - } - public float getTranslationY() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getTranslationY(); - } else { - return super.getTranslationY(); - } - } - public void setTranslationY(float translationY) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setTranslationY(translationY); - } else { - super.setTranslationY(translationY); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineHorizontalScrollView.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineHorizontalScrollView.java deleted file mode 100644 index 129b5aaa..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineHorizontalScrollView.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.actionbarsherlock.internal.nineoldandroids.widget; - -import android.content.Context; -import android.widget.HorizontalScrollView; -import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; - -public class NineHorizontalScrollView extends HorizontalScrollView { - private final AnimatorProxy mProxy; - - public NineHorizontalScrollView(Context context) { - super(context); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - - @Override - public void setVisibility(int visibility) { - if (mProxy != null) { - if (visibility == GONE) { - clearAnimation(); - } else if (visibility == VISIBLE) { - setAnimation(mProxy); - } - } - super.setVisibility(visibility); - } - - public float getAlpha() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getAlpha(); - } else { - return super.getAlpha(); - } - } - public void setAlpha(float alpha) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setAlpha(alpha); - } else { - super.setAlpha(alpha); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineLinearLayout.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineLinearLayout.java deleted file mode 100644 index 1f381013..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/widget/NineLinearLayout.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.actionbarsherlock.internal.nineoldandroids.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.LinearLayout; - -import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; - -public class NineLinearLayout extends LinearLayout { - private final AnimatorProxy mProxy; - - public NineLinearLayout(Context context, AttributeSet attrs) { - super(context, attrs); - mProxy = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(this) : null; - } - - @Override - public void setVisibility(int visibility) { - if (mProxy != null) { - if (visibility == GONE) { - clearAnimation(); - } else if (visibility == VISIBLE) { - setAnimation(mProxy); - } - } - super.setVisibility(visibility); - } - - public float getAlpha() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getAlpha(); - } else { - return super.getAlpha(); - } - } - public void setAlpha(float alpha) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setAlpha(alpha); - } else { - super.setAlpha(alpha); - } - } - public float getTranslationX() { - if (AnimatorProxy.NEEDS_PROXY) { - return mProxy.getTranslationX(); - } else { - return super.getTranslationX(); - } - } - public void setTranslationX(float translationX) { - if (AnimatorProxy.NEEDS_PROXY) { - mProxy.setTranslationX(translationX); - } else { - super.setTranslationX(translationX); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/ActionProviderWrapper.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/ActionProviderWrapper.java deleted file mode 100644 index b136d50f..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/ActionProviderWrapper.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.actionbarsherlock.internal.view; - -import com.actionbarsherlock.internal.view.menu.SubMenuWrapper; -import com.actionbarsherlock.view.ActionProvider; -import android.view.View; - -public class ActionProviderWrapper extends android.view.ActionProvider { - private final ActionProvider mProvider; - - - public ActionProviderWrapper(ActionProvider provider) { - super(null/*TODO*/); //XXX this *should* be unused - mProvider = provider; - } - - - public ActionProvider unwrap() { - return mProvider; - } - - @Override - public View onCreateActionView() { - return mProvider.onCreateActionView(); - } - - @Override - public boolean hasSubMenu() { - return mProvider.hasSubMenu(); - } - - @Override - public boolean onPerformDefaultAction() { - return mProvider.onPerformDefaultAction(); - } - - @Override - public void onPrepareSubMenu(android.view.SubMenu subMenu) { - mProvider.onPrepareSubMenu(new SubMenuWrapper(subMenu)); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/StandaloneActionMode.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/StandaloneActionMode.java deleted file mode 100644 index 0a87bd3f..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/StandaloneActionMode.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.actionbarsherlock.internal.view; - -import android.content.Context; -import android.view.View; -import android.view.accessibility.AccessibilityEvent; - -import java.lang.ref.WeakReference; - -import com.actionbarsherlock.internal.view.menu.MenuBuilder; -import com.actionbarsherlock.internal.view.menu.MenuPopupHelper; -import com.actionbarsherlock.internal.view.menu.SubMenuBuilder; -import com.actionbarsherlock.internal.widget.ActionBarContextView; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -public class StandaloneActionMode extends ActionMode implements MenuBuilder.Callback { - private Context mContext; - private ActionBarContextView mContextView; - private ActionMode.Callback mCallback; - private WeakReference mCustomView; - private boolean mFinished; - private boolean mFocusable; - - private MenuBuilder mMenu; - - public StandaloneActionMode(Context context, ActionBarContextView view, - ActionMode.Callback callback, boolean isFocusable) { - mContext = context; - mContextView = view; - mCallback = callback; - - mMenu = new MenuBuilder(context).setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - mMenu.setCallback(this); - mFocusable = isFocusable; - } - - @Override - public void setTitle(CharSequence title) { - mContextView.setTitle(title); - } - - @Override - public void setSubtitle(CharSequence subtitle) { - mContextView.setSubtitle(subtitle); - } - - @Override - public void setTitle(int resId) { - setTitle(mContext.getString(resId)); - } - - @Override - public void setSubtitle(int resId) { - setSubtitle(mContext.getString(resId)); - } - - @Override - public void setCustomView(View view) { - mContextView.setCustomView(view); - mCustomView = view != null ? new WeakReference(view) : null; - } - - @Override - public void invalidate() { - mCallback.onPrepareActionMode(this, mMenu); - } - - @Override - public void finish() { - if (mFinished) { - return; - } - mFinished = true; - - mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); - mCallback.onDestroyActionMode(this); - } - - @Override - public Menu getMenu() { - return mMenu; - } - - @Override - public CharSequence getTitle() { - return mContextView.getTitle(); - } - - @Override - public CharSequence getSubtitle() { - return mContextView.getSubtitle(); - } - - @Override - public View getCustomView() { - return mCustomView != null ? mCustomView.get() : null; - } - - @Override - public MenuInflater getMenuInflater() { - return new MenuInflater(mContext); - } - - public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { - return mCallback.onActionItemClicked(this, item); - } - - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - } - - public boolean onSubMenuSelected(SubMenuBuilder subMenu) { - if (!subMenu.hasVisibleItems()) { - return true; - } - - new MenuPopupHelper(mContext, subMenu).show(); - return true; - } - - public void onCloseSubMenu(SubMenuBuilder menu) { - } - - public void onMenuModeChange(MenuBuilder menu) { - invalidate(); - mContextView.showOverflowMenu(); - } - - public boolean isUiFocusable() { - return mFocusable; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/View_HasStateListenerSupport.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/View_HasStateListenerSupport.java deleted file mode 100644 index 7d45e81b..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/View_HasStateListenerSupport.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.actionbarsherlock.internal.view; - -public interface View_HasStateListenerSupport { - void addOnAttachStateChangeListener(View_OnAttachStateChangeListener listener); - void removeOnAttachStateChangeListener(View_OnAttachStateChangeListener listener); -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/View_OnAttachStateChangeListener.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/View_OnAttachStateChangeListener.java deleted file mode 100644 index 3869d329..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/View_OnAttachStateChangeListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.actionbarsherlock.internal.view; - -import android.view.View; - -public interface View_OnAttachStateChangeListener { - void onViewAttachedToWindow(View v); - void onViewDetachedFromWindow(View v); -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenu.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenu.java deleted file mode 100644 index 0354ad1a..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenu.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import java.util.ArrayList; -import java.util.List; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.view.KeyEvent; - -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -/** - * @hide - */ -public class ActionMenu implements Menu { - private Context mContext; - - private boolean mIsQwerty; - - private ArrayList mItems; - - public ActionMenu(Context context) { - mContext = context; - mItems = new ArrayList(); - } - - public Context getContext() { - return mContext; - } - - public MenuItem add(CharSequence title) { - return add(0, 0, 0, title); - } - - public MenuItem add(int titleRes) { - return add(0, 0, 0, titleRes); - } - - public MenuItem add(int groupId, int itemId, int order, int titleRes) { - return add(groupId, itemId, order, mContext.getResources().getString(titleRes)); - } - - public MenuItem add(int groupId, int itemId, int order, CharSequence title) { - ActionMenuItem item = new ActionMenuItem(getContext(), - groupId, itemId, 0, order, title); - mItems.add(order, item); - return item; - } - - public int addIntentOptions(int groupId, int itemId, int order, - ComponentName caller, Intent[] specifics, Intent intent, int flags, - MenuItem[] outSpecificItems) { - PackageManager pm = mContext.getPackageManager(); - final List lri = - pm.queryIntentActivityOptions(caller, specifics, intent, 0); - final int N = lri != null ? lri.size() : 0; - - if ((flags & FLAG_APPEND_TO_GROUP) == 0) { - removeGroup(groupId); - } - - for (int i=0; i= 0) { - outSpecificItems[ri.specificIndex] = item; - } - } - - return N; - } - - public SubMenu addSubMenu(CharSequence title) { - // TODO Implement submenus - return null; - } - - public SubMenu addSubMenu(int titleRes) { - // TODO Implement submenus - return null; - } - - public SubMenu addSubMenu(int groupId, int itemId, int order, - CharSequence title) { - // TODO Implement submenus - return null; - } - - public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) { - // TODO Implement submenus - return null; - } - - public void clear() { - mItems.clear(); - } - - public void close() { - } - - private int findItemIndex(int id) { - final ArrayList items = mItems; - final int itemCount = items.size(); - for (int i = 0; i < itemCount; i++) { - if (items.get(i).getItemId() == id) { - return i; - } - } - - return -1; - } - - public MenuItem findItem(int id) { - return mItems.get(findItemIndex(id)); - } - - public MenuItem getItem(int index) { - return mItems.get(index); - } - - public boolean hasVisibleItems() { - final ArrayList items = mItems; - final int itemCount = items.size(); - - for (int i = 0; i < itemCount; i++) { - if (items.get(i).isVisible()) { - return true; - } - } - - return false; - } - - private ActionMenuItem findItemWithShortcut(int keyCode, KeyEvent event) { - // TODO Make this smarter. - final boolean qwerty = mIsQwerty; - final ArrayList items = mItems; - final int itemCount = items.size(); - - for (int i = 0; i < itemCount; i++) { - ActionMenuItem item = items.get(i); - final char shortcut = qwerty ? item.getAlphabeticShortcut() : - item.getNumericShortcut(); - if (keyCode == shortcut) { - return item; - } - } - return null; - } - - public boolean isShortcutKey(int keyCode, KeyEvent event) { - return findItemWithShortcut(keyCode, event) != null; - } - - public boolean performIdentifierAction(int id, int flags) { - final int index = findItemIndex(id); - if (index < 0) { - return false; - } - - return mItems.get(index).invoke(); - } - - public boolean performShortcut(int keyCode, KeyEvent event, int flags) { - ActionMenuItem item = findItemWithShortcut(keyCode, event); - if (item == null) { - return false; - } - - return item.invoke(); - } - - public void removeGroup(int groupId) { - final ArrayList items = mItems; - int itemCount = items.size(); - int i = 0; - while (i < itemCount) { - if (items.get(i).getGroupId() == groupId) { - items.remove(i); - itemCount--; - } else { - i++; - } - } - } - - public void removeItem(int id) { - mItems.remove(findItemIndex(id)); - } - - public void setGroupCheckable(int group, boolean checkable, - boolean exclusive) { - final ArrayList items = mItems; - final int itemCount = items.size(); - - for (int i = 0; i < itemCount; i++) { - ActionMenuItem item = items.get(i); - if (item.getGroupId() == group) { - item.setCheckable(checkable); - item.setExclusiveCheckable(exclusive); - } - } - } - - public void setGroupEnabled(int group, boolean enabled) { - final ArrayList items = mItems; - final int itemCount = items.size(); - - for (int i = 0; i < itemCount; i++) { - ActionMenuItem item = items.get(i); - if (item.getGroupId() == group) { - item.setEnabled(enabled); - } - } - } - - public void setGroupVisible(int group, boolean visible) { - final ArrayList items = mItems; - final int itemCount = items.size(); - - for (int i = 0; i < itemCount; i++) { - ActionMenuItem item = items.get(i); - if (item.getGroupId() == group) { - item.setVisible(visible); - } - } - } - - public void setQwertyMode(boolean isQwerty) { - mIsQwerty = isQwerty; - } - - public int size() { - return mItems.size(); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItem.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItem.java deleted file mode 100644 index 510b9748..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItem.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import android.content.Context; -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.View; - -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -/** - * @hide - */ -public class ActionMenuItem implements MenuItem { - private final int mId; - private final int mGroup; - //UNUSED private final int mCategoryOrder; - private final int mOrdering; - - private CharSequence mTitle; - private CharSequence mTitleCondensed; - private Intent mIntent; - private char mShortcutNumericChar; - private char mShortcutAlphabeticChar; - - private Drawable mIconDrawable; - //UNUSED private int mIconResId = NO_ICON; - - private Context mContext; - - private MenuItem.OnMenuItemClickListener mClickListener; - - //UNUSED private static final int NO_ICON = 0; - - private int mFlags = ENABLED; - private static final int CHECKABLE = 0x00000001; - private static final int CHECKED = 0x00000002; - private static final int EXCLUSIVE = 0x00000004; - private static final int HIDDEN = 0x00000008; - private static final int ENABLED = 0x00000010; - - public ActionMenuItem(Context context, int group, int id, int categoryOrder, int ordering, - CharSequence title) { - mContext = context; - mId = id; - mGroup = group; - //UNUSED mCategoryOrder = categoryOrder; - mOrdering = ordering; - mTitle = title; - } - - public char getAlphabeticShortcut() { - return mShortcutAlphabeticChar; - } - - public int getGroupId() { - return mGroup; - } - - public Drawable getIcon() { - return mIconDrawable; - } - - public Intent getIntent() { - return mIntent; - } - - public int getItemId() { - return mId; - } - - public ContextMenuInfo getMenuInfo() { - return null; - } - - public char getNumericShortcut() { - return mShortcutNumericChar; - } - - public int getOrder() { - return mOrdering; - } - - public SubMenu getSubMenu() { - return null; - } - - public CharSequence getTitle() { - return mTitle; - } - - public CharSequence getTitleCondensed() { - return mTitleCondensed; - } - - public boolean hasSubMenu() { - return false; - } - - public boolean isCheckable() { - return (mFlags & CHECKABLE) != 0; - } - - public boolean isChecked() { - return (mFlags & CHECKED) != 0; - } - - public boolean isEnabled() { - return (mFlags & ENABLED) != 0; - } - - public boolean isVisible() { - return (mFlags & HIDDEN) == 0; - } - - public MenuItem setAlphabeticShortcut(char alphaChar) { - mShortcutAlphabeticChar = alphaChar; - return this; - } - - public MenuItem setCheckable(boolean checkable) { - mFlags = (mFlags & ~CHECKABLE) | (checkable ? CHECKABLE : 0); - return this; - } - - public ActionMenuItem setExclusiveCheckable(boolean exclusive) { - mFlags = (mFlags & ~EXCLUSIVE) | (exclusive ? EXCLUSIVE : 0); - return this; - } - - public MenuItem setChecked(boolean checked) { - mFlags = (mFlags & ~CHECKED) | (checked ? CHECKED : 0); - return this; - } - - public MenuItem setEnabled(boolean enabled) { - mFlags = (mFlags & ~ENABLED) | (enabled ? ENABLED : 0); - return this; - } - - public MenuItem setIcon(Drawable icon) { - mIconDrawable = icon; - //UNUSED mIconResId = NO_ICON; - return this; - } - - public MenuItem setIcon(int iconRes) { - //UNUSED mIconResId = iconRes; - mIconDrawable = mContext.getResources().getDrawable(iconRes); - return this; - } - - public MenuItem setIntent(Intent intent) { - mIntent = intent; - return this; - } - - public MenuItem setNumericShortcut(char numericChar) { - mShortcutNumericChar = numericChar; - return this; - } - - public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener menuItemClickListener) { - mClickListener = menuItemClickListener; - return this; - } - - public MenuItem setShortcut(char numericChar, char alphaChar) { - mShortcutNumericChar = numericChar; - mShortcutAlphabeticChar = alphaChar; - return this; - } - - public MenuItem setTitle(CharSequence title) { - mTitle = title; - return this; - } - - public MenuItem setTitle(int title) { - mTitle = mContext.getResources().getString(title); - return this; - } - - public MenuItem setTitleCondensed(CharSequence title) { - mTitleCondensed = title; - return this; - } - - public MenuItem setVisible(boolean visible) { - mFlags = (mFlags & HIDDEN) | (visible ? 0 : HIDDEN); - return this; - } - - public boolean invoke() { - if (mClickListener != null && mClickListener.onMenuItemClick(this)) { - return true; - } - - if (mIntent != null) { - mContext.startActivity(mIntent); - return true; - } - - return false; - } - - public void setShowAsAction(int show) { - // Do nothing. ActionMenuItems always show as action buttons. - } - - public MenuItem setActionView(View actionView) { - throw new UnsupportedOperationException(); - } - - public View getActionView() { - return null; - } - - @Override - public MenuItem setActionView(int resId) { - throw new UnsupportedOperationException(); - } - - @Override - public ActionProvider getActionProvider() { - return null; - } - - @Override - public MenuItem setActionProvider(ActionProvider actionProvider) { - throw new UnsupportedOperationException(); - } - - @Override - public MenuItem setShowAsActionFlags(int actionEnum) { - setShowAsAction(actionEnum); - return this; - } - - @Override - public boolean expandActionView() { - return false; - } - - @Override - public boolean collapseActionView() { - return false; - } - - @Override - public boolean isActionViewExpanded() { - return false; - } - - @Override - public MenuItem setOnActionExpandListener(OnActionExpandListener listener) { - // No need to save the listener; ActionMenuItem does not support collapsing items. - return this; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItemView.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItemView.java deleted file mode 100644 index dcb50f36..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuItemView.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import java.util.HashSet; -import java.util.Set; -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.View; -import android.view.accessibility.AccessibilityEvent; -import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.Toast; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.view.View_HasStateListenerSupport; -import com.actionbarsherlock.internal.view.View_OnAttachStateChangeListener; -import com.actionbarsherlock.internal.widget.CapitalizingButton; - -import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; - -/** - * @hide - */ -public class ActionMenuItemView extends LinearLayout - implements MenuView.ItemView, View.OnClickListener, View.OnLongClickListener, - ActionMenuView.ActionMenuChildView, View_HasStateListenerSupport { - //UNUSED private static final String TAG = "ActionMenuItemView"; - - private MenuItemImpl mItemData; - private CharSequence mTitle; - private MenuBuilder.ItemInvoker mItemInvoker; - - private ImageButton mImageButton; - private CapitalizingButton mTextButton; - private boolean mAllowTextWithIcon; - private boolean mExpandedFormat; - private int mMinWidth; - - private final Set mListeners = new HashSet(); - - public ActionMenuItemView(Context context) { - this(context, null); - } - - public ActionMenuItemView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) { - //TODO super(context, attrs, defStyle); - super(context, attrs); - mAllowTextWithIcon = getResources_getBoolean(context, - R.bool.abs__config_allowActionMenuItemTextWithIcon); - TypedArray a = context.obtainStyledAttributes(attrs, - R.styleable.SherlockActionMenuItemView, 0, 0); - mMinWidth = a.getDimensionPixelSize( - R.styleable.SherlockActionMenuItemView_android_minWidth, 0); - a.recycle(); - } - - @Override - public void addOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) { - mListeners.add(listener); - } - - @Override - public void removeOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) { - mListeners.remove(listener); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - for (View_OnAttachStateChangeListener listener : mListeners) { - listener.onViewAttachedToWindow(this); - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - for (View_OnAttachStateChangeListener listener : mListeners) { - listener.onViewDetachedFromWindow(this); - } - } - - @Override - public void onFinishInflate() { - - mImageButton = (ImageButton) findViewById(R.id.abs__imageButton); - mTextButton = (CapitalizingButton) findViewById(R.id.abs__textButton); - mImageButton.setOnClickListener(this); - mTextButton.setOnClickListener(this); - mImageButton.setOnLongClickListener(this); - setOnClickListener(this); - setOnLongClickListener(this); - } - - public MenuItemImpl getItemData() { - return mItemData; - } - - public void initialize(MenuItemImpl itemData, int menuType) { - mItemData = itemData; - - setIcon(itemData.getIcon()); - setTitle(itemData.getTitleForItemView(this)); // Title only takes effect if there is no icon - setId(itemData.getItemId()); - - setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE); - setEnabled(itemData.isEnabled()); - } - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - mImageButton.setEnabled(enabled); - mTextButton.setEnabled(enabled); - } - - public void onClick(View v) { - if (mItemInvoker != null) { - mItemInvoker.invokeItem(mItemData); - } - } - - public void setItemInvoker(MenuBuilder.ItemInvoker invoker) { - mItemInvoker = invoker; - } - - public boolean prefersCondensedTitle() { - return true; - } - - public void setCheckable(boolean checkable) { - // TODO Support checkable action items - } - - public void setChecked(boolean checked) { - // TODO Support checkable action items - } - - public void setExpandedFormat(boolean expandedFormat) { - if (mExpandedFormat != expandedFormat) { - mExpandedFormat = expandedFormat; - if (mItemData != null) { - mItemData.actionFormatChanged(); - } - } - } - - private void updateTextButtonVisibility() { - boolean visible = !TextUtils.isEmpty(mTextButton.getText()); - visible &= mImageButton.getDrawable() == null || - (mItemData.showsTextAsAction() && (mAllowTextWithIcon || mExpandedFormat)); - - mTextButton.setVisibility(visible ? VISIBLE : GONE); - } - - public void setIcon(Drawable icon) { - mImageButton.setImageDrawable(icon); - if (icon != null) { - mImageButton.setVisibility(VISIBLE); - } else { - mImageButton.setVisibility(GONE); - } - - updateTextButtonVisibility(); - } - - public boolean hasText() { - return mTextButton.getVisibility() != GONE; - } - - public void setShortcut(boolean showShortcut, char shortcutKey) { - // Action buttons don't show text for shortcut keys. - } - - public void setTitle(CharSequence title) { - mTitle = title; - - mTextButton.setTextCompat(mTitle); - - setContentDescription(mTitle); - updateTextButtonVisibility(); - } - - @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - onPopulateAccessibilityEvent(event); - return true; - } - - @Override - public void onPopulateAccessibilityEvent(AccessibilityEvent event) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - super.onPopulateAccessibilityEvent(event); - } - final CharSequence cdesc = getContentDescription(); - if (!TextUtils.isEmpty(cdesc)) { - event.getText().add(cdesc); - } - } - - @Override - public boolean dispatchHoverEvent(MotionEvent event) { - // Don't allow children to hover; we want this to be treated as a single component. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - return onHoverEvent(event); - } - return false; - } - - public boolean showsIcon() { - return true; - } - - public boolean needsDividerBefore() { - return hasText() && mItemData.getIcon() == null; - } - - public boolean needsDividerAfter() { - return hasText(); - } - - @Override - public boolean onLongClick(View v) { - if (hasText()) { - // Don't show the cheat sheet for items that already show text. - return false; - } - - final int[] screenPos = new int[2]; - final Rect displayFrame = new Rect(); - getLocationOnScreen(screenPos); - getWindowVisibleDisplayFrame(displayFrame); - - final Context context = getContext(); - final int width = getWidth(); - final int height = getHeight(); - final int midy = screenPos[1] + height / 2; - final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; - - Toast cheatSheet = Toast.makeText(context, mItemData.getTitle(), Toast.LENGTH_SHORT); - if (midy < displayFrame.height()) { - // Show along the top; follow action buttons - cheatSheet.setGravity(Gravity.TOP | Gravity.RIGHT, - screenWidth - screenPos[0] - width / 2, height); - } else { - // Show along the bottom center - cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height); - } - cheatSheet.show(); - return true; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - final int widthMode = MeasureSpec.getMode(widthMeasureSpec); - final int specSize = MeasureSpec.getSize(widthMeasureSpec); - final int oldMeasuredWidth = getMeasuredWidth(); - final int targetWidth = widthMode == MeasureSpec.AT_MOST ? Math.min(specSize, mMinWidth) - : mMinWidth; - - if (widthMode != MeasureSpec.EXACTLY && mMinWidth > 0 && oldMeasuredWidth < targetWidth) { - // Remeasure at exactly the minimum width. - super.onMeasure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY), - heightMeasureSpec); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java deleted file mode 100644 index 876a22c5..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java +++ /dev/null @@ -1,714 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getInteger; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; -import android.content.Context; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.SparseBooleanArray; -import android.view.SoundEffectConstants; -import android.view.View; -import android.view.View.MeasureSpec; -import android.view.ViewConfiguration; -import android.view.ViewGroup; -import android.widget.ImageButton; -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.view.View_HasStateListenerSupport; -import com.actionbarsherlock.internal.view.View_OnAttachStateChangeListener; -import com.actionbarsherlock.internal.view.menu.ActionMenuView.ActionMenuChildView; -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.view.MenuItem; - -/** - * MenuPresenter for building action menus as seen in the action bar and action modes. - */ -public class ActionMenuPresenter extends BaseMenuPresenter - implements ActionProvider.SubUiVisibilityListener { - //UNUSED private static final String TAG = "ActionMenuPresenter"; - - private View mOverflowButton; - private boolean mReserveOverflow; - private boolean mReserveOverflowSet; - private int mWidthLimit; - private int mActionItemWidthLimit; - private int mMaxItems; - private boolean mMaxItemsSet; - private boolean mStrictWidthLimit; - private boolean mWidthLimitSet; - private boolean mExpandedActionViewsExclusive; - - private int mMinCellSize; - - // Group IDs that have been added as actions - used temporarily, allocated here for reuse. - private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray(); - - private View mScrapActionButtonView; - - private OverflowPopup mOverflowPopup; - private ActionButtonSubmenu mActionButtonPopup; - - private OpenOverflowRunnable mPostedOpenRunnable; - - final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback(); - int mOpenSubMenuId; - - public ActionMenuPresenter(Context context) { - super(context, R.layout.abs__action_menu_layout, - R.layout.abs__action_menu_item_layout); - } - - @Override - public void initForMenu(Context context, MenuBuilder menu) { - super.initForMenu(context, menu); - - final Resources res = context.getResources(); - - if (!mReserveOverflowSet) { - mReserveOverflow = reserveOverflow(mContext); - } - - if (!mWidthLimitSet) { - mWidthLimit = res.getDisplayMetrics().widthPixels / 2; - } - - // Measure for initial configuration - if (!mMaxItemsSet) { - mMaxItems = getResources_getInteger(context, R.integer.abs__max_action_buttons); - } - - int width = mWidthLimit; - if (mReserveOverflow) { - if (mOverflowButton == null) { - mOverflowButton = new OverflowMenuButton(mSystemContext); - final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - mOverflowButton.measure(spec, spec); - } - width -= mOverflowButton.getMeasuredWidth(); - } else { - mOverflowButton = null; - } - - mActionItemWidthLimit = width; - - mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density); - - // Drop a scrap view as it may no longer reflect the proper context/config. - mScrapActionButtonView = null; - } - - public static boolean reserveOverflow(Context context) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB); - } else { - return !HasPermanentMenuKey.get(context); - } - } - - private static class HasPermanentMenuKey { - public static boolean get(Context context) { - return ViewConfiguration.get(context).hasPermanentMenuKey(); - } - } - - public void onConfigurationChanged(Configuration newConfig) { - if (!mMaxItemsSet) { - mMaxItems = getResources_getInteger(mContext, - R.integer.abs__max_action_buttons); - if (mMenu != null) { - mMenu.onItemsChanged(true); - } - } - } - - public void setWidthLimit(int width, boolean strict) { - mWidthLimit = width; - mStrictWidthLimit = strict; - mWidthLimitSet = true; - } - - public void setReserveOverflow(boolean reserveOverflow) { - mReserveOverflow = reserveOverflow; - mReserveOverflowSet = true; - } - - public void setItemLimit(int itemCount) { - mMaxItems = itemCount; - mMaxItemsSet = true; - } - - public void setExpandedActionViewsExclusive(boolean isExclusive) { - mExpandedActionViewsExclusive = isExclusive; - } - - @Override - public MenuView getMenuView(ViewGroup root) { - MenuView result = super.getMenuView(root); - ((ActionMenuView) result).setPresenter(this); - return result; - } - - @Override - public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) { - View actionView = item.getActionView(); - if (actionView == null || item.hasCollapsibleActionView()) { - if (!(convertView instanceof ActionMenuItemView)) { - convertView = null; - } - actionView = super.getItemView(item, convertView, parent); - } - actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE); - - final ActionMenuView menuParent = (ActionMenuView) parent; - final ViewGroup.LayoutParams lp = actionView.getLayoutParams(); - if (!menuParent.checkLayoutParams(lp)) { - actionView.setLayoutParams(menuParent.generateLayoutParams(lp)); - } - return actionView; - } - - @Override - public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) { - itemView.initialize(item, 0); - - final ActionMenuView menuView = (ActionMenuView) mMenuView; - ActionMenuItemView actionItemView = (ActionMenuItemView) itemView; - actionItemView.setItemInvoker(menuView); - } - - @Override - public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) { - return item.isActionButton(); - } - - @Override - public void updateMenuView(boolean cleared) { - super.updateMenuView(cleared); - - if (mMenu != null) { - final ArrayList actionItems = mMenu.getActionItems(); - final int count = actionItems.size(); - for (int i = 0; i < count; i++) { - final ActionProvider provider = actionItems.get(i).getActionProvider(); - if (provider != null) { - provider.setSubUiVisibilityListener(this); - } - } - } - - final ArrayList nonActionItems = mMenu != null ? - mMenu.getNonActionItems() : null; - - boolean hasOverflow = false; - if (mReserveOverflow && nonActionItems != null) { - final int count = nonActionItems.size(); - if (count == 1) { - hasOverflow = !nonActionItems.get(0).isActionViewExpanded(); - } else { - hasOverflow = count > 0; - } - } - - if (hasOverflow) { - if (mOverflowButton == null) { - mOverflowButton = new OverflowMenuButton(mSystemContext); - } - ViewGroup parent = (ViewGroup) mOverflowButton.getParent(); - if (parent != mMenuView) { - if (parent != null) { - parent.removeView(mOverflowButton); - } - ActionMenuView menuView = (ActionMenuView) mMenuView; - menuView.addView(mOverflowButton, menuView.generateOverflowButtonLayoutParams()); - } - } else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) { - ((ViewGroup) mMenuView).removeView(mOverflowButton); - } - - ((ActionMenuView) mMenuView).setOverflowReserved(mReserveOverflow); - } - - @Override - public boolean filterLeftoverView(ViewGroup parent, int childIndex) { - if (parent.getChildAt(childIndex) == mOverflowButton) return false; - return super.filterLeftoverView(parent, childIndex); - } - - public boolean onSubMenuSelected(SubMenuBuilder subMenu) { - if (!subMenu.hasVisibleItems()) return false; - - SubMenuBuilder topSubMenu = subMenu; - while (topSubMenu.getParentMenu() != mMenu) { - topSubMenu = (SubMenuBuilder) topSubMenu.getParentMenu(); - } - View anchor = findViewForItem(topSubMenu.getItem()); - if (anchor == null) { - if (mOverflowButton == null) return false; - anchor = mOverflowButton; - } - - mOpenSubMenuId = subMenu.getItem().getItemId(); - mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu); - mActionButtonPopup.setAnchorView(anchor); - mActionButtonPopup.show(); - super.onSubMenuSelected(subMenu); - return true; - } - - private View findViewForItem(MenuItem item) { - final ViewGroup parent = (ViewGroup) mMenuView; - if (parent == null) return null; - - final int count = parent.getChildCount(); - for (int i = 0; i < count; i++) { - final View child = parent.getChildAt(i); - if (child instanceof MenuView.ItemView && - ((MenuView.ItemView) child).getItemData() == item) { - return child; - } - } - return null; - } - - /** - * Display the overflow menu if one is present. - * @return true if the overflow menu was shown, false otherwise. - */ - public boolean showOverflowMenu() { - if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null && - mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) { - OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true); - mPostedOpenRunnable = new OpenOverflowRunnable(popup); - // Post this for later; we might still need a layout for the anchor to be right. - ((View) mMenuView).post(mPostedOpenRunnable); - - // ActionMenuPresenter uses null as a callback argument here - // to indicate overflow is opening. - super.onSubMenuSelected(null); - - return true; - } - return false; - } - - /** - * Hide the overflow menu if it is currently showing. - * - * @return true if the overflow menu was hidden, false otherwise. - */ - public boolean hideOverflowMenu() { - if (mPostedOpenRunnable != null && mMenuView != null) { - ((View) mMenuView).removeCallbacks(mPostedOpenRunnable); - mPostedOpenRunnable = null; - return true; - } - - MenuPopupHelper popup = mOverflowPopup; - if (popup != null) { - popup.dismiss(); - return true; - } - return false; - } - - /** - * Dismiss all popup menus - overflow and submenus. - * @return true if popups were dismissed, false otherwise. (This can be because none were open.) - */ - public boolean dismissPopupMenus() { - boolean result = hideOverflowMenu(); - result |= hideSubMenus(); - return result; - } - - /** - * Dismiss all submenu popups. - * - * @return true if popups were dismissed, false otherwise. (This can be because none were open.) - */ - public boolean hideSubMenus() { - if (mActionButtonPopup != null) { - mActionButtonPopup.dismiss(); - return true; - } - return false; - } - - /** - * @return true if the overflow menu is currently showing - */ - public boolean isOverflowMenuShowing() { - return mOverflowPopup != null && mOverflowPopup.isShowing(); - } - - /** - * @return true if space has been reserved in the action menu for an overflow item. - */ - public boolean isOverflowReserved() { - return mReserveOverflow; - } - - public boolean flagActionItems() { - final ArrayList visibleItems = mMenu.getVisibleItems(); - final int itemsSize = visibleItems.size(); - int maxActions = mMaxItems; - int widthLimit = mActionItemWidthLimit; - final int querySpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - final ViewGroup parent = (ViewGroup) mMenuView; - - int requiredItems = 0; - int requestedItems = 0; - int firstActionWidth = 0; - boolean hasOverflow = false; - for (int i = 0; i < itemsSize; i++) { - MenuItemImpl item = visibleItems.get(i); - if (item.requiresActionButton()) { - requiredItems++; - } else if (item.requestsActionButton()) { - requestedItems++; - } else { - hasOverflow = true; - } - if (mExpandedActionViewsExclusive && item.isActionViewExpanded()) { - // Overflow everything if we have an expanded action view and we're - // space constrained. - maxActions = 0; - } - } - - // Reserve a spot for the overflow item if needed. - if (mReserveOverflow && - (hasOverflow || requiredItems + requestedItems > maxActions)) { - maxActions--; - } - maxActions -= requiredItems; - - final SparseBooleanArray seenGroups = mActionButtonGroups; - seenGroups.clear(); - - int cellSize = 0; - int cellsRemaining = 0; - if (mStrictWidthLimit) { - cellsRemaining = widthLimit / mMinCellSize; - final int cellSizeRemaining = widthLimit % mMinCellSize; - cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining; - } - - // Flag as many more requested items as will fit. - for (int i = 0; i < itemsSize; i++) { - MenuItemImpl item = visibleItems.get(i); - - if (item.requiresActionButton()) { - View v = getItemView(item, mScrapActionButtonView, parent); - if (mScrapActionButtonView == null) { - mScrapActionButtonView = v; - } - if (mStrictWidthLimit) { - cellsRemaining -= ActionMenuView.measureChildForCells(v, - cellSize, cellsRemaining, querySpec, 0); - } else { - v.measure(querySpec, querySpec); - } - final int measuredWidth = v.getMeasuredWidth(); - widthLimit -= measuredWidth; - if (firstActionWidth == 0) { - firstActionWidth = measuredWidth; - } - final int groupId = item.getGroupId(); - if (groupId != 0) { - seenGroups.put(groupId, true); - } - item.setIsActionButton(true); - } else if (item.requestsActionButton()) { - // Items in a group with other items that already have an action slot - // can break the max actions rule, but not the width limit. - final int groupId = item.getGroupId(); - final boolean inGroup = seenGroups.get(groupId); - boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 && - (!mStrictWidthLimit || cellsRemaining > 0); - - if (isAction) { - View v = getItemView(item, mScrapActionButtonView, parent); - if (mScrapActionButtonView == null) { - mScrapActionButtonView = v; - } - if (mStrictWidthLimit) { - final int cells = ActionMenuView.measureChildForCells(v, - cellSize, cellsRemaining, querySpec, 0); - cellsRemaining -= cells; - if (cells == 0) { - isAction = false; - } - } else { - v.measure(querySpec, querySpec); - } - final int measuredWidth = v.getMeasuredWidth(); - widthLimit -= measuredWidth; - if (firstActionWidth == 0) { - firstActionWidth = measuredWidth; - } - - if (mStrictWidthLimit) { - isAction &= widthLimit >= 0; - } else { - // Did this push the entire first item past the limit? - isAction &= widthLimit + firstActionWidth > 0; - } - } - - if (isAction && groupId != 0) { - seenGroups.put(groupId, true); - } else if (inGroup) { - // We broke the width limit. Demote the whole group, they all overflow now. - seenGroups.put(groupId, false); - for (int j = 0; j < i; j++) { - MenuItemImpl areYouMyGroupie = visibleItems.get(j); - if (areYouMyGroupie.getGroupId() == groupId) { - // Give back the action slot - if (areYouMyGroupie.isActionButton()) maxActions++; - areYouMyGroupie.setIsActionButton(false); - } - } - } - - if (isAction) maxActions--; - - item.setIsActionButton(isAction); - } - } - return true; - } - - @Override - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - dismissPopupMenus(); - super.onCloseMenu(menu, allMenusAreClosing); - } - - @Override - public Parcelable onSaveInstanceState() { - SavedState state = new SavedState(); - state.openSubMenuId = mOpenSubMenuId; - return state; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - SavedState saved = (SavedState) state; - if (saved.openSubMenuId > 0) { - MenuItem item = mMenu.findItem(saved.openSubMenuId); - if (item != null) { - SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); - onSubMenuSelected(subMenu); - } - } - } - - @Override - public void onSubUiVisibilityChanged(boolean isVisible) { - if (isVisible) { - // Not a submenu, but treat it like one. - super.onSubMenuSelected(null); - } else { - mMenu.close(false); - } - } - - private static class SavedState implements Parcelable { - public int openSubMenuId; - - SavedState() { - } - - SavedState(Parcel in) { - openSubMenuId = in.readInt(); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(openSubMenuId); - } - - @SuppressWarnings("unused") - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - - private class OverflowMenuButton extends ImageButton implements ActionMenuChildView, View_HasStateListenerSupport { - private final Set mListeners = new HashSet(); - - public OverflowMenuButton(Context context) { - super(context, null, R.attr.actionOverflowButtonStyle); - - setClickable(true); - setFocusable(true); - setVisibility(VISIBLE); - setEnabled(true); - } - - @Override - public boolean performClick() { - if (super.performClick()) { - return true; - } - - playSoundEffect(SoundEffectConstants.CLICK); - showOverflowMenu(); - return true; - } - - public boolean needsDividerBefore() { - return false; - } - - public boolean needsDividerAfter() { - return false; - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - for (View_OnAttachStateChangeListener listener : mListeners) { - listener.onViewAttachedToWindow(this); - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - for (View_OnAttachStateChangeListener listener : mListeners) { - listener.onViewDetachedFromWindow(this); - } - - if (mOverflowPopup != null) mOverflowPopup.dismiss(); - } - - @Override - public void addOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) { - mListeners.add(listener); - } - - @Override - public void removeOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) { - mListeners.remove(listener); - } - } - - private class OverflowPopup extends MenuPopupHelper { - public OverflowPopup(Context context, MenuBuilder menu, View anchorView, - boolean overflowOnly) { - super(context, menu, anchorView, overflowOnly); - setCallback(mPopupPresenterCallback); - } - - @Override - public void onDismiss() { - super.onDismiss(); - mMenu.close(); - mOverflowPopup = null; - } - } - - private class ActionButtonSubmenu extends MenuPopupHelper { - //UNUSED private SubMenuBuilder mSubMenu; - - public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) { - super(context, subMenu); - //UNUSED mSubMenu = subMenu; - - MenuItemImpl item = (MenuItemImpl) subMenu.getItem(); - if (!item.isActionButton()) { - // Give a reasonable anchor to nested submenus. - setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton); - } - - setCallback(mPopupPresenterCallback); - - boolean preserveIconSpacing = false; - final int count = subMenu.size(); - for (int i = 0; i < count; i++) { - MenuItem childItem = subMenu.getItem(i); - if (childItem.isVisible() && childItem.getIcon() != null) { - preserveIconSpacing = true; - break; - } - } - setForceShowIcon(preserveIconSpacing); - } - - @Override - public void onDismiss() { - super.onDismiss(); - mActionButtonPopup = null; - mOpenSubMenuId = 0; - } - } - - private class PopupPresenterCallback implements MenuPresenter.Callback { - - @Override - public boolean onOpenSubMenu(MenuBuilder subMenu) { - if (subMenu == null) return false; - - mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId(); - return false; - } - - @Override - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - if (menu instanceof SubMenuBuilder) { - ((SubMenuBuilder) menu).getRootMenu().close(false); - } - } - } - - private class OpenOverflowRunnable implements Runnable { - private OverflowPopup mPopup; - - public OpenOverflowRunnable(OverflowPopup popup) { - mPopup = popup; - } - - public void run() { - mMenu.changeMenuMode(); - final View menuView = (View) mMenuView; - if (menuView != null && menuView.getWindowToken() != null && mPopup.tryShow()) { - mOverflowPopup = mPopup; - } - mPostedOpenRunnable = null; - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuView.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuView.java deleted file mode 100644 index 0e3b1ae0..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuView.java +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.actionbarsherlock.internal.view.menu; - -import android.content.Context; -import android.content.res.Configuration; -import android.graphics.Canvas; -import android.os.Build; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.view.ViewGroup; -import android.view.accessibility.AccessibilityEvent; -import android.widget.LinearLayout; -import com.actionbarsherlock.internal.widget.IcsLinearLayout; - -/** - * @hide - */ -public class ActionMenuView extends IcsLinearLayout implements MenuBuilder.ItemInvoker, MenuView { - //UNUSED private static final String TAG = "ActionMenuView"; - private static final boolean IS_FROYO = Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO; - - static final int MIN_CELL_SIZE = 56; // dips - static final int GENERATED_ITEM_PADDING = 4; // dips - - private MenuBuilder mMenu; - - private boolean mReserveOverflow; - private ActionMenuPresenter mPresenter; - private boolean mFormatItems; - private int mFormatItemsWidth; - private int mMinCellSize; - private int mGeneratedItemPadding; - //UNUSED private int mMeasuredExtraWidth; - - private boolean mFirst = true; - - public ActionMenuView(Context context) { - this(context, null); - } - - public ActionMenuView(Context context, AttributeSet attrs) { - super(context, attrs); - setBaselineAligned(false); - final float density = context.getResources().getDisplayMetrics().density; - mMinCellSize = (int) (MIN_CELL_SIZE * density); - mGeneratedItemPadding = (int) (GENERATED_ITEM_PADDING * density); - } - - public void setPresenter(ActionMenuPresenter presenter) { - mPresenter = presenter; - } - - public boolean isExpandedFormat() { - return mFormatItems; - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - if (IS_FROYO) { - super.onConfigurationChanged(newConfig); - } - mPresenter.updateMenuView(false); - - if (mPresenter != null && mPresenter.isOverflowMenuShowing()) { - mPresenter.hideOverflowMenu(); - mPresenter.showOverflowMenu(); - } - } - - @Override - protected void onDraw(Canvas canvas) { - //Need to trigger a relayout since we may have been added extremely - //late in the initial rendering (e.g., when contained in a ViewPager). - //See: https://github.com/JakeWharton/ActionBarSherlock/issues/272 - if (!IS_FROYO && mFirst) { - mFirst = false; - requestLayout(); - return; - } - super.onDraw(canvas); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // If we've been given an exact size to match, apply special formatting during layout. - final boolean wasFormatted = mFormatItems; - mFormatItems = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY; - - if (wasFormatted != mFormatItems) { - mFormatItemsWidth = 0; // Reset this when switching modes - } - - // Special formatting can change whether items can fit as action buttons. - // Kick the menu and update presenters when this changes. - final int widthSize = MeasureSpec.getMode(widthMeasureSpec); - if (mFormatItems && mMenu != null && widthSize != mFormatItemsWidth) { - mFormatItemsWidth = widthSize; - mMenu.onItemsChanged(true); - } - - if (mFormatItems) { - onMeasureExactFormat(widthMeasureSpec, heightMeasureSpec); - } else { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - } - - private void onMeasureExactFormat(int widthMeasureSpec, int heightMeasureSpec) { - // We already know the width mode is EXACTLY if we're here. - final int heightMode = MeasureSpec.getMode(heightMeasureSpec); - int widthSize = MeasureSpec.getSize(widthMeasureSpec); - int heightSize = MeasureSpec.getSize(heightMeasureSpec); - - final int widthPadding = getPaddingLeft() + getPaddingRight(); - final int heightPadding = getPaddingTop() + getPaddingBottom(); - - widthSize -= widthPadding; - - // Divide the view into cells. - final int cellCount = widthSize / mMinCellSize; - final int cellSizeRemaining = widthSize % mMinCellSize; - - if (cellCount == 0) { - // Give up, nothing fits. - setMeasuredDimension(widthSize, 0); - return; - } - - final int cellSize = mMinCellSize + cellSizeRemaining / cellCount; - - int cellsRemaining = cellCount; - int maxChildHeight = 0; - int maxCellsUsed = 0; - int expandableItemCount = 0; - int visibleItemCount = 0; - boolean hasOverflow = false; - - // This is used as a bitfield to locate the smallest items present. Assumes childCount < 64. - long smallestItemsAt = 0; - - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - if (child.getVisibility() == GONE) continue; - - final boolean isGeneratedItem = child instanceof ActionMenuItemView; - visibleItemCount++; - - if (isGeneratedItem) { - // Reset padding for generated menu item views; it may change below - // and views are recycled. - child.setPadding(mGeneratedItemPadding, 0, mGeneratedItemPadding, 0); - } - - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - lp.expanded = false; - lp.extraPixels = 0; - lp.cellsUsed = 0; - lp.expandable = false; - lp.leftMargin = 0; - lp.rightMargin = 0; - lp.preventEdgeOffset = isGeneratedItem && ((ActionMenuItemView) child).hasText(); - - // Overflow always gets 1 cell. No more, no less. - final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining; - - final int cellsUsed = measureChildForCells(child, cellSize, cellsAvailable, - heightMeasureSpec, heightPadding); - - maxCellsUsed = Math.max(maxCellsUsed, cellsUsed); - if (lp.expandable) expandableItemCount++; - if (lp.isOverflowButton) hasOverflow = true; - - cellsRemaining -= cellsUsed; - maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight()); - if (cellsUsed == 1) smallestItemsAt |= (1 << i); - } - - // When we have overflow and a single expanded (text) item, we want to try centering it - // visually in the available space even though overflow consumes some of it. - final boolean centerSingleExpandedItem = hasOverflow && visibleItemCount == 2; - - // Divide space for remaining cells if we have items that can expand. - // Try distributing whole leftover cells to smaller items first. - - boolean needsExpansion = false; - while (expandableItemCount > 0 && cellsRemaining > 0) { - int minCells = Integer.MAX_VALUE; - long minCellsAt = 0; // Bit locations are indices of relevant child views - int minCellsItemCount = 0; - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - - // Don't try to expand items that shouldn't. - if (!lp.expandable) continue; - - // Mark indices of children that can receive an extra cell. - if (lp.cellsUsed < minCells) { - minCells = lp.cellsUsed; - minCellsAt = 1 << i; - minCellsItemCount = 1; - } else if (lp.cellsUsed == minCells) { - minCellsAt |= 1 << i; - minCellsItemCount++; - } - } - - // Items that get expanded will always be in the set of smallest items when we're done. - smallestItemsAt |= minCellsAt; - - if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop. - - // We have enough cells, all minimum size items will be incremented. - minCells++; - - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - if ((minCellsAt & (1 << i)) == 0) { - // If this item is already at our small item count, mark it for later. - if (lp.cellsUsed == minCells) smallestItemsAt |= 1 << i; - continue; - } - - if (centerSingleExpandedItem && lp.preventEdgeOffset && cellsRemaining == 1) { - // Add padding to this item such that it centers. - child.setPadding(mGeneratedItemPadding + cellSize, 0, mGeneratedItemPadding, 0); - } - lp.cellsUsed++; - lp.expanded = true; - cellsRemaining--; - } - - needsExpansion = true; - } - - // Divide any space left that wouldn't divide along cell boundaries - // evenly among the smallest items - - final boolean singleItem = !hasOverflow && visibleItemCount == 1; - if (cellsRemaining > 0 && smallestItemsAt != 0 && - (cellsRemaining < visibleItemCount - 1 || singleItem || maxCellsUsed > 1)) { - float expandCount = Long.bitCount(smallestItemsAt); - - if (!singleItem) { - // The items at the far edges may only expand by half in order to pin to either side. - if ((smallestItemsAt & 1) != 0) { - LayoutParams lp = (LayoutParams) getChildAt(0).getLayoutParams(); - if (!lp.preventEdgeOffset) expandCount -= 0.5f; - } - if ((smallestItemsAt & (1 << (childCount - 1))) != 0) { - LayoutParams lp = ((LayoutParams) getChildAt(childCount - 1).getLayoutParams()); - if (!lp.preventEdgeOffset) expandCount -= 0.5f; - } - } - - final int extraPixels = expandCount > 0 ? - (int) (cellsRemaining * cellSize / expandCount) : 0; - - for (int i = 0; i < childCount; i++) { - if ((smallestItemsAt & (1 << i)) == 0) continue; - - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - if (child instanceof ActionMenuItemView) { - // If this is one of our views, expand and measure at the larger size. - lp.extraPixels = extraPixels; - lp.expanded = true; - if (i == 0 && !lp.preventEdgeOffset) { - // First item gets part of its new padding pushed out of sight. - // The last item will get this implicitly from layout. - lp.leftMargin = -extraPixels / 2; - } - needsExpansion = true; - } else if (lp.isOverflowButton) { - lp.extraPixels = extraPixels; - lp.expanded = true; - lp.rightMargin = -extraPixels / 2; - needsExpansion = true; - } else { - // If we don't know what it is, give it some margins instead - // and let it center within its space. We still want to pin - // against the edges. - if (i != 0) { - lp.leftMargin = extraPixels / 2; - } - if (i != childCount - 1) { - lp.rightMargin = extraPixels / 2; - } - } - } - - cellsRemaining = 0; - } - - // Remeasure any items that have had extra space allocated to them. - if (needsExpansion) { - int heightSpec = MeasureSpec.makeMeasureSpec(heightSize - heightPadding, heightMode); - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - - if (!lp.expanded) continue; - - final int width = lp.cellsUsed * cellSize + lp.extraPixels; - child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightSpec); - } - } - - if (heightMode != MeasureSpec.EXACTLY) { - heightSize = maxChildHeight; - } - - setMeasuredDimension(widthSize, heightSize); - //UNUSED mMeasuredExtraWidth = cellsRemaining * cellSize; - } - - /** - * Measure a child view to fit within cell-based formatting. The child's width - * will be measured to a whole multiple of cellSize. - * - *

Sets the expandable and cellsUsed fields of LayoutParams. - * - * @param child Child to measure - * @param cellSize Size of one cell - * @param cellsRemaining Number of cells remaining that this view can expand to fill - * @param parentHeightMeasureSpec MeasureSpec used by the parent view - * @param parentHeightPadding Padding present in the parent view - * @return Number of cells this child was measured to occupy - */ - static int measureChildForCells(View child, int cellSize, int cellsRemaining, - int parentHeightMeasureSpec, int parentHeightPadding) { - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - - final int childHeightSize = MeasureSpec.getSize(parentHeightMeasureSpec) - - parentHeightPadding; - final int childHeightMode = MeasureSpec.getMode(parentHeightMeasureSpec); - final int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeightSize, childHeightMode); - - int cellsUsed = 0; - if (cellsRemaining > 0) { - final int childWidthSpec = MeasureSpec.makeMeasureSpec( - cellSize * cellsRemaining, MeasureSpec.AT_MOST); - child.measure(childWidthSpec, childHeightSpec); - - final int measuredWidth = child.getMeasuredWidth(); - cellsUsed = measuredWidth / cellSize; - if (measuredWidth % cellSize != 0) cellsUsed++; - } - - final ActionMenuItemView itemView = child instanceof ActionMenuItemView ? - (ActionMenuItemView) child : null; - final boolean expandable = !lp.isOverflowButton && itemView != null && itemView.hasText(); - lp.expandable = expandable; - - lp.cellsUsed = cellsUsed; - final int targetWidth = cellsUsed * cellSize; - child.measure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY), - childHeightSpec); - return cellsUsed; - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - if (!mFormatItems) { - super.onLayout(changed, left, top, right, bottom); - return; - } - - final int childCount = getChildCount(); - final int midVertical = (top + bottom) / 2; - final int dividerWidth = 0;//getDividerWidth(); - int overflowWidth = 0; - //UNUSED int nonOverflowWidth = 0; - int nonOverflowCount = 0; - int widthRemaining = right - left - getPaddingRight() - getPaddingLeft(); - boolean hasOverflow = false; - for (int i = 0; i < childCount; i++) { - final View v = getChildAt(i); - if (v.getVisibility() == GONE) { - continue; - } - - LayoutParams p = (LayoutParams) v.getLayoutParams(); - if (p.isOverflowButton) { - overflowWidth = v.getMeasuredWidth(); - if (hasDividerBeforeChildAt(i)) { - overflowWidth += dividerWidth; - } - - int height = v.getMeasuredHeight(); - int r = getWidth() - getPaddingRight() - p.rightMargin; - int l = r - overflowWidth; - int t = midVertical - (height / 2); - int b = t + height; - v.layout(l, t, r, b); - - widthRemaining -= overflowWidth; - hasOverflow = true; - } else { - final int size = v.getMeasuredWidth() + p.leftMargin + p.rightMargin; - //UNUSED nonOverflowWidth += size; - widthRemaining -= size; - //if (hasDividerBeforeChildAt(i)) { - //UNUSED nonOverflowWidth += dividerWidth; - //} - nonOverflowCount++; - } - } - - if (childCount == 1 && !hasOverflow) { - // Center a single child - final View v = getChildAt(0); - final int width = v.getMeasuredWidth(); - final int height = v.getMeasuredHeight(); - final int midHorizontal = (right - left) / 2; - final int l = midHorizontal - width / 2; - final int t = midVertical - height / 2; - v.layout(l, t, l + width, t + height); - return; - } - - final int spacerCount = nonOverflowCount - (hasOverflow ? 0 : 1); - final int spacerSize = Math.max(0, spacerCount > 0 ? widthRemaining / spacerCount : 0); - - int startLeft = getPaddingLeft(); - for (int i = 0; i < childCount; i++) { - final View v = getChildAt(i); - final LayoutParams lp = (LayoutParams) v.getLayoutParams(); - if (v.getVisibility() == GONE || lp.isOverflowButton) { - continue; - } - - startLeft += lp.leftMargin; - int width = v.getMeasuredWidth(); - int height = v.getMeasuredHeight(); - int t = midVertical - height / 2; - v.layout(startLeft, t, startLeft + width, t + height); - startLeft += width + lp.rightMargin + spacerSize; - } - } - - @Override - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - mPresenter.dismissPopupMenus(); - } - - public boolean isOverflowReserved() { - return mReserveOverflow; - } - - public void setOverflowReserved(boolean reserveOverflow) { - mReserveOverflow = reserveOverflow; - } - - @Override - protected LayoutParams generateDefaultLayoutParams() { - LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT); - params.gravity = Gravity.CENTER_VERTICAL; - return params; - } - - @Override - public LayoutParams generateLayoutParams(AttributeSet attrs) { - return new LayoutParams(getContext(), attrs); - } - - @Override - protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { - if (p instanceof LayoutParams) { - LayoutParams result = new LayoutParams((LayoutParams) p); - if (result.gravity <= Gravity.NO_GRAVITY) { - result.gravity = Gravity.CENTER_VERTICAL; - } - return result; - } - return generateDefaultLayoutParams(); - } - - @Override - protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { - return p != null && p instanceof LayoutParams; - } - - public LayoutParams generateOverflowButtonLayoutParams() { - LayoutParams result = generateDefaultLayoutParams(); - result.isOverflowButton = true; - return result; - } - - public boolean invokeItem(MenuItemImpl item) { - return mMenu.performItemAction(item, 0); - } - - public int getWindowAnimations() { - return 0; - } - - public void initialize(MenuBuilder menu) { - mMenu = menu; - } - - //@Override - protected boolean hasDividerBeforeChildAt(int childIndex) { - if (childIndex == 0) { - return false; - } - final View childBefore = getChildAt(childIndex - 1); - final View child = getChildAt(childIndex); - boolean result = false; - if (childIndex < getChildCount() && childBefore instanceof ActionMenuChildView) { - result |= ((ActionMenuChildView) childBefore).needsDividerAfter(); - } - if (childIndex > 0 && child instanceof ActionMenuChildView) { - result |= ((ActionMenuChildView) child).needsDividerBefore(); - } - return result; - } - - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - return false; - } - - public interface ActionMenuChildView { - public boolean needsDividerBefore(); - public boolean needsDividerAfter(); - } - - public static class LayoutParams extends LinearLayout.LayoutParams { - public boolean isOverflowButton; - public int cellsUsed; - public int extraPixels; - public boolean expandable; - public boolean preventEdgeOffset; - - public boolean expanded; - - public LayoutParams(Context c, AttributeSet attrs) { - super(c, attrs); - } - - public LayoutParams(LayoutParams other) { - super((LinearLayout.LayoutParams) other); - isOverflowButton = other.isOverflowButton; - } - - public LayoutParams(int width, int height) { - super(width, height); - isOverflowButton = false; - } - - public LayoutParams(int width, int height, boolean isOverflowButton) { - super(width, height); - this.isOverflowButton = isOverflowButton; - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/BaseMenuPresenter.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/BaseMenuPresenter.java deleted file mode 100644 index 6da26f2a..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/BaseMenuPresenter.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import java.util.ArrayList; -import android.content.Context; -import android.os.Build; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -/** - * Base class for MenuPresenters that have a consistent container view and item - * views. Behaves similarly to an AdapterView in that existing item views will - * be reused if possible when items change. - */ -public abstract class BaseMenuPresenter implements MenuPresenter { - private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; - - protected Context mSystemContext; - protected Context mContext; - protected MenuBuilder mMenu; - protected LayoutInflater mSystemInflater; - protected LayoutInflater mInflater; - private Callback mCallback; - - private int mMenuLayoutRes; - private int mItemLayoutRes; - - protected MenuView mMenuView; - - private int mId; - - /** - * Construct a new BaseMenuPresenter. - * - * @param context Context for generating system-supplied views - * @param menuLayoutRes Layout resource ID for the menu container view - * @param itemLayoutRes Layout resource ID for a single item view - */ - public BaseMenuPresenter(Context context, int menuLayoutRes, int itemLayoutRes) { - mSystemContext = context; - mSystemInflater = LayoutInflater.from(context); - mMenuLayoutRes = menuLayoutRes; - mItemLayoutRes = itemLayoutRes; - } - - @Override - public void initForMenu(Context context, MenuBuilder menu) { - mContext = context; - mInflater = LayoutInflater.from(mContext); - mMenu = menu; - } - - @Override - public MenuView getMenuView(ViewGroup root) { - if (mMenuView == null) { - mMenuView = (MenuView) mSystemInflater.inflate(mMenuLayoutRes, root, false); - mMenuView.initialize(mMenu); - updateMenuView(true); - } - - return mMenuView; - } - - /** - * Reuses item views when it can - */ - public void updateMenuView(boolean cleared) { - final ViewGroup parent = (ViewGroup) mMenuView; - if (parent == null) return; - - int childIndex = 0; - if (mMenu != null) { - mMenu.flagActionItems(); - ArrayList visibleItems = mMenu.getVisibleItems(); - final int itemCount = visibleItems.size(); - for (int i = 0; i < itemCount; i++) { - MenuItemImpl item = visibleItems.get(i); - if (shouldIncludeItem(childIndex, item)) { - final View convertView = parent.getChildAt(childIndex); - final MenuItemImpl oldItem = convertView instanceof MenuView.ItemView ? - ((MenuView.ItemView) convertView).getItemData() : null; - final View itemView = getItemView(item, convertView, parent); - if (item != oldItem) { - // Don't let old states linger with new data. - itemView.setPressed(false); - if (IS_HONEYCOMB) itemView.jumpDrawablesToCurrentState(); - } - if (itemView != convertView) { - addItemView(itemView, childIndex); - } - childIndex++; - } - } - } - - // Remove leftover views. - while (childIndex < parent.getChildCount()) { - if (!filterLeftoverView(parent, childIndex)) { - childIndex++; - } - } - } - - /** - * Add an item view at the given index. - * - * @param itemView View to add - * @param childIndex Index within the parent to insert at - */ - protected void addItemView(View itemView, int childIndex) { - final ViewGroup currentParent = (ViewGroup) itemView.getParent(); - if (currentParent != null) { - currentParent.removeView(itemView); - } - ((ViewGroup) mMenuView).addView(itemView, childIndex); - } - - /** - * Filter the child view at index and remove it if appropriate. - * @param parent Parent to filter from - * @param childIndex Index to filter - * @return true if the child view at index was removed - */ - protected boolean filterLeftoverView(ViewGroup parent, int childIndex) { - parent.removeViewAt(childIndex); - return true; - } - - public void setCallback(Callback cb) { - mCallback = cb; - } - - /** - * Create a new item view that can be re-bound to other item data later. - * - * @return The new item view - */ - public MenuView.ItemView createItemView(ViewGroup parent) { - return (MenuView.ItemView) mSystemInflater.inflate(mItemLayoutRes, parent, false); - } - - /** - * Prepare an item view for use. See AdapterView for the basic idea at work here. - * This may require creating a new item view, but well-behaved implementations will - * re-use the view passed as convertView if present. The returned view will be populated - * with data from the item parameter. - * - * @param item Item to present - * @param convertView Existing view to reuse - * @param parent Intended parent view - use for inflation. - * @return View that presents the requested menu item - */ - public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) { - MenuView.ItemView itemView; - if (convertView instanceof MenuView.ItemView) { - itemView = (MenuView.ItemView) convertView; - } else { - itemView = createItemView(parent); - } - bindItemView(item, itemView); - return (View) itemView; - } - - /** - * Bind item data to an existing item view. - * - * @param item Item to bind - * @param itemView View to populate with item data - */ - public abstract void bindItemView(MenuItemImpl item, MenuView.ItemView itemView); - - /** - * Filter item by child index and item data. - * - * @param childIndex Indended presentation index of this item - * @param item Item to present - * @return true if this item should be included in this menu presentation; false otherwise - */ - public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) { - return true; - } - - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - if (mCallback != null) { - mCallback.onCloseMenu(menu, allMenusAreClosing); - } - } - - public boolean onSubMenuSelected(SubMenuBuilder menu) { - if (mCallback != null) { - return mCallback.onOpenSubMenu(menu); - } - return false; - } - - public boolean flagActionItems() { - return false; - } - - public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { - return false; - } - - public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { - return false; - } - - public int getId() { - return mId; - } - - public void setId(int id) { - mId = id; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ListMenuItemView.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ListMenuItemView.java deleted file mode 100644 index ac25c373..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/ListMenuItemView.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import com.actionbarsherlock.R; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.RadioButton; -import android.widget.TextView; - -/** - * The item view for each item in the ListView-based MenuViews. - */ -public class ListMenuItemView extends LinearLayout implements MenuView.ItemView { - private MenuItemImpl mItemData; - - private ImageView mIconView; - private RadioButton mRadioButton; - private TextView mTitleView; - private CheckBox mCheckBox; - private TextView mShortcutView; - - private Drawable mBackground; - private int mTextAppearance; - private Context mTextAppearanceContext; - private boolean mPreserveIconSpacing; - - //UNUSED private int mMenuType; - - private LayoutInflater mInflater; - - private boolean mForceShowIcon; - - final Context mContext; - - public ListMenuItemView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs); - mContext = context; - - TypedArray a = - context.obtainStyledAttributes( - attrs, R.styleable.SherlockMenuView, defStyle, 0); - - mBackground = a.getDrawable(R.styleable.SherlockMenuView_itemBackground); - mTextAppearance = a.getResourceId(R.styleable. - SherlockMenuView_itemTextAppearance, -1); - mPreserveIconSpacing = a.getBoolean( - R.styleable.SherlockMenuView_preserveIconSpacing, false); - mTextAppearanceContext = context; - - a.recycle(); - } - - public ListMenuItemView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - - setBackgroundDrawable(mBackground); - - mTitleView = (TextView) findViewById(R.id.abs__title); - if (mTextAppearance != -1) { - mTitleView.setTextAppearance(mTextAppearanceContext, - mTextAppearance); - } - - mShortcutView = (TextView) findViewById(R.id.abs__shortcut); - } - - public void initialize(MenuItemImpl itemData, int menuType) { - mItemData = itemData; - //UNUSED mMenuType = menuType; - - setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE); - - setTitle(itemData.getTitleForItemView(this)); - setCheckable(itemData.isCheckable()); - setShortcut(itemData.shouldShowShortcut(), itemData.getShortcut()); - setIcon(itemData.getIcon()); - setEnabled(itemData.isEnabled()); - } - - public void setForceShowIcon(boolean forceShow) { - mPreserveIconSpacing = mForceShowIcon = forceShow; - } - - public void setTitle(CharSequence title) { - if (title != null) { - mTitleView.setText(title); - - if (mTitleView.getVisibility() != VISIBLE) mTitleView.setVisibility(VISIBLE); - } else { - if (mTitleView.getVisibility() != GONE) mTitleView.setVisibility(GONE); - } - } - - public MenuItemImpl getItemData() { - return mItemData; - } - - public void setCheckable(boolean checkable) { - - if (!checkable && mRadioButton == null && mCheckBox == null) { - return; - } - - if (mRadioButton == null) { - insertRadioButton(); - } - if (mCheckBox == null) { - insertCheckBox(); - } - - // Depending on whether its exclusive check or not, the checkbox or - // radio button will be the one in use (and the other will be otherCompoundButton) - final CompoundButton compoundButton; - final CompoundButton otherCompoundButton; - - if (mItemData.isExclusiveCheckable()) { - compoundButton = mRadioButton; - otherCompoundButton = mCheckBox; - } else { - compoundButton = mCheckBox; - otherCompoundButton = mRadioButton; - } - - if (checkable) { - compoundButton.setChecked(mItemData.isChecked()); - - final int newVisibility = checkable ? VISIBLE : GONE; - if (compoundButton.getVisibility() != newVisibility) { - compoundButton.setVisibility(newVisibility); - } - - // Make sure the other compound button isn't visible - if (otherCompoundButton.getVisibility() != GONE) { - otherCompoundButton.setVisibility(GONE); - } - } else { - mCheckBox.setVisibility(GONE); - mRadioButton.setVisibility(GONE); - } - } - - public void setChecked(boolean checked) { - CompoundButton compoundButton; - - if (mItemData.isExclusiveCheckable()) { - if (mRadioButton == null) { - insertRadioButton(); - } - compoundButton = mRadioButton; - } else { - if (mCheckBox == null) { - insertCheckBox(); - } - compoundButton = mCheckBox; - } - - compoundButton.setChecked(checked); - } - - public void setShortcut(boolean showShortcut, char shortcutKey) { - final int newVisibility = (showShortcut && mItemData.shouldShowShortcut()) - ? VISIBLE : GONE; - - if (newVisibility == VISIBLE) { - mShortcutView.setText(mItemData.getShortcutLabel()); - } - - if (mShortcutView.getVisibility() != newVisibility) { - mShortcutView.setVisibility(newVisibility); - } - } - - public void setIcon(Drawable icon) { - final boolean showIcon = mItemData.shouldShowIcon() || mForceShowIcon; - if (!showIcon && !mPreserveIconSpacing) { - return; - } - - if (mIconView == null && icon == null && !mPreserveIconSpacing) { - return; - } - - if (mIconView == null) { - insertIconView(); - } - - if (icon != null || mPreserveIconSpacing) { - mIconView.setImageDrawable(showIcon ? icon : null); - - if (mIconView.getVisibility() != VISIBLE) { - mIconView.setVisibility(VISIBLE); - } - } else { - mIconView.setVisibility(GONE); - } - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - if (mIconView != null && mPreserveIconSpacing) { - // Enforce minimum icon spacing - ViewGroup.LayoutParams lp = getLayoutParams(); - LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); - if (lp.height > 0 && iconLp.width <= 0) { - iconLp.width = lp.height; - } - } - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - - private void insertIconView() { - LayoutInflater inflater = getInflater(); - mIconView = (ImageView) inflater.inflate(R.layout.abs__list_menu_item_icon, - this, false); - addView(mIconView, 0); - } - - private void insertRadioButton() { - LayoutInflater inflater = getInflater(); - mRadioButton = - (RadioButton) inflater.inflate(R.layout.abs__list_menu_item_radio, - this, false); - addView(mRadioButton); - } - - private void insertCheckBox() { - LayoutInflater inflater = getInflater(); - mCheckBox = - (CheckBox) inflater.inflate(R.layout.abs__list_menu_item_checkbox, - this, false); - addView(mCheckBox); - } - - public boolean prefersCondensedTitle() { - return false; - } - - public boolean showsIcon() { - return mForceShowIcon; - } - - private LayoutInflater getInflater() { - if (mInflater == null) { - mInflater = LayoutInflater.from(mContext); - } - return mInflater; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuBuilder.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuBuilder.java deleted file mode 100644 index 179b8f03..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuBuilder.java +++ /dev/null @@ -1,1335 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.Parcelable; -import android.util.SparseArray; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.KeyCharacterMap; -import android.view.KeyEvent; -import android.view.View; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -/** - * Implementation of the {@link android.view.Menu} interface for creating a - * standard menu UI. - */ -public class MenuBuilder implements Menu { - //UNUSED private static final String TAG = "MenuBuilder"; - - private static final String PRESENTER_KEY = "android:menu:presenters"; - private static final String ACTION_VIEW_STATES_KEY = "android:menu:actionviewstates"; - private static final String EXPANDED_ACTION_VIEW_ID = "android:menu:expandedactionview"; - - private static final int[] sCategoryToOrder = new int[] { - 1, /* No category */ - 4, /* CONTAINER */ - 5, /* SYSTEM */ - 3, /* SECONDARY */ - 2, /* ALTERNATIVE */ - 0, /* SELECTED_ALTERNATIVE */ - }; - - private final Context mContext; - private final Resources mResources; - - /** - * Whether the shortcuts should be qwerty-accessible. Use isQwertyMode() - * instead of accessing this directly. - */ - private boolean mQwertyMode; - - /** - * Whether the shortcuts should be visible on menus. Use isShortcutsVisible() - * instead of accessing this directly. - */ - private boolean mShortcutsVisible; - - /** - * Callback that will receive the various menu-related events generated by - * this class. Use getCallback to get a reference to the callback. - */ - private Callback mCallback; - - /** Contains all of the items for this menu */ - private ArrayList mItems; - - /** Contains only the items that are currently visible. This will be created/refreshed from - * {@link #getVisibleItems()} */ - private ArrayList mVisibleItems; - /** - * Whether or not the items (or any one item's shown state) has changed since it was last - * fetched from {@link #getVisibleItems()} - */ - private boolean mIsVisibleItemsStale; - - /** - * Contains only the items that should appear in the Action Bar, if present. - */ - private ArrayList mActionItems; - /** - * Contains items that should NOT appear in the Action Bar, if present. - */ - private ArrayList mNonActionItems; - - /** - * Whether or not the items (or any one item's action state) has changed since it was - * last fetched. - */ - private boolean mIsActionItemsStale; - - /** - * Default value for how added items should show in the action list. - */ - private int mDefaultShowAsAction = MenuItem.SHOW_AS_ACTION_NEVER; - - /** - * Current use case is Context Menus: As Views populate the context menu, each one has - * extra information that should be passed along. This is the current menu info that - * should be set on all items added to this menu. - */ - private ContextMenuInfo mCurrentMenuInfo; - - /** Header title for menu types that have a header (context and submenus) */ - CharSequence mHeaderTitle; - /** Header icon for menu types that have a header and support icons (context) */ - Drawable mHeaderIcon; - /** Header custom view for menu types that have a header and support custom views (context) */ - View mHeaderView; - - /** - * Contains the state of the View hierarchy for all menu views when the menu - * was frozen. - */ - //UNUSED private SparseArray mFrozenViewStates; - - /** - * Prevents onItemsChanged from doing its junk, useful for batching commands - * that may individually call onItemsChanged. - */ - private boolean mPreventDispatchingItemsChanged = false; - private boolean mItemsChangedWhileDispatchPrevented = false; - - private boolean mOptionalIconsVisible = false; - - private boolean mIsClosing = false; - - private ArrayList mTempShortcutItemList = new ArrayList(); - - private CopyOnWriteArrayList> mPresenters = - new CopyOnWriteArrayList>(); - - /** - * Currently expanded menu item; must be collapsed when we clear. - */ - private MenuItemImpl mExpandedItem; - - /** - * Called by menu to notify of close and selection changes. - */ - public interface Callback { - /** - * Called when a menu item is selected. - * @param menu The menu that is the parent of the item - * @param item The menu item that is selected - * @return whether the menu item selection was handled - */ - public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item); - - /** - * Called when the mode of the menu changes (for example, from icon to expanded). - * - * @param menu the menu that has changed modes - */ - public void onMenuModeChange(MenuBuilder menu); - } - - /** - * Called by menu items to execute their associated action - */ - public interface ItemInvoker { - public boolean invokeItem(MenuItemImpl item); - } - - public MenuBuilder(Context context) { - mContext = context; - mResources = context.getResources(); - - mItems = new ArrayList(); - - mVisibleItems = new ArrayList(); - mIsVisibleItemsStale = true; - - mActionItems = new ArrayList(); - mNonActionItems = new ArrayList(); - mIsActionItemsStale = true; - - setShortcutsVisibleInner(true); - } - - public MenuBuilder setDefaultShowAsAction(int defaultShowAsAction) { - mDefaultShowAsAction = defaultShowAsAction; - return this; - } - - /** - * Add a presenter to this menu. This will only hold a WeakReference; - * you do not need to explicitly remove a presenter, but you can using - * {@link #removeMenuPresenter(MenuPresenter)}. - * - * @param presenter The presenter to add - */ - public void addMenuPresenter(MenuPresenter presenter) { - mPresenters.add(new WeakReference(presenter)); - presenter.initForMenu(mContext, this); - mIsActionItemsStale = true; - } - - /** - * Remove a presenter from this menu. That presenter will no longer - * receive notifications of updates to this menu's data. - * - * @param presenter The presenter to remove - */ - public void removeMenuPresenter(MenuPresenter presenter) { - for (WeakReference ref : mPresenters) { - final MenuPresenter item = ref.get(); - if (item == null || item == presenter) { - mPresenters.remove(ref); - } - } - } - - private void dispatchPresenterUpdate(boolean cleared) { - if (mPresenters.isEmpty()) return; - - stopDispatchingItemsChanged(); - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else { - presenter.updateMenuView(cleared); - } - } - startDispatchingItemsChanged(); - } - - private boolean dispatchSubMenuSelected(SubMenuBuilder subMenu) { - if (mPresenters.isEmpty()) return false; - - boolean result = false; - - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else if (!result) { - result = presenter.onSubMenuSelected(subMenu); - } - } - return result; - } - - private void dispatchSaveInstanceState(Bundle outState) { - if (mPresenters.isEmpty()) return; - - SparseArray presenterStates = new SparseArray(); - - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else { - final int id = presenter.getId(); - if (id > 0) { - final Parcelable state = presenter.onSaveInstanceState(); - if (state != null) { - presenterStates.put(id, state); - } - } - } - } - - outState.putSparseParcelableArray(PRESENTER_KEY, presenterStates); - } - - private void dispatchRestoreInstanceState(Bundle state) { - SparseArray presenterStates = state.getSparseParcelableArray(PRESENTER_KEY); - - if (presenterStates == null || mPresenters.isEmpty()) return; - - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else { - final int id = presenter.getId(); - if (id > 0) { - Parcelable parcel = presenterStates.get(id); - if (parcel != null) { - presenter.onRestoreInstanceState(parcel); - } - } - } - } - } - - public void savePresenterStates(Bundle outState) { - dispatchSaveInstanceState(outState); - } - - public void restorePresenterStates(Bundle state) { - dispatchRestoreInstanceState(state); - } - - public void saveActionViewStates(Bundle outStates) { - SparseArray viewStates = null; - - final int itemCount = size(); - for (int i = 0; i < itemCount; i++) { - final MenuItem item = getItem(i); - final View v = item.getActionView(); - if (v != null && v.getId() != View.NO_ID) { - if (viewStates == null) { - viewStates = new SparseArray(); - } - v.saveHierarchyState(viewStates); - if (item.isActionViewExpanded()) { - outStates.putInt(EXPANDED_ACTION_VIEW_ID, item.getItemId()); - } - } - if (item.hasSubMenu()) { - final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); - subMenu.saveActionViewStates(outStates); - } - } - - if (viewStates != null) { - outStates.putSparseParcelableArray(getActionViewStatesKey(), viewStates); - } - } - - public void restoreActionViewStates(Bundle states) { - if (states == null) { - return; - } - - SparseArray viewStates = states.getSparseParcelableArray( - getActionViewStatesKey()); - - final int itemCount = size(); - for (int i = 0; i < itemCount; i++) { - final MenuItem item = getItem(i); - final View v = item.getActionView(); - if (v != null && v.getId() != View.NO_ID) { - v.restoreHierarchyState(viewStates); - } - if (item.hasSubMenu()) { - final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); - subMenu.restoreActionViewStates(states); - } - } - - final int expandedId = states.getInt(EXPANDED_ACTION_VIEW_ID); - if (expandedId > 0) { - MenuItem itemToExpand = findItem(expandedId); - if (itemToExpand != null) { - itemToExpand.expandActionView(); - } - } - } - - protected String getActionViewStatesKey() { - return ACTION_VIEW_STATES_KEY; - } - - public void setCallback(Callback cb) { - mCallback = cb; - } - - /** - * Adds an item to the menu. The other add methods funnel to this. - */ - private MenuItem addInternal(int group, int id, int categoryOrder, CharSequence title) { - final int ordering = getOrdering(categoryOrder); - - final MenuItemImpl item = new MenuItemImpl(this, group, id, categoryOrder, - ordering, title, mDefaultShowAsAction); - - if (mCurrentMenuInfo != null) { - // Pass along the current menu info - item.setMenuInfo(mCurrentMenuInfo); - } - - mItems.add(findInsertIndex(mItems, ordering), item); - onItemsChanged(true); - - return item; - } - - public MenuItem add(CharSequence title) { - return addInternal(0, 0, 0, title); - } - - public MenuItem add(int titleRes) { - return addInternal(0, 0, 0, mResources.getString(titleRes)); - } - - public MenuItem add(int group, int id, int categoryOrder, CharSequence title) { - return addInternal(group, id, categoryOrder, title); - } - - public MenuItem add(int group, int id, int categoryOrder, int title) { - return addInternal(group, id, categoryOrder, mResources.getString(title)); - } - - public SubMenu addSubMenu(CharSequence title) { - return addSubMenu(0, 0, 0, title); - } - - public SubMenu addSubMenu(int titleRes) { - return addSubMenu(0, 0, 0, mResources.getString(titleRes)); - } - - public SubMenu addSubMenu(int group, int id, int categoryOrder, CharSequence title) { - final MenuItemImpl item = (MenuItemImpl) addInternal(group, id, categoryOrder, title); - final SubMenuBuilder subMenu = new SubMenuBuilder(mContext, this, item); - item.setSubMenu(subMenu); - - return subMenu; - } - - public SubMenu addSubMenu(int group, int id, int categoryOrder, int title) { - return addSubMenu(group, id, categoryOrder, mResources.getString(title)); - } - - public int addIntentOptions(int group, int id, int categoryOrder, ComponentName caller, - Intent[] specifics, Intent intent, int flags, MenuItem[] outSpecificItems) { - PackageManager pm = mContext.getPackageManager(); - final List lri = - pm.queryIntentActivityOptions(caller, specifics, intent, 0); - final int N = lri != null ? lri.size() : 0; - - if ((flags & FLAG_APPEND_TO_GROUP) == 0) { - removeGroup(group); - } - - for (int i=0; i= 0) { - outSpecificItems[ri.specificIndex] = item; - } - } - - return N; - } - - public void removeItem(int id) { - removeItemAtInt(findItemIndex(id), true); - } - - public void removeGroup(int group) { - final int i = findGroupIndex(group); - - if (i >= 0) { - final int maxRemovable = mItems.size() - i; - int numRemoved = 0; - while ((numRemoved++ < maxRemovable) && (mItems.get(i).getGroupId() == group)) { - // Don't force update for each one, this method will do it at the end - removeItemAtInt(i, false); - } - - // Notify menu views - onItemsChanged(true); - } - } - - /** - * Remove the item at the given index and optionally forces menu views to - * update. - * - * @param index The index of the item to be removed. If this index is - * invalid an exception is thrown. - * @param updateChildrenOnMenuViews Whether to force update on menu views. - * Please make sure you eventually call this after your batch of - * removals. - */ - private void removeItemAtInt(int index, boolean updateChildrenOnMenuViews) { - if ((index < 0) || (index >= mItems.size())) return; - - mItems.remove(index); - - if (updateChildrenOnMenuViews) onItemsChanged(true); - } - - public void removeItemAt(int index) { - removeItemAtInt(index, true); - } - - public void clearAll() { - mPreventDispatchingItemsChanged = true; - clear(); - clearHeader(); - mPreventDispatchingItemsChanged = false; - mItemsChangedWhileDispatchPrevented = false; - onItemsChanged(true); - } - - public void clear() { - if (mExpandedItem != null) { - collapseItemActionView(mExpandedItem); - } - mItems.clear(); - - onItemsChanged(true); - } - - void setExclusiveItemChecked(MenuItem item) { - final int group = item.getGroupId(); - - final int N = mItems.size(); - for (int i = 0; i < N; i++) { - MenuItemImpl curItem = mItems.get(i); - if (curItem.getGroupId() == group) { - if (!curItem.isExclusiveCheckable()) continue; - if (!curItem.isCheckable()) continue; - - // Check the item meant to be checked, uncheck the others (that are in the group) - curItem.setCheckedInt(curItem == item); - } - } - } - - public void setGroupCheckable(int group, boolean checkable, boolean exclusive) { - final int N = mItems.size(); - - for (int i = 0; i < N; i++) { - MenuItemImpl item = mItems.get(i); - if (item.getGroupId() == group) { - item.setExclusiveCheckable(exclusive); - item.setCheckable(checkable); - } - } - } - - public void setGroupVisible(int group, boolean visible) { - final int N = mItems.size(); - - // We handle the notification of items being changed ourselves, so we use setVisibleInt rather - // than setVisible and at the end notify of items being changed - - boolean changedAtLeastOneItem = false; - for (int i = 0; i < N; i++) { - MenuItemImpl item = mItems.get(i); - if (item.getGroupId() == group) { - if (item.setVisibleInt(visible)) changedAtLeastOneItem = true; - } - } - - if (changedAtLeastOneItem) onItemsChanged(true); - } - - public void setGroupEnabled(int group, boolean enabled) { - final int N = mItems.size(); - - for (int i = 0; i < N; i++) { - MenuItemImpl item = mItems.get(i); - if (item.getGroupId() == group) { - item.setEnabled(enabled); - } - } - } - - public boolean hasVisibleItems() { - final int size = size(); - - for (int i = 0; i < size; i++) { - MenuItemImpl item = mItems.get(i); - if (item.isVisible()) { - return true; - } - } - - return false; - } - - public MenuItem findItem(int id) { - final int size = size(); - for (int i = 0; i < size; i++) { - MenuItemImpl item = mItems.get(i); - if (item.getItemId() == id) { - return item; - } else if (item.hasSubMenu()) { - MenuItem possibleItem = item.getSubMenu().findItem(id); - - if (possibleItem != null) { - return possibleItem; - } - } - } - - return null; - } - - public int findItemIndex(int id) { - final int size = size(); - - for (int i = 0; i < size; i++) { - MenuItemImpl item = mItems.get(i); - if (item.getItemId() == id) { - return i; - } - } - - return -1; - } - - public int findGroupIndex(int group) { - return findGroupIndex(group, 0); - } - - public int findGroupIndex(int group, int start) { - final int size = size(); - - if (start < 0) { - start = 0; - } - - for (int i = start; i < size; i++) { - final MenuItemImpl item = mItems.get(i); - - if (item.getGroupId() == group) { - return i; - } - } - - return -1; - } - - public int size() { - return mItems.size(); - } - - /** {@inheritDoc} */ - public MenuItem getItem(int index) { - return mItems.get(index); - } - - public boolean isShortcutKey(int keyCode, KeyEvent event) { - return findItemWithShortcutForKey(keyCode, event) != null; - } - - public void setQwertyMode(boolean isQwerty) { - mQwertyMode = isQwerty; - - onItemsChanged(false); - } - - /** - * Returns the ordering across all items. This will grab the category from - * the upper bits, find out how to order the category with respect to other - * categories, and combine it with the lower bits. - * - * @param categoryOrder The category order for a particular item (if it has - * not been or/add with a category, the default category is - * assumed). - * @return An ordering integer that can be used to order this item across - * all the items (even from other categories). - */ - private static int getOrdering(int categoryOrder) { - final int index = (categoryOrder & CATEGORY_MASK) >> CATEGORY_SHIFT; - - if (index < 0 || index >= sCategoryToOrder.length) { - throw new IllegalArgumentException("order does not contain a valid category."); - } - - return (sCategoryToOrder[index] << CATEGORY_SHIFT) | (categoryOrder & USER_MASK); - } - - /** - * @return whether the menu shortcuts are in qwerty mode or not - */ - boolean isQwertyMode() { - return mQwertyMode; - } - - /** - * Sets whether the shortcuts should be visible on menus. Devices without hardware - * key input will never make shortcuts visible even if this method is passed 'true'. - * - * @param shortcutsVisible Whether shortcuts should be visible (if true and a - * menu item does not have a shortcut defined, that item will - * still NOT show a shortcut) - */ - public void setShortcutsVisible(boolean shortcutsVisible) { - if (mShortcutsVisible == shortcutsVisible) return; - - setShortcutsVisibleInner(shortcutsVisible); - onItemsChanged(false); - } - - private void setShortcutsVisibleInner(boolean shortcutsVisible) { - mShortcutsVisible = shortcutsVisible - && mResources.getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS - && mResources.getBoolean( - R.bool.abs__config_showMenuShortcutsWhenKeyboardPresent); - } - - /** - * @return Whether shortcuts should be visible on menus. - */ - public boolean isShortcutsVisible() { - return mShortcutsVisible; - } - - Resources getResources() { - return mResources; - } - - public Context getContext() { - return mContext; - } - - boolean dispatchMenuItemSelected(MenuBuilder menu, MenuItem item) { - return mCallback != null && mCallback.onMenuItemSelected(menu, item); - } - - /** - * Dispatch a mode change event to this menu's callback. - */ - public void changeMenuMode() { - if (mCallback != null) { - mCallback.onMenuModeChange(this); - } - } - - private static int findInsertIndex(ArrayList items, int ordering) { - for (int i = items.size() - 1; i >= 0; i--) { - MenuItemImpl item = items.get(i); - if (item.getOrdering() <= ordering) { - return i + 1; - } - } - - return 0; - } - - public boolean performShortcut(int keyCode, KeyEvent event, int flags) { - final MenuItemImpl item = findItemWithShortcutForKey(keyCode, event); - - boolean handled = false; - - if (item != null) { - handled = performItemAction(item, flags); - } - - if ((flags & FLAG_ALWAYS_PERFORM_CLOSE) != 0) { - close(true); - } - - return handled; - } - - /* - * This function will return all the menu and sub-menu items that can - * be directly (the shortcut directly corresponds) and indirectly - * (the ALT-enabled char corresponds to the shortcut) associated - * with the keyCode. - */ - @SuppressWarnings("deprecation") - void findItemsWithShortcutForKey(List items, int keyCode, KeyEvent event) { - final boolean qwerty = isQwertyMode(); - final int metaState = event.getMetaState(); - final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData(); - // Get the chars associated with the keyCode (i.e using any chording combo) - final boolean isKeyCodeMapped = event.getKeyData(possibleChars); - // The delete key is not mapped to '\b' so we treat it specially - if (!isKeyCodeMapped && (keyCode != KeyEvent.KEYCODE_DEL)) { - return; - } - - // Look for an item whose shortcut is this key. - final int N = mItems.size(); - for (int i = 0; i < N; i++) { - MenuItemImpl item = mItems.get(i); - if (item.hasSubMenu()) { - ((MenuBuilder)item.getSubMenu()).findItemsWithShortcutForKey(items, keyCode, event); - } - final char shortcutChar = qwerty ? item.getAlphabeticShortcut() : item.getNumericShortcut(); - if (((metaState & (KeyEvent.META_SHIFT_ON | KeyEvent.META_SYM_ON)) == 0) && - (shortcutChar != 0) && - (shortcutChar == possibleChars.meta[0] - || shortcutChar == possibleChars.meta[2] - || (qwerty && shortcutChar == '\b' && - keyCode == KeyEvent.KEYCODE_DEL)) && - item.isEnabled()) { - items.add(item); - } - } - } - - /* - * We want to return the menu item associated with the key, but if there is no - * ambiguity (i.e. there is only one menu item corresponding to the key) we want - * to return it even if it's not an exact match; this allow the user to - * _not_ use the ALT key for example, making the use of shortcuts slightly more - * user-friendly. An example is on the G1, '!' and '1' are on the same key, and - * in Gmail, Menu+1 will trigger Menu+! (the actual shortcut). - * - * On the other hand, if two (or more) shortcuts corresponds to the same key, - * we have to only return the exact match. - */ - @SuppressWarnings("deprecation") - MenuItemImpl findItemWithShortcutForKey(int keyCode, KeyEvent event) { - // Get all items that can be associated directly or indirectly with the keyCode - ArrayList items = mTempShortcutItemList; - items.clear(); - findItemsWithShortcutForKey(items, keyCode, event); - - if (items.isEmpty()) { - return null; - } - - final int metaState = event.getMetaState(); - final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData(); - // Get the chars associated with the keyCode (i.e using any chording combo) - event.getKeyData(possibleChars); - - // If we have only one element, we can safely returns it - final int size = items.size(); - if (size == 1) { - return items.get(0); - } - - final boolean qwerty = isQwertyMode(); - // If we found more than one item associated with the key, - // we have to return the exact match - for (int i = 0; i < size; i++) { - final MenuItemImpl item = items.get(i); - final char shortcutChar = qwerty ? item.getAlphabeticShortcut() : - item.getNumericShortcut(); - if ((shortcutChar == possibleChars.meta[0] && - (metaState & KeyEvent.META_ALT_ON) == 0) - || (shortcutChar == possibleChars.meta[2] && - (metaState & KeyEvent.META_ALT_ON) != 0) - || (qwerty && shortcutChar == '\b' && - keyCode == KeyEvent.KEYCODE_DEL)) { - return item; - } - } - return null; - } - - public boolean performIdentifierAction(int id, int flags) { - // Look for an item whose identifier is the id. - return performItemAction(findItem(id), flags); - } - - public boolean performItemAction(MenuItem item, int flags) { - MenuItemImpl itemImpl = (MenuItemImpl) item; - - if (itemImpl == null || !itemImpl.isEnabled()) { - return false; - } - - boolean invoked = itemImpl.invoke(); - - if (itemImpl.hasCollapsibleActionView()) { - invoked |= itemImpl.expandActionView(); - if (invoked) close(true); - } else if (item.hasSubMenu()) { - close(false); - - final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); - final ActionProvider provider = item.getActionProvider(); - if (provider != null && provider.hasSubMenu()) { - provider.onPrepareSubMenu(subMenu); - } - invoked |= dispatchSubMenuSelected(subMenu); - if (!invoked) close(true); - } else { - if ((flags & FLAG_PERFORM_NO_CLOSE) == 0) { - close(true); - } - } - - return invoked; - } - - /** - * Closes the visible menu. - * - * @param allMenusAreClosing Whether the menus are completely closing (true), - * or whether there is another menu coming in this menu's place - * (false). For example, if the menu is closing because a - * sub menu is about to be shown, allMenusAreClosing - * is false. - */ - final void close(boolean allMenusAreClosing) { - if (mIsClosing) return; - - mIsClosing = true; - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else { - presenter.onCloseMenu(this, allMenusAreClosing); - } - } - mIsClosing = false; - } - - /** {@inheritDoc} */ - public void close() { - close(true); - } - - /** - * Called when an item is added or removed. - * - * @param structureChanged true if the menu structure changed, - * false if only item properties changed. - * (Visibility is a structural property since it affects layout.) - */ - void onItemsChanged(boolean structureChanged) { - if (!mPreventDispatchingItemsChanged) { - if (structureChanged) { - mIsVisibleItemsStale = true; - mIsActionItemsStale = true; - } - - dispatchPresenterUpdate(structureChanged); - } else { - mItemsChangedWhileDispatchPrevented = true; - } - } - - /** - * Stop dispatching item changed events to presenters until - * {@link #startDispatchingItemsChanged()} is called. Useful when - * many menu operations are going to be performed as a batch. - */ - public void stopDispatchingItemsChanged() { - if (!mPreventDispatchingItemsChanged) { - mPreventDispatchingItemsChanged = true; - mItemsChangedWhileDispatchPrevented = false; - } - } - - public void startDispatchingItemsChanged() { - mPreventDispatchingItemsChanged = false; - - if (mItemsChangedWhileDispatchPrevented) { - mItemsChangedWhileDispatchPrevented = false; - onItemsChanged(true); - } - } - - /** - * Called by {@link MenuItemImpl} when its visible flag is changed. - * @param item The item that has gone through a visibility change. - */ - void onItemVisibleChanged(MenuItemImpl item) { - // Notify of items being changed - mIsVisibleItemsStale = true; - onItemsChanged(true); - } - - /** - * Called by {@link MenuItemImpl} when its action request status is changed. - * @param item The item that has gone through a change in action request status. - */ - void onItemActionRequestChanged(MenuItemImpl item) { - // Notify of items being changed - mIsActionItemsStale = true; - onItemsChanged(true); - } - - ArrayList getVisibleItems() { - if (!mIsVisibleItemsStale) return mVisibleItems; - - // Refresh the visible items - mVisibleItems.clear(); - - final int itemsSize = mItems.size(); - MenuItemImpl item; - for (int i = 0; i < itemsSize; i++) { - item = mItems.get(i); - if (item.isVisible()) mVisibleItems.add(item); - } - - mIsVisibleItemsStale = false; - mIsActionItemsStale = true; - - return mVisibleItems; - } - - /** - * This method determines which menu items get to be 'action items' that will appear - * in an action bar and which items should be 'overflow items' in a secondary menu. - * The rules are as follows: - * - *

Items are considered for inclusion in the order specified within the menu. - * There is a limit of mMaxActionItems as a total count, optionally including the overflow - * menu button itself. This is a soft limit; if an item shares a group ID with an item - * previously included as an action item, the new item will stay with its group and become - * an action item itself even if it breaks the max item count limit. This is done to - * limit the conceptual complexity of the items presented within an action bar. Only a few - * unrelated concepts should be presented to the user in this space, and groups are treated - * as a single concept. - * - *

There is also a hard limit of consumed measurable space: mActionWidthLimit. This - * limit may be broken by a single item that exceeds the remaining space, but no further - * items may be added. If an item that is part of a group cannot fit within the remaining - * measured width, the entire group will be demoted to overflow. This is done to ensure room - * for navigation and other affordances in the action bar as well as reduce general UI clutter. - * - *

The space freed by demoting a full group cannot be consumed by future menu items. - * Once items begin to overflow, all future items become overflow items as well. This is - * to avoid inadvertent reordering that may break the app's intended design. - */ - public void flagActionItems() { - if (!mIsActionItemsStale) { - return; - } - - // Presenters flag action items as needed. - boolean flagged = false; - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else { - flagged |= presenter.flagActionItems(); - } - } - - if (flagged) { - mActionItems.clear(); - mNonActionItems.clear(); - ArrayList visibleItems = getVisibleItems(); - final int itemsSize = visibleItems.size(); - for (int i = 0; i < itemsSize; i++) { - MenuItemImpl item = visibleItems.get(i); - if (item.isActionButton()) { - mActionItems.add(item); - } else { - mNonActionItems.add(item); - } - } - } else { - // Nobody flagged anything, everything is a non-action item. - // (This happens during a first pass with no action-item presenters.) - mActionItems.clear(); - mNonActionItems.clear(); - mNonActionItems.addAll(getVisibleItems()); - } - mIsActionItemsStale = false; - } - - ArrayList getActionItems() { - flagActionItems(); - return mActionItems; - } - - ArrayList getNonActionItems() { - flagActionItems(); - return mNonActionItems; - } - - public void clearHeader() { - mHeaderIcon = null; - mHeaderTitle = null; - mHeaderView = null; - - onItemsChanged(false); - } - - private void setHeaderInternal(final int titleRes, final CharSequence title, final int iconRes, - final Drawable icon, final View view) { - final Resources r = getResources(); - - if (view != null) { - mHeaderView = view; - - // If using a custom view, then the title and icon aren't used - mHeaderTitle = null; - mHeaderIcon = null; - } else { - if (titleRes > 0) { - mHeaderTitle = r.getText(titleRes); - } else if (title != null) { - mHeaderTitle = title; - } - - if (iconRes > 0) { - mHeaderIcon = r.getDrawable(iconRes); - } else if (icon != null) { - mHeaderIcon = icon; - } - - // If using the title or icon, then a custom view isn't used - mHeaderView = null; - } - - // Notify of change - onItemsChanged(false); - } - - /** - * Sets the header's title. This replaces the header view. Called by the - * builder-style methods of subclasses. - * - * @param title The new title. - * @return This MenuBuilder so additional setters can be called. - */ - protected MenuBuilder setHeaderTitleInt(CharSequence title) { - setHeaderInternal(0, title, 0, null, null); - return this; - } - - /** - * Sets the header's title. This replaces the header view. Called by the - * builder-style methods of subclasses. - * - * @param titleRes The new title (as a resource ID). - * @return This MenuBuilder so additional setters can be called. - */ - protected MenuBuilder setHeaderTitleInt(int titleRes) { - setHeaderInternal(titleRes, null, 0, null, null); - return this; - } - - /** - * Sets the header's icon. This replaces the header view. Called by the - * builder-style methods of subclasses. - * - * @param icon The new icon. - * @return This MenuBuilder so additional setters can be called. - */ - protected MenuBuilder setHeaderIconInt(Drawable icon) { - setHeaderInternal(0, null, 0, icon, null); - return this; - } - - /** - * Sets the header's icon. This replaces the header view. Called by the - * builder-style methods of subclasses. - * - * @param iconRes The new icon (as a resource ID). - * @return This MenuBuilder so additional setters can be called. - */ - protected MenuBuilder setHeaderIconInt(int iconRes) { - setHeaderInternal(0, null, iconRes, null, null); - return this; - } - - /** - * Sets the header's view. This replaces the title and icon. Called by the - * builder-style methods of subclasses. - * - * @param view The new view. - * @return This MenuBuilder so additional setters can be called. - */ - protected MenuBuilder setHeaderViewInt(View view) { - setHeaderInternal(0, null, 0, null, view); - return this; - } - - public CharSequence getHeaderTitle() { - return mHeaderTitle; - } - - public Drawable getHeaderIcon() { - return mHeaderIcon; - } - - public View getHeaderView() { - return mHeaderView; - } - - /** - * Gets the root menu (if this is a submenu, find its root menu). - * @return The root menu. - */ - public MenuBuilder getRootMenu() { - return this; - } - - /** - * Sets the current menu info that is set on all items added to this menu - * (until this is called again with different menu info, in which case that - * one will be added to all subsequent item additions). - * - * @param menuInfo The extra menu information to add. - */ - public void setCurrentMenuInfo(ContextMenuInfo menuInfo) { - mCurrentMenuInfo = menuInfo; - } - - void setOptionalIconsVisible(boolean visible) { - mOptionalIconsVisible = visible; - } - - boolean getOptionalIconsVisible() { - return mOptionalIconsVisible; - } - - public boolean expandItemActionView(MenuItemImpl item) { - if (mPresenters.isEmpty()) return false; - - boolean expanded = false; - - stopDispatchingItemsChanged(); - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else if ((expanded = presenter.expandItemActionView(this, item))) { - break; - } - } - startDispatchingItemsChanged(); - - if (expanded) { - mExpandedItem = item; - } - return expanded; - } - - public boolean collapseItemActionView(MenuItemImpl item) { - if (mPresenters.isEmpty() || mExpandedItem != item) return false; - - boolean collapsed = false; - - stopDispatchingItemsChanged(); - for (WeakReference ref : mPresenters) { - final MenuPresenter presenter = ref.get(); - if (presenter == null) { - mPresenters.remove(ref); - } else if ((collapsed = presenter.collapseItemActionView(this, item))) { - break; - } - } - startDispatchingItemsChanged(); - - if (collapsed) { - mExpandedItem = null; - } - return collapsed; - } - - public MenuItemImpl getExpandedItem() { - return mExpandedItem; - } - - public boolean bindNativeOverflow(android.view.Menu menu, android.view.MenuItem.OnMenuItemClickListener listener, HashMap map) { - final List nonActionItems = getNonActionItems(); - if (nonActionItems == null || nonActionItems.size() == 0) { - return false; - } - - boolean visible = false; - menu.clear(); - for (MenuItemImpl nonActionItem : nonActionItems) { - if (!nonActionItem.isVisible()) { - continue; - } - visible = true; - - android.view.MenuItem nativeItem; - if (nonActionItem.hasSubMenu()) { - android.view.SubMenu nativeSub = menu.addSubMenu(nonActionItem.getGroupId(), nonActionItem.getItemId(), - nonActionItem.getOrder(), nonActionItem.getTitle()); - - SubMenuBuilder subMenu = (SubMenuBuilder)nonActionItem.getSubMenu(); - for (MenuItemImpl subItem : subMenu.getVisibleItems()) { - android.view.MenuItem nativeSubItem = nativeSub.add(subItem.getGroupId(), subItem.getItemId(), - subItem.getOrder(), subItem.getTitle()); - - nativeSubItem.setIcon(subItem.getIcon()); - nativeSubItem.setOnMenuItemClickListener(listener); - nativeSubItem.setEnabled(subItem.isEnabled()); - nativeSubItem.setIntent(subItem.getIntent()); - nativeSubItem.setNumericShortcut(subItem.getNumericShortcut()); - nativeSubItem.setAlphabeticShortcut(subItem.getAlphabeticShortcut()); - nativeSubItem.setTitleCondensed(subItem.getTitleCondensed()); - nativeSubItem.setCheckable(subItem.isCheckable()); - nativeSubItem.setChecked(subItem.isChecked()); - - if (subItem.isExclusiveCheckable()) { - nativeSub.setGroupCheckable(subItem.getGroupId(), true, true); - } - - map.put(nativeSubItem, subItem); - } - - nativeItem = nativeSub.getItem(); - } else { - nativeItem = menu.add(nonActionItem.getGroupId(), nonActionItem.getItemId(), - nonActionItem.getOrder(), nonActionItem.getTitle()); - } - nativeItem.setIcon(nonActionItem.getIcon()); - nativeItem.setOnMenuItemClickListener(listener); - nativeItem.setEnabled(nonActionItem.isEnabled()); - nativeItem.setIntent(nonActionItem.getIntent()); - nativeItem.setNumericShortcut(nonActionItem.getNumericShortcut()); - nativeItem.setAlphabeticShortcut(nonActionItem.getAlphabeticShortcut()); - nativeItem.setTitleCondensed(nonActionItem.getTitleCondensed()); - nativeItem.setCheckable(nonActionItem.isCheckable()); - nativeItem.setChecked(nonActionItem.isChecked()); - - if (nonActionItem.isExclusiveCheckable()) { - menu.setGroupCheckable(nonActionItem.getGroupId(), true, true); - } - - map.put(nativeItem, nonActionItem); - } - return visible; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemImpl.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemImpl.java deleted file mode 100644 index f5359fb4..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemImpl.java +++ /dev/null @@ -1,647 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.util.Log; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewDebug; -import android.widget.LinearLayout; - -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -/** - * @hide - */ -public final class MenuItemImpl implements MenuItem { - private static final String TAG = "MenuItemImpl"; - - private static final int SHOW_AS_ACTION_MASK = SHOW_AS_ACTION_NEVER | - SHOW_AS_ACTION_IF_ROOM | - SHOW_AS_ACTION_ALWAYS; - - private final int mId; - private final int mGroup; - private final int mCategoryOrder; - private final int mOrdering; - private CharSequence mTitle; - private CharSequence mTitleCondensed; - private Intent mIntent; - private char mShortcutNumericChar; - private char mShortcutAlphabeticChar; - - /** The icon's drawable which is only created as needed */ - private Drawable mIconDrawable; - /** - * The icon's resource ID which is used to get the Drawable when it is - * needed (if the Drawable isn't already obtained--only one of the two is - * needed). - */ - private int mIconResId = NO_ICON; - - /** The menu to which this item belongs */ - private MenuBuilder mMenu; - /** If this item should launch a sub menu, this is the sub menu to launch */ - private SubMenuBuilder mSubMenu; - - private Runnable mItemCallback; - private MenuItem.OnMenuItemClickListener mClickListener; - - private int mFlags = ENABLED; - private static final int CHECKABLE = 0x00000001; - private static final int CHECKED = 0x00000002; - private static final int EXCLUSIVE = 0x00000004; - private static final int HIDDEN = 0x00000008; - private static final int ENABLED = 0x00000010; - private static final int IS_ACTION = 0x00000020; - - private int mShowAsAction = SHOW_AS_ACTION_NEVER; - - private View mActionView; - private ActionProvider mActionProvider; - private OnActionExpandListener mOnActionExpandListener; - private boolean mIsActionViewExpanded = false; - - /** Used for the icon resource ID if this item does not have an icon */ - static final int NO_ICON = 0; - - /** - * Current use case is for context menu: Extra information linked to the - * View that added this item to the context menu. - */ - private ContextMenuInfo mMenuInfo; - - private static String sPrependShortcutLabel; - private static String sEnterShortcutLabel; - private static String sDeleteShortcutLabel; - private static String sSpaceShortcutLabel; - - - /** - * Instantiates this menu item. - * - * @param menu - * @param group Item ordering grouping control. The item will be added after - * all other items whose order is <= this number, and before any - * that are larger than it. This can also be used to define - * groups of items for batch state changes. Normally use 0. - * @param id Unique item ID. Use 0 if you do not need a unique ID. - * @param categoryOrder The ordering for this item. - * @param title The text to display for the item. - */ - MenuItemImpl(MenuBuilder menu, int group, int id, int categoryOrder, int ordering, - CharSequence title, int showAsAction) { - - /* TODO if (sPrependShortcutLabel == null) { - // This is instantiated from the UI thread, so no chance of sync issues - sPrependShortcutLabel = menu.getContext().getResources().getString( - com.android.internal.R.string.prepend_shortcut_label); - sEnterShortcutLabel = menu.getContext().getResources().getString( - com.android.internal.R.string.menu_enter_shortcut_label); - sDeleteShortcutLabel = menu.getContext().getResources().getString( - com.android.internal.R.string.menu_delete_shortcut_label); - sSpaceShortcutLabel = menu.getContext().getResources().getString( - com.android.internal.R.string.menu_space_shortcut_label); - }*/ - - mMenu = menu; - mId = id; - mGroup = group; - mCategoryOrder = categoryOrder; - mOrdering = ordering; - mTitle = title; - mShowAsAction = showAsAction; - } - - /** - * Invokes the item by calling various listeners or callbacks. - * - * @return true if the invocation was handled, false otherwise - */ - public boolean invoke() { - if (mClickListener != null && - mClickListener.onMenuItemClick(this)) { - return true; - } - - if (mMenu.dispatchMenuItemSelected(mMenu.getRootMenu(), this)) { - return true; - } - - if (mItemCallback != null) { - mItemCallback.run(); - return true; - } - - if (mIntent != null) { - try { - mMenu.getContext().startActivity(mIntent); - return true; - } catch (ActivityNotFoundException e) { - Log.e(TAG, "Can't find activity to handle intent; ignoring", e); - } - } - - if (mActionProvider != null && mActionProvider.onPerformDefaultAction()) { - return true; - } - - return false; - } - - public boolean isEnabled() { - return (mFlags & ENABLED) != 0; - } - - public MenuItem setEnabled(boolean enabled) { - if (enabled) { - mFlags |= ENABLED; - } else { - mFlags &= ~ENABLED; - } - - mMenu.onItemsChanged(false); - - return this; - } - - public int getGroupId() { - return mGroup; - } - - @ViewDebug.CapturedViewProperty - public int getItemId() { - return mId; - } - - public int getOrder() { - return mCategoryOrder; - } - - public int getOrdering() { - return mOrdering; - } - - public Intent getIntent() { - return mIntent; - } - - public MenuItem setIntent(Intent intent) { - mIntent = intent; - return this; - } - - Runnable getCallback() { - return mItemCallback; - } - - public MenuItem setCallback(Runnable callback) { - mItemCallback = callback; - return this; - } - - public char getAlphabeticShortcut() { - return mShortcutAlphabeticChar; - } - - public MenuItem setAlphabeticShortcut(char alphaChar) { - if (mShortcutAlphabeticChar == alphaChar) return this; - - mShortcutAlphabeticChar = Character.toLowerCase(alphaChar); - - mMenu.onItemsChanged(false); - - return this; - } - - public char getNumericShortcut() { - return mShortcutNumericChar; - } - - public MenuItem setNumericShortcut(char numericChar) { - if (mShortcutNumericChar == numericChar) return this; - - mShortcutNumericChar = numericChar; - - mMenu.onItemsChanged(false); - - return this; - } - - public MenuItem setShortcut(char numericChar, char alphaChar) { - mShortcutNumericChar = numericChar; - mShortcutAlphabeticChar = Character.toLowerCase(alphaChar); - - mMenu.onItemsChanged(false); - - return this; - } - - /** - * @return The active shortcut (based on QWERTY-mode of the menu). - */ - char getShortcut() { - return (mMenu.isQwertyMode() ? mShortcutAlphabeticChar : mShortcutNumericChar); - } - - /** - * @return The label to show for the shortcut. This includes the chording - * key (for example 'Menu+a'). Also, any non-human readable - * characters should be human readable (for example 'Menu+enter'). - */ - String getShortcutLabel() { - - char shortcut = getShortcut(); - if (shortcut == 0) { - return ""; - } - - StringBuilder sb = new StringBuilder(sPrependShortcutLabel); - switch (shortcut) { - - case '\n': - sb.append(sEnterShortcutLabel); - break; - - case '\b': - sb.append(sDeleteShortcutLabel); - break; - - case ' ': - sb.append(sSpaceShortcutLabel); - break; - - default: - sb.append(shortcut); - break; - } - - return sb.toString(); - } - - /** - * @return Whether this menu item should be showing shortcuts (depends on - * whether the menu should show shortcuts and whether this item has - * a shortcut defined) - */ - boolean shouldShowShortcut() { - // Show shortcuts if the menu is supposed to show shortcuts AND this item has a shortcut - return mMenu.isShortcutsVisible() && (getShortcut() != 0); - } - - public SubMenu getSubMenu() { - return mSubMenu; - } - - public boolean hasSubMenu() { - return mSubMenu != null; - } - - void setSubMenu(SubMenuBuilder subMenu) { - mSubMenu = subMenu; - - subMenu.setHeaderTitle(getTitle()); - } - - @ViewDebug.CapturedViewProperty - public CharSequence getTitle() { - return mTitle; - } - - /** - * Gets the title for a particular {@link ItemView} - * - * @param itemView The ItemView that is receiving the title - * @return Either the title or condensed title based on what the ItemView - * prefers - */ - CharSequence getTitleForItemView(MenuView.ItemView itemView) { - return ((itemView != null) && itemView.prefersCondensedTitle()) - ? getTitleCondensed() - : getTitle(); - } - - public MenuItem setTitle(CharSequence title) { - mTitle = title; - - mMenu.onItemsChanged(false); - - if (mSubMenu != null) { - mSubMenu.setHeaderTitle(title); - } - - return this; - } - - public MenuItem setTitle(int title) { - return setTitle(mMenu.getContext().getString(title)); - } - - public CharSequence getTitleCondensed() { - return mTitleCondensed != null ? mTitleCondensed : mTitle; - } - - public MenuItem setTitleCondensed(CharSequence title) { - mTitleCondensed = title; - - // Could use getTitle() in the loop below, but just cache what it would do here - if (title == null) { - title = mTitle; - } - - mMenu.onItemsChanged(false); - - return this; - } - - public Drawable getIcon() { - if (mIconDrawable != null) { - return mIconDrawable; - } - - if (mIconResId != NO_ICON) { - return mMenu.getResources().getDrawable(mIconResId); - } - - return null; - } - - public MenuItem setIcon(Drawable icon) { - mIconResId = NO_ICON; - mIconDrawable = icon; - mMenu.onItemsChanged(false); - - return this; - } - - public MenuItem setIcon(int iconResId) { - mIconDrawable = null; - mIconResId = iconResId; - - // If we have a view, we need to push the Drawable to them - mMenu.onItemsChanged(false); - - return this; - } - - public boolean isCheckable() { - return (mFlags & CHECKABLE) == CHECKABLE; - } - - public MenuItem setCheckable(boolean checkable) { - final int oldFlags = mFlags; - mFlags = (mFlags & ~CHECKABLE) | (checkable ? CHECKABLE : 0); - if (oldFlags != mFlags) { - mMenu.onItemsChanged(false); - } - - return this; - } - - public void setExclusiveCheckable(boolean exclusive) { - mFlags = (mFlags & ~EXCLUSIVE) | (exclusive ? EXCLUSIVE : 0); - } - - public boolean isExclusiveCheckable() { - return (mFlags & EXCLUSIVE) != 0; - } - - public boolean isChecked() { - return (mFlags & CHECKED) == CHECKED; - } - - public MenuItem setChecked(boolean checked) { - if ((mFlags & EXCLUSIVE) != 0) { - // Call the method on the Menu since it knows about the others in this - // exclusive checkable group - mMenu.setExclusiveItemChecked(this); - } else { - setCheckedInt(checked); - } - - return this; - } - - void setCheckedInt(boolean checked) { - final int oldFlags = mFlags; - mFlags = (mFlags & ~CHECKED) | (checked ? CHECKED : 0); - if (oldFlags != mFlags) { - mMenu.onItemsChanged(false); - } - } - - public boolean isVisible() { - return (mFlags & HIDDEN) == 0; - } - - /** - * Changes the visibility of the item. This method DOES NOT notify the - * parent menu of a change in this item, so this should only be called from - * methods that will eventually trigger this change. If unsure, use {@link #setVisible(boolean)} - * instead. - * - * @param shown Whether to show (true) or hide (false). - * @return Whether the item's shown state was changed - */ - boolean setVisibleInt(boolean shown) { - final int oldFlags = mFlags; - mFlags = (mFlags & ~HIDDEN) | (shown ? 0 : HIDDEN); - return oldFlags != mFlags; - } - - public MenuItem setVisible(boolean shown) { - // Try to set the shown state to the given state. If the shown state was changed - // (i.e. the previous state isn't the same as given state), notify the parent menu that - // the shown state has changed for this item - if (setVisibleInt(shown)) mMenu.onItemVisibleChanged(this); - - return this; - } - - public MenuItem setOnMenuItemClickListener(MenuItem.OnMenuItemClickListener clickListener) { - mClickListener = clickListener; - return this; - } - - @Override - public String toString() { - return mTitle.toString(); - } - - void setMenuInfo(ContextMenuInfo menuInfo) { - mMenuInfo = menuInfo; - } - - public ContextMenuInfo getMenuInfo() { - return mMenuInfo; - } - - public void actionFormatChanged() { - mMenu.onItemActionRequestChanged(this); - } - - /** - * @return Whether the menu should show icons for menu items. - */ - public boolean shouldShowIcon() { - return mMenu.getOptionalIconsVisible(); - } - - public boolean isActionButton() { - return (mFlags & IS_ACTION) == IS_ACTION; - } - - public boolean requestsActionButton() { - return (mShowAsAction & SHOW_AS_ACTION_IF_ROOM) == SHOW_AS_ACTION_IF_ROOM; - } - - public boolean requiresActionButton() { - return (mShowAsAction & SHOW_AS_ACTION_ALWAYS) == SHOW_AS_ACTION_ALWAYS; - } - - public void setIsActionButton(boolean isActionButton) { - if (isActionButton) { - mFlags |= IS_ACTION; - } else { - mFlags &= ~IS_ACTION; - } - } - - public boolean showsTextAsAction() { - return (mShowAsAction & SHOW_AS_ACTION_WITH_TEXT) == SHOW_AS_ACTION_WITH_TEXT; - } - - public void setShowAsAction(int actionEnum) { - switch (actionEnum & SHOW_AS_ACTION_MASK) { - case SHOW_AS_ACTION_ALWAYS: - case SHOW_AS_ACTION_IF_ROOM: - case SHOW_AS_ACTION_NEVER: - // Looks good! - break; - - default: - // Mutually exclusive options selected! - throw new IllegalArgumentException("SHOW_AS_ACTION_ALWAYS, SHOW_AS_ACTION_IF_ROOM," - + " and SHOW_AS_ACTION_NEVER are mutually exclusive."); - } - mShowAsAction = actionEnum; - mMenu.onItemActionRequestChanged(this); - } - - public MenuItem setActionView(View view) { - mActionView = view; - mActionProvider = null; - if (view != null && view.getId() == View.NO_ID && mId > 0) { - view.setId(mId); - } - mMenu.onItemActionRequestChanged(this); - return this; - } - - public MenuItem setActionView(int resId) { - final Context context = mMenu.getContext(); - final LayoutInflater inflater = LayoutInflater.from(context); - setActionView(inflater.inflate(resId, new LinearLayout(context), false)); - return this; - } - - public View getActionView() { - if (mActionView != null) { - return mActionView; - } else if (mActionProvider != null) { - mActionView = mActionProvider.onCreateActionView(); - return mActionView; - } else { - return null; - } - } - - public ActionProvider getActionProvider() { - return mActionProvider; - } - - public MenuItem setActionProvider(ActionProvider actionProvider) { - mActionView = null; - mActionProvider = actionProvider; - mMenu.onItemsChanged(true); // Measurement can be changed - return this; - } - - @Override - public MenuItem setShowAsActionFlags(int actionEnum) { - setShowAsAction(actionEnum); - return this; - } - - @Override - public boolean expandActionView() { - if ((mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) == 0 || mActionView == null) { - return false; - } - - if (mOnActionExpandListener == null || - mOnActionExpandListener.onMenuItemActionExpand(this)) { - return mMenu.expandItemActionView(this); - } - - return false; - } - - @Override - public boolean collapseActionView() { - if ((mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) == 0) { - return false; - } - if (mActionView == null) { - // We're already collapsed if we have no action view. - return true; - } - - if (mOnActionExpandListener == null || - mOnActionExpandListener.onMenuItemActionCollapse(this)) { - return mMenu.collapseItemActionView(this); - } - - return false; - } - - @Override - public MenuItem setOnActionExpandListener(OnActionExpandListener listener) { - mOnActionExpandListener = listener; - return this; - } - - public boolean hasCollapsibleActionView() { - return (mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) != 0 && mActionView != null; - } - - public void setActionViewExpanded(boolean isExpanded) { - mIsActionViewExpanded = isExpanded; - mMenu.onItemsChanged(false); - } - - public boolean isActionViewExpanded() { - return mIsActionViewExpanded; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemWrapper.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemWrapper.java deleted file mode 100644 index aaf2997b..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuItemWrapper.java +++ /dev/null @@ -1,310 +0,0 @@ -package com.actionbarsherlock.internal.view.menu; - -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.View; -import com.actionbarsherlock.internal.view.ActionProviderWrapper; -import com.actionbarsherlock.internal.widget.CollapsibleActionViewWrapper; -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.view.CollapsibleActionView; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -public class MenuItemWrapper implements MenuItem, android.view.MenuItem.OnMenuItemClickListener { - private final android.view.MenuItem mNativeItem; - private SubMenu mSubMenu = null; - private OnMenuItemClickListener mMenuItemClickListener = null; - private OnActionExpandListener mActionExpandListener = null; - private android.view.MenuItem.OnActionExpandListener mNativeActionExpandListener = null; - - - public MenuItemWrapper(android.view.MenuItem nativeItem) { - if (nativeItem == null) { - throw new IllegalStateException("Wrapped menu item cannot be null."); - } - mNativeItem = nativeItem; - } - - - @Override - public int getItemId() { - return mNativeItem.getItemId(); - } - - @Override - public int getGroupId() { - return mNativeItem.getGroupId(); - } - - @Override - public int getOrder() { - return mNativeItem.getOrder(); - } - - @Override - public MenuItem setTitle(CharSequence title) { - mNativeItem.setTitle(title); - return this; - } - - @Override - public MenuItem setTitle(int title) { - mNativeItem.setTitle(title); - return this; - } - - @Override - public CharSequence getTitle() { - return mNativeItem.getTitle(); - } - - @Override - public MenuItem setTitleCondensed(CharSequence title) { - mNativeItem.setTitleCondensed(title); - return this; - } - - @Override - public CharSequence getTitleCondensed() { - return mNativeItem.getTitleCondensed(); - } - - @Override - public MenuItem setIcon(Drawable icon) { - mNativeItem.setIcon(icon); - return this; - } - - @Override - public MenuItem setIcon(int iconRes) { - mNativeItem.setIcon(iconRes); - return this; - } - - @Override - public Drawable getIcon() { - return mNativeItem.getIcon(); - } - - @Override - public MenuItem setIntent(Intent intent) { - mNativeItem.setIntent(intent); - return this; - } - - @Override - public Intent getIntent() { - return mNativeItem.getIntent(); - } - - @Override - public MenuItem setShortcut(char numericChar, char alphaChar) { - mNativeItem.setShortcut(numericChar, alphaChar); - return this; - } - - @Override - public MenuItem setNumericShortcut(char numericChar) { - mNativeItem.setNumericShortcut(numericChar); - return this; - } - - @Override - public char getNumericShortcut() { - return mNativeItem.getNumericShortcut(); - } - - @Override - public MenuItem setAlphabeticShortcut(char alphaChar) { - mNativeItem.setAlphabeticShortcut(alphaChar); - return this; - } - - @Override - public char getAlphabeticShortcut() { - return mNativeItem.getAlphabeticShortcut(); - } - - @Override - public MenuItem setCheckable(boolean checkable) { - mNativeItem.setCheckable(checkable); - return this; - } - - @Override - public boolean isCheckable() { - return mNativeItem.isCheckable(); - } - - @Override - public MenuItem setChecked(boolean checked) { - mNativeItem.setChecked(checked); - return this; - } - - @Override - public boolean isChecked() { - return mNativeItem.isChecked(); - } - - @Override - public MenuItem setVisible(boolean visible) { - mNativeItem.setVisible(visible); - return this; - } - - @Override - public boolean isVisible() { - return mNativeItem.isVisible(); - } - - @Override - public MenuItem setEnabled(boolean enabled) { - mNativeItem.setEnabled(enabled); - return this; - } - - @Override - public boolean isEnabled() { - return mNativeItem.isEnabled(); - } - - @Override - public boolean hasSubMenu() { - return mNativeItem.hasSubMenu(); - } - - @Override - public SubMenu getSubMenu() { - if (hasSubMenu() && (mSubMenu == null)) { - mSubMenu = new SubMenuWrapper(mNativeItem.getSubMenu()); - } - return mSubMenu; - } - - @Override - public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener menuItemClickListener) { - mMenuItemClickListener = menuItemClickListener; - //Register ourselves as the listener to proxy - mNativeItem.setOnMenuItemClickListener(this); - return this; - } - - @Override - public boolean onMenuItemClick(android.view.MenuItem item) { - if (mMenuItemClickListener != null) { - return mMenuItemClickListener.onMenuItemClick(this); - } - return false; - } - - @Override - public ContextMenuInfo getMenuInfo() { - return mNativeItem.getMenuInfo(); - } - - @Override - public void setShowAsAction(int actionEnum) { - mNativeItem.setShowAsAction(actionEnum); - } - - @Override - public MenuItem setShowAsActionFlags(int actionEnum) { - mNativeItem.setShowAsActionFlags(actionEnum); - return this; - } - - @Override - public MenuItem setActionView(View view) { - if (view != null && view instanceof CollapsibleActionView) { - view = new CollapsibleActionViewWrapper(view); - } - mNativeItem.setActionView(view); - return this; - } - - @Override - public MenuItem setActionView(int resId) { - //Allow the native menu to inflate the resource - mNativeItem.setActionView(resId); - if (resId != 0) { - //Get newly created view - View view = mNativeItem.getActionView(); - if (view instanceof CollapsibleActionView) { - //Wrap it and re-set it - mNativeItem.setActionView(new CollapsibleActionViewWrapper(view)); - } - } - return this; - } - - @Override - public View getActionView() { - View actionView = mNativeItem.getActionView(); - if (actionView instanceof CollapsibleActionViewWrapper) { - return ((CollapsibleActionViewWrapper)actionView).unwrap(); - } - return actionView; - } - - @Override - public MenuItem setActionProvider(ActionProvider actionProvider) { - mNativeItem.setActionProvider(new ActionProviderWrapper(actionProvider)); - return this; - } - - @Override - public ActionProvider getActionProvider() { - android.view.ActionProvider nativeProvider = mNativeItem.getActionProvider(); - if (nativeProvider != null && nativeProvider instanceof ActionProviderWrapper) { - return ((ActionProviderWrapper)nativeProvider).unwrap(); - } - return null; - } - - @Override - public boolean expandActionView() { - return mNativeItem.expandActionView(); - } - - @Override - public boolean collapseActionView() { - return mNativeItem.collapseActionView(); - } - - @Override - public boolean isActionViewExpanded() { - return mNativeItem.isActionViewExpanded(); - } - - @Override - public MenuItem setOnActionExpandListener(OnActionExpandListener listener) { - mActionExpandListener = listener; - - if (mNativeActionExpandListener == null) { - mNativeActionExpandListener = new android.view.MenuItem.OnActionExpandListener() { - @Override - public boolean onMenuItemActionExpand(android.view.MenuItem menuItem) { - if (mActionExpandListener != null) { - return mActionExpandListener.onMenuItemActionExpand(MenuItemWrapper.this); - } - return false; - } - - @Override - public boolean onMenuItemActionCollapse(android.view.MenuItem menuItem) { - if (mActionExpandListener != null) { - return mActionExpandListener.onMenuItemActionCollapse(MenuItemWrapper.this); - } - return false; - } - }; - - //Register our inner-class as the listener to proxy method calls - mNativeItem.setOnActionExpandListener(mNativeActionExpandListener); - } - - return this; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuPopupHelper.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuPopupHelper.java deleted file mode 100644 index f030de31..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuPopupHelper.java +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import java.util.ArrayList; -import android.content.Context; -import android.content.res.Resources; -import android.database.DataSetObserver; -import android.os.Parcelable; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.MeasureSpec; -import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.FrameLayout; -import android.widget.ListAdapter; -import android.widget.PopupWindow; -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.view.View_HasStateListenerSupport; -import com.actionbarsherlock.internal.view.View_OnAttachStateChangeListener; -import com.actionbarsherlock.internal.widget.IcsListPopupWindow; -import com.actionbarsherlock.view.MenuItem; - -/** - * Presents a menu as a small, simple popup anchored to another view. - * @hide - */ -public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.OnKeyListener, - ViewTreeObserver.OnGlobalLayoutListener, PopupWindow.OnDismissListener, - View_OnAttachStateChangeListener, MenuPresenter { - //UNUSED private static final String TAG = "MenuPopupHelper"; - - static final int ITEM_LAYOUT = R.layout.abs__popup_menu_item_layout; - - private Context mContext; - private LayoutInflater mInflater; - private IcsListPopupWindow mPopup; - private MenuBuilder mMenu; - private int mPopupMaxWidth; - private View mAnchorView; - private boolean mOverflowOnly; - private ViewTreeObserver mTreeObserver; - - private MenuAdapter mAdapter; - - private Callback mPresenterCallback; - - boolean mForceShowIcon; - - private ViewGroup mMeasureParent; - - public MenuPopupHelper(Context context, MenuBuilder menu) { - this(context, menu, null, false); - } - - public MenuPopupHelper(Context context, MenuBuilder menu, View anchorView) { - this(context, menu, anchorView, false); - } - - public MenuPopupHelper(Context context, MenuBuilder menu, - View anchorView, boolean overflowOnly) { - mContext = context; - mInflater = LayoutInflater.from(context); - mMenu = menu; - mOverflowOnly = overflowOnly; - - final Resources res = context.getResources(); - mPopupMaxWidth = Math.max(res.getDisplayMetrics().widthPixels / 2, - res.getDimensionPixelSize(R.dimen.abs__config_prefDialogWidth)); - - mAnchorView = anchorView; - - menu.addMenuPresenter(this); - } - - public void setAnchorView(View anchor) { - mAnchorView = anchor; - } - - public void setForceShowIcon(boolean forceShow) { - mForceShowIcon = forceShow; - } - - public void show() { - if (!tryShow()) { - throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor"); - } - } - - public boolean tryShow() { - mPopup = new IcsListPopupWindow(mContext, null, R.attr.popupMenuStyle); - mPopup.setOnDismissListener(this); - mPopup.setOnItemClickListener(this); - - mAdapter = new MenuAdapter(mMenu); - mPopup.setAdapter(mAdapter); - mPopup.setModal(true); - - View anchor = mAnchorView; - if (anchor != null) { - final boolean addGlobalListener = mTreeObserver == null; - mTreeObserver = anchor.getViewTreeObserver(); // Refresh to latest - if (addGlobalListener) mTreeObserver.addOnGlobalLayoutListener(this); - ((View_HasStateListenerSupport)anchor).addOnAttachStateChangeListener(this); - mPopup.setAnchorView(anchor); - } else { - return false; - } - - mPopup.setContentWidth(Math.min(measureContentWidth(mAdapter), mPopupMaxWidth)); - mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); - mPopup.show(); - mPopup.getListView().setOnKeyListener(this); - return true; - } - - public void dismiss() { - if (isShowing()) { - mPopup.dismiss(); - } - } - - public void onDismiss() { - mPopup = null; - mMenu.close(); - if (mTreeObserver != null) { - if (!mTreeObserver.isAlive()) mTreeObserver = mAnchorView.getViewTreeObserver(); - mTreeObserver.removeGlobalOnLayoutListener(this); - mTreeObserver = null; - } - ((View_HasStateListenerSupport)mAnchorView).removeOnAttachStateChangeListener(this); - } - - public boolean isShowing() { - return mPopup != null && mPopup.isShowing(); - } - - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - MenuAdapter adapter = mAdapter; - adapter.mAdapterMenu.performItemAction(adapter.getItem(position), 0); - } - - public boolean onKey(View v, int keyCode, KeyEvent event) { - if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_MENU) { - dismiss(); - return true; - } - return false; - } - - private int measureContentWidth(ListAdapter adapter) { - // Menus don't tend to be long, so this is more sane than it looks. - int width = 0; - View itemView = null; - int itemType = 0; - final int widthMeasureSpec = - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - final int heightMeasureSpec = - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - final int count = adapter.getCount(); - for (int i = 0; i < count; i++) { - final int positionType = adapter.getItemViewType(i); - if (positionType != itemType) { - itemType = positionType; - itemView = null; - } - if (mMeasureParent == null) { - mMeasureParent = new FrameLayout(mContext); - } - itemView = adapter.getView(i, itemView, mMeasureParent); - itemView.measure(widthMeasureSpec, heightMeasureSpec); - width = Math.max(width, itemView.getMeasuredWidth()); - } - return width; - } - - @Override - public void onGlobalLayout() { - if (isShowing()) { - final View anchor = mAnchorView; - if (anchor == null || !anchor.isShown()) { - dismiss(); - } else if (isShowing()) { - // Recompute window size and position - mPopup.show(); - } - } - } - - @Override - public void onViewAttachedToWindow(View v) { - } - - @Override - public void onViewDetachedFromWindow(View v) { - if (mTreeObserver != null) { - if (!mTreeObserver.isAlive()) mTreeObserver = v.getViewTreeObserver(); - mTreeObserver.removeGlobalOnLayoutListener(this); - } - ((View_HasStateListenerSupport)v).removeOnAttachStateChangeListener(this); - } - - @Override - public void initForMenu(Context context, MenuBuilder menu) { - // Don't need to do anything; we added as a presenter in the constructor. - } - - @Override - public MenuView getMenuView(ViewGroup root) { - throw new UnsupportedOperationException("MenuPopupHelpers manage their own views"); - } - - @Override - public void updateMenuView(boolean cleared) { - if (mAdapter != null) mAdapter.notifyDataSetChanged(); - } - - @Override - public void setCallback(Callback cb) { - mPresenterCallback = cb; - } - - @Override - public boolean onSubMenuSelected(SubMenuBuilder subMenu) { - if (subMenu.hasVisibleItems()) { - MenuPopupHelper subPopup = new MenuPopupHelper(mContext, subMenu, mAnchorView, false); - subPopup.setCallback(mPresenterCallback); - - boolean preserveIconSpacing = false; - final int count = subMenu.size(); - for (int i = 0; i < count; i++) { - MenuItem childItem = subMenu.getItem(i); - if (childItem.isVisible() && childItem.getIcon() != null) { - preserveIconSpacing = true; - break; - } - } - subPopup.setForceShowIcon(preserveIconSpacing); - - if (subPopup.tryShow()) { - if (mPresenterCallback != null) { - mPresenterCallback.onOpenSubMenu(subMenu); - } - return true; - } - } - return false; - } - - @Override - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - // Only care about the (sub)menu we're presenting. - if (menu != mMenu) return; - - dismiss(); - if (mPresenterCallback != null) { - mPresenterCallback.onCloseMenu(menu, allMenusAreClosing); - } - } - - @Override - public boolean flagActionItems() { - return false; - } - - public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { - return false; - } - - public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { - return false; - } - - @Override - public int getId() { - return 0; - } - - @Override - public Parcelable onSaveInstanceState() { - return null; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - } - - private class MenuAdapter extends BaseAdapter { - private MenuBuilder mAdapterMenu; - private int mExpandedIndex = -1; - - public MenuAdapter(MenuBuilder menu) { - mAdapterMenu = menu; - registerDataSetObserver(new ExpandedIndexObserver()); - findExpandedIndex(); - } - - public int getCount() { - ArrayList items = mOverflowOnly ? - mAdapterMenu.getNonActionItems() : mAdapterMenu.getVisibleItems(); - if (mExpandedIndex < 0) { - return items.size(); - } - return items.size() - 1; - } - - public MenuItemImpl getItem(int position) { - ArrayList items = mOverflowOnly ? - mAdapterMenu.getNonActionItems() : mAdapterMenu.getVisibleItems(); - if (mExpandedIndex >= 0 && position >= mExpandedIndex) { - position++; - } - return items.get(position); - } - - public long getItemId(int position) { - // Since a menu item's ID is optional, we'll use the position as an - // ID for the item in the AdapterView - return position; - } - - public View getView(int position, View convertView, ViewGroup parent) { - if (convertView == null) { - convertView = mInflater.inflate(ITEM_LAYOUT, parent, false); - } - - MenuView.ItemView itemView = (MenuView.ItemView) convertView; - if (mForceShowIcon) { - ((ListMenuItemView) convertView).setForceShowIcon(true); - } - itemView.initialize(getItem(position), 0); - return convertView; - } - - void findExpandedIndex() { - final MenuItemImpl expandedItem = mMenu.getExpandedItem(); - if (expandedItem != null) { - final ArrayList items = mMenu.getNonActionItems(); - final int count = items.size(); - for (int i = 0; i < count; i++) { - final MenuItemImpl item = items.get(i); - if (item == expandedItem) { - mExpandedIndex = i; - return; - } - } - } - mExpandedIndex = -1; - } - } - - private class ExpandedIndexObserver extends DataSetObserver { - @Override - public void onChanged() { - mAdapter.findExpandedIndex(); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuPresenter.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuPresenter.java deleted file mode 100644 index c3f35472..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuPresenter.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import android.content.Context; -import android.os.Parcelable; -import android.view.ViewGroup; - -/** - * A MenuPresenter is responsible for building views for a Menu object. - * It takes over some responsibility from the old style monolithic MenuBuilder class. - */ -public interface MenuPresenter { - /** - * Called by menu implementation to notify another component of open/close events. - */ - public interface Callback { - /** - * Called when a menu is closing. - * @param menu - * @param allMenusAreClosing - */ - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing); - - /** - * Called when a submenu opens. Useful for notifying the application - * of menu state so that it does not attempt to hide the action bar - * while a submenu is open or similar. - * - * @param subMenu Submenu currently being opened - * @return true if the Callback will handle presenting the submenu, false if - * the presenter should attempt to do so. - */ - public boolean onOpenSubMenu(MenuBuilder subMenu); - } - - /** - * Initialize this presenter for the given context and menu. - * This method is called by MenuBuilder when a presenter is - * added. See {@link MenuBuilder#addMenuPresenter(MenuPresenter)} - * - * @param context Context for this presenter; used for view creation and resource management - * @param menu Menu to host - */ - public void initForMenu(Context context, MenuBuilder menu); - - /** - * Retrieve a MenuView to display the menu specified in - * {@link #initForMenu(Context, Menu)}. - * - * @param root Intended parent of the MenuView. - * @return A freshly created MenuView. - */ - public MenuView getMenuView(ViewGroup root); - - /** - * Update the menu UI in response to a change. Called by - * MenuBuilder during the normal course of operation. - * - * @param cleared true if the menu was entirely cleared - */ - public void updateMenuView(boolean cleared); - - /** - * Set a callback object that will be notified of menu events - * related to this specific presentation. - * @param cb Callback that will be notified of future events - */ - public void setCallback(Callback cb); - - /** - * Called by Menu implementations to indicate that a submenu item - * has been selected. An active Callback should be notified, and - * if applicable the presenter should present the submenu. - * - * @param subMenu SubMenu being opened - * @return true if the the event was handled, false otherwise. - */ - public boolean onSubMenuSelected(SubMenuBuilder subMenu); - - /** - * Called by Menu implementations to indicate that a menu or submenu is - * closing. Presenter implementations should close the representation - * of the menu indicated as necessary and notify a registered callback. - * - * @param menu Menu or submenu that is closing. - * @param allMenusAreClosing True if all associated menus are closing. - */ - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing); - - /** - * Called by Menu implementations to flag items that will be shown as actions. - * @return true if this presenter changed the action status of any items. - */ - public boolean flagActionItems(); - - /** - * Called when a menu item with a collapsable action view should expand its action view. - * - * @param menu Menu containing the item to be expanded - * @param item Item to be expanded - * @return true if this presenter expanded the action view, false otherwise. - */ - public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item); - - /** - * Called when a menu item with a collapsable action view should collapse its action view. - * - * @param menu Menu containing the item to be collapsed - * @param item Item to be collapsed - * @return true if this presenter collapsed the action view, false otherwise. - */ - public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item); - - /** - * Returns an ID for determining how to save/restore instance state. - * @return a valid ID value. - */ - public int getId(); - - /** - * Returns a Parcelable describing the current state of the presenter. - * It will be passed to the {@link #onRestoreInstanceState(Parcelable)} - * method of the presenter sharing the same ID later. - * @return The saved instance state - */ - public Parcelable onSaveInstanceState(); - - /** - * Supplies the previously saved instance state to be restored. - * @param state The previously saved instance state - */ - public void onRestoreInstanceState(Parcelable state); -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuView.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuView.java deleted file mode 100644 index 323ba2d8..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuView.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import android.graphics.drawable.Drawable; - -/** - * Minimal interface for a menu view. {@link #initialize(MenuBuilder)} must be called for the - * menu to be functional. - * - * @hide - */ -public interface MenuView { - /** - * Initializes the menu to the given menu. This should be called after the - * view is inflated. - * - * @param menu The menu that this MenuView should display. - */ - public void initialize(MenuBuilder menu); - - /** - * Returns the default animations to be used for this menu when entering/exiting. - * @return A resource ID for the default animations to be used for this menu. - */ - public int getWindowAnimations(); - - /** - * Minimal interface for a menu item view. {@link #initialize(MenuItemImpl, int)} must be called - * for the item to be functional. - */ - public interface ItemView { - /** - * Initializes with the provided MenuItemData. This should be called after the view is - * inflated. - * @param itemData The item that this ItemView should display. - * @param menuType The type of this menu, one of - * {@link MenuBuilder#TYPE_ICON}, {@link MenuBuilder#TYPE_EXPANDED}, - * {@link MenuBuilder#TYPE_DIALOG}). - */ - public void initialize(MenuItemImpl itemData, int menuType); - - /** - * Gets the item data that this view is displaying. - * @return the item data, or null if there is not one - */ - public MenuItemImpl getItemData(); - - /** - * Sets the title of the item view. - * @param title The title to set. - */ - public void setTitle(CharSequence title); - - /** - * Sets the enabled state of the item view. - * @param enabled Whether the item view should be enabled. - */ - public void setEnabled(boolean enabled); - - /** - * Displays the checkbox for the item view. This does not ensure the item view will be - * checked, for that use {@link #setChecked}. - * @param checkable Whether to display the checkbox or to hide it - */ - public void setCheckable(boolean checkable); - - /** - * Checks the checkbox for the item view. If the checkbox is hidden, it will NOT be - * made visible, call {@link #setCheckable(boolean)} for that. - * @param checked Whether the checkbox should be checked - */ - public void setChecked(boolean checked); - - /** - * Sets the shortcut for the item. - * @param showShortcut Whether a shortcut should be shown(if false, the value of - * shortcutKey should be ignored). - * @param shortcutKey The shortcut key that should be shown on the ItemView. - */ - public void setShortcut(boolean showShortcut, char shortcutKey); - - /** - * Set the icon of this item view. - * @param icon The icon of this item. null to hide the icon. - */ - public void setIcon(Drawable icon); - - /** - * Whether this item view prefers displaying the condensed title rather - * than the normal title. If a condensed title is not available, the - * normal title will be used. - * - * @return Whether this item view prefers displaying the condensed - * title. - */ - public boolean prefersCondensedTitle(); - - /** - * Whether this item view shows an icon. - * - * @return Whether this item view shows an icon. - */ - public boolean showsIcon(); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuWrapper.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuWrapper.java deleted file mode 100644 index 3d4dd42f..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/MenuWrapper.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.actionbarsherlock.internal.view.menu; - -import java.util.WeakHashMap; -import android.content.ComponentName; -import android.content.Intent; -import android.view.KeyEvent; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -public class MenuWrapper implements Menu { - private final android.view.Menu mNativeMenu; - - private final WeakHashMap mNativeMap = - new WeakHashMap(); - - - public MenuWrapper(android.view.Menu nativeMenu) { - mNativeMenu = nativeMenu; - } - - public android.view.Menu unwrap() { - return mNativeMenu; - } - - private MenuItem addInternal(android.view.MenuItem nativeItem) { - MenuItem item = new MenuItemWrapper(nativeItem); - mNativeMap.put(nativeItem, item); - return item; - } - - @Override - public MenuItem add(CharSequence title) { - return addInternal(mNativeMenu.add(title)); - } - - @Override - public MenuItem add(int titleRes) { - return addInternal(mNativeMenu.add(titleRes)); - } - - @Override - public MenuItem add(int groupId, int itemId, int order, CharSequence title) { - return addInternal(mNativeMenu.add(groupId, itemId, order, title)); - } - - @Override - public MenuItem add(int groupId, int itemId, int order, int titleRes) { - return addInternal(mNativeMenu.add(groupId, itemId, order, titleRes)); - } - - private SubMenu addInternal(android.view.SubMenu nativeSubMenu) { - SubMenu subMenu = new SubMenuWrapper(nativeSubMenu); - android.view.MenuItem nativeItem = nativeSubMenu.getItem(); - MenuItem item = subMenu.getItem(); - mNativeMap.put(nativeItem, item); - return subMenu; - } - - @Override - public SubMenu addSubMenu(CharSequence title) { - return addInternal(mNativeMenu.addSubMenu(title)); - } - - @Override - public SubMenu addSubMenu(int titleRes) { - return addInternal(mNativeMenu.addSubMenu(titleRes)); - } - - @Override - public SubMenu addSubMenu(int groupId, int itemId, int order, CharSequence title) { - return addInternal(mNativeMenu.addSubMenu(groupId, itemId, order, title)); - } - - @Override - public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) { - return addInternal(mNativeMenu.addSubMenu(groupId, itemId, order, titleRes)); - } - - @Override - public int addIntentOptions(int groupId, int itemId, int order, ComponentName caller, Intent[] specifics, Intent intent, int flags, MenuItem[] outSpecificItems) { - int result; - if (outSpecificItems != null) { - android.view.MenuItem[] nativeOutItems = new android.view.MenuItem[outSpecificItems.length]; - result = mNativeMenu.addIntentOptions(groupId, itemId, order, caller, specifics, intent, flags, nativeOutItems); - for (int i = 0, length = outSpecificItems.length; i < length; i++) { - outSpecificItems[i] = new MenuItemWrapper(nativeOutItems[i]); - } - } else { - result = mNativeMenu.addIntentOptions(groupId, itemId, order, caller, specifics, intent, flags, null); - } - return result; - } - - @Override - public void removeItem(int id) { - mNativeMenu.removeItem(id); - } - - @Override - public void removeGroup(int groupId) { - mNativeMenu.removeGroup(groupId); - } - - @Override - public void clear() { - mNativeMap.clear(); - mNativeMenu.clear(); - } - - @Override - public void setGroupCheckable(int group, boolean checkable, boolean exclusive) { - mNativeMenu.setGroupCheckable(group, checkable, exclusive); - } - - @Override - public void setGroupVisible(int group, boolean visible) { - mNativeMenu.setGroupVisible(group, visible); - } - - @Override - public void setGroupEnabled(int group, boolean enabled) { - mNativeMenu.setGroupEnabled(group, enabled); - } - - @Override - public boolean hasVisibleItems() { - return mNativeMenu.hasVisibleItems(); - } - - @Override - public MenuItem findItem(int id) { - android.view.MenuItem nativeItem = mNativeMenu.findItem(id); - return findItem(nativeItem); - } - - public MenuItem findItem(android.view.MenuItem nativeItem) { - if (nativeItem == null) { - return null; - } - - MenuItem wrapped = mNativeMap.get(nativeItem); - if (wrapped != null) { - return wrapped; - } - - return addInternal(nativeItem); - } - - @Override - public int size() { - return mNativeMenu.size(); - } - - @Override - public MenuItem getItem(int index) { - android.view.MenuItem nativeItem = mNativeMenu.getItem(index); - return findItem(nativeItem); - } - - @Override - public void close() { - mNativeMenu.close(); - } - - @Override - public boolean performShortcut(int keyCode, KeyEvent event, int flags) { - return mNativeMenu.performShortcut(keyCode, event, flags); - } - - @Override - public boolean isShortcutKey(int keyCode, KeyEvent event) { - return mNativeMenu.isShortcutKey(keyCode, event); - } - - @Override - public boolean performIdentifierAction(int id, int flags) { - return mNativeMenu.performIdentifierAction(id, flags); - } - - @Override - public void setQwertyMode(boolean isQwerty) { - mNativeMenu.setQwertyMode(isQwerty); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuBuilder.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuBuilder.java deleted file mode 100644 index 6679cf38..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuBuilder.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.view.menu; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.view.View; - -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -/** - * The model for a sub menu, which is an extension of the menu. Most methods are proxied to - * the parent menu. - */ -public class SubMenuBuilder extends MenuBuilder implements SubMenu { - private MenuBuilder mParentMenu; - private MenuItemImpl mItem; - - public SubMenuBuilder(Context context, MenuBuilder parentMenu, MenuItemImpl item) { - super(context); - - mParentMenu = parentMenu; - mItem = item; - } - - @Override - public void setQwertyMode(boolean isQwerty) { - mParentMenu.setQwertyMode(isQwerty); - } - - @Override - public boolean isQwertyMode() { - return mParentMenu.isQwertyMode(); - } - - @Override - public void setShortcutsVisible(boolean shortcutsVisible) { - mParentMenu.setShortcutsVisible(shortcutsVisible); - } - - @Override - public boolean isShortcutsVisible() { - return mParentMenu.isShortcutsVisible(); - } - - public Menu getParentMenu() { - return mParentMenu; - } - - public MenuItem getItem() { - return mItem; - } - - @Override - public void setCallback(Callback callback) { - mParentMenu.setCallback(callback); - } - - @Override - public MenuBuilder getRootMenu() { - return mParentMenu; - } - - @Override - boolean dispatchMenuItemSelected(MenuBuilder menu, MenuItem item) { - return super.dispatchMenuItemSelected(menu, item) || - mParentMenu.dispatchMenuItemSelected(menu, item); - } - - public SubMenu setIcon(Drawable icon) { - mItem.setIcon(icon); - return this; - } - - public SubMenu setIcon(int iconRes) { - mItem.setIcon(iconRes); - return this; - } - - public SubMenu setHeaderIcon(Drawable icon) { - return (SubMenu) super.setHeaderIconInt(icon); - } - - public SubMenu setHeaderIcon(int iconRes) { - return (SubMenu) super.setHeaderIconInt(iconRes); - } - - public SubMenu setHeaderTitle(CharSequence title) { - return (SubMenu) super.setHeaderTitleInt(title); - } - - public SubMenu setHeaderTitle(int titleRes) { - return (SubMenu) super.setHeaderTitleInt(titleRes); - } - - public SubMenu setHeaderView(View view) { - return (SubMenu) super.setHeaderViewInt(view); - } - - @Override - public boolean expandItemActionView(MenuItemImpl item) { - return mParentMenu.expandItemActionView(item); - } - - @Override - public boolean collapseItemActionView(MenuItemImpl item) { - return mParentMenu.collapseItemActionView(item); - } - - @Override - public String getActionViewStatesKey() { - final int itemId = mItem != null ? mItem.getItemId() : 0; - if (itemId == 0) { - return null; - } - return super.getActionViewStatesKey() + ":" + itemId; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuWrapper.java b/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuWrapper.java deleted file mode 100644 index 7d307acb..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/view/menu/SubMenuWrapper.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.actionbarsherlock.internal.view.menu; - -import android.graphics.drawable.Drawable; -import android.view.View; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.SubMenu; - -public class SubMenuWrapper extends MenuWrapper implements SubMenu { - private final android.view.SubMenu mNativeSubMenu; - private MenuItem mItem = null; - - public SubMenuWrapper(android.view.SubMenu nativeSubMenu) { - super(nativeSubMenu); - mNativeSubMenu = nativeSubMenu; - } - - - @Override - public SubMenu setHeaderTitle(int titleRes) { - mNativeSubMenu.setHeaderTitle(titleRes); - return this; - } - - @Override - public SubMenu setHeaderTitle(CharSequence title) { - mNativeSubMenu.setHeaderTitle(title); - return this; - } - - @Override - public SubMenu setHeaderIcon(int iconRes) { - mNativeSubMenu.setHeaderIcon(iconRes); - return this; - } - - @Override - public SubMenu setHeaderIcon(Drawable icon) { - mNativeSubMenu.setHeaderIcon(icon); - return this; - } - - @Override - public SubMenu setHeaderView(View view) { - mNativeSubMenu.setHeaderView(view); - return this; - } - - @Override - public void clearHeader() { - mNativeSubMenu.clearHeader(); - } - - @Override - public SubMenu setIcon(int iconRes) { - mNativeSubMenu.setIcon(iconRes); - return this; - } - - @Override - public SubMenu setIcon(Drawable icon) { - mNativeSubMenu.setIcon(icon); - return this; - } - - @Override - public MenuItem getItem() { - if (mItem == null) { - mItem = new MenuItemWrapper(mNativeSubMenu.getItem()); - } - return mItem; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/AbsActionBarView.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/AbsActionBarView.java deleted file mode 100644 index 3a4a4467..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/AbsActionBarView.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.Configuration; -import android.content.res.TypedArray; -import android.os.Build; -import android.util.AttributeSet; -import android.view.View; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; -import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet; -import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; -import com.actionbarsherlock.internal.nineoldandroids.view.NineViewGroup; -import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; -import com.actionbarsherlock.internal.view.menu.ActionMenuView; - -import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; - -public abstract class AbsActionBarView extends NineViewGroup { - protected ActionMenuView mMenuView; - protected ActionMenuPresenter mActionMenuPresenter; - protected ActionBarContainer mSplitView; - protected boolean mSplitActionBar; - protected boolean mSplitWhenNarrow; - protected int mContentHeight; - - final Context mContext; - - protected Animator mVisibilityAnim; - protected final VisibilityAnimListener mVisAnimListener = new VisibilityAnimListener(); - - private static final /*Time*/Interpolator sAlphaInterpolator = new DecelerateInterpolator(); - - private static final int FADE_DURATION = 200; - - public AbsActionBarView(Context context) { - super(context); - mContext = context; - } - - public AbsActionBarView(Context context, AttributeSet attrs) { - super(context, attrs); - mContext = context; - } - - public AbsActionBarView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - mContext = context; - } - - /* - * Must be public so we can dispatch pre-2.2 via ActionBarImpl. - */ - @Override - public void onConfigurationChanged(Configuration newConfig) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { - super.onConfigurationChanged(newConfig); - } else if (mMenuView != null) { - mMenuView.onConfigurationChanged(newConfig); - } - - // Action bar can change size on configuration changes. - // Reread the desired height from the theme-specified style. - TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.SherlockActionBar, - R.attr.actionBarStyle, 0); - setContentHeight(a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0)); - a.recycle(); - if (mSplitWhenNarrow) { - setSplitActionBar(getResources_getBoolean(getContext(), - R.bool.abs__split_action_bar_is_narrow)); - } - if (mActionMenuPresenter != null) { - mActionMenuPresenter.onConfigurationChanged(newConfig); - } - } - - /** - * Sets whether the bar should be split right now, no questions asked. - * @param split true if the bar should split - */ - public void setSplitActionBar(boolean split) { - mSplitActionBar = split; - } - - /** - * Sets whether the bar should split if we enter a narrow screen configuration. - * @param splitWhenNarrow true if the bar should check to split after a config change - */ - public void setSplitWhenNarrow(boolean splitWhenNarrow) { - mSplitWhenNarrow = splitWhenNarrow; - } - - public void setContentHeight(int height) { - mContentHeight = height; - requestLayout(); - } - - public int getContentHeight() { - return mContentHeight; - } - - public void setSplitView(ActionBarContainer splitView) { - mSplitView = splitView; - } - - /** - * @return Current visibility or if animating, the visibility being animated to. - */ - public int getAnimatedVisibility() { - if (mVisibilityAnim != null) { - return mVisAnimListener.mFinalVisibility; - } - return getVisibility(); - } - - public void animateToVisibility(int visibility) { - if (mVisibilityAnim != null) { - mVisibilityAnim.cancel(); - } - if (visibility == VISIBLE) { - if (getVisibility() != VISIBLE) { - setAlpha(0); - if (mSplitView != null && mMenuView != null) { - mMenuView.setAlpha(0); - } - } - ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 1); - anim.setDuration(FADE_DURATION); - anim.setInterpolator(sAlphaInterpolator); - if (mSplitView != null && mMenuView != null) { - AnimatorSet set = new AnimatorSet(); - ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, "alpha", 1); - splitAnim.setDuration(FADE_DURATION); - set.addListener(mVisAnimListener.withFinalVisibility(visibility)); - set.play(anim).with(splitAnim); - set.start(); - } else { - anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); - anim.start(); - } - } else { - ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 0); - anim.setDuration(FADE_DURATION); - anim.setInterpolator(sAlphaInterpolator); - if (mSplitView != null && mMenuView != null) { - AnimatorSet set = new AnimatorSet(); - ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, "alpha", 0); - splitAnim.setDuration(FADE_DURATION); - set.addListener(mVisAnimListener.withFinalVisibility(visibility)); - set.play(anim).with(splitAnim); - set.start(); - } else { - anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); - anim.start(); - } - } - } - - @Override - public void setVisibility(int visibility) { - if (mVisibilityAnim != null) { - mVisibilityAnim.end(); - } - super.setVisibility(visibility); - } - - public boolean showOverflowMenu() { - if (mActionMenuPresenter != null) { - return mActionMenuPresenter.showOverflowMenu(); - } - return false; - } - - public void postShowOverflowMenu() { - post(new Runnable() { - public void run() { - showOverflowMenu(); - } - }); - } - - public boolean hideOverflowMenu() { - if (mActionMenuPresenter != null) { - return mActionMenuPresenter.hideOverflowMenu(); - } - return false; - } - - public boolean isOverflowMenuShowing() { - if (mActionMenuPresenter != null) { - return mActionMenuPresenter.isOverflowMenuShowing(); - } - return false; - } - - public boolean isOverflowReserved() { - return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved(); - } - - public void dismissPopupMenus() { - if (mActionMenuPresenter != null) { - mActionMenuPresenter.dismissPopupMenus(); - } - } - - protected int measureChildView(View child, int availableWidth, int childSpecHeight, - int spacing) { - child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), - childSpecHeight); - - availableWidth -= child.getMeasuredWidth(); - availableWidth -= spacing; - - return Math.max(0, availableWidth); - } - - protected int positionChild(View child, int x, int y, int contentHeight) { - int childWidth = child.getMeasuredWidth(); - int childHeight = child.getMeasuredHeight(); - int childTop = y + (contentHeight - childHeight) / 2; - - child.layout(x, childTop, x + childWidth, childTop + childHeight); - - return childWidth; - } - - protected int positionChildInverse(View child, int x, int y, int contentHeight) { - int childWidth = child.getMeasuredWidth(); - int childHeight = child.getMeasuredHeight(); - int childTop = y + (contentHeight - childHeight) / 2; - - child.layout(x - childWidth, childTop, x, childTop + childHeight); - - return childWidth; - } - - protected class VisibilityAnimListener implements Animator.AnimatorListener { - private boolean mCanceled = false; - int mFinalVisibility; - - public VisibilityAnimListener withFinalVisibility(int visibility) { - mFinalVisibility = visibility; - return this; - } - - @Override - public void onAnimationStart(Animator animation) { - setVisibility(VISIBLE); - mVisibilityAnim = animation; - mCanceled = false; - } - - @Override - public void onAnimationEnd(Animator animation) { - if (mCanceled) return; - - mVisibilityAnim = null; - setVisibility(mFinalVisibility); - if (mSplitView != null && mMenuView != null) { - mMenuView.setVisibility(mFinalVisibility); - } - } - - @Override - public void onAnimationCancel(Animator animation) { - mCanceled = true; - } - - @Override - public void onAnimationRepeat(Animator animation) { - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java deleted file mode 100644 index 1d9c68b3..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.internal.nineoldandroids.widget.NineFrameLayout; - -/** - * This class acts as a container for the action bar view and action mode context views. - * It applies special styles as needed to help handle animated transitions between them. - * @hide - */ -public class ActionBarContainer extends NineFrameLayout { - private boolean mIsTransitioning; - private View mTabContainer; - private ActionBarView mActionBarView; - - private Drawable mBackground; - private Drawable mStackedBackground; - private Drawable mSplitBackground; - private boolean mIsSplit; - private boolean mIsStacked; - - public ActionBarContainer(Context context) { - this(context, null); - } - - public ActionBarContainer(Context context, AttributeSet attrs) { - super(context, attrs); - - setBackgroundDrawable(null); - - TypedArray a = context.obtainStyledAttributes(attrs, - R.styleable.SherlockActionBar); - mBackground = a.getDrawable(R.styleable.SherlockActionBar_background); - mStackedBackground = a.getDrawable( - R.styleable.SherlockActionBar_backgroundStacked); - - //Fix for issue #379 - if (mStackedBackground instanceof ColorDrawable && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); - Canvas c = new Canvas(bitmap); - mStackedBackground.draw(c); - int color = bitmap.getPixel(0, 0); - bitmap.recycle(); - mStackedBackground = new IcsColorDrawable(color); - } - - if (getId() == R.id.abs__split_action_bar) { - mIsSplit = true; - mSplitBackground = a.getDrawable( - R.styleable.SherlockActionBar_backgroundSplit); - } - a.recycle(); - - setWillNotDraw(mIsSplit ? mSplitBackground == null : - mBackground == null && mStackedBackground == null); - } - - @Override - public void onFinishInflate() { - super.onFinishInflate(); - mActionBarView = (ActionBarView) findViewById(R.id.abs__action_bar); - } - - public void setPrimaryBackground(Drawable bg) { - mBackground = bg; - invalidate(); - } - - public void setStackedBackground(Drawable bg) { - mStackedBackground = bg; - invalidate(); - } - - public void setSplitBackground(Drawable bg) { - mSplitBackground = bg; - invalidate(); - } - - /** - * Set the action bar into a "transitioning" state. While transitioning - * the bar will block focus and touch from all of its descendants. This - * prevents the user from interacting with the bar while it is animating - * in or out. - * - * @param isTransitioning true if the bar is currently transitioning, false otherwise. - */ - public void setTransitioning(boolean isTransitioning) { - mIsTransitioning = isTransitioning; - setDescendantFocusability(isTransitioning ? FOCUS_BLOCK_DESCENDANTS - : FOCUS_AFTER_DESCENDANTS); - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - return mIsTransitioning || super.onInterceptTouchEvent(ev); - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - super.onTouchEvent(ev); - - // An action bar always eats touch events. - return true; - } - - @Override - public boolean onHoverEvent(MotionEvent ev) { - super.onHoverEvent(ev); - - // An action bar always eats hover events. - return true; - } - - public void setTabContainer(ScrollingTabContainerView tabView) { - if (mTabContainer != null) { - removeView(mTabContainer); - } - mTabContainer = tabView; - if (tabView != null) { - addView(tabView); - final ViewGroup.LayoutParams lp = tabView.getLayoutParams(); - lp.width = LayoutParams.MATCH_PARENT; - lp.height = LayoutParams.WRAP_CONTENT; - tabView.setAllowCollapse(false); - } - } - - public View getTabContainer() { - return mTabContainer; - } - - @Override - public void onDraw(Canvas canvas) { - if (getWidth() == 0 || getHeight() == 0) { - return; - } - - if (mIsSplit) { - if (mSplitBackground != null) mSplitBackground.draw(canvas); - } else { - if (mBackground != null) { - mBackground.draw(canvas); - } - if (mStackedBackground != null && mIsStacked) { - mStackedBackground.draw(canvas); - } - } - } - - //This causes the animation reflection to fail on pre-HC platforms - //@Override - //public android.view.ActionMode startActionModeForChild(View child, android.view.ActionMode.Callback callback) { - // // No starting an action mode for an action bar child! (Where would it go?) - // return null; - //} - - @Override - public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - if (mActionBarView == null) return; - - final LayoutParams lp = (LayoutParams) mActionBarView.getLayoutParams(); - final int actionBarViewHeight = mActionBarView.isCollapsed() ? 0 : - mActionBarView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; - - if (mTabContainer != null && mTabContainer.getVisibility() != GONE) { - final int mode = MeasureSpec.getMode(heightMeasureSpec); - if (mode == MeasureSpec.AT_MOST) { - final int maxHeight = MeasureSpec.getSize(heightMeasureSpec); - setMeasuredDimension(getMeasuredWidth(), - Math.min(actionBarViewHeight + mTabContainer.getMeasuredHeight(), - maxHeight)); - } - } - } - - @Override - public void onLayout(boolean changed, int l, int t, int r, int b) { - super.onLayout(changed, l, t, r, b); - - final boolean hasTabs = mTabContainer != null && mTabContainer.getVisibility() != GONE; - - if (mTabContainer != null && mTabContainer.getVisibility() != GONE) { - final int containerHeight = getMeasuredHeight(); - final int tabHeight = mTabContainer.getMeasuredHeight(); - - if ((mActionBarView.getDisplayOptions() & ActionBar.DISPLAY_SHOW_HOME) == 0) { - // Not showing home, put tabs on top. - final int count = getChildCount(); - for (int i = 0; i < count; i++) { - final View child = getChildAt(i); - - if (child == mTabContainer) continue; - - if (!mActionBarView.isCollapsed()) { - child.offsetTopAndBottom(tabHeight); - } - } - mTabContainer.layout(l, 0, r, tabHeight); - } else { - mTabContainer.layout(l, containerHeight - tabHeight, r, containerHeight); - } - } - - boolean needsInvalidate = false; - if (mIsSplit) { - if (mSplitBackground != null) { - mSplitBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); - needsInvalidate = true; - } - } else { - if (mBackground != null) { - mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(), - mActionBarView.getRight(), mActionBarView.getBottom()); - needsInvalidate = true; - } - if ((mIsStacked = hasTabs && mStackedBackground != null)) { - mStackedBackground.setBounds(mTabContainer.getLeft(), mTabContainer.getTop(), - mTabContainer.getRight(), mTabContainer.getBottom()); - needsInvalidate = true; - } - } - - if (needsInvalidate) { - invalidate(); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/ActionBarContextView.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/ActionBarContextView.java deleted file mode 100644 index 9ec250f3..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/ActionBarContextView.java +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.accessibility.AccessibilityEvent; -import android.view.animation.DecelerateInterpolator; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; -import com.actionbarsherlock.internal.nineoldandroids.animation.Animator.AnimatorListener; -import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet; -import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; -import com.actionbarsherlock.internal.nineoldandroids.view.animation.AnimatorProxy; -import com.actionbarsherlock.internal.nineoldandroids.widget.NineLinearLayout; -import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; -import com.actionbarsherlock.internal.view.menu.ActionMenuView; -import com.actionbarsherlock.internal.view.menu.MenuBuilder; -import com.actionbarsherlock.view.ActionMode; - -/** - * @hide - */ -public class ActionBarContextView extends AbsActionBarView implements AnimatorListener { - //UNUSED private static final String TAG = "ActionBarContextView"; - - private CharSequence mTitle; - private CharSequence mSubtitle; - - private NineLinearLayout mClose; - private View mCustomView; - private LinearLayout mTitleLayout; - private TextView mTitleView; - private TextView mSubtitleView; - private int mTitleStyleRes; - private int mSubtitleStyleRes; - private Drawable mSplitBackground; - - private Animator mCurrentAnimation; - private boolean mAnimateInOnLayout; - private int mAnimationMode; - - private static final int ANIMATE_IDLE = 0; - private static final int ANIMATE_IN = 1; - private static final int ANIMATE_OUT = 2; - - public ActionBarContextView(Context context) { - this(context, null); - } - - public ActionBarContextView(Context context, AttributeSet attrs) { - this(context, attrs, R.attr.actionModeStyle); - } - - public ActionBarContextView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockActionMode, defStyle, 0); - setBackgroundDrawable(a.getDrawable( - R.styleable.SherlockActionMode_background)); - mTitleStyleRes = a.getResourceId( - R.styleable.SherlockActionMode_titleTextStyle, 0); - mSubtitleStyleRes = a.getResourceId( - R.styleable.SherlockActionMode_subtitleTextStyle, 0); - - mContentHeight = a.getLayoutDimension( - R.styleable.SherlockActionMode_height, 0); - - mSplitBackground = a.getDrawable( - R.styleable.SherlockActionMode_backgroundSplit); - - a.recycle(); - } - - @Override - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - if (mActionMenuPresenter != null) { - mActionMenuPresenter.hideOverflowMenu(); - mActionMenuPresenter.hideSubMenus(); - } - } - - @Override - public void setSplitActionBar(boolean split) { - if (mSplitActionBar != split) { - if (mActionMenuPresenter != null) { - // Mode is already active; move everything over and adjust the menu itself. - final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.MATCH_PARENT); - if (!split) { - mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); - mMenuView.setBackgroundDrawable(null); - final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); - if (oldParent != null) oldParent.removeView(mMenuView); - addView(mMenuView, layoutParams); - } else { - // Allow full screen width in split mode. - mActionMenuPresenter.setWidthLimit( - getContext().getResources().getDisplayMetrics().widthPixels, true); - // No limit to the item count; use whatever will fit. - mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); - // Span the whole width - layoutParams.width = LayoutParams.MATCH_PARENT; - layoutParams.height = mContentHeight; - mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); - mMenuView.setBackgroundDrawable(mSplitBackground); - final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); - if (oldParent != null) oldParent.removeView(mMenuView); - mSplitView.addView(mMenuView, layoutParams); - } - } - super.setSplitActionBar(split); - } - } - - public void setContentHeight(int height) { - mContentHeight = height; - } - - public void setCustomView(View view) { - if (mCustomView != null) { - removeView(mCustomView); - } - mCustomView = view; - if (mTitleLayout != null) { - removeView(mTitleLayout); - mTitleLayout = null; - } - if (view != null) { - addView(view); - } - requestLayout(); - } - - public void setTitle(CharSequence title) { - mTitle = title; - initTitle(); - } - - public void setSubtitle(CharSequence subtitle) { - mSubtitle = subtitle; - initTitle(); - } - - public CharSequence getTitle() { - return mTitle; - } - - public CharSequence getSubtitle() { - return mSubtitle; - } - - private void initTitle() { - if (mTitleLayout == null) { - LayoutInflater inflater = LayoutInflater.from(getContext()); - inflater.inflate(R.layout.abs__action_bar_title_item, this); - mTitleLayout = (LinearLayout) getChildAt(getChildCount() - 1); - mTitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_title); - mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_subtitle); - if (mTitleStyleRes != 0) { - mTitleView.setTextAppearance(mContext, mTitleStyleRes); - } - if (mSubtitleStyleRes != 0) { - mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes); - } - } - - mTitleView.setText(mTitle); - mSubtitleView.setText(mSubtitle); - - final boolean hasTitle = !TextUtils.isEmpty(mTitle); - final boolean hasSubtitle = !TextUtils.isEmpty(mSubtitle); - mSubtitleView.setVisibility(hasSubtitle ? VISIBLE : GONE); - mTitleLayout.setVisibility(hasTitle || hasSubtitle ? VISIBLE : GONE); - if (mTitleLayout.getParent() == null) { - addView(mTitleLayout); - } - } - - public void initForMode(final ActionMode mode) { - if (mClose == null) { - LayoutInflater inflater = LayoutInflater.from(mContext); - mClose = (NineLinearLayout)inflater.inflate(R.layout.abs__action_mode_close_item, this, false); - addView(mClose); - } else if (mClose.getParent() == null) { - addView(mClose); - } - - View closeButton = mClose.findViewById(R.id.abs__action_mode_close_button); - closeButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - mode.finish(); - } - }); - - final MenuBuilder menu = (MenuBuilder) mode.getMenu(); - if (mActionMenuPresenter != null) { - mActionMenuPresenter.dismissPopupMenus(); - } - mActionMenuPresenter = new ActionMenuPresenter(mContext); - mActionMenuPresenter.setReserveOverflow(true); - - final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.MATCH_PARENT); - if (!mSplitActionBar) { - menu.addMenuPresenter(mActionMenuPresenter); - mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); - mMenuView.setBackgroundDrawable(null); - addView(mMenuView, layoutParams); - } else { - // Allow full screen width in split mode. - mActionMenuPresenter.setWidthLimit( - getContext().getResources().getDisplayMetrics().widthPixels, true); - // No limit to the item count; use whatever will fit. - mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); - // Span the whole width - layoutParams.width = LayoutParams.MATCH_PARENT; - layoutParams.height = mContentHeight; - menu.addMenuPresenter(mActionMenuPresenter); - mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); - mMenuView.setBackgroundDrawable(mSplitBackground); - mSplitView.addView(mMenuView, layoutParams); - } - - mAnimateInOnLayout = true; - } - - public void closeMode() { - if (mAnimationMode == ANIMATE_OUT) { - // Called again during close; just finish what we were doing. - return; - } - if (mClose == null) { - killMode(); - return; - } - - finishAnimation(); - mAnimationMode = ANIMATE_OUT; - mCurrentAnimation = makeOutAnimation(); - mCurrentAnimation.start(); - } - - private void finishAnimation() { - final Animator a = mCurrentAnimation; - if (a != null) { - mCurrentAnimation = null; - a.end(); - } - } - - public void killMode() { - finishAnimation(); - removeAllViews(); - if (mSplitView != null) { - mSplitView.removeView(mMenuView); - } - mCustomView = null; - mMenuView = null; - mAnimateInOnLayout = false; - } - - @Override - public boolean showOverflowMenu() { - if (mActionMenuPresenter != null) { - return mActionMenuPresenter.showOverflowMenu(); - } - return false; - } - - @Override - public boolean hideOverflowMenu() { - if (mActionMenuPresenter != null) { - return mActionMenuPresenter.hideOverflowMenu(); - } - return false; - } - - @Override - public boolean isOverflowMenuShowing() { - if (mActionMenuPresenter != null) { - return mActionMenuPresenter.isOverflowMenuShowing(); - } - return false; - } - - @Override - protected ViewGroup.LayoutParams generateDefaultLayoutParams() { - // Used by custom views if they don't supply layout params. Everything else - // added to an ActionBarContextView should have them already. - return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - } - - @Override - public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { - return new MarginLayoutParams(getContext(), attrs); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int widthMode = MeasureSpec.getMode(widthMeasureSpec); - if (widthMode != MeasureSpec.EXACTLY) { - throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + - "with android:layout_width=\"match_parent\" (or fill_parent)"); - } - - final int heightMode = MeasureSpec.getMode(heightMeasureSpec); - if (heightMode == MeasureSpec.UNSPECIFIED) { - throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + - "with android:layout_height=\"wrap_content\""); - } - - final int contentWidth = MeasureSpec.getSize(widthMeasureSpec); - - int maxHeight = mContentHeight > 0 ? - mContentHeight : MeasureSpec.getSize(heightMeasureSpec); - - final int verticalPadding = getPaddingTop() + getPaddingBottom(); - int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight(); - final int height = maxHeight - verticalPadding; - final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); - - if (mClose != null) { - availableWidth = measureChildView(mClose, availableWidth, childSpecHeight, 0); - MarginLayoutParams lp = (MarginLayoutParams) mClose.getLayoutParams(); - availableWidth -= lp.leftMargin + lp.rightMargin; - } - - if (mMenuView != null && mMenuView.getParent() == this) { - availableWidth = measureChildView(mMenuView, availableWidth, - childSpecHeight, 0); - } - - if (mTitleLayout != null && mCustomView == null) { - availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0); - } - - if (mCustomView != null) { - ViewGroup.LayoutParams lp = mCustomView.getLayoutParams(); - final int customWidthMode = lp.width != LayoutParams.WRAP_CONTENT ? - MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; - final int customWidth = lp.width >= 0 ? - Math.min(lp.width, availableWidth) : availableWidth; - final int customHeightMode = lp.height != LayoutParams.WRAP_CONTENT ? - MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; - final int customHeight = lp.height >= 0 ? - Math.min(lp.height, height) : height; - mCustomView.measure(MeasureSpec.makeMeasureSpec(customWidth, customWidthMode), - MeasureSpec.makeMeasureSpec(customHeight, customHeightMode)); - } - - if (mContentHeight <= 0) { - int measuredHeight = 0; - final int count = getChildCount(); - for (int i = 0; i < count; i++) { - View v = getChildAt(i); - int paddedViewHeight = v.getMeasuredHeight() + verticalPadding; - if (paddedViewHeight > measuredHeight) { - measuredHeight = paddedViewHeight; - } - } - setMeasuredDimension(contentWidth, measuredHeight); - } else { - setMeasuredDimension(contentWidth, maxHeight); - } - } - - private Animator makeInAnimation() { - mClose.setTranslationX(-mClose.getWidth() - - ((MarginLayoutParams) mClose.getLayoutParams()).leftMargin); - ObjectAnimator buttonAnimator = ObjectAnimator.ofFloat(mClose, "translationX", 0); - buttonAnimator.setDuration(200); - buttonAnimator.addListener(this); - buttonAnimator.setInterpolator(new DecelerateInterpolator()); - - AnimatorSet set = new AnimatorSet(); - AnimatorSet.Builder b = set.play(buttonAnimator); - - if (mMenuView != null) { - final int count = mMenuView.getChildCount(); - if (count > 0) { - for (int i = count - 1, j = 0; i >= 0; i--, j++) { - AnimatorProxy child = AnimatorProxy.wrap(mMenuView.getChildAt(i)); - child.setScaleY(0); - ObjectAnimator a = ObjectAnimator.ofFloat(child, "scaleY", 0, 1); - a.setDuration(100); - a.setStartDelay(j * 70); - b.with(a); - } - } - } - - return set; - } - - private Animator makeOutAnimation() { - ObjectAnimator buttonAnimator = ObjectAnimator.ofFloat(mClose, "translationX", - -mClose.getWidth() - ((MarginLayoutParams) mClose.getLayoutParams()).leftMargin); - buttonAnimator.setDuration(200); - buttonAnimator.addListener(this); - buttonAnimator.setInterpolator(new DecelerateInterpolator()); - - AnimatorSet set = new AnimatorSet(); - AnimatorSet.Builder b = set.play(buttonAnimator); - - if (mMenuView != null) { - final int count = mMenuView.getChildCount(); - if (count > 0) { - for (int i = 0; i < 0; i++) { - AnimatorProxy child = AnimatorProxy.wrap(mMenuView.getChildAt(i)); - child.setScaleY(0); - ObjectAnimator a = ObjectAnimator.ofFloat(child, "scaleY", 0); - a.setDuration(100); - a.setStartDelay(i * 70); - b.with(a); - } - } - } - - return set; - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - int x = getPaddingLeft(); - final int y = getPaddingTop(); - final int contentHeight = b - t - getPaddingTop() - getPaddingBottom(); - - if (mClose != null && mClose.getVisibility() != GONE) { - MarginLayoutParams lp = (MarginLayoutParams) mClose.getLayoutParams(); - x += lp.leftMargin; - x += positionChild(mClose, x, y, contentHeight); - x += lp.rightMargin; - - if (mAnimateInOnLayout) { - mAnimationMode = ANIMATE_IN; - mCurrentAnimation = makeInAnimation(); - mCurrentAnimation.start(); - mAnimateInOnLayout = false; - } - } - - if (mTitleLayout != null && mCustomView == null) { - x += positionChild(mTitleLayout, x, y, contentHeight); - } - - if (mCustomView != null) { - x += positionChild(mCustomView, x, y, contentHeight); - } - - x = r - l - getPaddingRight(); - - if (mMenuView != null) { - x -= positionChildInverse(mMenuView, x, y, contentHeight); - } - } - - @Override - public void onAnimationStart(Animator animation) { - } - - @Override - public void onAnimationEnd(Animator animation) { - if (mAnimationMode == ANIMATE_OUT) { - killMode(); - } - mAnimationMode = ANIMATE_IDLE; - } - - @Override - public void onAnimationCancel(Animator animation) { - } - - @Override - public void onAnimationRepeat(Animator animation) { - } - - @Override - public boolean shouldDelayChildPressedState() { - return false; - } - - @Override - public void onInitializeAccessibilityEvent(AccessibilityEvent event) { - if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { - // Action mode started - //TODO event.setSource(this); - event.setClassName(getClass().getName()); - event.setPackageName(getContext().getPackageName()); - event.setContentDescription(mTitle); - } else { - //TODO super.onInitializeAccessibilityEvent(event); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/ActionBarView.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/ActionBarView.java deleted file mode 100644 index 4636de17..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/ActionBarView.java +++ /dev/null @@ -1,1548 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.widget; - -import org.xmlpull.v1.XmlPullParser; -import android.app.Activity; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.AssetManager; -import android.content.res.Configuration; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.util.Log; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; -import android.view.accessibility.AccessibilityEvent; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.SpinnerAdapter; -import android.widget.TextView; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.app.ActionBar.OnNavigationListener; -import com.actionbarsherlock.internal.ActionBarSherlockCompat; -import com.actionbarsherlock.internal.view.menu.ActionMenuItem; -import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; -import com.actionbarsherlock.internal.view.menu.ActionMenuView; -import com.actionbarsherlock.internal.view.menu.MenuBuilder; -import com.actionbarsherlock.internal.view.menu.MenuItemImpl; -import com.actionbarsherlock.internal.view.menu.MenuPresenter; -import com.actionbarsherlock.internal.view.menu.MenuView; -import com.actionbarsherlock.internal.view.menu.SubMenuBuilder; -import com.actionbarsherlock.view.CollapsibleActionView; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.Window; - -import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; - -/** - * @hide - */ -public class ActionBarView extends AbsActionBarView { - private static final String TAG = "ActionBarView"; - private static final boolean DEBUG = false; - - /** - * Display options applied by default - */ - public static final int DISPLAY_DEFAULT = 0; - - /** - * Display options that require re-layout as opposed to a simple invalidate - */ - private static final int DISPLAY_RELAYOUT_MASK = - ActionBar.DISPLAY_SHOW_HOME | - ActionBar.DISPLAY_USE_LOGO | - ActionBar.DISPLAY_HOME_AS_UP | - ActionBar.DISPLAY_SHOW_CUSTOM | - ActionBar.DISPLAY_SHOW_TITLE; - - private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.LEFT | Gravity.CENTER_VERTICAL; - - private int mNavigationMode; - private int mDisplayOptions = -1; - private CharSequence mTitle; - private CharSequence mSubtitle; - private Drawable mIcon; - private Drawable mLogo; - - private HomeView mHomeLayout; - private HomeView mExpandedHomeLayout; - private LinearLayout mTitleLayout; - private TextView mTitleView; - private TextView mSubtitleView; - private View mTitleUpView; - - private IcsSpinner mSpinner; - private IcsLinearLayout mListNavLayout; - private ScrollingTabContainerView mTabScrollView; - private View mCustomNavView; - private IcsProgressBar mProgressView; - private IcsProgressBar mIndeterminateProgressView; - - private int mProgressBarPadding; - private int mItemPadding; - - private int mTitleStyleRes; - private int mSubtitleStyleRes; - private int mProgressStyle; - private int mIndeterminateProgressStyle; - - private boolean mUserTitle; - private boolean mIncludeTabs; - private boolean mIsCollapsable; - private boolean mIsCollapsed; - - private MenuBuilder mOptionsMenu; - - private ActionBarContextView mContextView; - - private ActionMenuItem mLogoNavItem; - - private SpinnerAdapter mSpinnerAdapter; - private OnNavigationListener mCallback; - - //UNUSED private Runnable mTabSelector; - - private ExpandedActionViewMenuPresenter mExpandedMenuPresenter; - View mExpandedActionView; - - Window.Callback mWindowCallback; - - @SuppressWarnings("rawtypes") - private final IcsAdapterView.OnItemSelectedListener mNavItemSelectedListener = - new IcsAdapterView.OnItemSelectedListener() { - public void onItemSelected(IcsAdapterView parent, View view, int position, long id) { - if (mCallback != null) { - mCallback.onNavigationItemSelected(position, id); - } - } - public void onNothingSelected(IcsAdapterView parent) { - // Do nothing - } - }; - - private final OnClickListener mExpandedActionViewUpListener = new OnClickListener() { - @Override - public void onClick(View v) { - final MenuItemImpl item = mExpandedMenuPresenter.mCurrentExpandedItem; - if (item != null) { - item.collapseActionView(); - } - } - }; - - private final OnClickListener mUpClickListener = new OnClickListener() { - public void onClick(View v) { - mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mLogoNavItem); - } - }; - - public ActionBarView(Context context, AttributeSet attrs) { - super(context, attrs); - - // Background is always provided by the container. - setBackgroundResource(0); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockActionBar, - R.attr.actionBarStyle, 0); - - ApplicationInfo appInfo = context.getApplicationInfo(); - PackageManager pm = context.getPackageManager(); - mNavigationMode = a.getInt(R.styleable.SherlockActionBar_navigationMode, - ActionBar.NAVIGATION_MODE_STANDARD); - mTitle = a.getText(R.styleable.SherlockActionBar_title); - mSubtitle = a.getText(R.styleable.SherlockActionBar_subtitle); - - mLogo = a.getDrawable(R.styleable.SherlockActionBar_logo); - if (mLogo == null) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - if (context instanceof Activity) { - //Even though native methods existed in API 9 and 10 they don't work - //so just parse the manifest to look for the logo pre-Honeycomb - final int resId = loadLogoFromManifest((Activity) context); - if (resId != 0) { - mLogo = context.getResources().getDrawable(resId); - } - } - } else { - if (context instanceof Activity) { - try { - mLogo = pm.getActivityLogo(((Activity) context).getComponentName()); - } catch (NameNotFoundException e) { - Log.e(TAG, "Activity component name not found!", e); - } - } - if (mLogo == null) { - mLogo = appInfo.loadLogo(pm); - } - } - } - - mIcon = a.getDrawable(R.styleable.SherlockActionBar_icon); - if (mIcon == null) { - if (context instanceof Activity) { - try { - mIcon = pm.getActivityIcon(((Activity) context).getComponentName()); - } catch (NameNotFoundException e) { - Log.e(TAG, "Activity component name not found!", e); - } - } - if (mIcon == null) { - mIcon = appInfo.loadIcon(pm); - } - } - - final LayoutInflater inflater = LayoutInflater.from(context); - - final int homeResId = a.getResourceId( - R.styleable.SherlockActionBar_homeLayout, - R.layout.abs__action_bar_home); - - mHomeLayout = (HomeView) inflater.inflate(homeResId, this, false); - - mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, this, false); - mExpandedHomeLayout.setUp(true); - mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener); - mExpandedHomeLayout.setContentDescription(getResources().getText( - R.string.abs__action_bar_up_description)); - - mTitleStyleRes = a.getResourceId(R.styleable.SherlockActionBar_titleTextStyle, 0); - mSubtitleStyleRes = a.getResourceId(R.styleable.SherlockActionBar_subtitleTextStyle, 0); - mProgressStyle = a.getResourceId(R.styleable.SherlockActionBar_progressBarStyle, 0); - mIndeterminateProgressStyle = a.getResourceId( - R.styleable.SherlockActionBar_indeterminateProgressStyle, 0); - - mProgressBarPadding = a.getDimensionPixelOffset(R.styleable.SherlockActionBar_progressBarPadding, 0); - mItemPadding = a.getDimensionPixelOffset(R.styleable.SherlockActionBar_itemPadding, 0); - - setDisplayOptions(a.getInt(R.styleable.SherlockActionBar_displayOptions, DISPLAY_DEFAULT)); - - final int customNavId = a.getResourceId(R.styleable.SherlockActionBar_customNavigationLayout, 0); - if (customNavId != 0) { - mCustomNavView = inflater.inflate(customNavId, this, false); - mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD; - setDisplayOptions(mDisplayOptions | ActionBar.DISPLAY_SHOW_CUSTOM); - } - - mContentHeight = a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0); - - a.recycle(); - - mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle); - mHomeLayout.setOnClickListener(mUpClickListener); - mHomeLayout.setClickable(true); - mHomeLayout.setFocusable(true); - } - - /** - * Attempt to programmatically load the logo from the manifest file of an - * activity by using an XML pull parser. This should allow us to read the - * logo attribute regardless of the platform it is being run on. - * - * @param activity Activity instance. - * @return Logo resource ID. - */ - private static int loadLogoFromManifest(Activity activity) { - int logo = 0; - try { - final String thisPackage = activity.getClass().getName(); - if (DEBUG) Log.i(TAG, "Parsing AndroidManifest.xml for " + thisPackage); - - final String packageName = activity.getApplicationInfo().packageName; - final AssetManager am = activity.createPackageContext(packageName, 0).getAssets(); - final XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml"); - - int eventType = xml.getEventType(); - while (eventType != XmlPullParser.END_DOCUMENT) { - if (eventType == XmlPullParser.START_TAG) { - String name = xml.getName(); - - if ("application".equals(name)) { - //Check if the has the attribute - if (DEBUG) Log.d(TAG, "Got "); - - for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { - if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); - - if ("logo".equals(xml.getAttributeName(i))) { - logo = xml.getAttributeResourceValue(i, 0); - break; //out of for loop - } - } - } else if ("activity".equals(name)) { - //Check if the is us and has the attribute - if (DEBUG) Log.d(TAG, "Got "); - Integer activityLogo = null; - String activityPackage = null; - boolean isOurActivity = false; - - for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { - if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); - - //We need both uiOptions and name attributes - String attrName = xml.getAttributeName(i); - if ("logo".equals(attrName)) { - activityLogo = xml.getAttributeResourceValue(i, 0); - } else if ("name".equals(attrName)) { - activityPackage = ActionBarSherlockCompat.cleanActivityName(packageName, xml.getAttributeValue(i)); - if (!thisPackage.equals(activityPackage)) { - break; //on to the next - } - isOurActivity = true; - } - - //Make sure we have both attributes before processing - if ((activityLogo != null) && (activityPackage != null)) { - //Our activity, logo specified, override with our value - logo = activityLogo.intValue(); - } - } - if (isOurActivity) { - //If we matched our activity but it had no logo don't - //do any more processing of the manifest - break; - } - } - } - eventType = xml.nextToken(); - } - } catch (Exception e) { - e.printStackTrace(); - } - if (DEBUG) Log.i(TAG, "Returning " + Integer.toHexString(logo)); - return logo; - } - - /* - * Must be public so we can dispatch pre-2.2 via ActionBarImpl. - */ - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - mTitleView = null; - mSubtitleView = null; - mTitleUpView = null; - if (mTitleLayout != null && mTitleLayout.getParent() == this) { - removeView(mTitleLayout); - } - mTitleLayout = null; - if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { - initTitle(); - } - - if (mTabScrollView != null && mIncludeTabs) { - ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams(); - if (lp != null) { - lp.width = LayoutParams.WRAP_CONTENT; - lp.height = LayoutParams.MATCH_PARENT; - } - mTabScrollView.setAllowCollapse(true); - } - } - - /** - * Set the window callback used to invoke menu items; used for dispatching home button presses. - * @param cb Window callback to dispatch to - */ - public void setWindowCallback(Window.Callback cb) { - mWindowCallback = cb; - } - - @Override - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - //UNUSED removeCallbacks(mTabSelector); - if (mActionMenuPresenter != null) { - mActionMenuPresenter.hideOverflowMenu(); - mActionMenuPresenter.hideSubMenus(); - } - } - - @Override - public boolean shouldDelayChildPressedState() { - return false; - } - - public void initProgress() { - mProgressView = new IcsProgressBar(mContext, null, 0, mProgressStyle); - mProgressView.setId(R.id.abs__progress_horizontal); - mProgressView.setMax(10000); - addView(mProgressView); - } - - public void initIndeterminateProgress() { - mIndeterminateProgressView = new IcsProgressBar(mContext, null, 0, mIndeterminateProgressStyle); - mIndeterminateProgressView.setId(R.id.abs__progress_circular); - addView(mIndeterminateProgressView); - } - - @Override - public void setSplitActionBar(boolean splitActionBar) { - if (mSplitActionBar != splitActionBar) { - if (mMenuView != null) { - final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); - if (oldParent != null) { - oldParent.removeView(mMenuView); - } - if (splitActionBar) { - if (mSplitView != null) { - mSplitView.addView(mMenuView); - } - } else { - addView(mMenuView); - } - } - if (mSplitView != null) { - mSplitView.setVisibility(splitActionBar ? VISIBLE : GONE); - } - super.setSplitActionBar(splitActionBar); - } - } - - public boolean isSplitActionBar() { - return mSplitActionBar; - } - - public boolean hasEmbeddedTabs() { - return mIncludeTabs; - } - - public void setEmbeddedTabView(ScrollingTabContainerView tabs) { - if (mTabScrollView != null) { - removeView(mTabScrollView); - } - mTabScrollView = tabs; - mIncludeTabs = tabs != null; - if (mIncludeTabs && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) { - addView(mTabScrollView); - ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams(); - lp.width = LayoutParams.WRAP_CONTENT; - lp.height = LayoutParams.MATCH_PARENT; - tabs.setAllowCollapse(true); - } - } - - public void setCallback(OnNavigationListener callback) { - mCallback = callback; - } - - public void setMenu(Menu menu, MenuPresenter.Callback cb) { - if (menu == mOptionsMenu) return; - - if (mOptionsMenu != null) { - mOptionsMenu.removeMenuPresenter(mActionMenuPresenter); - mOptionsMenu.removeMenuPresenter(mExpandedMenuPresenter); - } - - MenuBuilder builder = (MenuBuilder) menu; - mOptionsMenu = builder; - if (mMenuView != null) { - final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); - if (oldParent != null) { - oldParent.removeView(mMenuView); - } - } - if (mActionMenuPresenter == null) { - mActionMenuPresenter = new ActionMenuPresenter(mContext); - mActionMenuPresenter.setCallback(cb); - mActionMenuPresenter.setId(R.id.abs__action_menu_presenter); - mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter(); - } - - ActionMenuView menuView; - final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.MATCH_PARENT); - if (!mSplitActionBar) { - mActionMenuPresenter.setExpandedActionViewsExclusive( - getResources_getBoolean(getContext(), - R.bool.abs__action_bar_expanded_action_views_exclusive)); - configPresenters(builder); - menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); - final ViewGroup oldParent = (ViewGroup) menuView.getParent(); - if (oldParent != null && oldParent != this) { - oldParent.removeView(menuView); - } - addView(menuView, layoutParams); - } else { - mActionMenuPresenter.setExpandedActionViewsExclusive(false); - // Allow full screen width in split mode. - mActionMenuPresenter.setWidthLimit( - getContext().getResources().getDisplayMetrics().widthPixels, true); - // No limit to the item count; use whatever will fit. - mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); - // Span the whole width - layoutParams.width = LayoutParams.MATCH_PARENT; - configPresenters(builder); - menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); - if (mSplitView != null) { - final ViewGroup oldParent = (ViewGroup) menuView.getParent(); - if (oldParent != null && oldParent != mSplitView) { - oldParent.removeView(menuView); - } - menuView.setVisibility(getAnimatedVisibility()); - mSplitView.addView(menuView, layoutParams); - } else { - // We'll add this later if we missed it this time. - menuView.setLayoutParams(layoutParams); - } - } - mMenuView = menuView; - } - - private void configPresenters(MenuBuilder builder) { - if (builder != null) { - builder.addMenuPresenter(mActionMenuPresenter); - builder.addMenuPresenter(mExpandedMenuPresenter); - } else { - mActionMenuPresenter.initForMenu(mContext, null); - mExpandedMenuPresenter.initForMenu(mContext, null); - mActionMenuPresenter.updateMenuView(true); - mExpandedMenuPresenter.updateMenuView(true); - } - } - - public boolean hasExpandedActionView() { - return mExpandedMenuPresenter != null && - mExpandedMenuPresenter.mCurrentExpandedItem != null; - } - - public void collapseActionView() { - final MenuItemImpl item = mExpandedMenuPresenter == null ? null : - mExpandedMenuPresenter.mCurrentExpandedItem; - if (item != null) { - item.collapseActionView(); - } - } - - public void setCustomNavigationView(View view) { - final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0; - if (mCustomNavView != null && showCustom) { - removeView(mCustomNavView); - } - mCustomNavView = view; - if (mCustomNavView != null && showCustom) { - addView(mCustomNavView); - } - } - - public CharSequence getTitle() { - return mTitle; - } - - /** - * Set the action bar title. This will always replace or override window titles. - * @param title Title to set - * - * @see #setWindowTitle(CharSequence) - */ - public void setTitle(CharSequence title) { - mUserTitle = true; - setTitleImpl(title); - } - - /** - * Set the window title. A window title will always be replaced or overridden by a user title. - * @param title Title to set - * - * @see #setTitle(CharSequence) - */ - public void setWindowTitle(CharSequence title) { - if (!mUserTitle) { - setTitleImpl(title); - } - } - - private void setTitleImpl(CharSequence title) { - mTitle = title; - if (mTitleView != null) { - mTitleView.setText(title); - final boolean visible = mExpandedActionView == null && - (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 && - (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle)); - mTitleLayout.setVisibility(visible ? VISIBLE : GONE); - } - if (mLogoNavItem != null) { - mLogoNavItem.setTitle(title); - } - } - - public CharSequence getSubtitle() { - return mSubtitle; - } - - public void setSubtitle(CharSequence subtitle) { - mSubtitle = subtitle; - if (mSubtitleView != null) { - mSubtitleView.setText(subtitle); - mSubtitleView.setVisibility(subtitle != null ? VISIBLE : GONE); - final boolean visible = mExpandedActionView == null && - (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 && - (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle)); - mTitleLayout.setVisibility(visible ? VISIBLE : GONE); - } - } - - public void setHomeButtonEnabled(boolean enable) { - mHomeLayout.setEnabled(enable); - mHomeLayout.setFocusable(enable); - // Make sure the home button has an accurate content description for accessibility. - if (!enable) { - mHomeLayout.setContentDescription(null); - } else if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) { - mHomeLayout.setContentDescription(mContext.getResources().getText( - R.string.abs__action_bar_up_description)); - } else { - mHomeLayout.setContentDescription(mContext.getResources().getText( - R.string.abs__action_bar_home_description)); - } - } - - public void setDisplayOptions(int options) { - final int flagsChanged = mDisplayOptions == -1 ? -1 : options ^ mDisplayOptions; - mDisplayOptions = options; - - if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) { - final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0; - final int vis = showHome && mExpandedActionView == null ? VISIBLE : GONE; - mHomeLayout.setVisibility(vis); - - if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) { - final boolean setUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0; - mHomeLayout.setUp(setUp); - - // Showing home as up implicitly enables interaction with it. - // In honeycomb it was always enabled, so make this transition - // a bit easier for developers in the common case. - // (It would be silly to show it as up without responding to it.) - if (setUp) { - setHomeButtonEnabled(true); - } - } - - if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) { - final boolean logoVis = mLogo != null && (options & ActionBar.DISPLAY_USE_LOGO) != 0; - mHomeLayout.setIcon(logoVis ? mLogo : mIcon); - } - - if ((flagsChanged & ActionBar.DISPLAY_SHOW_TITLE) != 0) { - if ((options & ActionBar.DISPLAY_SHOW_TITLE) != 0) { - initTitle(); - } else { - removeView(mTitleLayout); - } - } - - if (mTitleLayout != null && (flagsChanged & - (ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME)) != 0) { - final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0; - mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE); - mTitleLayout.setEnabled(!showHome && homeAsUp); - } - - if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) { - if ((options & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { - addView(mCustomNavView); - } else { - removeView(mCustomNavView); - } - } - - requestLayout(); - } else { - invalidate(); - } - - // Make sure the home button has an accurate content description for accessibility. - if (!mHomeLayout.isEnabled()) { - mHomeLayout.setContentDescription(null); - } else if ((options & ActionBar.DISPLAY_HOME_AS_UP) != 0) { - mHomeLayout.setContentDescription(mContext.getResources().getText( - R.string.abs__action_bar_up_description)); - } else { - mHomeLayout.setContentDescription(mContext.getResources().getText( - R.string.abs__action_bar_home_description)); - } - } - - public void setIcon(Drawable icon) { - mIcon = icon; - if (icon != null && - ((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null)) { - mHomeLayout.setIcon(icon); - } - } - - public void setIcon(int resId) { - setIcon(mContext.getResources().getDrawable(resId)); - } - - public void setLogo(Drawable logo) { - mLogo = logo; - if (logo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) { - mHomeLayout.setIcon(logo); - } - } - - public void setLogo(int resId) { - setLogo(mContext.getResources().getDrawable(resId)); - } - - public void setNavigationMode(int mode) { - final int oldMode = mNavigationMode; - if (mode != oldMode) { - switch (oldMode) { - case ActionBar.NAVIGATION_MODE_LIST: - if (mListNavLayout != null) { - removeView(mListNavLayout); - } - break; - case ActionBar.NAVIGATION_MODE_TABS: - if (mTabScrollView != null && mIncludeTabs) { - removeView(mTabScrollView); - } - } - - switch (mode) { - case ActionBar.NAVIGATION_MODE_LIST: - if (mSpinner == null) { - mSpinner = new IcsSpinner(mContext, null, - R.attr.actionDropDownStyle); - mListNavLayout = (IcsLinearLayout) LayoutInflater.from(mContext) - .inflate(R.layout.abs__action_bar_tab_bar_view, null); - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( - LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - params.gravity = Gravity.CENTER; - mListNavLayout.addView(mSpinner, params); - } - if (mSpinner.getAdapter() != mSpinnerAdapter) { - mSpinner.setAdapter(mSpinnerAdapter); - } - mSpinner.setOnItemSelectedListener(mNavItemSelectedListener); - addView(mListNavLayout); - break; - case ActionBar.NAVIGATION_MODE_TABS: - if (mTabScrollView != null && mIncludeTabs) { - addView(mTabScrollView); - } - break; - } - mNavigationMode = mode; - requestLayout(); - } - } - - public void setDropdownAdapter(SpinnerAdapter adapter) { - mSpinnerAdapter = adapter; - if (mSpinner != null) { - mSpinner.setAdapter(adapter); - } - } - - public SpinnerAdapter getDropdownAdapter() { - return mSpinnerAdapter; - } - - public void setDropdownSelectedPosition(int position) { - mSpinner.setSelection(position); - } - - public int getDropdownSelectedPosition() { - return mSpinner.getSelectedItemPosition(); - } - - public View getCustomNavigationView() { - return mCustomNavView; - } - - public int getNavigationMode() { - return mNavigationMode; - } - - public int getDisplayOptions() { - return mDisplayOptions; - } - - @Override - protected ViewGroup.LayoutParams generateDefaultLayoutParams() { - // Used by custom nav views if they don't supply layout params. Everything else - // added to an ActionBarView should have them already. - return new ActionBar.LayoutParams(DEFAULT_CUSTOM_GRAVITY); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - - addView(mHomeLayout); - - if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { - final ViewParent parent = mCustomNavView.getParent(); - if (parent != this) { - if (parent instanceof ViewGroup) { - ((ViewGroup) parent).removeView(mCustomNavView); - } - addView(mCustomNavView); - } - } - } - - private void initTitle() { - if (mTitleLayout == null) { - LayoutInflater inflater = LayoutInflater.from(getContext()); - mTitleLayout = (LinearLayout) inflater.inflate(R.layout.abs__action_bar_title_item, - this, false); - mTitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_title); - mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_subtitle); - mTitleUpView = mTitleLayout.findViewById(R.id.abs__up); - - mTitleLayout.setOnClickListener(mUpClickListener); - - if (mTitleStyleRes != 0) { - mTitleView.setTextAppearance(mContext, mTitleStyleRes); - } - if (mTitle != null) { - mTitleView.setText(mTitle); - } - - if (mSubtitleStyleRes != 0) { - mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes); - } - if (mSubtitle != null) { - mSubtitleView.setText(mSubtitle); - mSubtitleView.setVisibility(VISIBLE); - } - - final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0; - final boolean showHome = (mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0; - mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE); - mTitleLayout.setEnabled(homeAsUp && !showHome); - } - - addView(mTitleLayout); - if (mExpandedActionView != null || - (TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle))) { - // Don't show while in expanded mode or with empty text - mTitleLayout.setVisibility(GONE); - } - } - - public void setContextView(ActionBarContextView view) { - mContextView = view; - } - - public void setCollapsable(boolean collapsable) { - mIsCollapsable = collapsable; - } - - public boolean isCollapsed() { - return mIsCollapsed; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int childCount = getChildCount(); - if (mIsCollapsable) { - int visibleChildren = 0; - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - if (child.getVisibility() != GONE && - !(child == mMenuView && mMenuView.getChildCount() == 0)) { - visibleChildren++; - } - } - - if (visibleChildren == 0) { - // No size for an empty action bar when collapsable. - setMeasuredDimension(0, 0); - mIsCollapsed = true; - return; - } - } - mIsCollapsed = false; - - int widthMode = MeasureSpec.getMode(widthMeasureSpec); - if (widthMode != MeasureSpec.EXACTLY) { - throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + - "with android:layout_width=\"match_parent\" (or fill_parent)"); - } - - int heightMode = MeasureSpec.getMode(heightMeasureSpec); - if (heightMode != MeasureSpec.AT_MOST) { - throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + - "with android:layout_height=\"wrap_content\""); - } - - int contentWidth = MeasureSpec.getSize(widthMeasureSpec); - - int maxHeight = mContentHeight > 0 ? - mContentHeight : MeasureSpec.getSize(heightMeasureSpec); - - final int verticalPadding = getPaddingTop() + getPaddingBottom(); - final int paddingLeft = getPaddingLeft(); - final int paddingRight = getPaddingRight(); - final int height = maxHeight - verticalPadding; - final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); - - int availableWidth = contentWidth - paddingLeft - paddingRight; - int leftOfCenter = availableWidth / 2; - int rightOfCenter = leftOfCenter; - - HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; - - if (homeLayout.getVisibility() != GONE) { - final ViewGroup.LayoutParams lp = homeLayout.getLayoutParams(); - int homeWidthSpec; - if (lp.width < 0) { - homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST); - } else { - homeWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); - } - homeLayout.measure(homeWidthSpec, - MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); - final int homeWidth = homeLayout.getMeasuredWidth() + homeLayout.getLeftOffset(); - availableWidth = Math.max(0, availableWidth - homeWidth); - leftOfCenter = Math.max(0, availableWidth - homeWidth); - } - - if (mMenuView != null && mMenuView.getParent() == this) { - availableWidth = measureChildView(mMenuView, availableWidth, - childSpecHeight, 0); - rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth()); - } - - if (mIndeterminateProgressView != null && - mIndeterminateProgressView.getVisibility() != GONE) { - availableWidth = measureChildView(mIndeterminateProgressView, availableWidth, - childSpecHeight, 0); - rightOfCenter = Math.max(0, - rightOfCenter - mIndeterminateProgressView.getMeasuredWidth()); - } - - final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && - (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; - - if (mExpandedActionView == null) { - switch (mNavigationMode) { - case ActionBar.NAVIGATION_MODE_LIST: - if (mListNavLayout != null) { - final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding; - availableWidth = Math.max(0, availableWidth - itemPaddingSize); - leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize); - mListNavLayout.measure( - MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), - MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); - final int listNavWidth = mListNavLayout.getMeasuredWidth(); - availableWidth = Math.max(0, availableWidth - listNavWidth); - leftOfCenter = Math.max(0, leftOfCenter - listNavWidth); - } - break; - case ActionBar.NAVIGATION_MODE_TABS: - if (mTabScrollView != null) { - final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding; - availableWidth = Math.max(0, availableWidth - itemPaddingSize); - leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize); - mTabScrollView.measure( - MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), - MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); - final int tabWidth = mTabScrollView.getMeasuredWidth(); - availableWidth = Math.max(0, availableWidth - tabWidth); - leftOfCenter = Math.max(0, leftOfCenter - tabWidth); - } - break; - } - } - - View customView = null; - if (mExpandedActionView != null) { - customView = mExpandedActionView; - } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && - mCustomNavView != null) { - customView = mCustomNavView; - } - - if (customView != null) { - final ViewGroup.LayoutParams lp = generateLayoutParams(customView.getLayoutParams()); - final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? - (ActionBar.LayoutParams) lp : null; - - int horizontalMargin = 0; - int verticalMargin = 0; - if (ablp != null) { - horizontalMargin = ablp.leftMargin + ablp.rightMargin; - verticalMargin = ablp.topMargin + ablp.bottomMargin; - } - - // If the action bar is wrapping to its content height, don't allow a custom - // view to MATCH_PARENT. - int customNavHeightMode; - if (mContentHeight <= 0) { - customNavHeightMode = MeasureSpec.AT_MOST; - } else { - customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ? - MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; - } - final int customNavHeight = Math.max(0, - (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin); - - final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ? - MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; - int customNavWidth = Math.max(0, - (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth) - - horizontalMargin); - final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY) & - Gravity.HORIZONTAL_GRAVITY_MASK; - - // Centering a custom view is treated specially; we try to center within the whole - // action bar rather than in the available space. - if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.MATCH_PARENT) { - customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2; - } - - customView.measure( - MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode), - MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode)); - availableWidth -= horizontalMargin + customView.getMeasuredWidth(); - } - - if (mExpandedActionView == null && showTitle) { - availableWidth = measureChildView(mTitleLayout, availableWidth, - MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0); - leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth()); - } - - if (mContentHeight <= 0) { - int measuredHeight = 0; - for (int i = 0; i < childCount; i++) { - View v = getChildAt(i); - int paddedViewHeight = v.getMeasuredHeight() + verticalPadding; - if (paddedViewHeight > measuredHeight) { - measuredHeight = paddedViewHeight; - } - } - setMeasuredDimension(contentWidth, measuredHeight); - } else { - setMeasuredDimension(contentWidth, maxHeight); - } - - if (mContextView != null) { - mContextView.setContentHeight(getMeasuredHeight()); - } - - if (mProgressView != null && mProgressView.getVisibility() != GONE) { - mProgressView.measure(MeasureSpec.makeMeasureSpec( - contentWidth - mProgressBarPadding * 2, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST)); - } - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - int x = getPaddingLeft(); - final int y = getPaddingTop(); - final int contentHeight = b - t - getPaddingTop() - getPaddingBottom(); - - if (contentHeight <= 0) { - // Nothing to do if we can't see anything. - return; - } - - HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; - if (homeLayout.getVisibility() != GONE) { - final int leftOffset = homeLayout.getLeftOffset(); - x += positionChild(homeLayout, x + leftOffset, y, contentHeight) + leftOffset; - } - - if (mExpandedActionView == null) { - final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && - (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; - if (showTitle) { - x += positionChild(mTitleLayout, x, y, contentHeight); - } - - switch (mNavigationMode) { - case ActionBar.NAVIGATION_MODE_STANDARD: - break; - case ActionBar.NAVIGATION_MODE_LIST: - if (mListNavLayout != null) { - if (showTitle) x += mItemPadding; - x += positionChild(mListNavLayout, x, y, contentHeight) + mItemPadding; - } - break; - case ActionBar.NAVIGATION_MODE_TABS: - if (mTabScrollView != null) { - if (showTitle) x += mItemPadding; - x += positionChild(mTabScrollView, x, y, contentHeight) + mItemPadding; - } - break; - } - } - - int menuLeft = r - l - getPaddingRight(); - if (mMenuView != null && mMenuView.getParent() == this) { - positionChildInverse(mMenuView, menuLeft, y, contentHeight); - menuLeft -= mMenuView.getMeasuredWidth(); - } - - if (mIndeterminateProgressView != null && - mIndeterminateProgressView.getVisibility() != GONE) { - positionChildInverse(mIndeterminateProgressView, menuLeft, y, contentHeight); - menuLeft -= mIndeterminateProgressView.getMeasuredWidth(); - } - - View customView = null; - if (mExpandedActionView != null) { - customView = mExpandedActionView; - } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && - mCustomNavView != null) { - customView = mCustomNavView; - } - if (customView != null) { - ViewGroup.LayoutParams lp = customView.getLayoutParams(); - final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? - (ActionBar.LayoutParams) lp : null; - - final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY; - final int navWidth = customView.getMeasuredWidth(); - - int topMargin = 0; - int bottomMargin = 0; - if (ablp != null) { - x += ablp.leftMargin; - menuLeft -= ablp.rightMargin; - topMargin = ablp.topMargin; - bottomMargin = ablp.bottomMargin; - } - - int hgravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; - // See if we actually have room to truly center; if not push against left or right. - if (hgravity == Gravity.CENTER_HORIZONTAL) { - final int centeredLeft = ((getRight() - getLeft()) - navWidth) / 2; - if (centeredLeft < x) { - hgravity = Gravity.LEFT; - } else if (centeredLeft + navWidth > menuLeft) { - hgravity = Gravity.RIGHT; - } - } else if (gravity == -1) { - hgravity = Gravity.LEFT; - } - - int xpos = 0; - switch (hgravity) { - case Gravity.CENTER_HORIZONTAL: - xpos = ((getRight() - getLeft()) - navWidth) / 2; - break; - case Gravity.LEFT: - xpos = x; - break; - case Gravity.RIGHT: - xpos = menuLeft - navWidth; - break; - } - - int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; - - if (gravity == -1) { - vgravity = Gravity.CENTER_VERTICAL; - } - - int ypos = 0; - switch (vgravity) { - case Gravity.CENTER_VERTICAL: - final int paddedTop = getPaddingTop(); - final int paddedBottom = getBottom() - getTop() - getPaddingBottom(); - ypos = ((paddedBottom - paddedTop) - customView.getMeasuredHeight()) / 2; - break; - case Gravity.TOP: - ypos = getPaddingTop() + topMargin; - break; - case Gravity.BOTTOM: - ypos = getHeight() - getPaddingBottom() - customView.getMeasuredHeight() - - bottomMargin; - break; - } - final int customWidth = customView.getMeasuredWidth(); - customView.layout(xpos, ypos, xpos + customWidth, - ypos + customView.getMeasuredHeight()); - x += customWidth; - } - - if (mProgressView != null) { - mProgressView.bringToFront(); - final int halfProgressHeight = mProgressView.getMeasuredHeight() / 2; - mProgressView.layout(mProgressBarPadding, -halfProgressHeight, - mProgressBarPadding + mProgressView.getMeasuredWidth(), halfProgressHeight); - } - } - - @Override - public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { - return new ActionBar.LayoutParams(getContext(), attrs); - } - - @Override - public ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) { - if (lp == null) { - lp = generateDefaultLayoutParams(); - } - return lp; - } - - @Override - public Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - SavedState state = new SavedState(superState); - - if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) { - state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId(); - } - - state.isOverflowOpen = isOverflowMenuShowing(); - - return state; - } - - @Override - public void onRestoreInstanceState(Parcelable p) { - SavedState state = (SavedState) p; - - super.onRestoreInstanceState(state.getSuperState()); - - if (state.expandedMenuItemId != 0 && - mExpandedMenuPresenter != null && mOptionsMenu != null) { - final MenuItem item = mOptionsMenu.findItem(state.expandedMenuItemId); - if (item != null) { - item.expandActionView(); - } - } - - if (state.isOverflowOpen) { - postShowOverflowMenu(); - } - } - - static class SavedState extends BaseSavedState { - int expandedMenuItemId; - boolean isOverflowOpen; - - SavedState(Parcelable superState) { - super(superState); - } - - private SavedState(Parcel in) { - super(in); - expandedMenuItemId = in.readInt(); - isOverflowOpen = in.readInt() != 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeInt(expandedMenuItemId); - out.writeInt(isOverflowOpen ? 1 : 0); - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - - public static class HomeView extends FrameLayout { - private View mUpView; - private ImageView mIconView; - private int mUpWidth; - - public HomeView(Context context) { - this(context, null); - } - - public HomeView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public void setUp(boolean isUp) { - mUpView.setVisibility(isUp ? VISIBLE : GONE); - } - - public void setIcon(Drawable icon) { - mIconView.setImageDrawable(icon); - } - - @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - onPopulateAccessibilityEvent(event); - return true; - } - - @Override - public void onPopulateAccessibilityEvent(AccessibilityEvent event) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - super.onPopulateAccessibilityEvent(event); - } - final CharSequence cdesc = getContentDescription(); - if (!TextUtils.isEmpty(cdesc)) { - event.getText().add(cdesc); - } - } - - @Override - public boolean dispatchHoverEvent(MotionEvent event) { - // Don't allow children to hover; we want this to be treated as a single component. - return onHoverEvent(event); - } - - @Override - protected void onFinishInflate() { - mUpView = findViewById(R.id.abs__up); - mIconView = (ImageView) findViewById(R.id.abs__home); - } - - public int getLeftOffset() { - return mUpView.getVisibility() == GONE ? mUpWidth : 0; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0); - final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams(); - mUpWidth = upLp.leftMargin + mUpView.getMeasuredWidth() + upLp.rightMargin; - int width = mUpView.getVisibility() == GONE ? 0 : mUpWidth; - int height = upLp.topMargin + mUpView.getMeasuredHeight() + upLp.bottomMargin; - measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0); - final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); - width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin; - height = Math.max(height, - iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin); - - final int widthMode = MeasureSpec.getMode(widthMeasureSpec); - final int heightMode = MeasureSpec.getMode(heightMeasureSpec); - final int widthSize = MeasureSpec.getSize(widthMeasureSpec); - final int heightSize = MeasureSpec.getSize(heightMeasureSpec); - - switch (widthMode) { - case MeasureSpec.AT_MOST: - width = Math.min(width, widthSize); - break; - case MeasureSpec.EXACTLY: - width = widthSize; - break; - case MeasureSpec.UNSPECIFIED: - default: - break; - } - switch (heightMode) { - case MeasureSpec.AT_MOST: - height = Math.min(height, heightSize); - break; - case MeasureSpec.EXACTLY: - height = heightSize; - break; - case MeasureSpec.UNSPECIFIED: - default: - break; - } - setMeasuredDimension(width, height); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - final int vCenter = (b - t) / 2; - //UNUSED int width = r - l; - int upOffset = 0; - if (mUpView.getVisibility() != GONE) { - final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams(); - final int upHeight = mUpView.getMeasuredHeight(); - final int upWidth = mUpView.getMeasuredWidth(); - final int upTop = vCenter - upHeight / 2; - mUpView.layout(0, upTop, upWidth, upTop + upHeight); - upOffset = upLp.leftMargin + upWidth + upLp.rightMargin; - //UNUSED width -= upOffset; - l += upOffset; - } - final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); - final int iconHeight = mIconView.getMeasuredHeight(); - final int iconWidth = mIconView.getMeasuredWidth(); - final int hCenter = (r - l) / 2; - final int iconLeft = upOffset + Math.max(iconLp.leftMargin, hCenter - iconWidth / 2); - final int iconTop = Math.max(iconLp.topMargin, vCenter - iconHeight / 2); - mIconView.layout(iconLeft, iconTop, iconLeft + iconWidth, iconTop + iconHeight); - } - } - - private class ExpandedActionViewMenuPresenter implements MenuPresenter { - MenuBuilder mMenu; - MenuItemImpl mCurrentExpandedItem; - - @Override - public void initForMenu(Context context, MenuBuilder menu) { - // Clear the expanded action view when menus change. - if (mMenu != null && mCurrentExpandedItem != null) { - mMenu.collapseItemActionView(mCurrentExpandedItem); - } - mMenu = menu; - } - - @Override - public MenuView getMenuView(ViewGroup root) { - return null; - } - - @Override - public void updateMenuView(boolean cleared) { - // Make sure the expanded item we have is still there. - if (mCurrentExpandedItem != null) { - boolean found = false; - - if (mMenu != null) { - final int count = mMenu.size(); - for (int i = 0; i < count; i++) { - final MenuItem item = mMenu.getItem(i); - if (item == mCurrentExpandedItem) { - found = true; - break; - } - } - } - - if (!found) { - // The item we had expanded disappeared. Collapse. - collapseItemActionView(mMenu, mCurrentExpandedItem); - } - } - } - - @Override - public void setCallback(Callback cb) { - } - - @Override - public boolean onSubMenuSelected(SubMenuBuilder subMenu) { - return false; - } - - @Override - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - } - - @Override - public boolean flagActionItems() { - return false; - } - - @Override - public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { - mExpandedActionView = item.getActionView(); - mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(/* TODO getResources() */)); - mCurrentExpandedItem = item; - if (mExpandedActionView.getParent() != ActionBarView.this) { - addView(mExpandedActionView); - } - if (mExpandedHomeLayout.getParent() != ActionBarView.this) { - addView(mExpandedHomeLayout); - } - mHomeLayout.setVisibility(GONE); - if (mTitleLayout != null) mTitleLayout.setVisibility(GONE); - if (mTabScrollView != null) mTabScrollView.setVisibility(GONE); - if (mSpinner != null) mSpinner.setVisibility(GONE); - if (mCustomNavView != null) mCustomNavView.setVisibility(GONE); - requestLayout(); - item.setActionViewExpanded(true); - - if (mExpandedActionView instanceof CollapsibleActionView) { - ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded(); - } - - return true; - } - - @Override - public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { - // Do this before detaching the actionview from the hierarchy, in case - // it needs to dismiss the soft keyboard, etc. - if (mExpandedActionView instanceof CollapsibleActionView) { - ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed(); - } - - removeView(mExpandedActionView); - removeView(mExpandedHomeLayout); - mExpandedActionView = null; - if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) { - mHomeLayout.setVisibility(VISIBLE); - } - if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { - if (mTitleLayout == null) { - initTitle(); - } else { - mTitleLayout.setVisibility(VISIBLE); - } - } - if (mTabScrollView != null && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) { - mTabScrollView.setVisibility(VISIBLE); - } - if (mSpinner != null && mNavigationMode == ActionBar.NAVIGATION_MODE_LIST) { - mSpinner.setVisibility(VISIBLE); - } - if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { - mCustomNavView.setVisibility(VISIBLE); - } - mExpandedHomeLayout.setIcon(null); - mCurrentExpandedItem = null; - requestLayout(); - item.setActionViewExpanded(false); - - return true; - } - - @Override - public int getId() { - return 0; - } - - @Override - public Parcelable onSaveInstanceState() { - return null; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java deleted file mode 100644 index fa3698f3..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import java.util.Locale; -import android.content.Context; -import android.content.res.TypedArray; -import android.os.Build; -import android.util.AttributeSet; -import android.widget.Button; - -public class CapitalizingButton extends Button { - private static final boolean SANS_ICE_CREAM = Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH; - private static final boolean IS_GINGERBREAD = Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD; - - private static final int[] R_styleable_Button = new int[] { - android.R.attr.textAllCaps - }; - private static final int R_styleable_Button_textAllCaps = 0; - - private boolean mAllCaps; - - public CapitalizingButton(Context context, AttributeSet attrs) { - super(context, attrs); - - TypedArray a = context.obtainStyledAttributes(attrs, R_styleable_Button); - mAllCaps = a.getBoolean(R_styleable_Button_textAllCaps, true); - a.recycle(); - } - - public void setTextCompat(CharSequence text) { - if (SANS_ICE_CREAM && mAllCaps && text != null) { - if (IS_GINGERBREAD) { - setText(text.toString().toUpperCase(Locale.ROOT)); - } else { - setText(text.toString().toUpperCase()); - } - } else { - setText(text); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/CapitalizingTextView.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/CapitalizingTextView.java deleted file mode 100644 index cae8b8ae..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/CapitalizingTextView.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.TypedArray; -import android.os.Build; -import android.util.AttributeSet; -import android.widget.TextView; - -import java.util.Locale; - -public class CapitalizingTextView extends TextView { - private static final boolean SANS_ICE_CREAM = Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH; - private static final boolean IS_GINGERBREAD = Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD; - - private static final int[] R_styleable_TextView = new int[] { - android.R.attr.textAllCaps - }; - private static final int R_styleable_TextView_textAllCaps = 0; - - private boolean mAllCaps; - - public CapitalizingTextView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public CapitalizingTextView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - TypedArray a = context.obtainStyledAttributes(attrs, R_styleable_TextView, defStyle, 0); - mAllCaps = a.getBoolean(R_styleable_TextView_textAllCaps, true); - a.recycle(); - } - - public void setTextCompat(CharSequence text) { - if (SANS_ICE_CREAM && mAllCaps && text != null) { - if (IS_GINGERBREAD) { - try { - setText(text.toString().toUpperCase(Locale.ROOT)); - } catch (NoSuchFieldError e) { - //Some manufacturer broke Locale.ROOT. See #572. - setText(text.toString().toUpperCase()); - } - } else { - setText(text.toString().toUpperCase()); - } - } else { - setText(text); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/CollapsibleActionViewWrapper.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/CollapsibleActionViewWrapper.java deleted file mode 100644 index 14f092c8..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/CollapsibleActionViewWrapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import android.view.View; -import android.widget.FrameLayout; -import com.actionbarsherlock.view.CollapsibleActionView; - -/** - * Wraps an ABS collapsible action view in a native container that delegates the calls. - */ -public class CollapsibleActionViewWrapper extends FrameLayout implements android.view.CollapsibleActionView { - private final CollapsibleActionView child; - - public CollapsibleActionViewWrapper(View child) { - super(child.getContext()); - this.child = (CollapsibleActionView) child; - addView(child); - } - - @Override public void onActionViewExpanded() { - child.onActionViewExpanded(); - } - - @Override public void onActionViewCollapsed() { - child.onActionViewCollapsed(); - } - - public View unwrap() { - return getChildAt(0); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java deleted file mode 100644 index ad1b4f0a..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import static android.view.View.MeasureSpec.EXACTLY; -import android.content.Context; -import android.content.res.TypedArray; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.util.TypedValue; -import android.widget.LinearLayout; -import com.actionbarsherlock.R; - -public class FakeDialogPhoneWindow extends LinearLayout { - final TypedValue mMinWidthMajor = new TypedValue(); - final TypedValue mMinWidthMinor = new TypedValue(); - - public FakeDialogPhoneWindow(Context context, AttributeSet attrs) { - super(context, attrs); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockTheme); - - a.getValue(R.styleable.SherlockTheme_windowMinWidthMajor, mMinWidthMajor); - a.getValue(R.styleable.SherlockTheme_windowMinWidthMinor, mMinWidthMinor); - - a.recycle(); - } - - /* Stolen from PhoneWindow */ - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); - final boolean isPortrait = metrics.widthPixels < metrics.heightPixels; - - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - int width = getMeasuredWidth(); - boolean measure = false; - - widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, EXACTLY); - - final TypedValue tv = isPortrait ? mMinWidthMinor : mMinWidthMajor; - - if (tv.type != TypedValue.TYPE_NULL) { - final int min; - if (tv.type == TypedValue.TYPE_DIMENSION) { - min = (int)tv.getDimension(metrics); - } else if (tv.type == TypedValue.TYPE_FRACTION) { - min = (int)tv.getFraction(metrics.widthPixels, metrics.widthPixels); - } else { - min = 0; - } - - if (width < min) { - widthMeasureSpec = MeasureSpec.makeMeasureSpec(min, EXACTLY); - measure = true; - } - } - - // TODO: Support height? - - if (measure) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsAbsSpinner.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsAbsSpinner.java deleted file mode 100644 index ce0cb3bc..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsAbsSpinner.java +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.database.DataSetObserver; -import android.graphics.Rect; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.AttributeSet; -import android.util.SparseArray; -import android.view.View; -import android.view.ViewGroup; -import android.widget.SpinnerAdapter; - -/** - * An abstract base class for spinner widgets. SDK users will probably not - * need to use this class. - * - * @attr ref android.R.styleable#AbsSpinner_entries - */ -public abstract class IcsAbsSpinner extends IcsAdapterView { - private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; - - SpinnerAdapter mAdapter; - - int mHeightMeasureSpec; - int mWidthMeasureSpec; - boolean mBlockLayoutRequests; - - int mSelectionLeftPadding = 0; - int mSelectionTopPadding = 0; - int mSelectionRightPadding = 0; - int mSelectionBottomPadding = 0; - final Rect mSpinnerPadding = new Rect(); - - final RecycleBin mRecycler = new RecycleBin(); - private DataSetObserver mDataSetObserver; - - /** Temporary frame to hold a child View's frame rectangle */ - private Rect mTouchFrame; - - public IcsAbsSpinner(Context context) { - super(context); - initAbsSpinner(); - } - - public IcsAbsSpinner(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public IcsAbsSpinner(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - initAbsSpinner(); - - /* - TypedArray a = context.obtainStyledAttributes(attrs, - com.android.internal.R.styleable.AbsSpinner, defStyle, 0); - - CharSequence[] entries = a.getTextArray(R.styleable.AbsSpinner_entries); - if (entries != null) { - ArrayAdapter adapter = - new ArrayAdapter(context, - R.layout.simple_spinner_item, entries); - adapter.setDropDownViewResource(R.layout.simple_spinner_dropdown_item); - setAdapter(adapter); - } - - a.recycle(); - */ - } - - /** - * Common code for different constructor flavors - */ - private void initAbsSpinner() { - setFocusable(true); - setWillNotDraw(false); - } - - /** - * The Adapter is used to provide the data which backs this Spinner. - * It also provides methods to transform spinner items based on their position - * relative to the selected item. - * @param adapter The SpinnerAdapter to use for this Spinner - */ - @Override - public void setAdapter(SpinnerAdapter adapter) { - if (null != mAdapter) { - mAdapter.unregisterDataSetObserver(mDataSetObserver); - resetList(); - } - - mAdapter = adapter; - - mOldSelectedPosition = INVALID_POSITION; - mOldSelectedRowId = INVALID_ROW_ID; - - if (mAdapter != null) { - mOldItemCount = mItemCount; - mItemCount = mAdapter.getCount(); - checkFocus(); - - mDataSetObserver = new AdapterDataSetObserver(); - mAdapter.registerDataSetObserver(mDataSetObserver); - - int position = mItemCount > 0 ? 0 : INVALID_POSITION; - - setSelectedPositionInt(position); - setNextSelectedPositionInt(position); - - if (mItemCount == 0) { - // Nothing selected - checkSelectionChanged(); - } - - } else { - checkFocus(); - resetList(); - // Nothing selected - checkSelectionChanged(); - } - - requestLayout(); - } - - /** - * Clear out all children from the list - */ - void resetList() { - mDataChanged = false; - mNeedSync = false; - - removeAllViewsInLayout(); - mOldSelectedPosition = INVALID_POSITION; - mOldSelectedRowId = INVALID_ROW_ID; - - setSelectedPositionInt(INVALID_POSITION); - setNextSelectedPositionInt(INVALID_POSITION); - invalidate(); - } - - /** - * @see android.view.View#measure(int, int) - * - * Figure out the dimensions of this Spinner. The width comes from - * the widthMeasureSpec as Spinnners can't have their width set to - * UNSPECIFIED. The height is based on the height of the selected item - * plus padding. - */ - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int widthMode = MeasureSpec.getMode(widthMeasureSpec); - int widthSize; - int heightSize; - - final int mPaddingLeft = getPaddingLeft(); - final int mPaddingTop = getPaddingTop(); - final int mPaddingRight = getPaddingRight(); - final int mPaddingBottom = getPaddingBottom(); - - mSpinnerPadding.left = mPaddingLeft > mSelectionLeftPadding ? mPaddingLeft - : mSelectionLeftPadding; - mSpinnerPadding.top = mPaddingTop > mSelectionTopPadding ? mPaddingTop - : mSelectionTopPadding; - mSpinnerPadding.right = mPaddingRight > mSelectionRightPadding ? mPaddingRight - : mSelectionRightPadding; - mSpinnerPadding.bottom = mPaddingBottom > mSelectionBottomPadding ? mPaddingBottom - : mSelectionBottomPadding; - - if (mDataChanged) { - handleDataChanged(); - } - - int preferredHeight = 0; - int preferredWidth = 0; - boolean needsMeasuring = true; - - int selectedPosition = getSelectedItemPosition(); - if (selectedPosition >= 0 && mAdapter != null && selectedPosition < mAdapter.getCount()) { - // Try looking in the recycler. (Maybe we were measured once already) - View view = mRecycler.get(selectedPosition); - if (view == null) { - // Make a new one - view = mAdapter.getView(selectedPosition, null, this); - } - - if (view != null) { - // Put in recycler for re-measuring and/or layout - mRecycler.put(selectedPosition, view); - } - - if (view != null) { - if (view.getLayoutParams() == null) { - mBlockLayoutRequests = true; - view.setLayoutParams(generateDefaultLayoutParams()); - mBlockLayoutRequests = false; - } - measureChild(view, widthMeasureSpec, heightMeasureSpec); - - preferredHeight = getChildHeight(view) + mSpinnerPadding.top + mSpinnerPadding.bottom; - preferredWidth = getChildWidth(view) + mSpinnerPadding.left + mSpinnerPadding.right; - - needsMeasuring = false; - } - } - - if (needsMeasuring) { - // No views -- just use padding - preferredHeight = mSpinnerPadding.top + mSpinnerPadding.bottom; - if (widthMode == MeasureSpec.UNSPECIFIED) { - preferredWidth = mSpinnerPadding.left + mSpinnerPadding.right; - } - } - - preferredHeight = Math.max(preferredHeight, getSuggestedMinimumHeight()); - preferredWidth = Math.max(preferredWidth, getSuggestedMinimumWidth()); - - if (IS_HONEYCOMB) { - heightSize = resolveSizeAndState(preferredHeight, heightMeasureSpec, 0); - widthSize = resolveSizeAndState(preferredWidth, widthMeasureSpec, 0); - } else { - heightSize = resolveSize(preferredHeight, heightMeasureSpec); - widthSize = resolveSize(preferredWidth, widthMeasureSpec); - } - - setMeasuredDimension(widthSize, heightSize); - mHeightMeasureSpec = heightMeasureSpec; - mWidthMeasureSpec = widthMeasureSpec; - } - - int getChildHeight(View child) { - return child.getMeasuredHeight(); - } - - int getChildWidth(View child) { - return child.getMeasuredWidth(); - } - - @Override - protected ViewGroup.LayoutParams generateDefaultLayoutParams() { - return new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - } - - void recycleAllViews() { - final int childCount = getChildCount(); - final IcsAbsSpinner.RecycleBin recycleBin = mRecycler; - final int position = mFirstPosition; - - // All views go in recycler - for (int i = 0; i < childCount; i++) { - View v = getChildAt(i); - int index = position + i; - recycleBin.put(index, v); - } - } - - /** - * Jump directly to a specific item in the adapter data. - */ - public void setSelection(int position, boolean animate) { - // Animate only if requested position is already on screen somewhere - boolean shouldAnimate = animate && mFirstPosition <= position && - position <= mFirstPosition + getChildCount() - 1; - setSelectionInt(position, shouldAnimate); - } - - @Override - public void setSelection(int position) { - setNextSelectedPositionInt(position); - requestLayout(); - invalidate(); - } - - - /** - * Makes the item at the supplied position selected. - * - * @param position Position to select - * @param animate Should the transition be animated - * - */ - void setSelectionInt(int position, boolean animate) { - if (position != mOldSelectedPosition) { - mBlockLayoutRequests = true; - int delta = position - mSelectedPosition; - setNextSelectedPositionInt(position); - layout(delta, animate); - mBlockLayoutRequests = false; - } - } - - abstract void layout(int delta, boolean animate); - - @Override - public View getSelectedView() { - if (mItemCount > 0 && mSelectedPosition >= 0) { - return getChildAt(mSelectedPosition - mFirstPosition); - } else { - return null; - } - } - - /** - * Override to prevent spamming ourselves with layout requests - * as we place views - * - * @see android.view.View#requestLayout() - */ - @Override - public void requestLayout() { - if (!mBlockLayoutRequests) { - super.requestLayout(); - } - } - - @Override - public SpinnerAdapter getAdapter() { - return mAdapter; - } - - @Override - public int getCount() { - return mItemCount; - } - - /** - * Maps a point to a position in the list. - * - * @param x X in local coordinate - * @param y Y in local coordinate - * @return The position of the item which contains the specified point, or - * {@link #INVALID_POSITION} if the point does not intersect an item. - */ - public int pointToPosition(int x, int y) { - Rect frame = mTouchFrame; - if (frame == null) { - mTouchFrame = new Rect(); - frame = mTouchFrame; - } - - final int count = getChildCount(); - for (int i = count - 1; i >= 0; i--) { - View child = getChildAt(i); - if (child.getVisibility() == View.VISIBLE) { - child.getHitRect(frame); - if (frame.contains(x, y)) { - return mFirstPosition + i; - } - } - } - return INVALID_POSITION; - } - - static class SavedState extends BaseSavedState { - long selectedId; - int position; - - /** - * Constructor called from {@link AbsSpinner#onSaveInstanceState()} - */ - SavedState(Parcelable superState) { - super(superState); - } - - /** - * Constructor called from {@link #CREATOR} - */ - private SavedState(Parcel in) { - super(in); - selectedId = in.readLong(); - position = in.readInt(); - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeLong(selectedId); - out.writeInt(position); - } - - @Override - public String toString() { - return "AbsSpinner.SavedState{" - + Integer.toHexString(System.identityHashCode(this)) - + " selectedId=" + selectedId - + " position=" + position + "}"; - } - - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - - @Override - public Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - ss.selectedId = getSelectedItemId(); - if (ss.selectedId >= 0) { - ss.position = getSelectedItemPosition(); - } else { - ss.position = INVALID_POSITION; - } - return ss; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - SavedState ss = (SavedState) state; - - super.onRestoreInstanceState(ss.getSuperState()); - - if (ss.selectedId >= 0) { - mDataChanged = true; - mNeedSync = true; - mSyncRowId = ss.selectedId; - mSyncPosition = ss.position; - mSyncMode = SYNC_SELECTED_POSITION; - requestLayout(); - } - } - - class RecycleBin { - private final SparseArray mScrapHeap = new SparseArray(); - - public void put(int position, View v) { - mScrapHeap.put(position, v); - } - - View get(int position) { - // System.out.print("Looking for " + position); - View result = mScrapHeap.get(position); - if (result != null) { - // System.out.println(" HIT"); - mScrapHeap.delete(position); - } else { - // System.out.println(" MISS"); - } - return result; - } - - void clear() { - final SparseArray scrapHeap = mScrapHeap; - final int count = scrapHeap.size(); - for (int i = 0; i < count; i++) { - final View view = scrapHeap.valueAt(i); - if (view != null) { - removeDetachedView(view, true); - } - } - scrapHeap.clear(); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsAdapterView.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsAdapterView.java deleted file mode 100644 index c786dc5c..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsAdapterView.java +++ /dev/null @@ -1,1160 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.database.DataSetObserver; -import android.os.Parcelable; -import android.os.SystemClock; -import android.util.AttributeSet; -import android.util.SparseArray; -import android.view.ContextMenu; -import android.view.SoundEffectConstants; -import android.view.View; -import android.view.ViewDebug; -import android.view.ViewGroup; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; -import android.widget.Adapter; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; - - -/** - * An AdapterView is a view whose children are determined by an {@link Adapter}. - * - *

- * See {@link ListView}, {@link GridView}, {@link Spinner} and - * {@link Gallery} for commonly used subclasses of AdapterView. - * - *

- *

Developer Guides

- *

For more information about using AdapterView, read the - * Binding to Data with AdapterView - * developer guide.

- */ -public abstract class IcsAdapterView extends ViewGroup { - - /** - * The item view type returned by {@link Adapter#getItemViewType(int)} when - * the adapter does not want the item's view recycled. - */ - public static final int ITEM_VIEW_TYPE_IGNORE = -1; - - /** - * The item view type returned by {@link Adapter#getItemViewType(int)} when - * the item is a header or footer. - */ - public static final int ITEM_VIEW_TYPE_HEADER_OR_FOOTER = -2; - - /** - * The position of the first child displayed - */ - @ViewDebug.ExportedProperty(category = "scrolling") - int mFirstPosition = 0; - - /** - * The offset in pixels from the top of the AdapterView to the top - * of the view to select during the next layout. - */ - int mSpecificTop; - - /** - * Position from which to start looking for mSyncRowId - */ - int mSyncPosition; - - /** - * Row id to look for when data has changed - */ - long mSyncRowId = INVALID_ROW_ID; - - /** - * Height of the view when mSyncPosition and mSyncRowId where set - */ - long mSyncHeight; - - /** - * True if we need to sync to mSyncRowId - */ - boolean mNeedSync = false; - - /** - * Indicates whether to sync based on the selection or position. Possible - * values are {@link #SYNC_SELECTED_POSITION} or - * {@link #SYNC_FIRST_POSITION}. - */ - int mSyncMode; - - /** - * Our height after the last layout - */ - private int mLayoutHeight; - - /** - * Sync based on the selected child - */ - static final int SYNC_SELECTED_POSITION = 0; - - /** - * Sync based on the first child displayed - */ - static final int SYNC_FIRST_POSITION = 1; - - /** - * Maximum amount of time to spend in {@link #findSyncPosition()} - */ - static final int SYNC_MAX_DURATION_MILLIS = 100; - - /** - * Indicates that this view is currently being laid out. - */ - boolean mInLayout = false; - - /** - * The listener that receives notifications when an item is selected. - */ - OnItemSelectedListener mOnItemSelectedListener; - - /** - * The listener that receives notifications when an item is clicked. - */ - OnItemClickListener mOnItemClickListener; - - /** - * The listener that receives notifications when an item is long clicked. - */ - OnItemLongClickListener mOnItemLongClickListener; - - /** - * True if the data has changed since the last layout - */ - boolean mDataChanged; - - /** - * The position within the adapter's data set of the item to select - * during the next layout. - */ - @ViewDebug.ExportedProperty(category = "list") - int mNextSelectedPosition = INVALID_POSITION; - - /** - * The item id of the item to select during the next layout. - */ - long mNextSelectedRowId = INVALID_ROW_ID; - - /** - * The position within the adapter's data set of the currently selected item. - */ - @ViewDebug.ExportedProperty(category = "list") - int mSelectedPosition = INVALID_POSITION; - - /** - * The item id of the currently selected item. - */ - long mSelectedRowId = INVALID_ROW_ID; - - /** - * View to show if there are no items to show. - */ - private View mEmptyView; - - /** - * The number of items in the current adapter. - */ - @ViewDebug.ExportedProperty(category = "list") - int mItemCount; - - /** - * The number of items in the adapter before a data changed event occurred. - */ - int mOldItemCount; - - /** - * Represents an invalid position. All valid positions are in the range 0 to 1 less than the - * number of items in the current adapter. - */ - public static final int INVALID_POSITION = -1; - - /** - * Represents an empty or invalid row id - */ - public static final long INVALID_ROW_ID = Long.MIN_VALUE; - - /** - * The last selected position we used when notifying - */ - int mOldSelectedPosition = INVALID_POSITION; - - /** - * The id of the last selected position we used when notifying - */ - long mOldSelectedRowId = INVALID_ROW_ID; - - /** - * Indicates what focusable state is requested when calling setFocusable(). - * In addition to this, this view has other criteria for actually - * determining the focusable state (such as whether its empty or the text - * filter is shown). - * - * @see #setFocusable(boolean) - * @see #checkFocus() - */ - private boolean mDesiredFocusableState; - private boolean mDesiredFocusableInTouchModeState; - - private SelectionNotifier mSelectionNotifier; - /** - * When set to true, calls to requestLayout() will not propagate up the parent hierarchy. - * This is used to layout the children during a layout pass. - */ - boolean mBlockLayoutRequests = false; - - public IcsAdapterView(Context context) { - super(context); - } - - public IcsAdapterView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public IcsAdapterView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - /** - * Register a callback to be invoked when an item in this AdapterView has - * been clicked. - * - * @param listener The callback that will be invoked. - */ - public void setOnItemClickListener(OnItemClickListener listener) { - mOnItemClickListener = listener; - } - - /** - * @return The callback to be invoked with an item in this AdapterView has - * been clicked, or null id no callback has been set. - */ - public final OnItemClickListener getOnItemClickListener() { - return mOnItemClickListener; - } - - /** - * Call the OnItemClickListener, if it is defined. - * - * @param view The view within the AdapterView that was clicked. - * @param position The position of the view in the adapter. - * @param id The row id of the item that was clicked. - * @return True if there was an assigned OnItemClickListener that was - * called, false otherwise is returned. - */ - public boolean performItemClick(View view, int position, long id) { - if (mOnItemClickListener != null) { - playSoundEffect(SoundEffectConstants.CLICK); - if (view != null) { - view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); - } - mOnItemClickListener.onItemClick(/*this*/null, view, position, id); - return true; - } - - return false; - } - - /** - * Interface definition for a callback to be invoked when an item in this - * view has been clicked and held. - */ - public interface OnItemLongClickListener { - /** - * Callback method to be invoked when an item in this view has been - * clicked and held. - * - * Implementers can call getItemAtPosition(position) if they need to access - * the data associated with the selected item. - * - * @param parent The AbsListView where the click happened - * @param view The view within the AbsListView that was clicked - * @param position The position of the view in the list - * @param id The row id of the item that was clicked - * - * @return true if the callback consumed the long click, false otherwise - */ - boolean onItemLongClick(IcsAdapterView parent, View view, int position, long id); - } - - - /** - * Register a callback to be invoked when an item in this AdapterView has - * been clicked and held - * - * @param listener The callback that will run - */ - public void setOnItemLongClickListener(OnItemLongClickListener listener) { - if (!isLongClickable()) { - setLongClickable(true); - } - mOnItemLongClickListener = listener; - } - - /** - * @return The callback to be invoked with an item in this AdapterView has - * been clicked and held, or null id no callback as been set. - */ - public final OnItemLongClickListener getOnItemLongClickListener() { - return mOnItemLongClickListener; - } - - /** - * Interface definition for a callback to be invoked when - * an item in this view has been selected. - */ - public interface OnItemSelectedListener { - /** - *

Callback method to be invoked when an item in this view has been - * selected. This callback is invoked only when the newly selected - * position is different from the previously selected position or if - * there was no selected item.

- * - * Impelmenters can call getItemAtPosition(position) if they need to access the - * data associated with the selected item. - * - * @param parent The AdapterView where the selection happened - * @param view The view within the AdapterView that was clicked - * @param position The position of the view in the adapter - * @param id The row id of the item that is selected - */ - void onItemSelected(IcsAdapterView parent, View view, int position, long id); - - /** - * Callback method to be invoked when the selection disappears from this - * view. The selection can disappear for instance when touch is activated - * or when the adapter becomes empty. - * - * @param parent The AdapterView that now contains no selected item. - */ - void onNothingSelected(IcsAdapterView parent); - } - - - /** - * Register a callback to be invoked when an item in this AdapterView has - * been selected. - * - * @param listener The callback that will run - */ - public void setOnItemSelectedListener(OnItemSelectedListener listener) { - mOnItemSelectedListener = listener; - } - - public final OnItemSelectedListener getOnItemSelectedListener() { - return mOnItemSelectedListener; - } - - /** - * Extra menu information provided to the - * {@link android.view.View.OnCreateContextMenuListener#onCreateContextMenu(ContextMenu, View, ContextMenuInfo) } - * callback when a context menu is brought up for this AdapterView. - * - */ - public static class AdapterContextMenuInfo implements ContextMenu.ContextMenuInfo { - - public AdapterContextMenuInfo(View targetView, int position, long id) { - this.targetView = targetView; - this.position = position; - this.id = id; - } - - /** - * The child view for which the context menu is being displayed. This - * will be one of the children of this AdapterView. - */ - public View targetView; - - /** - * The position in the adapter for which the context menu is being - * displayed. - */ - public int position; - - /** - * The row id of the item for which the context menu is being displayed. - */ - public long id; - } - - /** - * Returns the adapter currently associated with this widget. - * - * @return The adapter used to provide this view's content. - */ - public abstract T getAdapter(); - - /** - * Sets the adapter that provides the data and the views to represent the data - * in this widget. - * - * @param adapter The adapter to use to create this view's content. - */ - public abstract void setAdapter(T adapter); - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @param child Ignored. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void addView(View child) { - throw new UnsupportedOperationException("addView(View) is not supported in AdapterView"); - } - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @param child Ignored. - * @param index Ignored. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void addView(View child, int index) { - throw new UnsupportedOperationException("addView(View, int) is not supported in AdapterView"); - } - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @param child Ignored. - * @param params Ignored. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void addView(View child, LayoutParams params) { - throw new UnsupportedOperationException("addView(View, LayoutParams) " - + "is not supported in AdapterView"); - } - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @param child Ignored. - * @param index Ignored. - * @param params Ignored. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void addView(View child, int index, LayoutParams params) { - throw new UnsupportedOperationException("addView(View, int, LayoutParams) " - + "is not supported in AdapterView"); - } - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @param child Ignored. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void removeView(View child) { - throw new UnsupportedOperationException("removeView(View) is not supported in AdapterView"); - } - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @param index Ignored. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void removeViewAt(int index) { - throw new UnsupportedOperationException("removeViewAt(int) is not supported in AdapterView"); - } - - /** - * This method is not supported and throws an UnsupportedOperationException when called. - * - * @throws UnsupportedOperationException Every time this method is invoked. - */ - @Override - public void removeAllViews() { - throw new UnsupportedOperationException("removeAllViews() is not supported in AdapterView"); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - mLayoutHeight = getHeight(); - } - - /** - * Return the position of the currently selected item within the adapter's data set - * - * @return int Position (starting at 0), or {@link #INVALID_POSITION} if there is nothing selected. - */ - @ViewDebug.CapturedViewProperty - public int getSelectedItemPosition() { - return mNextSelectedPosition; - } - - /** - * @return The id corresponding to the currently selected item, or {@link #INVALID_ROW_ID} - * if nothing is selected. - */ - @ViewDebug.CapturedViewProperty - public long getSelectedItemId() { - return mNextSelectedRowId; - } - - /** - * @return The view corresponding to the currently selected item, or null - * if nothing is selected - */ - public abstract View getSelectedView(); - - /** - * @return The data corresponding to the currently selected item, or - * null if there is nothing selected. - */ - public Object getSelectedItem() { - T adapter = getAdapter(); - int selection = getSelectedItemPosition(); - if (adapter != null && adapter.getCount() > 0 && selection >= 0) { - return adapter.getItem(selection); - } else { - return null; - } - } - - /** - * @return The number of items owned by the Adapter associated with this - * AdapterView. (This is the number of data items, which may be - * larger than the number of visible views.) - */ - @ViewDebug.CapturedViewProperty - public int getCount() { - return mItemCount; - } - - /** - * Get the position within the adapter's data set for the view, where view is a an adapter item - * or a descendant of an adapter item. - * - * @param view an adapter item, or a descendant of an adapter item. This must be visible in this - * AdapterView at the time of the call. - * @return the position within the adapter's data set of the view, or {@link #INVALID_POSITION} - * if the view does not correspond to a list item (or it is not currently visible). - */ - public int getPositionForView(View view) { - View listItem = view; - try { - View v; - while (!(v = (View) listItem.getParent()).equals(this)) { - listItem = v; - } - } catch (ClassCastException e) { - // We made it up to the window without find this list view - return INVALID_POSITION; - } - - // Search the children for the list item - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - if (getChildAt(i).equals(listItem)) { - return mFirstPosition + i; - } - } - - // Child not found! - return INVALID_POSITION; - } - - /** - * Returns the position within the adapter's data set for the first item - * displayed on screen. - * - * @return The position within the adapter's data set - */ - public int getFirstVisiblePosition() { - return mFirstPosition; - } - - /** - * Returns the position within the adapter's data set for the last item - * displayed on screen. - * - * @return The position within the adapter's data set - */ - public int getLastVisiblePosition() { - return mFirstPosition + getChildCount() - 1; - } - - /** - * Sets the currently selected item. To support accessibility subclasses that - * override this method must invoke the overriden super method first. - * - * @param position Index (starting at 0) of the data item to be selected. - */ - public abstract void setSelection(int position); - - /** - * Sets the view to show if the adapter is empty - */ - public void setEmptyView(View emptyView) { - mEmptyView = emptyView; - - final T adapter = getAdapter(); - final boolean empty = ((adapter == null) || adapter.isEmpty()); - updateEmptyStatus(empty); - } - - /** - * When the current adapter is empty, the AdapterView can display a special view - * call the empty view. The empty view is used to provide feedback to the user - * that no data is available in this AdapterView. - * - * @return The view to show if the adapter is empty. - */ - public View getEmptyView() { - return mEmptyView; - } - - /** - * Indicates whether this view is in filter mode. Filter mode can for instance - * be enabled by a user when typing on the keyboard. - * - * @return True if the view is in filter mode, false otherwise. - */ - boolean isInFilterMode() { - return false; - } - - @Override - public void setFocusable(boolean focusable) { - final T adapter = getAdapter(); - final boolean empty = adapter == null || adapter.getCount() == 0; - - mDesiredFocusableState = focusable; - if (!focusable) { - mDesiredFocusableInTouchModeState = false; - } - - super.setFocusable(focusable && (!empty || isInFilterMode())); - } - - @Override - public void setFocusableInTouchMode(boolean focusable) { - final T adapter = getAdapter(); - final boolean empty = adapter == null || adapter.getCount() == 0; - - mDesiredFocusableInTouchModeState = focusable; - if (focusable) { - mDesiredFocusableState = true; - } - - super.setFocusableInTouchMode(focusable && (!empty || isInFilterMode())); - } - - void checkFocus() { - final T adapter = getAdapter(); - final boolean empty = adapter == null || adapter.getCount() == 0; - final boolean focusable = !empty || isInFilterMode(); - // The order in which we set focusable in touch mode/focusable may matter - // for the client, see View.setFocusableInTouchMode() comments for more - // details - super.setFocusableInTouchMode(focusable && mDesiredFocusableInTouchModeState); - super.setFocusable(focusable && mDesiredFocusableState); - if (mEmptyView != null) { - updateEmptyStatus((adapter == null) || adapter.isEmpty()); - } - } - - /** - * Update the status of the list based on the empty parameter. If empty is true and - * we have an empty view, display it. In all the other cases, make sure that the listview - * is VISIBLE and that the empty view is GONE (if it's not null). - */ - private void updateEmptyStatus(boolean empty) { - if (isInFilterMode()) { - empty = false; - } - - if (empty) { - if (mEmptyView != null) { - mEmptyView.setVisibility(View.VISIBLE); - setVisibility(View.GONE); - } else { - // If the caller just removed our empty view, make sure the list view is visible - setVisibility(View.VISIBLE); - } - - // We are now GONE, so pending layouts will not be dispatched. - // Force one here to make sure that the state of the list matches - // the state of the adapter. - if (mDataChanged) { - this.onLayout(false, getLeft(), getTop(), getRight(), getBottom()); - } - } else { - if (mEmptyView != null) mEmptyView.setVisibility(View.GONE); - setVisibility(View.VISIBLE); - } - } - - /** - * Gets the data associated with the specified position in the list. - * - * @param position Which data to get - * @return The data associated with the specified position in the list - */ - public Object getItemAtPosition(int position) { - T adapter = getAdapter(); - return (adapter == null || position < 0) ? null : adapter.getItem(position); - } - - public long getItemIdAtPosition(int position) { - T adapter = getAdapter(); - return (adapter == null || position < 0) ? INVALID_ROW_ID : adapter.getItemId(position); - } - - @Override - public void setOnClickListener(OnClickListener l) { - throw new RuntimeException("Don't call setOnClickListener for an AdapterView. " - + "You probably want setOnItemClickListener instead"); - } - - /** - * Override to prevent freezing of any views created by the adapter. - */ - @Override - protected void dispatchSaveInstanceState(SparseArray container) { - dispatchFreezeSelfOnly(container); - } - - /** - * Override to prevent thawing of any views created by the adapter. - */ - @Override - protected void dispatchRestoreInstanceState(SparseArray container) { - dispatchThawSelfOnly(container); - } - - class AdapterDataSetObserver extends DataSetObserver { - - private Parcelable mInstanceState = null; - - @Override - public void onChanged() { - mDataChanged = true; - mOldItemCount = mItemCount; - mItemCount = getAdapter().getCount(); - - // Detect the case where a cursor that was previously invalidated has - // been repopulated with new data. - if (IcsAdapterView.this.getAdapter().hasStableIds() && mInstanceState != null - && mOldItemCount == 0 && mItemCount > 0) { - IcsAdapterView.this.onRestoreInstanceState(mInstanceState); - mInstanceState = null; - } else { - rememberSyncState(); - } - checkFocus(); - requestLayout(); - } - - @Override - public void onInvalidated() { - mDataChanged = true; - - if (IcsAdapterView.this.getAdapter().hasStableIds()) { - // Remember the current state for the case where our hosting activity is being - // stopped and later restarted - mInstanceState = IcsAdapterView.this.onSaveInstanceState(); - } - - // Data is invalid so we should reset our state - mOldItemCount = mItemCount; - mItemCount = 0; - mSelectedPosition = INVALID_POSITION; - mSelectedRowId = INVALID_ROW_ID; - mNextSelectedPosition = INVALID_POSITION; - mNextSelectedRowId = INVALID_ROW_ID; - mNeedSync = false; - - checkFocus(); - requestLayout(); - } - - public void clearSavedState() { - mInstanceState = null; - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - removeCallbacks(mSelectionNotifier); - } - - private class SelectionNotifier implements Runnable { - public void run() { - if (mDataChanged) { - // Data has changed between when this SelectionNotifier - // was posted and now. We need to wait until the AdapterView - // has been synched to the new data. - if (getAdapter() != null) { - post(this); - } - } else { - fireOnSelected(); - } - } - } - - void selectionChanged() { - if (mOnItemSelectedListener != null) { - if (mInLayout || mBlockLayoutRequests) { - // If we are in a layout traversal, defer notification - // by posting. This ensures that the view tree is - // in a consistent state and is able to accomodate - // new layout or invalidate requests. - if (mSelectionNotifier == null) { - mSelectionNotifier = new SelectionNotifier(); - } - post(mSelectionNotifier); - } else { - fireOnSelected(); - } - } - - // we fire selection events here not in View - if (mSelectedPosition != ListView.INVALID_POSITION && isShown() && !isInTouchMode()) { - sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); - } - } - - private void fireOnSelected() { - if (mOnItemSelectedListener == null) - return; - - int selection = this.getSelectedItemPosition(); - if (selection >= 0) { - View v = getSelectedView(); - mOnItemSelectedListener.onItemSelected(this, v, selection, - getAdapter().getItemId(selection)); - } else { - mOnItemSelectedListener.onNothingSelected(this); - } - } - - @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - View selectedView = getSelectedView(); - if (selectedView != null && selectedView.getVisibility() == VISIBLE - && selectedView.dispatchPopulateAccessibilityEvent(event)) { - return true; - } - return false; - } - - @Override - public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) { - if (super.onRequestSendAccessibilityEvent(child, event)) { - // Add a record for ourselves as well. - AccessibilityEvent record = AccessibilityEvent.obtain(); - onInitializeAccessibilityEvent(record); - // Populate with the text of the requesting child. - child.dispatchPopulateAccessibilityEvent(record); - event.appendRecord(record); - return true; - } - return false; - } - - @Override - public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { - super.onInitializeAccessibilityNodeInfo(info); - info.setScrollable(isScrollableForAccessibility()); - View selectedView = getSelectedView(); - if (selectedView != null) { - info.setEnabled(selectedView.isEnabled()); - } - } - - @Override - public void onInitializeAccessibilityEvent(AccessibilityEvent event) { - super.onInitializeAccessibilityEvent(event); - event.setScrollable(isScrollableForAccessibility()); - View selectedView = getSelectedView(); - if (selectedView != null) { - event.setEnabled(selectedView.isEnabled()); - } - event.setCurrentItemIndex(getSelectedItemPosition()); - event.setFromIndex(getFirstVisiblePosition()); - event.setToIndex(getLastVisiblePosition()); - event.setItemCount(getCount()); - } - - private boolean isScrollableForAccessibility() { - T adapter = getAdapter(); - if (adapter != null) { - final int itemCount = adapter.getCount(); - return itemCount > 0 - && (getFirstVisiblePosition() > 0 || getLastVisiblePosition() < itemCount - 1); - } - return false; - } - - @Override - protected boolean canAnimate() { - return super.canAnimate() && mItemCount > 0; - } - - void handleDataChanged() { - final int count = mItemCount; - boolean found = false; - - if (count > 0) { - - int newPos; - - // Find the row we are supposed to sync to - if (mNeedSync) { - // Update this first, since setNextSelectedPositionInt inspects - // it - mNeedSync = false; - - // See if we can find a position in the new data with the same - // id as the old selection - newPos = findSyncPosition(); - if (newPos >= 0) { - // Verify that new selection is selectable - int selectablePos = lookForSelectablePosition(newPos, true); - if (selectablePos == newPos) { - // Same row id is selected - setNextSelectedPositionInt(newPos); - found = true; - } - } - } - if (!found) { - // Try to use the same position if we can't find matching data - newPos = getSelectedItemPosition(); - - // Pin position to the available range - if (newPos >= count) { - newPos = count - 1; - } - if (newPos < 0) { - newPos = 0; - } - - // Make sure we select something selectable -- first look down - int selectablePos = lookForSelectablePosition(newPos, true); - if (selectablePos < 0) { - // Looking down didn't work -- try looking up - selectablePos = lookForSelectablePosition(newPos, false); - } - if (selectablePos >= 0) { - setNextSelectedPositionInt(selectablePos); - checkSelectionChanged(); - found = true; - } - } - } - if (!found) { - // Nothing is selected - mSelectedPosition = INVALID_POSITION; - mSelectedRowId = INVALID_ROW_ID; - mNextSelectedPosition = INVALID_POSITION; - mNextSelectedRowId = INVALID_ROW_ID; - mNeedSync = false; - checkSelectionChanged(); - } - } - - void checkSelectionChanged() { - if ((mSelectedPosition != mOldSelectedPosition) || (mSelectedRowId != mOldSelectedRowId)) { - selectionChanged(); - mOldSelectedPosition = mSelectedPosition; - mOldSelectedRowId = mSelectedRowId; - } - } - - /** - * Searches the adapter for a position matching mSyncRowId. The search starts at mSyncPosition - * and then alternates between moving up and moving down until 1) we find the right position, or - * 2) we run out of time, or 3) we have looked at every position - * - * @return Position of the row that matches mSyncRowId, or {@link #INVALID_POSITION} if it can't - * be found - */ - int findSyncPosition() { - int count = mItemCount; - - if (count == 0) { - return INVALID_POSITION; - } - - long idToMatch = mSyncRowId; - int seed = mSyncPosition; - - // If there isn't a selection don't hunt for it - if (idToMatch == INVALID_ROW_ID) { - return INVALID_POSITION; - } - - // Pin seed to reasonable values - seed = Math.max(0, seed); - seed = Math.min(count - 1, seed); - - long endTime = SystemClock.uptimeMillis() + SYNC_MAX_DURATION_MILLIS; - - long rowId; - - // first position scanned so far - int first = seed; - - // last position scanned so far - int last = seed; - - // True if we should move down on the next iteration - boolean next = false; - - // True when we have looked at the first item in the data - boolean hitFirst; - - // True when we have looked at the last item in the data - boolean hitLast; - - // Get the item ID locally (instead of getItemIdAtPosition), so - // we need the adapter - T adapter = getAdapter(); - if (adapter == null) { - return INVALID_POSITION; - } - - while (SystemClock.uptimeMillis() <= endTime) { - rowId = adapter.getItemId(seed); - if (rowId == idToMatch) { - // Found it! - return seed; - } - - hitLast = last == count - 1; - hitFirst = first == 0; - - if (hitLast && hitFirst) { - // Looked at everything - break; - } - - if (hitFirst || (next && !hitLast)) { - // Either we hit the top, or we are trying to move down - last++; - seed = last; - // Try going up next time - next = false; - } else if (hitLast || (!next && !hitFirst)) { - // Either we hit the bottom, or we are trying to move up - first--; - seed = first; - // Try going down next time - next = true; - } - - } - - return INVALID_POSITION; - } - - /** - * Find a position that can be selected (i.e., is not a separator). - * - * @param position The starting position to look at. - * @param lookDown Whether to look down for other positions. - * @return The next selectable position starting at position and then searching either up or - * down. Returns {@link #INVALID_POSITION} if nothing can be found. - */ - int lookForSelectablePosition(int position, boolean lookDown) { - return position; - } - - /** - * Utility to keep mSelectedPosition and mSelectedRowId in sync - * @param position Our current position - */ - void setSelectedPositionInt(int position) { - mSelectedPosition = position; - mSelectedRowId = getItemIdAtPosition(position); - } - - /** - * Utility to keep mNextSelectedPosition and mNextSelectedRowId in sync - * @param position Intended value for mSelectedPosition the next time we go - * through layout - */ - void setNextSelectedPositionInt(int position) { - mNextSelectedPosition = position; - mNextSelectedRowId = getItemIdAtPosition(position); - // If we are trying to sync to the selection, update that too - if (mNeedSync && mSyncMode == SYNC_SELECTED_POSITION && position >= 0) { - mSyncPosition = position; - mSyncRowId = mNextSelectedRowId; - } - } - - /** - * Remember enough information to restore the screen state when the data has - * changed. - * - */ - void rememberSyncState() { - if (getChildCount() > 0) { - mNeedSync = true; - mSyncHeight = mLayoutHeight; - if (mSelectedPosition >= 0) { - // Sync the selection state - View v = getChildAt(mSelectedPosition - mFirstPosition); - mSyncRowId = mNextSelectedRowId; - mSyncPosition = mNextSelectedPosition; - if (v != null) { - mSpecificTop = v.getTop(); - } - mSyncMode = SYNC_SELECTED_POSITION; - } else { - // Sync the based on the offset of the first view - View v = getChildAt(0); - T adapter = getAdapter(); - if (mFirstPosition >= 0 && mFirstPosition < adapter.getCount()) { - mSyncRowId = adapter.getItemId(mFirstPosition); - } else { - mSyncRowId = NO_ID; - } - mSyncPosition = mFirstPosition; - if (v != null) { - mSpecificTop = v.getTop(); - } - mSyncMode = SYNC_FIRST_POSITION; - } - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsColorDrawable.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsColorDrawable.java deleted file mode 100644 index a78b3f71..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsColorDrawable.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.Paint; -import android.graphics.drawable.Drawable; - -/** - * A version of {@link android.graphics.drawable.ColorDrawable} that respects bounds. - */ -public class IcsColorDrawable extends Drawable { - private int color; - private final Paint paint = new Paint(); - - public IcsColorDrawable(int color) { - this.color = color; - } - - @Override public void draw(Canvas canvas) { - if ((color >>> 24) != 0) { - paint.setColor(color); - canvas.drawRect(getBounds(), paint); - } - } - - @Override - public void setAlpha(int alpha) { - if (alpha != (color >>> 24)) { - color = (color & 0x00FFFFFF) & (alpha << 24); - invalidateSelf(); - } - } - - @Override public void setColorFilter(ColorFilter colorFilter) { - //Ignored - } - - @Override public int getOpacity() { - return color >>> 24; - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java deleted file mode 100644 index 4947c41d..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java +++ /dev/null @@ -1,410 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.View; -import android.widget.LinearLayout; - -import com.actionbarsherlock.internal.nineoldandroids.widget.NineLinearLayout; - -/** - * A simple extension of a regular linear layout that supports the divider API - * of Android 4.0+. The dividers are added adjacent to the children by changing - * their layout params. If you need to rely on the margins which fall in the - * same orientation as the layout you should wrap the child in a simple - * {@link android.widget.FrameLayout} so it can receive the margin. - */ -public class IcsLinearLayout extends NineLinearLayout { - private static final int[] R_styleable_LinearLayout = new int[] { - /* 0 */ android.R.attr.divider, - /* 1 */ android.R.attr.measureWithLargestChild, - /* 2 */ android.R.attr.showDividers, - /* 3 */ android.R.attr.dividerPadding, - }; - private static final int LinearLayout_divider = 0; - private static final int LinearLayout_measureWithLargestChild = 1; - private static final int LinearLayout_showDividers = 2; - private static final int LinearLayout_dividerPadding = 3; - - /** - * Don't show any dividers. - */ - public static final int SHOW_DIVIDER_NONE = 0; - /** - * Show a divider at the beginning of the group. - */ - public static final int SHOW_DIVIDER_BEGINNING = 1; - /** - * Show dividers between each item in the group. - */ - public static final int SHOW_DIVIDER_MIDDLE = 2; - /** - * Show a divider at the end of the group. - */ - public static final int SHOW_DIVIDER_END = 4; - - - private Drawable mDivider; - private int mDividerWidth; - private int mDividerHeight; - private int mShowDividers; - private int mDividerPadding; - - private boolean mUseLargestChild; - - public IcsLinearLayout(Context context, AttributeSet attrs) { - super(context, attrs); - - TypedArray a = context.obtainStyledAttributes(attrs, /*com.android.internal.R.styleable.*/R_styleable_LinearLayout); - - setDividerDrawable(a.getDrawable(/*com.android.internal.R.styleable.*/LinearLayout_divider)); - mShowDividers = a.getInt(/*com.android.internal.R.styleable.*/LinearLayout_showDividers, SHOW_DIVIDER_NONE); - mDividerPadding = a.getDimensionPixelSize(/*com.android.internal.R.styleable.*/LinearLayout_dividerPadding, 0); - mUseLargestChild = a.getBoolean(/*com.android.internal.R.styleable.*/LinearLayout_measureWithLargestChild, false); - - a.recycle(); - } - - /** - * Set how dividers should be shown between items in this layout - * - * @param showDividers One or more of {@link #SHOW_DIVIDER_BEGINNING}, - * {@link #SHOW_DIVIDER_MIDDLE}, or {@link #SHOW_DIVIDER_END}, - * or {@link #SHOW_DIVIDER_NONE} to show no dividers. - */ - public void setShowDividers(int showDividers) { - if (showDividers != mShowDividers) { - requestLayout(); - invalidate(); //XXX This is required if you are toggling a divider off - } - mShowDividers = showDividers; - } - - /** - * @return A flag set indicating how dividers should be shown around items. - * @see #setShowDividers(int) - */ - public int getShowDividers() { - return mShowDividers; - } - - /** - * Set a drawable to be used as a divider between items. - * @param divider Drawable that will divide each item. - * @see #setShowDividers(int) - */ - public void setDividerDrawable(Drawable divider) { - if (divider == mDivider) { - return; - } - mDivider = divider; - if (divider != null) { - mDividerWidth = divider.getIntrinsicWidth(); - mDividerHeight = divider.getIntrinsicHeight(); - } else { - mDividerWidth = 0; - mDividerHeight = 0; - } - setWillNotDraw(divider == null); - requestLayout(); - } - - /** - * Set padding displayed on both ends of dividers. - * - * @param padding Padding value in pixels that will be applied to each end - * - * @see #setShowDividers(int) - * @see #setDividerDrawable(Drawable) - * @see #getDividerPadding() - */ - public void setDividerPadding(int padding) { - mDividerPadding = padding; - } - - /** - * Get the padding size used to inset dividers in pixels - * - * @see #setShowDividers(int) - * @see #setDividerDrawable(Drawable) - * @see #setDividerPadding(int) - */ - public int getDividerPadding() { - return mDividerPadding; - } - - /** - * Get the width of the current divider drawable. - * - * @hide Used internally by framework. - */ - public int getDividerWidth() { - return mDividerWidth; - } - - @Override - protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) { - final int index = indexOfChild(child); - final int orientation = getOrientation(); - final LayoutParams params = (LayoutParams) child.getLayoutParams(); - if (hasDividerBeforeChildAt(index)) { - if (orientation == VERTICAL) { - //Account for the divider by pushing everything up - params.topMargin = mDividerHeight; - } else { - //Account for the divider by pushing everything left - params.leftMargin = mDividerWidth; - } - } - - final int count = getChildCount(); - if (index == count - 1) { - if (hasDividerBeforeChildAt(count)) { - if (orientation == VERTICAL) { - params.bottomMargin = mDividerHeight; - } else { - params.rightMargin = mDividerWidth; - } - } - } - super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed); - } - - @Override - protected void onDraw(Canvas canvas) { - if (mDivider != null) { - if (getOrientation() == VERTICAL) { - drawDividersVertical(canvas); - } else { - drawDividersHorizontal(canvas); - } - } - super.onDraw(canvas); - } - - void drawDividersVertical(Canvas canvas) { - final int count = getChildCount(); - for (int i = 0; i < count; i++) { - final View child = getChildAt(i); - - if (child != null && child.getVisibility() != GONE) { - if (hasDividerBeforeChildAt(i)) { - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - final int top = child.getTop() - lp.topMargin/* - mDividerHeight*/; - drawHorizontalDivider(canvas, top); - } - } - } - - if (hasDividerBeforeChildAt(count)) { - final View child = getChildAt(count - 1); - int bottom = 0; - if (child == null) { - bottom = getHeight() - getPaddingBottom() - mDividerHeight; - } else { - //final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - bottom = child.getBottom()/* + lp.bottomMargin*/; - } - drawHorizontalDivider(canvas, bottom); - } - } - - void drawDividersHorizontal(Canvas canvas) { - final int count = getChildCount(); - for (int i = 0; i < count; i++) { - final View child = getChildAt(i); - - if (child != null && child.getVisibility() != GONE) { - if (hasDividerBeforeChildAt(i)) { - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - final int left = child.getLeft() - lp.leftMargin/* - mDividerWidth*/; - drawVerticalDivider(canvas, left); - } - } - } - - if (hasDividerBeforeChildAt(count)) { - final View child = getChildAt(count - 1); - int right = 0; - if (child == null) { - right = getWidth() - getPaddingRight() - mDividerWidth; - } else { - //final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - right = child.getRight()/* + lp.rightMargin*/; - } - drawVerticalDivider(canvas, right); - } - } - - void drawHorizontalDivider(Canvas canvas, int top) { - mDivider.setBounds(getPaddingLeft() + mDividerPadding, top, - getWidth() - getPaddingRight() - mDividerPadding, top + mDividerHeight); - mDivider.draw(canvas); - } - - void drawVerticalDivider(Canvas canvas, int left) { - mDivider.setBounds(left, getPaddingTop() + mDividerPadding, - left + mDividerWidth, getHeight() - getPaddingBottom() - mDividerPadding); - mDivider.draw(canvas); - } - - /** - * Determines where to position dividers between children. - * - * @param childIndex Index of child to check for preceding divider - * @return true if there should be a divider before the child at childIndex - * @hide Pending API consideration. Currently only used internally by the system. - */ - protected boolean hasDividerBeforeChildAt(int childIndex) { - if (childIndex == 0) { - return (mShowDividers & SHOW_DIVIDER_BEGINNING) != 0; - } else if (childIndex == getChildCount()) { - return (mShowDividers & SHOW_DIVIDER_END) != 0; - } else if ((mShowDividers & SHOW_DIVIDER_MIDDLE) != 0) { - boolean hasVisibleViewBefore = false; - for (int i = childIndex - 1; i >= 0; i--) { - if (getChildAt(i).getVisibility() != GONE) { - hasVisibleViewBefore = true; - break; - } - } - return hasVisibleViewBefore; - } - return false; - } - - /** - * When true, all children with a weight will be considered having - * the minimum size of the largest child. If false, all children are - * measured normally. - * - * @return True to measure children with a weight using the minimum - * size of the largest child, false otherwise. - * - * @attr ref android.R.styleable#LinearLayout_measureWithLargestChild - */ - public boolean isMeasureWithLargestChildEnabled() { - return mUseLargestChild; - } - - /** - * When set to true, all children with a weight will be considered having - * the minimum size of the largest child. If false, all children are - * measured normally. - * - * Disabled by default. - * - * @param enabled True to measure children with a weight using the - * minimum size of the largest child, false otherwise. - * - * @attr ref android.R.styleable#LinearLayout_measureWithLargestChild - */ - public void setMeasureWithLargestChildEnabled(boolean enabled) { - mUseLargestChild = enabled; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - if (mUseLargestChild) { - final int orientation = getOrientation(); - switch (orientation) { - case HORIZONTAL: - useLargestChildHorizontal(); - break; - - case VERTICAL: - useLargestChildVertical(); - break; - } - } - } - - private void useLargestChildHorizontal() { - final int childCount = getChildCount(); - - // Find largest child width - int largestChildWidth = 0; - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - largestChildWidth = Math.max(child.getMeasuredWidth(), largestChildWidth); - } - - int totalWidth = 0; - // Re-measure childs - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - - if (child == null || child.getVisibility() == View.GONE) { - continue; - } - - final LinearLayout.LayoutParams lp = - (LinearLayout.LayoutParams) child.getLayoutParams(); - - float childExtra = lp.weight; - if (childExtra > 0) { - child.measure( - MeasureSpec.makeMeasureSpec(largestChildWidth, - MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), - MeasureSpec.EXACTLY)); - totalWidth += largestChildWidth; - - } else { - totalWidth += child.getMeasuredWidth(); - } - - totalWidth += lp.leftMargin + lp.rightMargin; - } - - totalWidth += getPaddingLeft() + getPaddingRight(); - setMeasuredDimension(totalWidth, getMeasuredHeight()); - } - - private void useLargestChildVertical() { - final int childCount = getChildCount(); - - // Find largest child width - int largestChildHeight = 0; - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - largestChildHeight = Math.max(child.getMeasuredHeight(), largestChildHeight); - } - - int totalHeight = 0; - // Re-measure childs - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - - if (child == null || child.getVisibility() == View.GONE) { - continue; - } - - final LinearLayout.LayoutParams lp = - (LinearLayout.LayoutParams) child.getLayoutParams(); - - float childExtra = lp.weight; - if (childExtra > 0) { - child.measure( - MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), - MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(largestChildHeight, - MeasureSpec.EXACTLY)); - totalHeight += largestChildHeight; - - } else { - totalHeight += child.getMeasuredHeight(); - } - - totalHeight += lp.leftMargin + lp.rightMargin; - } - - totalHeight += getPaddingLeft() + getPaddingRight(); - setMeasuredDimension(getMeasuredWidth(), totalHeight); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java deleted file mode 100644 index d13c6cea..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java +++ /dev/null @@ -1,644 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import com.actionbarsherlock.R; - -import android.content.Context; -import android.content.res.Resources; -import android.database.DataSetObserver; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.Handler; -import android.util.AttributeSet; -import android.view.ContextThemeWrapper; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.MeasureSpec; -import android.view.View.OnTouchListener; -import android.view.ViewGroup; -import android.view.ViewParent; -import android.widget.AbsListView; -import android.widget.AdapterView; -import android.widget.LinearLayout; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.PopupWindow; - -/** - * A proxy between pre- and post-Honeycomb implementations of this class. - */ -public class IcsListPopupWindow { - /** - * This value controls the length of time that the user - * must leave a pointer down without scrolling to expand - * the autocomplete dropdown list to cover the IME. - */ - private static final int EXPAND_LIST_TIMEOUT = 250; - - private Context mContext; - private PopupWindow mPopup; - private ListAdapter mAdapter; - private DropDownListView mDropDownList; - - private int mDropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT; - private int mDropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT; - private int mDropDownHorizontalOffset; - private int mDropDownVerticalOffset; - private boolean mDropDownVerticalOffsetSet; - - private int mListItemExpandMaximum = Integer.MAX_VALUE; - - private View mPromptView; - private int mPromptPosition = POSITION_PROMPT_ABOVE; - - private DataSetObserver mObserver; - - private View mDropDownAnchorView; - - private Drawable mDropDownListHighlight; - - private AdapterView.OnItemClickListener mItemClickListener; - private AdapterView.OnItemSelectedListener mItemSelectedListener; - - private final ResizePopupRunnable mResizePopupRunnable = new ResizePopupRunnable(); - private final PopupTouchInterceptor mTouchInterceptor = new PopupTouchInterceptor(); - private final PopupScrollListener mScrollListener = new PopupScrollListener(); - private final ListSelectorHider mHideSelector = new ListSelectorHider(); - - private Handler mHandler = new Handler(); - - private Rect mTempRect = new Rect(); - - private boolean mModal; - - public static final int POSITION_PROMPT_ABOVE = 0; - public static final int POSITION_PROMPT_BELOW = 1; - - public IcsListPopupWindow(Context context) { - this(context, null, R.attr.listPopupWindowStyle); - } - - public IcsListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr) { - mContext = context; - mPopup = new PopupWindow(context, attrs, defStyleAttr); - mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); - } - - public IcsListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - mContext = context; - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - Context wrapped = new ContextThemeWrapper(context, defStyleRes); - mPopup = new PopupWindow(wrapped, attrs, defStyleAttr); - } else { - mPopup = new PopupWindow(context, attrs, defStyleAttr, defStyleRes); - } - mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); - } - - public void setAdapter(ListAdapter adapter) { - if (mObserver == null) { - mObserver = new PopupDataSetObserver(); - } else if (mAdapter != null) { - mAdapter.unregisterDataSetObserver(mObserver); - } - mAdapter = adapter; - if (mAdapter != null) { - adapter.registerDataSetObserver(mObserver); - } - - if (mDropDownList != null) { - mDropDownList.setAdapter(mAdapter); - } - } - - public void setPromptPosition(int position) { - mPromptPosition = position; - } - - public void setModal(boolean modal) { - mModal = true; - mPopup.setFocusable(modal); - } - - public void setBackgroundDrawable(Drawable d) { - mPopup.setBackgroundDrawable(d); - } - - public void setAnchorView(View anchor) { - mDropDownAnchorView = anchor; - } - - public void setHorizontalOffset(int offset) { - mDropDownHorizontalOffset = offset; - } - - public void setVerticalOffset(int offset) { - mDropDownVerticalOffset = offset; - mDropDownVerticalOffsetSet = true; - } - - public void setContentWidth(int width) { - Drawable popupBackground = mPopup.getBackground(); - if (popupBackground != null) { - popupBackground.getPadding(mTempRect); - mDropDownWidth = mTempRect.left + mTempRect.right + width; - } else { - mDropDownWidth = width; - } - } - - public void setOnItemClickListener(AdapterView.OnItemClickListener clickListener) { - mItemClickListener = clickListener; - } - - public void show() { - int height = buildDropDown(); - - int widthSpec = 0; - int heightSpec = 0; - - boolean noInputMethod = isInputMethodNotNeeded(); - //XXX mPopup.setAllowScrollingAnchorParent(!noInputMethod); - - if (mPopup.isShowing()) { - if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { - // The call to PopupWindow's update method below can accept -1 for any - // value you do not want to update. - widthSpec = -1; - } else if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { - widthSpec = mDropDownAnchorView.getWidth(); - } else { - widthSpec = mDropDownWidth; - } - - if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { - // The call to PopupWindow's update method below can accept -1 for any - // value you do not want to update. - heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.MATCH_PARENT; - if (noInputMethod) { - mPopup.setWindowLayoutMode( - mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? - ViewGroup.LayoutParams.MATCH_PARENT : 0, 0); - } else { - mPopup.setWindowLayoutMode( - mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? - ViewGroup.LayoutParams.MATCH_PARENT : 0, - ViewGroup.LayoutParams.MATCH_PARENT); - } - } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { - heightSpec = height; - } else { - heightSpec = mDropDownHeight; - } - - mPopup.setOutsideTouchable(true); - - mPopup.update(mDropDownAnchorView, mDropDownHorizontalOffset, - mDropDownVerticalOffset, widthSpec, heightSpec); - } else { - if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { - widthSpec = ViewGroup.LayoutParams.MATCH_PARENT; - } else { - if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { - mPopup.setWidth(mDropDownAnchorView.getWidth()); - } else { - mPopup.setWidth(mDropDownWidth); - } - } - - if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { - heightSpec = ViewGroup.LayoutParams.MATCH_PARENT; - } else { - if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { - mPopup.setHeight(height); - } else { - mPopup.setHeight(mDropDownHeight); - } - } - - mPopup.setWindowLayoutMode(widthSpec, heightSpec); - //XXX mPopup.setClipToScreenEnabled(true); - - // use outside touchable to dismiss drop down when touching outside of it, so - // only set this if the dropdown is not always visible - mPopup.setOutsideTouchable(true); - mPopup.setTouchInterceptor(mTouchInterceptor); - mPopup.showAsDropDown(mDropDownAnchorView, - mDropDownHorizontalOffset, mDropDownVerticalOffset); - mDropDownList.setSelection(ListView.INVALID_POSITION); - - if (!mModal || mDropDownList.isInTouchMode()) { - clearListSelection(); - } - if (!mModal) { - mHandler.post(mHideSelector); - } - } - } - - public void dismiss() { - mPopup.dismiss(); - if (mPromptView != null) { - final ViewParent parent = mPromptView.getParent(); - if (parent instanceof ViewGroup) { - final ViewGroup group = (ViewGroup) parent; - group.removeView(mPromptView); - } - } - mPopup.setContentView(null); - mDropDownList = null; - mHandler.removeCallbacks(mResizePopupRunnable); - } - - public void setOnDismissListener(PopupWindow.OnDismissListener listener) { - mPopup.setOnDismissListener(listener); - } - - public void setInputMethodMode(int mode) { - mPopup.setInputMethodMode(mode); - } - - public void clearListSelection() { - final DropDownListView list = mDropDownList; - if (list != null) { - // WARNING: Please read the comment where mListSelectionHidden is declared - list.mListSelectionHidden = true; - //XXX list.hideSelector(); - list.requestLayout(); - } - } - - public boolean isShowing() { - return mPopup.isShowing(); - } - - private boolean isInputMethodNotNeeded() { - return mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; - } - - public ListView getListView() { - return mDropDownList; - } - - private int buildDropDown() { - ViewGroup dropDownView; - int otherHeights = 0; - - if (mDropDownList == null) { - Context context = mContext; - - mDropDownList = new DropDownListView(context, !mModal); - if (mDropDownListHighlight != null) { - mDropDownList.setSelector(mDropDownListHighlight); - } - mDropDownList.setAdapter(mAdapter); - mDropDownList.setOnItemClickListener(mItemClickListener); - mDropDownList.setFocusable(true); - mDropDownList.setFocusableInTouchMode(true); - mDropDownList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - public void onItemSelected(AdapterView parent, View view, - int position, long id) { - - if (position != -1) { - DropDownListView dropDownList = mDropDownList; - - if (dropDownList != null) { - dropDownList.mListSelectionHidden = false; - } - } - } - - public void onNothingSelected(AdapterView parent) { - } - }); - mDropDownList.setOnScrollListener(mScrollListener); - - if (mItemSelectedListener != null) { - mDropDownList.setOnItemSelectedListener(mItemSelectedListener); - } - - dropDownView = mDropDownList; - - View hintView = mPromptView; - if (hintView != null) { - // if an hint has been specified, we accomodate more space for it and - // add a text view in the drop down menu, at the bottom of the list - LinearLayout hintContainer = new LinearLayout(context); - hintContainer.setOrientation(LinearLayout.VERTICAL); - - LinearLayout.LayoutParams hintParams = new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, 0, 1.0f - ); - - switch (mPromptPosition) { - case POSITION_PROMPT_BELOW: - hintContainer.addView(dropDownView, hintParams); - hintContainer.addView(hintView); - break; - - case POSITION_PROMPT_ABOVE: - hintContainer.addView(hintView); - hintContainer.addView(dropDownView, hintParams); - break; - - default: - break; - } - - // measure the hint's height to find how much more vertical space - // we need to add to the drop down's height - int widthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.AT_MOST); - int heightSpec = MeasureSpec.UNSPECIFIED; - hintView.measure(widthSpec, heightSpec); - - hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams(); - otherHeights = hintView.getMeasuredHeight() + hintParams.topMargin - + hintParams.bottomMargin; - - dropDownView = hintContainer; - } - - mPopup.setContentView(dropDownView); - } else { - dropDownView = (ViewGroup) mPopup.getContentView(); - final View view = mPromptView; - if (view != null) { - LinearLayout.LayoutParams hintParams = - (LinearLayout.LayoutParams) view.getLayoutParams(); - otherHeights = view.getMeasuredHeight() + hintParams.topMargin - + hintParams.bottomMargin; - } - } - - // getMaxAvailableHeight() subtracts the padding, so we put it back - // to get the available height for the whole window - int padding = 0; - Drawable background = mPopup.getBackground(); - if (background != null) { - background.getPadding(mTempRect); - padding = mTempRect.top + mTempRect.bottom; - - // If we don't have an explicit vertical offset, determine one from the window - // background so that content will line up. - if (!mDropDownVerticalOffsetSet) { - mDropDownVerticalOffset = -mTempRect.top; - } - } - - // Max height available on the screen for a popup. - boolean ignoreBottomDecorations = - mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; - final int maxHeight = /*mPopup.*/getMaxAvailableHeight( - mDropDownAnchorView, mDropDownVerticalOffset, ignoreBottomDecorations); - - if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { - return maxHeight + padding; - } - - final int listContent = /*mDropDownList.*/measureHeightOfChildren(MeasureSpec.UNSPECIFIED, - 0, -1/*ListView.NO_POSITION*/, maxHeight - otherHeights, -1); - // add padding only if the list has items in it, that way we don't show - // the popup if it is not needed - if (listContent > 0) otherHeights += padding; - - return listContent + otherHeights; - } - - private int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) { - final Rect displayFrame = new Rect(); - anchor.getWindowVisibleDisplayFrame(displayFrame); - - final int[] anchorPos = new int[2]; - anchor.getLocationOnScreen(anchorPos); - - int bottomEdge = displayFrame.bottom; - if (ignoreBottomDecorations) { - Resources res = anchor.getContext().getResources(); - bottomEdge = res.getDisplayMetrics().heightPixels; - } - final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset; - final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset; - - // anchorPos[1] is distance from anchor to top of screen - int returnedHeight = Math.max(distanceToBottom, distanceToTop); - if (mPopup.getBackground() != null) { - mPopup.getBackground().getPadding(mTempRect); - returnedHeight -= mTempRect.top + mTempRect.bottom; - } - - return returnedHeight; - } - - private int measureHeightOfChildren(int widthMeasureSpec, int startPosition, int endPosition, - final int maxHeight, int disallowPartialChildPosition) { - - final ListAdapter adapter = mAdapter; - if (adapter == null) { - return mDropDownList.getListPaddingTop() + mDropDownList.getListPaddingBottom(); - } - - // Include the padding of the list - int returnedHeight = mDropDownList.getListPaddingTop() + mDropDownList.getListPaddingBottom(); - final int dividerHeight = ((mDropDownList.getDividerHeight() > 0) && mDropDownList.getDivider() != null) ? mDropDownList.getDividerHeight() : 0; - // The previous height value that was less than maxHeight and contained - // no partial children - int prevHeightWithoutPartialChild = 0; - int i; - View child; - - // mItemCount - 1 since endPosition parameter is inclusive - endPosition = (endPosition == -1/*NO_POSITION*/) ? adapter.getCount() - 1 : endPosition; - - for (i = startPosition; i <= endPosition; ++i) { - child = mAdapter.getView(i, null, mDropDownList); - if (mDropDownList.getCacheColorHint() != 0) { - child.setDrawingCacheBackgroundColor(mDropDownList.getCacheColorHint()); - } - - measureScrapChild(child, i, widthMeasureSpec); - - if (i > 0) { - // Count the divider for all but one child - returnedHeight += dividerHeight; - } - - returnedHeight += child.getMeasuredHeight(); - - if (returnedHeight >= maxHeight) { - // We went over, figure out which height to return. If returnedHeight > maxHeight, - // then the i'th position did not fit completely. - return (disallowPartialChildPosition >= 0) // Disallowing is enabled (> -1) - && (i > disallowPartialChildPosition) // We've past the min pos - && (prevHeightWithoutPartialChild > 0) // We have a prev height - && (returnedHeight != maxHeight) // i'th child did not fit completely - ? prevHeightWithoutPartialChild - : maxHeight; - } - - if ((disallowPartialChildPosition >= 0) && (i >= disallowPartialChildPosition)) { - prevHeightWithoutPartialChild = returnedHeight; - } - } - - // At this point, we went through the range of children, and they each - // completely fit, so return the returnedHeight - return returnedHeight; - } - private void measureScrapChild(View child, int position, int widthMeasureSpec) { - ListView.LayoutParams p = (ListView.LayoutParams) child.getLayoutParams(); - if (p == null) { - p = new ListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT, 0); - child.setLayoutParams(p); - } - //XXX p.viewType = mAdapter.getItemViewType(position); - //XXX p.forceAdd = true; - - int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec, - mDropDownList.getPaddingLeft() + mDropDownList.getPaddingRight(), p.width); - int lpHeight = p.height; - int childHeightSpec; - if (lpHeight > 0) { - childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); - } else { - childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - } - child.measure(childWidthSpec, childHeightSpec); - } - - private static class DropDownListView extends ListView { - /* - * WARNING: This is a workaround for a touch mode issue. - * - * Touch mode is propagated lazily to windows. This causes problems in - * the following scenario: - * - Type something in the AutoCompleteTextView and get some results - * - Move down with the d-pad to select an item in the list - * - Move up with the d-pad until the selection disappears - * - Type more text in the AutoCompleteTextView *using the soft keyboard* - * and get new results; you are now in touch mode - * - The selection comes back on the first item in the list, even though - * the list is supposed to be in touch mode - * - * Using the soft keyboard triggers the touch mode change but that change - * is propagated to our window only after the first list layout, therefore - * after the list attempts to resurrect the selection. - * - * The trick to work around this issue is to pretend the list is in touch - * mode when we know that the selection should not appear, that is when - * we know the user moved the selection away from the list. - * - * This boolean is set to true whenever we explicitly hide the list's - * selection and reset to false whenever we know the user moved the - * selection back to the list. - * - * When this boolean is true, isInTouchMode() returns true, otherwise it - * returns super.isInTouchMode(). - */ - private boolean mListSelectionHidden; - - private boolean mHijackFocus; - - public DropDownListView(Context context, boolean hijackFocus) { - super(context, null, /*com.android.internal.*/R.attr.dropDownListViewStyle); - mHijackFocus = hijackFocus; - // TODO: Add an API to control this - setCacheColorHint(0); // Transparent, since the background drawable could be anything. - } - - //XXX @Override - //View obtainView(int position, boolean[] isScrap) { - // View view = super.obtainView(position, isScrap); - - // if (view instanceof TextView) { - // ((TextView) view).setHorizontallyScrolling(true); - // } - - // return view; - //} - - @Override - public boolean isInTouchMode() { - // WARNING: Please read the comment where mListSelectionHidden is declared - return (mHijackFocus && mListSelectionHidden) || super.isInTouchMode(); - } - - @Override - public boolean hasWindowFocus() { - return mHijackFocus || super.hasWindowFocus(); - } - - @Override - public boolean isFocused() { - return mHijackFocus || super.isFocused(); - } - - @Override - public boolean hasFocus() { - return mHijackFocus || super.hasFocus(); - } - } - - private class PopupDataSetObserver extends DataSetObserver { - @Override - public void onChanged() { - if (isShowing()) { - // Resize the popup to fit new content - show(); - } - } - - @Override - public void onInvalidated() { - dismiss(); - } - } - - private class ListSelectorHider implements Runnable { - public void run() { - clearListSelection(); - } - } - - private class ResizePopupRunnable implements Runnable { - public void run() { - if (mDropDownList != null && mDropDownList.getCount() > mDropDownList.getChildCount() && - mDropDownList.getChildCount() <= mListItemExpandMaximum) { - mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); - show(); - } - } - } - - private class PopupTouchInterceptor implements OnTouchListener { - public boolean onTouch(View v, MotionEvent event) { - final int action = event.getAction(); - final int x = (int) event.getX(); - final int y = (int) event.getY(); - - if (action == MotionEvent.ACTION_DOWN && - mPopup != null && mPopup.isShowing() && - (x >= 0 && x < mPopup.getWidth() && y >= 0 && y < mPopup.getHeight())) { - mHandler.postDelayed(mResizePopupRunnable, EXPAND_LIST_TIMEOUT); - } else if (action == MotionEvent.ACTION_UP) { - mHandler.removeCallbacks(mResizePopupRunnable); - } - return false; - } - } - - private class PopupScrollListener implements ListView.OnScrollListener { - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, - int totalItemCount) { - - } - - public void onScrollStateChanged(AbsListView view, int scrollState) { - if (scrollState == SCROLL_STATE_TOUCH_SCROLL && - !isInputMethodNotNeeded() && mPopup.getContentView() != null) { - mHandler.removeCallbacks(mResizePopupRunnable); - mResizePopupRunnable.run(); - } - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java deleted file mode 100644 index 1c02d4ac..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsProgressBar.java +++ /dev/null @@ -1,1193 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.BitmapShader; -import android.graphics.Canvas; -import android.graphics.Rect; -import android.graphics.Shader; -import android.graphics.drawable.Animatable; -import android.graphics.drawable.AnimationDrawable; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.ClipDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; -import android.graphics.drawable.ShapeDrawable; -import android.graphics.drawable.shapes.RoundRectShape; -import android.graphics.drawable.shapes.Shape; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.SystemClock; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.view.ViewDebug; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; -import android.view.animation.AlphaAnimation; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.view.animation.Interpolator; -import android.view.animation.LinearInterpolator; -import android.view.animation.Transformation; -import android.widget.RemoteViews.RemoteView; - - -/** - *

- * Visual indicator of progress in some operation. Displays a bar to the user - * representing how far the operation has progressed; the application can - * change the amount of progress (modifying the length of the bar) as it moves - * forward. There is also a secondary progress displayable on a progress bar - * which is useful for displaying intermediate progress, such as the buffer - * level during a streaming playback progress bar. - *

- * - *

- * A progress bar can also be made indeterminate. In indeterminate mode, the - * progress bar shows a cyclic animation without an indication of progress. This mode is used by - * applications when the length of the task is unknown. The indeterminate progress bar can be either - * a spinning wheel or a horizontal bar. - *

- * - *

The following code example shows how a progress bar can be used from - * a worker thread to update the user interface to notify the user of progress: - *

- * - *
- * public class MyActivity extends Activity {
- *     private static final int PROGRESS = 0x1;
- *
- *     private ProgressBar mProgress;
- *     private int mProgressStatus = 0;
- *
- *     private Handler mHandler = new Handler();
- *
- *     protected void onCreate(Bundle icicle) {
- *         super.onCreate(icicle);
- *
- *         setContentView(R.layout.progressbar_activity);
- *
- *         mProgress = (ProgressBar) findViewById(R.id.progress_bar);
- *
- *         // Start lengthy operation in a background thread
- *         new Thread(new Runnable() {
- *             public void run() {
- *                 while (mProgressStatus < 100) {
- *                     mProgressStatus = doWork();
- *
- *                     // Update the progress bar
- *                     mHandler.post(new Runnable() {
- *                         public void run() {
- *                             mProgress.setProgress(mProgressStatus);
- *                         }
- *                     });
- *                 }
- *             }
- *         }).start();
- *     }
- * }
- * - *

To add a progress bar to a layout file, you can use the {@code <ProgressBar>} element. - * By default, the progress bar is a spinning wheel (an indeterminate indicator). To change to a - * horizontal progress bar, apply the {@link android.R.style#Widget_ProgressBar_Horizontal - * Widget.ProgressBar.Horizontal} style, like so:

- * - *
- * <ProgressBar
- *     style="@android:style/Widget.ProgressBar.Horizontal"
- *     ... />
- * - *

If you will use the progress bar to show real progress, you must use the horizontal bar. You - * can then increment the progress with {@link #incrementProgressBy incrementProgressBy()} or - * {@link #setProgress setProgress()}. By default, the progress bar is full when it reaches 100. If - * necessary, you can adjust the maximum value (the value for a full bar) using the {@link - * android.R.styleable#ProgressBar_max android:max} attribute. Other attributes available are listed - * below.

- * - *

Another common style to apply to the progress bar is {@link - * android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}, which shows a smaller - * version of the spinning wheel—useful when waiting for content to load. - * For example, you can insert this kind of progress bar into your default layout for - * a view that will be populated by some content fetched from the Internet—the spinning wheel - * appears immediately and when your application receives the content, it replaces the progress bar - * with the loaded content. For example:

- * - *
- * <LinearLayout
- *     android:orientation="horizontal"
- *     ... >
- *     <ProgressBar
- *         android:layout_width="wrap_content"
- *         android:layout_height="wrap_content"
- *         style="@android:style/Widget.ProgressBar.Small"
- *         android:layout_marginRight="5dp" />
- *     <TextView
- *         android:layout_width="wrap_content"
- *         android:layout_height="wrap_content"
- *         android:text="@string/loading" />
- * </LinearLayout>
- * - *

Other progress bar styles provided by the system include:

- *
    - *
  • {@link android.R.style#Widget_ProgressBar_Horizontal Widget.ProgressBar.Horizontal}
  • - *
  • {@link android.R.style#Widget_ProgressBar_Small Widget.ProgressBar.Small}
  • - *
  • {@link android.R.style#Widget_ProgressBar_Large Widget.ProgressBar.Large}
  • - *
  • {@link android.R.style#Widget_ProgressBar_Inverse Widget.ProgressBar.Inverse}
  • - *
  • {@link android.R.style#Widget_ProgressBar_Small_Inverse - * Widget.ProgressBar.Small.Inverse}
  • - *
  • {@link android.R.style#Widget_ProgressBar_Large_Inverse - * Widget.ProgressBar.Large.Inverse}
  • - *
- *

The "inverse" styles provide an inverse color scheme for the spinner, which may be necessary - * if your application uses a light colored theme (a white background).

- * - *

XML attributes - *

- * See {@link android.R.styleable#ProgressBar ProgressBar Attributes}, - * {@link android.R.styleable#View View Attributes} - *

- * - * @attr ref android.R.styleable#ProgressBar_animationResolution - * @attr ref android.R.styleable#ProgressBar_indeterminate - * @attr ref android.R.styleable#ProgressBar_indeterminateBehavior - * @attr ref android.R.styleable#ProgressBar_indeterminateDrawable - * @attr ref android.R.styleable#ProgressBar_indeterminateDuration - * @attr ref android.R.styleable#ProgressBar_indeterminateOnly - * @attr ref android.R.styleable#ProgressBar_interpolator - * @attr ref android.R.styleable#ProgressBar_max - * @attr ref android.R.styleable#ProgressBar_maxHeight - * @attr ref android.R.styleable#ProgressBar_maxWidth - * @attr ref android.R.styleable#ProgressBar_minHeight - * @attr ref android.R.styleable#ProgressBar_minWidth - * @attr ref android.R.styleable#ProgressBar_progress - * @attr ref android.R.styleable#ProgressBar_progressDrawable - * @attr ref android.R.styleable#ProgressBar_secondaryProgress - */ -@RemoteView -public class IcsProgressBar extends View { - private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; - private static final int MAX_LEVEL = 10000; - private static final int ANIMATION_RESOLUTION = 200; - private static final int TIMEOUT_SEND_ACCESSIBILITY_EVENT = 200; - - private static final int[] ProgressBar = new int[] { - android.R.attr.maxWidth, - android.R.attr.maxHeight, - android.R.attr.max, - android.R.attr.progress, - android.R.attr.secondaryProgress, - android.R.attr.indeterminate, - android.R.attr.indeterminateOnly, - android.R.attr.indeterminateDrawable, - android.R.attr.progressDrawable, - android.R.attr.indeterminateDuration, - android.R.attr.indeterminateBehavior, - android.R.attr.minWidth, - android.R.attr.minHeight, - android.R.attr.interpolator, - android.R.attr.animationResolution, - }; - private static final int ProgressBar_maxWidth = 0; - private static final int ProgressBar_maxHeight = 1; - private static final int ProgressBar_max = 2; - private static final int ProgressBar_progress = 3; - private static final int ProgressBar_secondaryProgress = 4; - private static final int ProgressBar_indeterminate = 5; - private static final int ProgressBar_indeterminateOnly = 6; - private static final int ProgressBar_indeterminateDrawable = 7; - private static final int ProgressBar_progressDrawable = 8; - private static final int ProgressBar_indeterminateDuration = 9; - private static final int ProgressBar_indeterminateBehavior = 10; - private static final int ProgressBar_minWidth = 11; - private static final int ProgressBar_minHeight = 12; - private static final int ProgressBar_interpolator = 13; - private static final int ProgressBar_animationResolution = 14; - - int mMinWidth; - int mMaxWidth; - int mMinHeight; - int mMaxHeight; - - private int mProgress; - private int mSecondaryProgress; - private int mMax; - - private int mBehavior; - private int mDuration; - private boolean mIndeterminate; - private boolean mOnlyIndeterminate; - private Transformation mTransformation; - private AlphaAnimation mAnimation; - private Drawable mIndeterminateDrawable; - private int mIndeterminateRealLeft; - private int mIndeterminateRealTop; - private Drawable mProgressDrawable; - private Drawable mCurrentDrawable; - Bitmap mSampleTile; - private boolean mNoInvalidate; - private Interpolator mInterpolator; - private RefreshProgressRunnable mRefreshProgressRunnable; - private long mUiThreadId; - private boolean mShouldStartAnimationDrawable; - private long mLastDrawTime; - - private boolean mInDrawing; - - private int mAnimationResolution; - - private AccessibilityManager mAccessibilityManager; - private AccessibilityEventSender mAccessibilityEventSender; - - /** - * Create a new progress bar with range 0...100 and initial progress of 0. - * @param context the application environment - */ - public IcsProgressBar(Context context) { - this(context, null); - } - - public IcsProgressBar(Context context, AttributeSet attrs) { - this(context, attrs, android.R.attr.progressBarStyle); - } - - public IcsProgressBar(Context context, AttributeSet attrs, int defStyle) { - this(context, attrs, defStyle, 0); - } - - /** - * @hide - */ - public IcsProgressBar(Context context, AttributeSet attrs, int defStyle, int styleRes) { - super(context, attrs, defStyle); - mUiThreadId = Thread.currentThread().getId(); - initProgressBar(); - - TypedArray a = - context.obtainStyledAttributes(attrs, /*R.styleable.*/ProgressBar, defStyle, styleRes); - - mNoInvalidate = true; - - Drawable drawable = a.getDrawable(/*R.styleable.*/ProgressBar_progressDrawable); - if (drawable != null) { - drawable = tileify(drawable, false); - // Calling this method can set mMaxHeight, make sure the corresponding - // XML attribute for mMaxHeight is read after calling this method - setProgressDrawable(drawable); - } - - - mDuration = a.getInt(/*R.styleable.*/ProgressBar_indeterminateDuration, mDuration); - - mMinWidth = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_minWidth, mMinWidth); - mMaxWidth = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_maxWidth, mMaxWidth); - mMinHeight = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_minHeight, mMinHeight); - mMaxHeight = a.getDimensionPixelSize(/*R.styleable.*/ProgressBar_maxHeight, mMaxHeight); - - mBehavior = a.getInt(/*R.styleable.*/ProgressBar_indeterminateBehavior, mBehavior); - - final int resID = a.getResourceId( - /*com.android.internal.R.styleable.*/ProgressBar_interpolator, - android.R.anim.linear_interpolator); // default to linear interpolator - if (resID > 0) { - setInterpolator(context, resID); - } - - setMax(a.getInt(/*R.styleable.*/ProgressBar_max, mMax)); - - setProgress(a.getInt(/*R.styleable.*/ProgressBar_progress, mProgress)); - - setSecondaryProgress( - a.getInt(/*R.styleable.*/ProgressBar_secondaryProgress, mSecondaryProgress)); - - drawable = a.getDrawable(/*R.styleable.*/ProgressBar_indeterminateDrawable); - if (drawable != null) { - drawable = tileifyIndeterminate(drawable); - setIndeterminateDrawable(drawable); - } - - mOnlyIndeterminate = a.getBoolean( - /*R.styleable.*/ProgressBar_indeterminateOnly, mOnlyIndeterminate); - - mNoInvalidate = false; - - setIndeterminate(mOnlyIndeterminate || a.getBoolean( - /*R.styleable.*/ProgressBar_indeterminate, mIndeterminate)); - - mAnimationResolution = a.getInteger(/*R.styleable.*/ProgressBar_animationResolution, - ANIMATION_RESOLUTION); - - a.recycle(); - - mAccessibilityManager = (AccessibilityManager)context.getSystemService(Context.ACCESSIBILITY_SERVICE); - } - - /** - * Converts a drawable to a tiled version of itself. It will recursively - * traverse layer and state list drawables. - */ - private Drawable tileify(Drawable drawable, boolean clip) { - - if (drawable instanceof LayerDrawable) { - LayerDrawable background = (LayerDrawable) drawable; - final int N = background.getNumberOfLayers(); - Drawable[] outDrawables = new Drawable[N]; - - for (int i = 0; i < N; i++) { - int id = background.getId(i); - outDrawables[i] = tileify(background.getDrawable(i), - (id == android.R.id.progress || id == android.R.id.secondaryProgress)); - } - - LayerDrawable newBg = new LayerDrawable(outDrawables); - - for (int i = 0; i < N; i++) { - newBg.setId(i, background.getId(i)); - } - - return newBg; - - }/* else if (drawable instanceof StateListDrawable) { - StateListDrawable in = (StateListDrawable) drawable; - StateListDrawable out = new StateListDrawable(); - int numStates = in.getStateCount(); - for (int i = 0; i < numStates; i++) { - out.addState(in.getStateSet(i), tileify(in.getStateDrawable(i), clip)); - } - return out; - - }*/ else if (drawable instanceof BitmapDrawable) { - final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap(); - if (mSampleTile == null) { - mSampleTile = tileBitmap; - } - - final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape()); - - final BitmapShader bitmapShader = new BitmapShader(tileBitmap, - Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); - shapeDrawable.getPaint().setShader(bitmapShader); - - return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT, - ClipDrawable.HORIZONTAL) : shapeDrawable; - } - - return drawable; - } - - Shape getDrawableShape() { - final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 }; - return new RoundRectShape(roundedCorners, null, null); - } - - /** - * Convert a AnimationDrawable for use as a barberpole animation. - * Each frame of the animation is wrapped in a ClipDrawable and - * given a tiling BitmapShader. - */ - private Drawable tileifyIndeterminate(Drawable drawable) { - if (drawable instanceof AnimationDrawable) { - AnimationDrawable background = (AnimationDrawable) drawable; - final int N = background.getNumberOfFrames(); - AnimationDrawable newBg = new AnimationDrawable(); - newBg.setOneShot(background.isOneShot()); - - for (int i = 0; i < N; i++) { - Drawable frame = tileify(background.getFrame(i), true); - frame.setLevel(10000); - newBg.addFrame(frame, background.getDuration(i)); - } - newBg.setLevel(10000); - drawable = newBg; - } - return drawable; - } - - /** - *

- * Initialize the progress bar's default values: - *

- *
    - *
  • progress = 0
  • - *
  • max = 100
  • - *
  • animation duration = 4000 ms
  • - *
  • indeterminate = false
  • - *
  • behavior = repeat
  • - *
- */ - private void initProgressBar() { - mMax = 100; - mProgress = 0; - mSecondaryProgress = 0; - mIndeterminate = false; - mOnlyIndeterminate = false; - mDuration = 4000; - mBehavior = AlphaAnimation.RESTART; - mMinWidth = 24; - mMaxWidth = 48; - mMinHeight = 24; - mMaxHeight = 48; - } - - /** - *

Indicate whether this progress bar is in indeterminate mode.

- * - * @return true if the progress bar is in indeterminate mode - */ - @ViewDebug.ExportedProperty(category = "progress") - public synchronized boolean isIndeterminate() { - return mIndeterminate; - } - - /** - *

Change the indeterminate mode for this progress bar. In indeterminate - * mode, the progress is ignored and the progress bar shows an infinite - * animation instead.

- * - * If this progress bar's style only supports indeterminate mode (such as the circular - * progress bars), then this will be ignored. - * - * @param indeterminate true to enable the indeterminate mode - */ - public synchronized void setIndeterminate(boolean indeterminate) { - if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) { - mIndeterminate = indeterminate; - - if (indeterminate) { - // swap between indeterminate and regular backgrounds - mCurrentDrawable = mIndeterminateDrawable; - startAnimation(); - } else { - mCurrentDrawable = mProgressDrawable; - stopAnimation(); - } - } - } - - /** - *

Get the drawable used to draw the progress bar in - * indeterminate mode.

- * - * @return a {@link android.graphics.drawable.Drawable} instance - * - * @see #setIndeterminateDrawable(android.graphics.drawable.Drawable) - * @see #setIndeterminate(boolean) - */ - public Drawable getIndeterminateDrawable() { - return mIndeterminateDrawable; - } - - /** - *

Define the drawable used to draw the progress bar in - * indeterminate mode.

- * - * @param d the new drawable - * - * @see #getIndeterminateDrawable() - * @see #setIndeterminate(boolean) - */ - public void setIndeterminateDrawable(Drawable d) { - if (d != null) { - d.setCallback(this); - } - mIndeterminateDrawable = d; - if (mIndeterminate) { - mCurrentDrawable = d; - postInvalidate(); - } - } - - /** - *

Get the drawable used to draw the progress bar in - * progress mode.

- * - * @return a {@link android.graphics.drawable.Drawable} instance - * - * @see #setProgressDrawable(android.graphics.drawable.Drawable) - * @see #setIndeterminate(boolean) - */ - public Drawable getProgressDrawable() { - return mProgressDrawable; - } - - /** - *

Define the drawable used to draw the progress bar in - * progress mode.

- * - * @param d the new drawable - * - * @see #getProgressDrawable() - * @see #setIndeterminate(boolean) - */ - public void setProgressDrawable(Drawable d) { - boolean needUpdate; - if (mProgressDrawable != null && d != mProgressDrawable) { - mProgressDrawable.setCallback(null); - needUpdate = true; - } else { - needUpdate = false; - } - - if (d != null) { - d.setCallback(this); - - // Make sure the ProgressBar is always tall enough - int drawableHeight = d.getMinimumHeight(); - if (mMaxHeight < drawableHeight) { - mMaxHeight = drawableHeight; - requestLayout(); - } - } - mProgressDrawable = d; - if (!mIndeterminate) { - mCurrentDrawable = d; - postInvalidate(); - } - - if (needUpdate) { - updateDrawableBounds(getWidth(), getHeight()); - updateDrawableState(); - doRefreshProgress(android.R.id.progress, mProgress, false, false); - doRefreshProgress(android.R.id.secondaryProgress, mSecondaryProgress, false, false); - } - } - - /** - * @return The drawable currently used to draw the progress bar - */ - Drawable getCurrentDrawable() { - return mCurrentDrawable; - } - - @Override - protected boolean verifyDrawable(Drawable who) { - return who == mProgressDrawable || who == mIndeterminateDrawable - || super.verifyDrawable(who); - } - - @Override - public void jumpDrawablesToCurrentState() { - super.jumpDrawablesToCurrentState(); - if (mProgressDrawable != null) mProgressDrawable.jumpToCurrentState(); - if (mIndeterminateDrawable != null) mIndeterminateDrawable.jumpToCurrentState(); - } - - @Override - public void postInvalidate() { - if (!mNoInvalidate) { - super.postInvalidate(); - } - } - - private class RefreshProgressRunnable implements Runnable { - - private int mId; - private int mProgress; - private boolean mFromUser; - - RefreshProgressRunnable(int id, int progress, boolean fromUser) { - mId = id; - mProgress = progress; - mFromUser = fromUser; - } - - public void run() { - doRefreshProgress(mId, mProgress, mFromUser, true); - // Put ourselves back in the cache when we are done - mRefreshProgressRunnable = this; - } - - public void setup(int id, int progress, boolean fromUser) { - mId = id; - mProgress = progress; - mFromUser = fromUser; - } - - } - - private synchronized void doRefreshProgress(int id, int progress, boolean fromUser, - boolean callBackToApp) { - float scale = mMax > 0 ? (float) progress / (float) mMax : 0; - final Drawable d = mCurrentDrawable; - if (d != null) { - Drawable progressDrawable = null; - - if (d instanceof LayerDrawable) { - progressDrawable = ((LayerDrawable) d).findDrawableByLayerId(id); - } - - final int level = (int) (scale * MAX_LEVEL); - (progressDrawable != null ? progressDrawable : d).setLevel(level); - } else { - invalidate(); - } - - if (callBackToApp && id == android.R.id.progress) { - onProgressRefresh(scale, fromUser); - } - } - - void onProgressRefresh(float scale, boolean fromUser) { - if (mAccessibilityManager.isEnabled()) { - scheduleAccessibilityEventSender(); - } - } - - private synchronized void refreshProgress(int id, int progress, boolean fromUser) { - if (mUiThreadId == Thread.currentThread().getId()) { - doRefreshProgress(id, progress, fromUser, true); - } else { - RefreshProgressRunnable r; - if (mRefreshProgressRunnable != null) { - // Use cached RefreshProgressRunnable if available - r = mRefreshProgressRunnable; - // Uncache it - mRefreshProgressRunnable = null; - r.setup(id, progress, fromUser); - } else { - // Make a new one - r = new RefreshProgressRunnable(id, progress, fromUser); - } - post(r); - } - } - - /** - *

Set the current progress to the specified value. Does not do anything - * if the progress bar is in indeterminate mode.

- * - * @param progress the new progress, between 0 and {@link #getMax()} - * - * @see #setIndeterminate(boolean) - * @see #isIndeterminate() - * @see #getProgress() - * @see #incrementProgressBy(int) - */ - public synchronized void setProgress(int progress) { - setProgress(progress, false); - } - - synchronized void setProgress(int progress, boolean fromUser) { - if (mIndeterminate) { - return; - } - - if (progress < 0) { - progress = 0; - } - - if (progress > mMax) { - progress = mMax; - } - - if (progress != mProgress) { - mProgress = progress; - refreshProgress(android.R.id.progress, mProgress, fromUser); - } - } - - /** - *

- * Set the current secondary progress to the specified value. Does not do - * anything if the progress bar is in indeterminate mode. - *

- * - * @param secondaryProgress the new secondary progress, between 0 and {@link #getMax()} - * @see #setIndeterminate(boolean) - * @see #isIndeterminate() - * @see #getSecondaryProgress() - * @see #incrementSecondaryProgressBy(int) - */ - public synchronized void setSecondaryProgress(int secondaryProgress) { - if (mIndeterminate) { - return; - } - - if (secondaryProgress < 0) { - secondaryProgress = 0; - } - - if (secondaryProgress > mMax) { - secondaryProgress = mMax; - } - - if (secondaryProgress != mSecondaryProgress) { - mSecondaryProgress = secondaryProgress; - refreshProgress(android.R.id.secondaryProgress, mSecondaryProgress, false); - } - } - - /** - *

Get the progress bar's current level of progress. Return 0 when the - * progress bar is in indeterminate mode.

- * - * @return the current progress, between 0 and {@link #getMax()} - * - * @see #setIndeterminate(boolean) - * @see #isIndeterminate() - * @see #setProgress(int) - * @see #setMax(int) - * @see #getMax() - */ - @ViewDebug.ExportedProperty(category = "progress") - public synchronized int getProgress() { - return mIndeterminate ? 0 : mProgress; - } - - /** - *

Get the progress bar's current level of secondary progress. Return 0 when the - * progress bar is in indeterminate mode.

- * - * @return the current secondary progress, between 0 and {@link #getMax()} - * - * @see #setIndeterminate(boolean) - * @see #isIndeterminate() - * @see #setSecondaryProgress(int) - * @see #setMax(int) - * @see #getMax() - */ - @ViewDebug.ExportedProperty(category = "progress") - public synchronized int getSecondaryProgress() { - return mIndeterminate ? 0 : mSecondaryProgress; - } - - /** - *

Return the upper limit of this progress bar's range.

- * - * @return a positive integer - * - * @see #setMax(int) - * @see #getProgress() - * @see #getSecondaryProgress() - */ - @ViewDebug.ExportedProperty(category = "progress") - public synchronized int getMax() { - return mMax; - } - - /** - *

Set the range of the progress bar to 0...max.

- * - * @param max the upper range of this progress bar - * - * @see #getMax() - * @see #setProgress(int) - * @see #setSecondaryProgress(int) - */ - public synchronized void setMax(int max) { - if (max < 0) { - max = 0; - } - if (max != mMax) { - mMax = max; - postInvalidate(); - - if (mProgress > max) { - mProgress = max; - } - refreshProgress(android.R.id.progress, mProgress, false); - } - } - - /** - *

Increase the progress bar's progress by the specified amount.

- * - * @param diff the amount by which the progress must be increased - * - * @see #setProgress(int) - */ - public synchronized final void incrementProgressBy(int diff) { - setProgress(mProgress + diff); - } - - /** - *

Increase the progress bar's secondary progress by the specified amount.

- * - * @param diff the amount by which the secondary progress must be increased - * - * @see #setSecondaryProgress(int) - */ - public synchronized final void incrementSecondaryProgressBy(int diff) { - setSecondaryProgress(mSecondaryProgress + diff); - } - - /** - *

Start the indeterminate progress animation.

- */ - void startAnimation() { - if (getVisibility() != VISIBLE) { - return; - } - - if (mIndeterminateDrawable instanceof Animatable) { - mShouldStartAnimationDrawable = true; - mAnimation = null; - } else { - if (mInterpolator == null) { - mInterpolator = new LinearInterpolator(); - } - - mTransformation = new Transformation(); - mAnimation = new AlphaAnimation(0.0f, 1.0f); - mAnimation.setRepeatMode(mBehavior); - mAnimation.setRepeatCount(Animation.INFINITE); - mAnimation.setDuration(mDuration); - mAnimation.setInterpolator(mInterpolator); - mAnimation.setStartTime(Animation.START_ON_FIRST_FRAME); - } - postInvalidate(); - } - - /** - *

Stop the indeterminate progress animation.

- */ - void stopAnimation() { - mAnimation = null; - mTransformation = null; - if (mIndeterminateDrawable instanceof Animatable) { - ((Animatable) mIndeterminateDrawable).stop(); - mShouldStartAnimationDrawable = false; - } - postInvalidate(); - } - - /** - * Sets the acceleration curve for the indeterminate animation. - * The interpolator is loaded as a resource from the specified context. - * - * @param context The application environment - * @param resID The resource identifier of the interpolator to load - */ - public void setInterpolator(Context context, int resID) { - setInterpolator(AnimationUtils.loadInterpolator(context, resID)); - } - - /** - * Sets the acceleration curve for the indeterminate animation. - * Defaults to a linear interpolation. - * - * @param interpolator The interpolator which defines the acceleration curve - */ - public void setInterpolator(Interpolator interpolator) { - mInterpolator = interpolator; - } - - /** - * Gets the acceleration curve type for the indeterminate animation. - * - * @return the {@link Interpolator} associated to this animation - */ - public Interpolator getInterpolator() { - return mInterpolator; - } - - @Override - public void setVisibility(int v) { - if (getVisibility() != v) { - super.setVisibility(v); - - if (mIndeterminate) { - // let's be nice with the UI thread - if (v == GONE || v == INVISIBLE) { - stopAnimation(); - } else { - startAnimation(); - } - } - } - } - - @Override - protected void onVisibilityChanged(View changedView, int visibility) { - super.onVisibilityChanged(changedView, visibility); - - if (mIndeterminate) { - // let's be nice with the UI thread - if (visibility == GONE || visibility == INVISIBLE) { - stopAnimation(); - } else { - startAnimation(); - } - } - } - - @Override - public void invalidateDrawable(Drawable dr) { - if (!mInDrawing) { - if (verifyDrawable(dr)) { - final Rect dirty = dr.getBounds(); - final int scrollX = getScrollX() + getPaddingLeft(); - final int scrollY = getScrollY() + getPaddingTop(); - - invalidate(dirty.left + scrollX, dirty.top + scrollY, - dirty.right + scrollX, dirty.bottom + scrollY); - } else { - super.invalidateDrawable(dr); - } - } - } - - /** - * @hide - * - @Override - public int getResolvedLayoutDirection(Drawable who) { - return (who == mProgressDrawable || who == mIndeterminateDrawable) ? - getResolvedLayoutDirection() : super.getResolvedLayoutDirection(who); - } - */ - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - updateDrawableBounds(w, h); - } - - private void updateDrawableBounds(int w, int h) { - // onDraw will translate the canvas so we draw starting at 0,0 - int right = w - getPaddingRight() - getPaddingLeft(); - int bottom = h - getPaddingBottom() - getPaddingTop(); - int top = 0; - int left = 0; - - if (mIndeterminateDrawable != null) { - // Aspect ratio logic does not apply to AnimationDrawables - if (mOnlyIndeterminate && !(mIndeterminateDrawable instanceof AnimationDrawable)) { - // Maintain aspect ratio. Certain kinds of animated drawables - // get very confused otherwise. - final int intrinsicWidth = mIndeterminateDrawable.getIntrinsicWidth(); - final int intrinsicHeight = mIndeterminateDrawable.getIntrinsicHeight(); - final float intrinsicAspect = (float) intrinsicWidth / intrinsicHeight; - final float boundAspect = (float) w / h; - if (intrinsicAspect != boundAspect) { - if (boundAspect > intrinsicAspect) { - // New width is larger. Make it smaller to match height. - final int width = (int) (h * intrinsicAspect); - left = (w - width) / 2; - right = left + width; - } else { - // New height is larger. Make it smaller to match width. - final int height = (int) (w * (1 / intrinsicAspect)); - top = (h - height) / 2; - bottom = top + height; - } - } - } - mIndeterminateDrawable.setBounds(0, 0, right - left, bottom - top); - mIndeterminateRealLeft = left; - mIndeterminateRealTop = top; - } - - if (mProgressDrawable != null) { - mProgressDrawable.setBounds(0, 0, right, bottom); - } - } - - @Override - protected synchronized void onDraw(Canvas canvas) { - super.onDraw(canvas); - - Drawable d = mCurrentDrawable; - if (d != null) { - // Translate canvas so a indeterminate circular progress bar with padding - // rotates properly in its animation - canvas.save(); - canvas.translate(getPaddingLeft() + mIndeterminateRealLeft, getPaddingTop() + mIndeterminateRealTop); - long time = getDrawingTime(); - if (mAnimation != null) { - mAnimation.getTransformation(time, mTransformation); - float scale = mTransformation.getAlpha(); - try { - mInDrawing = true; - d.setLevel((int) (scale * MAX_LEVEL)); - } finally { - mInDrawing = false; - } - if (SystemClock.uptimeMillis() - mLastDrawTime >= mAnimationResolution) { - mLastDrawTime = SystemClock.uptimeMillis(); - postInvalidateDelayed(mAnimationResolution); - } - } - d.draw(canvas); - canvas.restore(); - if (mShouldStartAnimationDrawable && d instanceof Animatable) { - ((Animatable) d).start(); - mShouldStartAnimationDrawable = false; - } - } - } - - @Override - protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - Drawable d = mCurrentDrawable; - - int dw = 0; - int dh = 0; - if (d != null) { - dw = Math.max(mMinWidth, Math.min(mMaxWidth, d.getIntrinsicWidth())); - dh = Math.max(mMinHeight, Math.min(mMaxHeight, d.getIntrinsicHeight())); - } - updateDrawableState(); - dw += getPaddingLeft() + getPaddingRight(); - dh += getPaddingTop() + getPaddingBottom(); - - if (IS_HONEYCOMB) { - setMeasuredDimension(View.resolveSizeAndState(dw, widthMeasureSpec, 0), - View.resolveSizeAndState(dh, heightMeasureSpec, 0)); - } else { - setMeasuredDimension(View.resolveSize(dw, widthMeasureSpec), - View.resolveSize(dh, heightMeasureSpec)); - } - } - - @Override - protected void drawableStateChanged() { - super.drawableStateChanged(); - updateDrawableState(); - } - - private void updateDrawableState() { - int[] state = getDrawableState(); - - if (mProgressDrawable != null && mProgressDrawable.isStateful()) { - mProgressDrawable.setState(state); - } - - if (mIndeterminateDrawable != null && mIndeterminateDrawable.isStateful()) { - mIndeterminateDrawable.setState(state); - } - } - - static class SavedState extends BaseSavedState { - int progress; - int secondaryProgress; - - /** - * Constructor called from {@link IcsProgressBar#onSaveInstanceState()} - */ - SavedState(Parcelable superState) { - super(superState); - } - - /** - * Constructor called from {@link #CREATOR} - */ - private SavedState(Parcel in) { - super(in); - progress = in.readInt(); - secondaryProgress = in.readInt(); - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeInt(progress); - out.writeInt(secondaryProgress); - } - - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - - @Override - public Parcelable onSaveInstanceState() { - // Force our ancestor class to save its state - Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - - ss.progress = mProgress; - ss.secondaryProgress = mSecondaryProgress; - - return ss; - } - - @Override - public void onRestoreInstanceState(Parcelable state) { - SavedState ss = (SavedState) state; - super.onRestoreInstanceState(ss.getSuperState()); - - setProgress(ss.progress); - setSecondaryProgress(ss.secondaryProgress); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - if (mIndeterminate) { - startAnimation(); - } - } - - @Override - protected void onDetachedFromWindow() { - if (mIndeterminate) { - stopAnimation(); - } - if(mRefreshProgressRunnable != null) { - removeCallbacks(mRefreshProgressRunnable); - } - if (mAccessibilityEventSender != null) { - removeCallbacks(mAccessibilityEventSender); - } - // This should come after stopAnimation(), otherwise an invalidate message remains in the - // queue, which can prevent the entire view hierarchy from being GC'ed during a rotation - super.onDetachedFromWindow(); - } - - @Override - public void onInitializeAccessibilityEvent(AccessibilityEvent event) { - super.onInitializeAccessibilityEvent(event); - event.setItemCount(mMax); - event.setCurrentItemIndex(mProgress); - } - - /** - * Schedule a command for sending an accessibility event. - *
- * Note: A command is used to ensure that accessibility events - * are sent at most one in a given time frame to save - * system resources while the progress changes quickly. - */ - private void scheduleAccessibilityEventSender() { - if (mAccessibilityEventSender == null) { - mAccessibilityEventSender = new AccessibilityEventSender(); - } else { - removeCallbacks(mAccessibilityEventSender); - } - postDelayed(mAccessibilityEventSender, TIMEOUT_SEND_ACCESSIBILITY_EVENT); - } - - /** - * Command for sending an accessibility event. - */ - private class AccessibilityEventSender implements Runnable { - public void run() { - sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsSpinner.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsSpinner.java deleted file mode 100644 index 038d1e03..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsSpinner.java +++ /dev/null @@ -1,703 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.internal.widget; - -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; -import com.actionbarsherlock.R; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.res.TypedArray; -import android.database.DataSetObserver; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.PopupWindow; -import android.widget.SpinnerAdapter; - - -/** - * A view that displays one child at a time and lets the user pick among them. - * The items in the Spinner come from the {@link Adapter} associated with - * this view. - * - *

See the Spinner - * tutorial.

- * - * @attr ref android.R.styleable#Spinner_prompt - */ -public class IcsSpinner extends IcsAbsSpinner implements OnClickListener { - //private static final String TAG = "Spinner"; - - // Only measure this many items to get a decent max width. - private static final int MAX_ITEMS_MEASURED = 15; - - /** - * Use a dialog window for selecting spinner options. - */ - //public static final int MODE_DIALOG = 0; - - /** - * Use a dropdown anchored to the Spinner for selecting spinner options. - */ - public static final int MODE_DROPDOWN = 1; - - /** - * Use the theme-supplied value to select the dropdown mode. - */ - //private static final int MODE_THEME = -1; - - private SpinnerPopup mPopup; - private DropDownAdapter mTempAdapter; - int mDropDownWidth; - - private int mGravity; - private boolean mDisableChildrenWhenDisabled; - - private Rect mTempRect = new Rect(); - - public IcsSpinner(Context context, AttributeSet attrs) { - this(context, attrs, R.attr.actionDropDownStyle); - } - - /** - * Construct a new spinner with the given context's theme, the supplied attribute set, - * and default style. - * - * @param context The Context the view is running in, through which it can - * access the current theme, resources, etc. - * @param attrs The attributes of the XML tag that is inflating the view. - * @param defStyle The default style to apply to this view. If 0, no style - * will be applied (beyond what is included in the theme). This may - * either be an attribute resource, whose value will be retrieved - * from the current theme, or an explicit style resource. - */ - public IcsSpinner(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - TypedArray a = context.obtainStyledAttributes(attrs, - R.styleable.SherlockSpinner, defStyle, 0); - - - DropdownPopup popup = new DropdownPopup(context, attrs, defStyle); - - mDropDownWidth = a.getLayoutDimension( - R.styleable.SherlockSpinner_android_dropDownWidth, - ViewGroup.LayoutParams.WRAP_CONTENT); - popup.setBackgroundDrawable(a.getDrawable( - R.styleable.SherlockSpinner_android_popupBackground)); - final int verticalOffset = a.getDimensionPixelOffset( - R.styleable.SherlockSpinner_android_dropDownVerticalOffset, 0); - if (verticalOffset != 0) { - popup.setVerticalOffset(verticalOffset); - } - - final int horizontalOffset = a.getDimensionPixelOffset( - R.styleable.SherlockSpinner_android_dropDownHorizontalOffset, 0); - if (horizontalOffset != 0) { - popup.setHorizontalOffset(horizontalOffset); - } - - mPopup = popup; - - mGravity = a.getInt(R.styleable.SherlockSpinner_android_gravity, Gravity.CENTER); - - mPopup.setPromptText(a.getString(R.styleable.SherlockSpinner_android_prompt)); - - mDisableChildrenWhenDisabled = true; - - a.recycle(); - - // Base constructor can call setAdapter before we initialize mPopup. - // Finish setting things up if this happened. - if (mTempAdapter != null) { - mPopup.setAdapter(mTempAdapter); - mTempAdapter = null; - } - } - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - if (mDisableChildrenWhenDisabled) { - final int count = getChildCount(); - for (int i = 0; i < count; i++) { - getChildAt(i).setEnabled(enabled); - } - } - } - - /** - * Describes how the selected item view is positioned. Currently only the horizontal component - * is used. The default is determined by the current theme. - * - * @param gravity See {@link android.view.Gravity} - * - * @attr ref android.R.styleable#Spinner_gravity - */ - public void setGravity(int gravity) { - if (mGravity != gravity) { - if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) { - gravity |= Gravity.LEFT; - } - mGravity = gravity; - requestLayout(); - } - } - - @Override - public void setAdapter(SpinnerAdapter adapter) { - super.setAdapter(adapter); - - if (mPopup != null) { - mPopup.setAdapter(new DropDownAdapter(adapter)); - } else { - mTempAdapter = new DropDownAdapter(adapter); - } - } - - @Override - public int getBaseline() { - View child = null; - - if (getChildCount() > 0) { - child = getChildAt(0); - } else if (mAdapter != null && mAdapter.getCount() > 0) { - child = makeAndAddView(0); - mRecycler.put(0, child); - removeAllViewsInLayout(); - } - - if (child != null) { - final int childBaseline = child.getBaseline(); - return childBaseline >= 0 ? child.getTop() + childBaseline : -1; - } else { - return -1; - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - - if (mPopup != null && mPopup.isShowing()) { - mPopup.dismiss(); - } - } - - /** - *

A spinner does not support item click events. Calling this method - * will raise an exception.

- * - * @param l this listener will be ignored - */ - @Override - public void setOnItemClickListener(OnItemClickListener l) { - throw new RuntimeException("setOnItemClickListener cannot be used with a spinner."); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - if (mPopup != null && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST) { - final int measuredWidth = getMeasuredWidth(); - setMeasuredDimension(Math.min(Math.max(measuredWidth, - measureContentWidth(getAdapter(), getBackground())), - MeasureSpec.getSize(widthMeasureSpec)), - getMeasuredHeight()); - } - } - - /** - * @see android.view.View#onLayout(boolean,int,int,int,int) - * - * Creates and positions all views - * - */ - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - super.onLayout(changed, l, t, r, b); - mInLayout = true; - layout(0, false); - mInLayout = false; - } - - /** - * Creates and positions all views for this Spinner. - * - * @param delta Change in the selected position. +1 moves selection is moving to the right, - * so views are scrolling to the left. -1 means selection is moving to the left. - */ - @Override - void layout(int delta, boolean animate) { - int childrenLeft = mSpinnerPadding.left; - int childrenWidth = getRight() - getLeft() - mSpinnerPadding.left - mSpinnerPadding.right; - - if (mDataChanged) { - handleDataChanged(); - } - - // Handle the empty set by removing all views - if (mItemCount == 0) { - resetList(); - return; - } - - if (mNextSelectedPosition >= 0) { - setSelectedPositionInt(mNextSelectedPosition); - } - - recycleAllViews(); - - // Clear out old views - removeAllViewsInLayout(); - - // Make selected view and position it - mFirstPosition = mSelectedPosition; - View sel = makeAndAddView(mSelectedPosition); - int width = sel.getMeasuredWidth(); - int selectedOffset = childrenLeft; - switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { - case Gravity.CENTER_HORIZONTAL: - selectedOffset = childrenLeft + (childrenWidth / 2) - (width / 2); - break; - case Gravity.RIGHT: - selectedOffset = childrenLeft + childrenWidth - width; - break; - } - sel.offsetLeftAndRight(selectedOffset); - - // Flush any cached views that did not get reused above - mRecycler.clear(); - - invalidate(); - - checkSelectionChanged(); - - mDataChanged = false; - mNeedSync = false; - setNextSelectedPositionInt(mSelectedPosition); - } - - /** - * Obtain a view, either by pulling an existing view from the recycler or - * by getting a new one from the adapter. If we are animating, make sure - * there is enough information in the view's layout parameters to animate - * from the old to new positions. - * - * @param position Position in the spinner for the view to obtain - * @return A view that has been added to the spinner - */ - private View makeAndAddView(int position) { - - View child; - - if (!mDataChanged) { - child = mRecycler.get(position); - if (child != null) { - // Position the view - setUpChild(child); - - return child; - } - } - - // Nothing found in the recycler -- ask the adapter for a view - child = mAdapter.getView(position, null, this); - - // Position the view - setUpChild(child); - - return child; - } - - /** - * Helper for makeAndAddView to set the position of a view - * and fill out its layout paramters. - * - * @param child The view to position - */ - private void setUpChild(View child) { - - // Respect layout params that are already in the view. Otherwise - // make some up... - ViewGroup.LayoutParams lp = child.getLayoutParams(); - if (lp == null) { - lp = generateDefaultLayoutParams(); - } - - addViewInLayout(child, 0, lp); - - child.setSelected(hasFocus()); - if (mDisableChildrenWhenDisabled) { - child.setEnabled(isEnabled()); - } - - // Get measure specs - int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, - mSpinnerPadding.top + mSpinnerPadding.bottom, lp.height); - int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, - mSpinnerPadding.left + mSpinnerPadding.right, lp.width); - - // Measure child - child.measure(childWidthSpec, childHeightSpec); - - int childLeft; - int childRight; - - // Position vertically based on gravity setting - int childTop = mSpinnerPadding.top - + ((getMeasuredHeight() - mSpinnerPadding.bottom - - mSpinnerPadding.top - child.getMeasuredHeight()) / 2); - int childBottom = childTop + child.getMeasuredHeight(); - - int width = child.getMeasuredWidth(); - childLeft = 0; - childRight = childLeft + width; - - child.layout(childLeft, childTop, childRight, childBottom); - } - - @Override - public boolean performClick() { - boolean handled = super.performClick(); - - if (!handled) { - handled = true; - - if (!mPopup.isShowing()) { - mPopup.show(); - } - } - - return handled; - } - - public void onClick(DialogInterface dialog, int which) { - setSelection(which); - dialog.dismiss(); - } - - /** - * Sets the prompt to display when the dialog is shown. - * @param prompt the prompt to set - */ - public void setPrompt(CharSequence prompt) { - mPopup.setPromptText(prompt); - } - - /** - * Sets the prompt to display when the dialog is shown. - * @param promptId the resource ID of the prompt to display when the dialog is shown - */ - public void setPromptId(int promptId) { - setPrompt(getContext().getText(promptId)); - } - - /** - * @return The prompt to display when the dialog is shown - */ - public CharSequence getPrompt() { - return mPopup.getHintText(); - } - - int measureContentWidth(SpinnerAdapter adapter, Drawable background) { - if (adapter == null) { - return 0; - } - - int width = 0; - View itemView = null; - int itemType = 0; - final int widthMeasureSpec = - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - final int heightMeasureSpec = - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - - // Make sure the number of items we'll measure is capped. If it's a huge data set - // with wildly varying sizes, oh well. - int start = Math.max(0, getSelectedItemPosition()); - final int end = Math.min(adapter.getCount(), start + MAX_ITEMS_MEASURED); - final int count = end - start; - start = Math.max(0, start - (MAX_ITEMS_MEASURED - count)); - for (int i = start; i < end; i++) { - final int positionType = adapter.getItemViewType(i); - if (positionType != itemType) { - itemType = positionType; - itemView = null; - } - itemView = adapter.getView(i, itemView, this); - if (itemView.getLayoutParams() == null) { - itemView.setLayoutParams(new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT)); - } - itemView.measure(widthMeasureSpec, heightMeasureSpec); - width = Math.max(width, itemView.getMeasuredWidth()); - } - - // Add background padding to measured width - if (background != null) { - background.getPadding(mTempRect); - width += mTempRect.left + mTempRect.right; - } - - return width; - } - - /** - *

Wrapper class for an Adapter. Transforms the embedded Adapter instance - * into a ListAdapter.

- */ - private static class DropDownAdapter implements ListAdapter, SpinnerAdapter { - private SpinnerAdapter mAdapter; - private ListAdapter mListAdapter; - - /** - *

Creates a new ListAdapter wrapper for the specified adapter.

- * - * @param adapter the Adapter to transform into a ListAdapter - */ - public DropDownAdapter(SpinnerAdapter adapter) { - this.mAdapter = adapter; - if (adapter instanceof ListAdapter) { - this.mListAdapter = (ListAdapter) adapter; - } - } - - public int getCount() { - return mAdapter == null ? 0 : mAdapter.getCount(); - } - - public Object getItem(int position) { - return mAdapter == null ? null : mAdapter.getItem(position); - } - - public long getItemId(int position) { - return mAdapter == null ? -1 : mAdapter.getItemId(position); - } - - public View getView(int position, View convertView, ViewGroup parent) { - return getDropDownView(position, convertView, parent); - } - - public View getDropDownView(int position, View convertView, ViewGroup parent) { - return mAdapter == null ? null : - mAdapter.getDropDownView(position, convertView, parent); - } - - public boolean hasStableIds() { - return mAdapter != null && mAdapter.hasStableIds(); - } - - public void registerDataSetObserver(DataSetObserver observer) { - if (mAdapter != null) { - mAdapter.registerDataSetObserver(observer); - } - } - - public void unregisterDataSetObserver(DataSetObserver observer) { - if (mAdapter != null) { - mAdapter.unregisterDataSetObserver(observer); - } - } - - /** - * If the wrapped SpinnerAdapter is also a ListAdapter, delegate this call. - * Otherwise, return true. - */ - public boolean areAllItemsEnabled() { - final ListAdapter adapter = mListAdapter; - if (adapter != null) { - return adapter.areAllItemsEnabled(); - } else { - return true; - } - } - - /** - * If the wrapped SpinnerAdapter is also a ListAdapter, delegate this call. - * Otherwise, return true. - */ - public boolean isEnabled(int position) { - final ListAdapter adapter = mListAdapter; - if (adapter != null) { - return adapter.isEnabled(position); - } else { - return true; - } - } - - public int getItemViewType(int position) { - return 0; - } - - public int getViewTypeCount() { - return 1; - } - - public boolean isEmpty() { - return getCount() == 0; - } - } - - /** - * Implements some sort of popup selection interface for selecting a spinner option. - * Allows for different spinner modes. - */ - private interface SpinnerPopup { - public void setAdapter(ListAdapter adapter); - - /** - * Show the popup - */ - public void show(); - - /** - * Dismiss the popup - */ - public void dismiss(); - - /** - * @return true if the popup is showing, false otherwise. - */ - public boolean isShowing(); - - /** - * Set hint text to be displayed to the user. This should provide - * a description of the choice being made. - * @param hintText Hint text to set. - */ - public void setPromptText(CharSequence hintText); - public CharSequence getHintText(); - } - - /* - private class DialogPopup implements SpinnerPopup, DialogInterface.OnClickListener { - private AlertDialog mPopup; - private ListAdapter mListAdapter; - private CharSequence mPrompt; - - public void dismiss() { - mPopup.dismiss(); - mPopup = null; - } - - public boolean isShowing() { - return mPopup != null ? mPopup.isShowing() : false; - } - - public void setAdapter(ListAdapter adapter) { - mListAdapter = adapter; - } - - public void setPromptText(CharSequence hintText) { - mPrompt = hintText; - } - - public CharSequence getHintText() { - return mPrompt; - } - - public void show() { - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); - if (mPrompt != null) { - builder.setTitle(mPrompt); - } - mPopup = builder.setSingleChoiceItems(mListAdapter, - getSelectedItemPosition(), this).show(); - } - - public void onClick(DialogInterface dialog, int which) { - setSelection(which); - dismiss(); - } - } - */ - - private class DropdownPopup extends IcsListPopupWindow implements SpinnerPopup { - private CharSequence mHintText; - private ListAdapter mAdapter; - - public DropdownPopup(Context context, AttributeSet attrs, int defStyleRes) { - super(context, attrs, 0, defStyleRes); - - setAnchorView(IcsSpinner.this); - setModal(true); - setPromptPosition(POSITION_PROMPT_ABOVE); - setOnItemClickListener(new OnItemClickListener() { - @SuppressWarnings("rawtypes") - public void onItemClick(AdapterView parent, View v, int position, long id) { - IcsSpinner.this.setSelection(position); - dismiss(); - } - }); - } - - @Override - public void setAdapter(ListAdapter adapter) { - super.setAdapter(adapter); - mAdapter = adapter; - } - - public CharSequence getHintText() { - return mHintText; - } - - public void setPromptText(CharSequence hintText) { - // Hint text is ignored for dropdowns, but maintain it here. - mHintText = hintText; - } - - @Override - public void show() { - final int spinnerPaddingLeft = IcsSpinner.this.getPaddingLeft(); - if (mDropDownWidth == WRAP_CONTENT) { - final int spinnerWidth = IcsSpinner.this.getWidth(); - final int spinnerPaddingRight = IcsSpinner.this.getPaddingRight(); - setContentWidth(Math.max( - measureContentWidth((SpinnerAdapter) mAdapter, getBackground()), - spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight)); - } else if (mDropDownWidth == MATCH_PARENT) { - final int spinnerWidth = IcsSpinner.this.getWidth(); - final int spinnerPaddingRight = IcsSpinner.this.getPaddingRight(); - setContentWidth(spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight); - } else { - setContentWidth(mDropDownWidth); - } - final Drawable background = getBackground(); - int bgOffset = 0; - if (background != null) { - background.getPadding(mTempRect); - bgOffset = -mTempRect.left; - } - setHorizontalOffset(bgOffset + spinnerPaddingLeft); - setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); - super.show(); - getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); - setSelection(IcsSpinner.this.getSelectedItemPosition()); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsView.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsView.java deleted file mode 100644 index a7185d08..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsView.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import android.view.View; - -final class IcsView { - //No instances - private IcsView() {} - - /** - * Return only the state bits of {@link #getMeasuredWidthAndState()} - * and {@link #getMeasuredHeightAndState()}, combined into one integer. - * The width component is in the regular bits {@link #MEASURED_STATE_MASK} - * and the height component is at the shifted bits - * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}. - */ - public static int getMeasuredStateInt(View child) { - return (child.getMeasuredWidth()&View.MEASURED_STATE_MASK) - | ((child.getMeasuredHeight()>>View.MEASURED_HEIGHT_STATE_SHIFT) - & (View.MEASURED_STATE_MASK>>View.MEASURED_HEIGHT_STATE_SHIFT)); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java deleted file mode 100644 index 48fb5d8b..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.actionbarsherlock.internal.widget; - -import android.content.Context; -import android.content.res.Configuration; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.text.TextUtils.TruncateAt; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ListView; -import com.actionbarsherlock.R; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; -import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; -import com.actionbarsherlock.internal.nineoldandroids.widget.NineHorizontalScrollView; - -/** - * This widget implements the dynamic action bar tab behavior that can change - * across different configurations or circumstances. - */ -public class ScrollingTabContainerView extends NineHorizontalScrollView - implements IcsAdapterView.OnItemSelectedListener { - //UNUSED private static final String TAG = "ScrollingTabContainerView"; - Runnable mTabSelector; - private TabClickListener mTabClickListener; - - private IcsLinearLayout mTabLayout; - private IcsSpinner mTabSpinner; - private boolean mAllowCollapse; - - private LayoutInflater mInflater; - - int mMaxTabWidth; - private int mContentHeight; - private int mSelectedTabIndex; - - protected Animator mVisibilityAnim; - protected final VisibilityAnimListener mVisAnimListener = new VisibilityAnimListener(); - - private static final /*Time*/Interpolator sAlphaInterpolator = new DecelerateInterpolator(); - - private static final int FADE_DURATION = 200; - - public ScrollingTabContainerView(Context context) { - super(context); - setHorizontalScrollBarEnabled(false); - - TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.SherlockActionBar, - R.attr.actionBarStyle, 0); - setContentHeight(a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0)); - a.recycle(); - - mInflater = LayoutInflater.from(context); - - mTabLayout = createTabLayout(); - addView(mTabLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - } - - @Override - public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int widthMode = MeasureSpec.getMode(widthMeasureSpec); - final boolean lockedExpanded = widthMode == MeasureSpec.EXACTLY; - setFillViewport(lockedExpanded); - - final int childCount = mTabLayout.getChildCount(); - if (childCount > 1 && - (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)) { - if (childCount > 2) { - mMaxTabWidth = (int) (MeasureSpec.getSize(widthMeasureSpec) * 0.4f); - } else { - mMaxTabWidth = MeasureSpec.getSize(widthMeasureSpec) / 2; - } - } else { - mMaxTabWidth = -1; - } - - heightMeasureSpec = MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY); - - final boolean canCollapse = !lockedExpanded && mAllowCollapse; - - if (canCollapse) { - // See if we should expand - mTabLayout.measure(MeasureSpec.UNSPECIFIED, heightMeasureSpec); - if (mTabLayout.getMeasuredWidth() > MeasureSpec.getSize(widthMeasureSpec)) { - performCollapse(); - } else { - performExpand(); - } - } else { - performExpand(); - } - - final int oldWidth = getMeasuredWidth(); - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - final int newWidth = getMeasuredWidth(); - - if (lockedExpanded && oldWidth != newWidth) { - // Recenter the tab display if we're at a new (scrollable) size. - setTabSelected(mSelectedTabIndex); - } - } - - /** - * Indicates whether this view is collapsed into a dropdown menu instead - * of traditional tabs. - * @return true if showing as a spinner - */ - private boolean isCollapsed() { - return mTabSpinner != null && mTabSpinner.getParent() == this; - } - - public void setAllowCollapse(boolean allowCollapse) { - mAllowCollapse = allowCollapse; - } - - private void performCollapse() { - if (isCollapsed()) return; - - if (mTabSpinner == null) { - mTabSpinner = createSpinner(); - } - removeView(mTabLayout); - addView(mTabSpinner, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - if (mTabSpinner.getAdapter() == null) { - mTabSpinner.setAdapter(new TabAdapter()); - } - if (mTabSelector != null) { - removeCallbacks(mTabSelector); - mTabSelector = null; - } - mTabSpinner.setSelection(mSelectedTabIndex); - } - - private boolean performExpand() { - if (!isCollapsed()) return false; - - removeView(mTabSpinner); - addView(mTabLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - setTabSelected(mTabSpinner.getSelectedItemPosition()); - return false; - } - - public void setTabSelected(int position) { - mSelectedTabIndex = position; - final int tabCount = mTabLayout.getChildCount(); - for (int i = 0; i < tabCount; i++) { - final View child = mTabLayout.getChildAt(i); - final boolean isSelected = i == position; - child.setSelected(isSelected); - if (isSelected) { - animateToTab(position); - } - } - } - - public void setContentHeight(int contentHeight) { - mContentHeight = contentHeight; - requestLayout(); - } - - private IcsLinearLayout createTabLayout() { - final IcsLinearLayout tabLayout = (IcsLinearLayout) LayoutInflater.from(getContext()) - .inflate(R.layout.abs__action_bar_tab_bar_view, null); - tabLayout.setMeasureWithLargestChildEnabled(true); - tabLayout.setLayoutParams(new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)); - return tabLayout; - } - - private IcsSpinner createSpinner() { - final IcsSpinner spinner = new IcsSpinner(getContext(), null, - R.attr.actionDropDownStyle); - spinner.setLayoutParams(new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)); - spinner.setOnItemSelectedListener(this); - return spinner; - } - - @Override - protected void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - // Action bar can change size on configuration changes. - // Reread the desired height from the theme-specified style. - TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.SherlockActionBar, - R.attr.actionBarStyle, 0); - setContentHeight(a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0)); - a.recycle(); - } - - public void animateToVisibility(int visibility) { - if (mVisibilityAnim != null) { - mVisibilityAnim.cancel(); - } - if (visibility == VISIBLE) { - if (getVisibility() != VISIBLE) { - setAlpha(0); - } - ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 1); - anim.setDuration(FADE_DURATION); - anim.setInterpolator(sAlphaInterpolator); - - anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); - anim.start(); - } else { - ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 0); - anim.setDuration(FADE_DURATION); - anim.setInterpolator(sAlphaInterpolator); - - anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); - anim.start(); - } - } - - public void animateToTab(final int position) { - final View tabView = mTabLayout.getChildAt(position); - if (mTabSelector != null) { - removeCallbacks(mTabSelector); - } - mTabSelector = new Runnable() { - public void run() { - final int scrollPos = tabView.getLeft() - (getWidth() - tabView.getWidth()) / 2; - smoothScrollTo(scrollPos, 0); - mTabSelector = null; - } - }; - post(mTabSelector); - } - - @Override - public void onAttachedToWindow() { - super.onAttachedToWindow(); - if (mTabSelector != null) { - // Re-post the selector we saved - post(mTabSelector); - } - } - - @Override - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - if (mTabSelector != null) { - removeCallbacks(mTabSelector); - } - } - - private TabView createTabView(ActionBar.Tab tab, boolean forAdapter) { - //Workaround for not being able to pass a defStyle on pre-3.0 - final TabView tabView = (TabView)mInflater.inflate(R.layout.abs__action_bar_tab, null); - tabView.init(this, tab, forAdapter); - - if (forAdapter) { - tabView.setBackgroundDrawable(null); - tabView.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, - mContentHeight)); - } else { - tabView.setFocusable(true); - - if (mTabClickListener == null) { - mTabClickListener = new TabClickListener(); - } - tabView.setOnClickListener(mTabClickListener); - } - return tabView; - } - - public void addTab(ActionBar.Tab tab, boolean setSelected) { - TabView tabView = createTabView(tab, false); - mTabLayout.addView(tabView, new IcsLinearLayout.LayoutParams(0, - LayoutParams.MATCH_PARENT, 1)); - if (mTabSpinner != null) { - ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); - } - if (setSelected) { - tabView.setSelected(true); - } - if (mAllowCollapse) { - requestLayout(); - } - } - - public void addTab(ActionBar.Tab tab, int position, boolean setSelected) { - final TabView tabView = createTabView(tab, false); - mTabLayout.addView(tabView, position, new IcsLinearLayout.LayoutParams( - 0, LayoutParams.MATCH_PARENT, 1)); - if (mTabSpinner != null) { - ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); - } - if (setSelected) { - tabView.setSelected(true); - } - if (mAllowCollapse) { - requestLayout(); - } - } - - public void updateTab(int position) { - ((TabView) mTabLayout.getChildAt(position)).update(); - if (mTabSpinner != null) { - ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); - } - if (mAllowCollapse) { - requestLayout(); - } - } - - public void removeTabAt(int position) { - mTabLayout.removeViewAt(position); - if (mTabSpinner != null) { - ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); - } - if (mAllowCollapse) { - requestLayout(); - } - } - - public void removeAllTabs() { - mTabLayout.removeAllViews(); - if (mTabSpinner != null) { - ((TabAdapter) mTabSpinner.getAdapter()).notifyDataSetChanged(); - } - if (mAllowCollapse) { - requestLayout(); - } - } - - @Override - public void onItemSelected(IcsAdapterView parent, View view, int position, long id) { - TabView tabView = (TabView) view; - tabView.getTab().select(); - } - - @Override - public void onNothingSelected(IcsAdapterView parent) { - } - - public static class TabView extends LinearLayout { - private ScrollingTabContainerView mParent; - private ActionBar.Tab mTab; - private CapitalizingTextView mTextView; - private ImageView mIconView; - private View mCustomView; - - public TabView(Context context, AttributeSet attrs) { - //TODO super(context, null, R.attr.actionBarTabStyle); - super(context, attrs); - } - - public void init(ScrollingTabContainerView parent, ActionBar.Tab tab, boolean forList) { - mParent = parent; - mTab = tab; - - if (forList) { - setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); - } - - update(); - } - - public void bindTab(ActionBar.Tab tab) { - mTab = tab; - update(); - } - - @Override - public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - // Re-measure if we went beyond our maximum size. - if (mParent.mMaxTabWidth > 0 && getMeasuredWidth() > mParent.mMaxTabWidth) { - super.onMeasure(MeasureSpec.makeMeasureSpec(mParent.mMaxTabWidth, MeasureSpec.EXACTLY), - heightMeasureSpec); - } - } - - public void update() { - final ActionBar.Tab tab = mTab; - final View custom = tab.getCustomView(); - if (custom != null) { - final ViewParent customParent = custom.getParent(); - if (customParent != this) { - if (customParent != null) ((ViewGroup) customParent).removeView(custom); - addView(custom); - } - mCustomView = custom; - if (mTextView != null) mTextView.setVisibility(GONE); - if (mIconView != null) { - mIconView.setVisibility(GONE); - mIconView.setImageDrawable(null); - } - } else { - if (mCustomView != null) { - removeView(mCustomView); - mCustomView = null; - } - - final Drawable icon = tab.getIcon(); - final CharSequence text = tab.getText(); - - if (icon != null) { - if (mIconView == null) { - ImageView iconView = new ImageView(getContext()); - LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT); - lp.gravity = Gravity.CENTER_VERTICAL; - iconView.setLayoutParams(lp); - addView(iconView, 0); - mIconView = iconView; - } - mIconView.setImageDrawable(icon); - mIconView.setVisibility(VISIBLE); - } else if (mIconView != null) { - mIconView.setVisibility(GONE); - mIconView.setImageDrawable(null); - } - - if (text != null) { - if (mTextView == null) { - CapitalizingTextView textView = new CapitalizingTextView(getContext(), null, - R.attr.actionBarTabTextStyle); - textView.setEllipsize(TruncateAt.END); - LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, - LayoutParams.WRAP_CONTENT); - lp.gravity = Gravity.CENTER_VERTICAL; - textView.setLayoutParams(lp); - addView(textView); - mTextView = textView; - } - mTextView.setTextCompat(text); - mTextView.setVisibility(VISIBLE); - } else if (mTextView != null) { - mTextView.setVisibility(GONE); - mTextView.setText(null); - } - - if (mIconView != null) { - mIconView.setContentDescription(tab.getContentDescription()); - } - } - } - - public ActionBar.Tab getTab() { - return mTab; - } - } - - private class TabAdapter extends BaseAdapter { - @Override - public int getCount() { - return mTabLayout.getChildCount(); - } - - @Override - public Object getItem(int position) { - return ((TabView) mTabLayout.getChildAt(position)).getTab(); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - if (convertView == null) { - convertView = createTabView((ActionBar.Tab) getItem(position), true); - } else { - ((TabView) convertView).bindTab((ActionBar.Tab) getItem(position)); - } - return convertView; - } - } - - private class TabClickListener implements OnClickListener { - public void onClick(View view) { - TabView tabView = (TabView) view; - tabView.getTab().select(); - final int tabCount = mTabLayout.getChildCount(); - for (int i = 0; i < tabCount; i++) { - final View child = mTabLayout.getChildAt(i); - child.setSelected(child == view); - } - } - } - - protected class VisibilityAnimListener implements Animator.AnimatorListener { - private boolean mCanceled = false; - private int mFinalVisibility; - - public VisibilityAnimListener withFinalVisibility(int visibility) { - mFinalVisibility = visibility; - return this; - } - - @Override - public void onAnimationStart(Animator animation) { - setVisibility(VISIBLE); - mVisibilityAnim = animation; - mCanceled = false; - } - - @Override - public void onAnimationEnd(Animator animation) { - if (mCanceled) return; - - mVisibilityAnim = null; - setVisibility(mFinalVisibility); - } - - @Override - public void onAnimationCancel(Animator animation) { - mCanceled = true; - } - - @Override - public void onAnimationRepeat(Animator animation) { - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/ActionMode.java b/actionbarsherlock/src/com/actionbarsherlock/view/ActionMode.java deleted file mode 100644 index 81b4cd4d..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/view/ActionMode.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import android.view.View; - - -/** - * Represents a contextual mode of the user interface. Action modes can be used for - * modal interactions with content and replace parts of the normal UI until finished. - * Examples of good action modes include selection modes, search, content editing, etc. - */ -public abstract class ActionMode { - private Object mTag; - - /** - * Set a tag object associated with this ActionMode. - * - *

Like the tag available to views, this allows applications to associate arbitrary - * data with an ActionMode for later reference. - * - * @param tag Tag to associate with this ActionMode - * - * @see #getTag() - */ - public void setTag(Object tag) { - mTag = tag; - } - - /** - * Retrieve the tag object associated with this ActionMode. - * - *

Like the tag available to views, this allows applications to associate arbitrary - * data with an ActionMode for later reference. - * - * @return Tag associated with this ActionMode - * - * @see #setTag(Object) - */ - public Object getTag() { - return mTag; - } - - /** - * Set the title of the action mode. This method will have no visible effect if - * a custom view has been set. - * - * @param title Title string to set - * - * @see #setTitle(int) - * @see #setCustomView(View) - */ - public abstract void setTitle(CharSequence title); - - /** - * Set the title of the action mode. This method will have no visible effect if - * a custom view has been set. - * - * @param resId Resource ID of a string to set as the title - * - * @see #setTitle(CharSequence) - * @see #setCustomView(View) - */ - public abstract void setTitle(int resId); - - /** - * Set the subtitle of the action mode. This method will have no visible effect if - * a custom view has been set. - * - * @param subtitle Subtitle string to set - * - * @see #setSubtitle(int) - * @see #setCustomView(View) - */ - public abstract void setSubtitle(CharSequence subtitle); - - /** - * Set the subtitle of the action mode. This method will have no visible effect if - * a custom view has been set. - * - * @param resId Resource ID of a string to set as the subtitle - * - * @see #setSubtitle(CharSequence) - * @see #setCustomView(View) - */ - public abstract void setSubtitle(int resId); - - /** - * Set a custom view for this action mode. The custom view will take the place of - * the title and subtitle. Useful for things like search boxes. - * - * @param view Custom view to use in place of the title/subtitle. - * - * @see #setTitle(CharSequence) - * @see #setSubtitle(CharSequence) - */ - public abstract void setCustomView(View view); - - /** - * Invalidate the action mode and refresh menu content. The mode's - * {@link ActionMode.Callback} will have its - * {@link Callback#onPrepareActionMode(ActionMode, Menu)} method called. - * If it returns true the menu will be scanned for updated content and any relevant changes - * will be reflected to the user. - */ - public abstract void invalidate(); - - /** - * Finish and close this action mode. The action mode's {@link ActionMode.Callback} will - * have its {@link Callback#onDestroyActionMode(ActionMode)} method called. - */ - public abstract void finish(); - - /** - * Returns the menu of actions that this action mode presents. - * @return The action mode's menu. - */ - public abstract Menu getMenu(); - - /** - * Returns the current title of this action mode. - * @return Title text - */ - public abstract CharSequence getTitle(); - - /** - * Returns the current subtitle of this action mode. - * @return Subtitle text - */ - public abstract CharSequence getSubtitle(); - - /** - * Returns the current custom view for this action mode. - * @return The current custom view - */ - public abstract View getCustomView(); - - /** - * Returns a {@link MenuInflater} with the ActionMode's context. - */ - public abstract MenuInflater getMenuInflater(); - - /** - * Returns whether the UI presenting this action mode can take focus or not. - * This is used by internal components within the framework that would otherwise - * present an action mode UI that requires focus, such as an EditText as a custom view. - * - * @return true if the UI used to show this action mode can take focus - * @hide Internal use only - */ - public boolean isUiFocusable() { - return true; - } - - /** - * Callback interface for action modes. Supplied to - * {@link View#startActionMode(Callback)}, a Callback - * configures and handles events raised by a user's interaction with an action mode. - * - *

An action mode's lifecycle is as follows: - *

    - *
  • {@link Callback#onCreateActionMode(ActionMode, Menu)} once on initial - * creation
  • - *
  • {@link Callback#onPrepareActionMode(ActionMode, Menu)} after creation - * and any time the {@link ActionMode} is invalidated
  • - *
  • {@link Callback#onActionItemClicked(ActionMode, MenuItem)} any time a - * contextual action button is clicked
  • - *
  • {@link Callback#onDestroyActionMode(ActionMode)} when the action mode - * is closed
  • - *
- */ - public interface Callback { - /** - * Called when action mode is first created. The menu supplied will be used to - * generate action buttons for the action mode. - * - * @param mode ActionMode being created - * @param menu Menu used to populate action buttons - * @return true if the action mode should be created, false if entering this - * mode should be aborted. - */ - public boolean onCreateActionMode(ActionMode mode, Menu menu); - - /** - * Called to refresh an action mode's action menu whenever it is invalidated. - * - * @param mode ActionMode being prepared - * @param menu Menu used to populate action buttons - * @return true if the menu or action mode was updated, false otherwise. - */ - public boolean onPrepareActionMode(ActionMode mode, Menu menu); - - /** - * Called to report a user click on an action button. - * - * @param mode The current ActionMode - * @param item The item that was clicked - * @return true if this callback handled the event, false if the standard MenuItem - * invocation should continue. - */ - public boolean onActionItemClicked(ActionMode mode, MenuItem item); - - /** - * Called when an action mode is about to be exited and destroyed. - * - * @param mode The current ActionMode being destroyed - */ - public void onDestroyActionMode(ActionMode mode); - } -} \ No newline at end of file diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/ActionProvider.java b/actionbarsherlock/src/com/actionbarsherlock/view/ActionProvider.java deleted file mode 100644 index ae7cb1fe..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/view/ActionProvider.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import android.content.Context; -import android.view.View; - -/** - * This class is a mediator for accomplishing a given task, for example sharing a file. - * It is responsible for creating a view that performs an action that accomplishes the task. - * This class also implements other functions such a performing a default action. - *

- * An ActionProvider can be optionally specified for a {@link MenuItem} and in such a - * case it will be responsible for creating the action view that appears in the - * {@link android.app.ActionBar} as a substitute for the menu item when the item is - * displayed as an action item. Also the provider is responsible for performing a - * default action if a menu item placed on the overflow menu of the ActionBar is - * selected and none of the menu item callbacks has handled the selection. For this - * case the provider can also optionally provide a sub-menu for accomplishing the - * task at hand. - *

- *

- * There are two ways for using an action provider for creating and handling of action views: - *

    - *
  • - * Setting the action provider on a {@link MenuItem} directly by calling - * {@link MenuItem#setActionProvider(ActionProvider)}. - *
  • - *
  • - * Declaring the action provider in the menu XML resource. For example: - *
    - * 
    - *   <item android:id="@+id/my_menu_item"
    - *     android:title="Title"
    - *     android:icon="@drawable/my_menu_item_icon"
    - *     android:showAsAction="ifRoom"
    - *     android:actionProviderClass="foo.bar.SomeActionProvider" />
    - * 
    - * 
    - *
  • - *
- *

- * - * @see MenuItem#setActionProvider(ActionProvider) - * @see MenuItem#getActionProvider() - */ -public abstract class ActionProvider { - private SubUiVisibilityListener mSubUiVisibilityListener; - - /** - * Creates a new instance. - * - * @param context Context for accessing resources. - */ - public ActionProvider(Context context) { - } - - /** - * Factory method for creating new action views. - * - * @return A new action view. - */ - public abstract View onCreateActionView(); - - /** - * Performs an optional default action. - *

- * For the case of an action provider placed in a menu item not shown as an action this - * method is invoked if previous callbacks for processing menu selection has handled - * the event. - *

- *

- * A menu item selection is processed in the following order: - *

    - *
  • - * Receiving a call to {@link MenuItem.OnMenuItemClickListener#onMenuItemClick - * MenuItem.OnMenuItemClickListener.onMenuItemClick}. - *
  • - *
  • - * Receiving a call to {@link android.app.Activity#onOptionsItemSelected(MenuItem) - * Activity.onOptionsItemSelected(MenuItem)} - *
  • - *
  • - * Receiving a call to {@link android.app.Fragment#onOptionsItemSelected(MenuItem) - * Fragment.onOptionsItemSelected(MenuItem)} - *
  • - *
  • - * Launching the {@link android.content.Intent} set via - * {@link MenuItem#setIntent(android.content.Intent) MenuItem.setIntent(android.content.Intent)} - *
  • - *
  • - * Invoking this method. - *
  • - *
- *

- *

- * The default implementation does not perform any action and returns false. - *

- */ - public boolean onPerformDefaultAction() { - return false; - } - - /** - * Determines if this ActionProvider has a submenu associated with it. - * - *

Associated submenus will be shown when an action view is not. This - * provider instance will receive a call to {@link #onPrepareSubMenu(SubMenu)} - * after the call to {@link #onPerformDefaultAction()} and before a submenu is - * displayed to the user. - * - * @return true if the item backed by this provider should have an associated submenu - */ - public boolean hasSubMenu() { - return false; - } - - /** - * Called to prepare an associated submenu for the menu item backed by this ActionProvider. - * - *

if {@link #hasSubMenu()} returns true, this method will be called when the - * menu item is selected to prepare the submenu for presentation to the user. Apps - * may use this to create or alter submenu content right before display. - * - * @param subMenu Submenu that will be displayed - */ - public void onPrepareSubMenu(SubMenu subMenu) { - } - - /** - * Notify the system that the visibility of an action view's sub-UI such as - * an anchored popup has changed. This will affect how other system - * visibility notifications occur. - * - * @hide Pending future API approval - */ - public void subUiVisibilityChanged(boolean isVisible) { - if (mSubUiVisibilityListener != null) { - mSubUiVisibilityListener.onSubUiVisibilityChanged(isVisible); - } - } - - /** - * @hide Internal use only - */ - public void setSubUiVisibilityListener(SubUiVisibilityListener listener) { - mSubUiVisibilityListener = listener; - } - - /** - * @hide Internal use only - */ - public interface SubUiVisibilityListener { - public void onSubUiVisibilityChanged(boolean isVisible); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/CollapsibleActionView.java b/actionbarsherlock/src/com/actionbarsherlock/view/CollapsibleActionView.java deleted file mode 100644 index 43281b01..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/view/CollapsibleActionView.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -/** - * When a {@link View} implements this interface it will receive callbacks - * when expanded or collapsed as an action view alongside the optional, - * app-specified callbacks to {@link OnActionExpandListener}. - * - *

See {@link MenuItem} for more information about action views. - * See {@link android.app.ActionBar} for more information about the action bar. - */ -public interface CollapsibleActionView { - /** - * Called when this view is expanded as an action view. - * See {@link MenuItem#expandActionView()}. - */ - public void onActionViewExpanded(); - - /** - * Called when this view is collapsed as an action view. - * See {@link MenuItem#collapseActionView()}. - */ - public void onActionViewCollapsed(); -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/Menu.java b/actionbarsherlock/src/com/actionbarsherlock/view/Menu.java deleted file mode 100644 index 951f4cce..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/view/Menu.java +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import android.content.ComponentName; -import android.content.Intent; -import android.view.KeyEvent; - -/** - * Interface for managing the items in a menu. - *

- * By default, every Activity supports an options menu of actions or options. - * You can add items to this menu and handle clicks on your additions. The - * easiest way of adding menu items is inflating an XML file into the - * {@link Menu} via {@link MenuInflater}. The easiest way of attaching code to - * clicks is via {@link Activity#onOptionsItemSelected(MenuItem)} and - * {@link Activity#onContextItemSelected(MenuItem)}. - *

- * Different menu types support different features: - *

    - *
  1. Context menus: Do not support item shortcuts and item icons. - *
  2. Options menus: The icon menus do not support item check - * marks and only show the item's - * {@link MenuItem#setTitleCondensed(CharSequence) condensed title}. The - * expanded menus (only available if six or more menu items are visible, - * reached via the 'More' item in the icon menu) do not show item icons, and - * item check marks are discouraged. - *
  3. Sub menus: Do not support item icons, or nested sub menus. - *
- * - *
- *

Developer Guides

- *

For more information about creating menus, read the - * Menus developer guide.

- *
- */ -public interface Menu { - - /** - * This is the part of an order integer that the user can provide. - * @hide - */ - static final int USER_MASK = 0x0000ffff; - /** - * Bit shift of the user portion of the order integer. - * @hide - */ - static final int USER_SHIFT = 0; - - /** - * This is the part of an order integer that supplies the category of the - * item. - * @hide - */ - static final int CATEGORY_MASK = 0xffff0000; - /** - * Bit shift of the category portion of the order integer. - * @hide - */ - static final int CATEGORY_SHIFT = 16; - - /** - * Value to use for group and item identifier integers when you don't care - * about them. - */ - static final int NONE = 0; - - /** - * First value for group and item identifier integers. - */ - static final int FIRST = 1; - - // Implementation note: Keep these CATEGORY_* in sync with the category enum - // in attrs.xml - - /** - * Category code for the order integer for items/groups that are part of a - * container -- or/add this with your base value. - */ - static final int CATEGORY_CONTAINER = 0x00010000; - - /** - * Category code for the order integer for items/groups that are provided by - * the system -- or/add this with your base value. - */ - static final int CATEGORY_SYSTEM = 0x00020000; - - /** - * Category code for the order integer for items/groups that are - * user-supplied secondary (infrequently used) options -- or/add this with - * your base value. - */ - static final int CATEGORY_SECONDARY = 0x00030000; - - /** - * Category code for the order integer for items/groups that are - * alternative actions on the data that is currently displayed -- or/add - * this with your base value. - */ - static final int CATEGORY_ALTERNATIVE = 0x00040000; - - /** - * Flag for {@link #addIntentOptions}: if set, do not automatically remove - * any existing menu items in the same group. - */ - static final int FLAG_APPEND_TO_GROUP = 0x0001; - - /** - * Flag for {@link #performShortcut}: if set, do not close the menu after - * executing the shortcut. - */ - static final int FLAG_PERFORM_NO_CLOSE = 0x0001; - - /** - * Flag for {@link #performShortcut(int, KeyEvent, int)}: if set, always - * close the menu after executing the shortcut. Closing the menu also resets - * the prepared state. - */ - static final int FLAG_ALWAYS_PERFORM_CLOSE = 0x0002; - - /** - * Add a new item to the menu. This item displays the given title for its - * label. - * - * @param title The text to display for the item. - * @return The newly added menu item. - */ - public MenuItem add(CharSequence title); - - /** - * Add a new item to the menu. This item displays the given title for its - * label. - * - * @param titleRes Resource identifier of title string. - * @return The newly added menu item. - */ - public MenuItem add(int titleRes); - - /** - * Add a new item to the menu. This item displays the given title for its - * label. - * - * @param groupId The group identifier that this item should be part of. - * This can be used to define groups of items for batch state - * changes. Normally use {@link #NONE} if an item should not be in a - * group. - * @param itemId Unique item ID. Use {@link #NONE} if you do not need a - * unique ID. - * @param order The order for the item. Use {@link #NONE} if you do not care - * about the order. See {@link MenuItem#getOrder()}. - * @param title The text to display for the item. - * @return The newly added menu item. - */ - public MenuItem add(int groupId, int itemId, int order, CharSequence title); - - /** - * Variation on {@link #add(int, int, int, CharSequence)} that takes a - * string resource identifier instead of the string itself. - * - * @param groupId The group identifier that this item should be part of. - * This can also be used to define groups of items for batch state - * changes. Normally use {@link #NONE} if an item should not be in a - * group. - * @param itemId Unique item ID. Use {@link #NONE} if you do not need a - * unique ID. - * @param order The order for the item. Use {@link #NONE} if you do not care - * about the order. See {@link MenuItem#getOrder()}. - * @param titleRes Resource identifier of title string. - * @return The newly added menu item. - */ - public MenuItem add(int groupId, int itemId, int order, int titleRes); - - /** - * Add a new sub-menu to the menu. This item displays the given title for - * its label. To modify other attributes on the submenu's menu item, use - * {@link SubMenu#getItem()}. - * - * @param title The text to display for the item. - * @return The newly added sub-menu - */ - SubMenu addSubMenu(final CharSequence title); - - /** - * Add a new sub-menu to the menu. This item displays the given title for - * its label. To modify other attributes on the submenu's menu item, use - * {@link SubMenu#getItem()}. - * - * @param titleRes Resource identifier of title string. - * @return The newly added sub-menu - */ - SubMenu addSubMenu(final int titleRes); - - /** - * Add a new sub-menu to the menu. This item displays the given - * title for its label. To modify other attributes on the - * submenu's menu item, use {@link SubMenu#getItem()}. - *

- * Note that you can only have one level of sub-menus, i.e. you cannnot add - * a subMenu to a subMenu: An {@link UnsupportedOperationException} will be - * thrown if you try. - * - * @param groupId The group identifier that this item should be part of. - * This can also be used to define groups of items for batch state - * changes. Normally use {@link #NONE} if an item should not be in a - * group. - * @param itemId Unique item ID. Use {@link #NONE} if you do not need a - * unique ID. - * @param order The order for the item. Use {@link #NONE} if you do not care - * about the order. See {@link MenuItem#getOrder()}. - * @param title The text to display for the item. - * @return The newly added sub-menu - */ - SubMenu addSubMenu(final int groupId, final int itemId, int order, final CharSequence title); - - /** - * Variation on {@link #addSubMenu(int, int, int, CharSequence)} that takes - * a string resource identifier for the title instead of the string itself. - * - * @param groupId The group identifier that this item should be part of. - * This can also be used to define groups of items for batch state - * changes. Normally use {@link #NONE} if an item should not be in a group. - * @param itemId Unique item ID. Use {@link #NONE} if you do not need a unique ID. - * @param order The order for the item. Use {@link #NONE} if you do not care about the - * order. See {@link MenuItem#getOrder()}. - * @param titleRes Resource identifier of title string. - * @return The newly added sub-menu - */ - SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes); - - /** - * Add a group of menu items corresponding to actions that can be performed - * for a particular Intent. The Intent is most often configured with a null - * action, the data that the current activity is working with, and includes - * either the {@link Intent#CATEGORY_ALTERNATIVE} or - * {@link Intent#CATEGORY_SELECTED_ALTERNATIVE} to find activities that have - * said they would like to be included as optional action. You can, however, - * use any Intent you want. - * - *

- * See {@link android.content.pm.PackageManager#queryIntentActivityOptions} - * for more * details on the caller, specifics, and - * intent arguments. The list returned by that function is used - * to populate the resulting menu items. - * - *

- * All of the menu items of possible options for the intent will be added - * with the given group and id. You can use the group to control ordering of - * the items in relation to other items in the menu. Normally this function - * will automatically remove any existing items in the menu in the same - * group and place a divider above and below the added items; this behavior - * can be modified with the flags parameter. For each of the - * generated items {@link MenuItem#setIntent} is called to associate the - * appropriate Intent with the item; this means the activity will - * automatically be started for you without having to do anything else. - * - * @param groupId The group identifier that the items should be part of. - * This can also be used to define groups of items for batch state - * changes. Normally use {@link #NONE} if the items should not be in - * a group. - * @param itemId Unique item ID. Use {@link #NONE} if you do not need a - * unique ID. - * @param order The order for the items. Use {@link #NONE} if you do not - * care about the order. See {@link MenuItem#getOrder()}. - * @param caller The current activity component name as defined by - * queryIntentActivityOptions(). - * @param specifics Specific items to place first as defined by - * queryIntentActivityOptions(). - * @param intent Intent describing the kinds of items to populate in the - * list as defined by queryIntentActivityOptions(). - * @param flags Additional options controlling how the items are added. - * @param outSpecificItems Optional array in which to place the menu items - * that were generated for each of the specifics that were - * requested. Entries may be null if no activity was found for that - * specific action. - * @return The number of menu items that were added. - * - * @see #FLAG_APPEND_TO_GROUP - * @see MenuItem#setIntent - * @see android.content.pm.PackageManager#queryIntentActivityOptions - */ - public int addIntentOptions(int groupId, int itemId, int order, - ComponentName caller, Intent[] specifics, - Intent intent, int flags, MenuItem[] outSpecificItems); - - /** - * Remove the item with the given identifier. - * - * @param id The item to be removed. If there is no item with this - * identifier, nothing happens. - */ - public void removeItem(int id); - - /** - * Remove all items in the given group. - * - * @param groupId The group to be removed. If there are no items in this - * group, nothing happens. - */ - public void removeGroup(int groupId); - - /** - * Remove all existing items from the menu, leaving it empty as if it had - * just been created. - */ - public void clear(); - - /** - * Control whether a particular group of items can show a check mark. This - * is similar to calling {@link MenuItem#setCheckable} on all of the menu items - * with the given group identifier, but in addition you can control whether - * this group contains a mutually-exclusive set items. This should be called - * after the items of the group have been added to the menu. - * - * @param group The group of items to operate on. - * @param checkable Set to true to allow a check mark, false to - * disallow. The default is false. - * @param exclusive If set to true, only one item in this group can be - * checked at a time; checking an item will automatically - * uncheck all others in the group. If set to false, each - * item can be checked independently of the others. - * - * @see MenuItem#setCheckable - * @see MenuItem#setChecked - */ - public void setGroupCheckable(int group, boolean checkable, boolean exclusive); - - /** - * Show or hide all menu items that are in the given group. - * - * @param group The group of items to operate on. - * @param visible If true the items are visible, else they are hidden. - * - * @see MenuItem#setVisible - */ - public void setGroupVisible(int group, boolean visible); - - /** - * Enable or disable all menu items that are in the given group. - * - * @param group The group of items to operate on. - * @param enabled If true the items will be enabled, else they will be disabled. - * - * @see MenuItem#setEnabled - */ - public void setGroupEnabled(int group, boolean enabled); - - /** - * Return whether the menu currently has item items that are visible. - * - * @return True if there is one or more item visible, - * else false. - */ - public boolean hasVisibleItems(); - - /** - * Return the menu item with a particular identifier. - * - * @param id The identifier to find. - * - * @return The menu item object, or null if there is no item with - * this identifier. - */ - public MenuItem findItem(int id); - - /** - * Get the number of items in the menu. Note that this will change any - * times items are added or removed from the menu. - * - * @return The item count. - */ - public int size(); - - /** - * Gets the menu item at the given index. - * - * @param index The index of the menu item to return. - * @return The menu item. - * @exception IndexOutOfBoundsException - * when {@code index < 0 || >= size()} - */ - public MenuItem getItem(int index); - - /** - * Closes the menu, if open. - */ - public void close(); - - /** - * Execute the menu item action associated with the given shortcut - * character. - * - * @param keyCode The keycode of the shortcut key. - * @param event Key event message. - * @param flags Additional option flags or 0. - * - * @return If the given shortcut exists and is shown, returns - * true; else returns false. - * - * @see #FLAG_PERFORM_NO_CLOSE - */ - public boolean performShortcut(int keyCode, KeyEvent event, int flags); - - /** - * Is a keypress one of the defined shortcut keys for this window. - * @param keyCode the key code from {@link KeyEvent} to check. - * @param event the {@link KeyEvent} to use to help check. - */ - boolean isShortcutKey(int keyCode, KeyEvent event); - - /** - * Execute the menu item action associated with the given menu identifier. - * - * @param id Identifier associated with the menu item. - * @param flags Additional option flags or 0. - * - * @return If the given identifier exists and is shown, returns - * true; else returns false. - * - * @see #FLAG_PERFORM_NO_CLOSE - */ - public boolean performIdentifierAction(int id, int flags); - - - /** - * Control whether the menu should be running in qwerty mode (alphabetic - * shortcuts) or 12-key mode (numeric shortcuts). - * - * @param isQwerty If true the menu will use alphabetic shortcuts; else it - * will use numeric shortcuts. - */ - public void setQwertyMode(boolean isQwerty); -} - diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/MenuInflater.java b/actionbarsherlock/src/com/actionbarsherlock/view/MenuInflater.java deleted file mode 100644 index 5a0f4085..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/view/MenuInflater.java +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * 2011 Jake Wharton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import android.content.Context; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.util.AttributeSet; -import android.util.Log; -import android.util.TypedValue; -import android.util.Xml; -import android.view.InflateException; -import android.view.View; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.view.menu.MenuItemImpl; - -/** - * This class is used to instantiate menu XML files into Menu objects. - *

- * For performance reasons, menu inflation relies heavily on pre-processing of - * XML files that is done at build time. Therefore, it is not currently possible - * to use MenuInflater with an XmlPullParser over a plain XML file at runtime; - * it only works with an XmlPullParser returned from a compiled resource (R. - * something file.) - */ -public class MenuInflater { - private static final String LOG_TAG = "MenuInflater"; - - /** Menu tag name in XML. */ - private static final String XML_MENU = "menu"; - - /** Group tag name in XML. */ - private static final String XML_GROUP = "group"; - - /** Item tag name in XML. */ - private static final String XML_ITEM = "item"; - - private static final int NO_ID = 0; - - private static final Class[] ACTION_VIEW_CONSTRUCTOR_SIGNATURE = new Class[] {Context.class}; - - private static final Class[] ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE = ACTION_VIEW_CONSTRUCTOR_SIGNATURE; - - private final Object[] mActionViewConstructorArguments; - - private final Object[] mActionProviderConstructorArguments; - - private Context mContext; - private Object mRealOwner; - - /** - * Constructs a menu inflater. - * - * @see Activity#getMenuInflater() - */ - public MenuInflater(Context context) { - mContext = context; - mRealOwner = context; - mActionViewConstructorArguments = new Object[] {context}; - mActionProviderConstructorArguments = mActionViewConstructorArguments; - } - - /** - * Constructs a menu inflater. - * - * @see Activity#getMenuInflater() - * @hide - */ - public MenuInflater(Context context, Object realOwner) { - mContext = context; - mRealOwner = realOwner; - mActionViewConstructorArguments = new Object[] {context}; - mActionProviderConstructorArguments = mActionViewConstructorArguments; - } - - /** - * Inflate a menu hierarchy from the specified XML resource. Throws - * {@link InflateException} if there is an error. - * - * @param menuRes Resource ID for an XML layout resource to load (e.g., - * R.menu.main_activity) - * @param menu The Menu to inflate into. The items and submenus will be - * added to this Menu. - */ - public void inflate(int menuRes, Menu menu) { - XmlResourceParser parser = null; - try { - parser = mContext.getResources().getLayout(menuRes); - AttributeSet attrs = Xml.asAttributeSet(parser); - - parseMenu(parser, attrs, menu); - } catch (XmlPullParserException e) { - throw new InflateException("Error inflating menu XML", e); - } catch (IOException e) { - throw new InflateException("Error inflating menu XML", e); - } finally { - if (parser != null) parser.close(); - } - } - - /** - * Called internally to fill the given menu. If a sub menu is seen, it will - * call this recursively. - */ - private void parseMenu(XmlPullParser parser, AttributeSet attrs, Menu menu) - throws XmlPullParserException, IOException { - MenuState menuState = new MenuState(menu); - - int eventType = parser.getEventType(); - String tagName; - boolean lookingForEndOfUnknownTag = false; - String unknownTagName = null; - - // This loop will skip to the menu start tag - do { - if (eventType == XmlPullParser.START_TAG) { - tagName = parser.getName(); - if (tagName.equals(XML_MENU)) { - // Go to next tag - eventType = parser.next(); - break; - } - - throw new RuntimeException("Expecting menu, got " + tagName); - } - eventType = parser.next(); - } while (eventType != XmlPullParser.END_DOCUMENT); - - boolean reachedEndOfMenu = false; - while (!reachedEndOfMenu) { - switch (eventType) { - case XmlPullParser.START_TAG: - if (lookingForEndOfUnknownTag) { - break; - } - - tagName = parser.getName(); - if (tagName.equals(XML_GROUP)) { - menuState.readGroup(attrs); - } else if (tagName.equals(XML_ITEM)) { - menuState.readItem(attrs); - } else if (tagName.equals(XML_MENU)) { - // A menu start tag denotes a submenu for an item - SubMenu subMenu = menuState.addSubMenuItem(); - - // Parse the submenu into returned SubMenu - parseMenu(parser, attrs, subMenu); - } else { - lookingForEndOfUnknownTag = true; - unknownTagName = tagName; - } - break; - - case XmlPullParser.END_TAG: - tagName = parser.getName(); - if (lookingForEndOfUnknownTag && tagName.equals(unknownTagName)) { - lookingForEndOfUnknownTag = false; - unknownTagName = null; - } else if (tagName.equals(XML_GROUP)) { - menuState.resetGroup(); - } else if (tagName.equals(XML_ITEM)) { - // Add the item if it hasn't been added (if the item was - // a submenu, it would have been added already) - if (!menuState.hasAddedItem()) { - if (menuState.itemActionProvider != null && - menuState.itemActionProvider.hasSubMenu()) { - menuState.addSubMenuItem(); - } else { - menuState.addItem(); - } - } - } else if (tagName.equals(XML_MENU)) { - reachedEndOfMenu = true; - } - break; - - case XmlPullParser.END_DOCUMENT: - throw new RuntimeException("Unexpected end of document"); - } - - eventType = parser.next(); - } - } - - private static class InflatedOnMenuItemClickListener - implements MenuItem.OnMenuItemClickListener { - private static final Class[] PARAM_TYPES = new Class[] { MenuItem.class }; - - private Object mRealOwner; - private Method mMethod; - - public InflatedOnMenuItemClickListener(Object realOwner, String methodName) { - mRealOwner = realOwner; - Class c = realOwner.getClass(); - try { - mMethod = c.getMethod(methodName, PARAM_TYPES); - } catch (Exception e) { - InflateException ex = new InflateException( - "Couldn't resolve menu item onClick handler " + methodName + - " in class " + c.getName()); - ex.initCause(e); - throw ex; - } - } - - public boolean onMenuItemClick(MenuItem item) { - try { - if (mMethod.getReturnType() == Boolean.TYPE) { - return (Boolean) mMethod.invoke(mRealOwner, item); - } else { - mMethod.invoke(mRealOwner, item); - return true; - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - /** - * State for the current menu. - *

- * Groups can not be nested unless there is another menu (which will have - * its state class). - */ - private class MenuState { - private Menu menu; - - /* - * Group state is set on items as they are added, allowing an item to - * override its group state. (As opposed to set on items at the group end tag.) - */ - private int groupId; - private int groupCategory; - private int groupOrder; - private int groupCheckable; - private boolean groupVisible; - private boolean groupEnabled; - - private boolean itemAdded; - private int itemId; - private int itemCategoryOrder; - private CharSequence itemTitle; - private CharSequence itemTitleCondensed; - private int itemIconResId; - private char itemAlphabeticShortcut; - private char itemNumericShortcut; - /** - * Sync to attrs.xml enum: - * - 0: none - * - 1: all - * - 2: exclusive - */ - private int itemCheckable; - private boolean itemChecked; - private boolean itemVisible; - private boolean itemEnabled; - - /** - * Sync to attrs.xml enum, values in MenuItem: - * - 0: never - * - 1: ifRoom - * - 2: always - * - -1: Safe sentinel for "no value". - */ - private int itemShowAsAction; - - private int itemActionViewLayout; - private String itemActionViewClassName; - private String itemActionProviderClassName; - - private String itemListenerMethodName; - - private ActionProvider itemActionProvider; - - private static final int defaultGroupId = NO_ID; - private static final int defaultItemId = NO_ID; - private static final int defaultItemCategory = 0; - private static final int defaultItemOrder = 0; - private static final int defaultItemCheckable = 0; - private static final boolean defaultItemChecked = false; - private static final boolean defaultItemVisible = true; - private static final boolean defaultItemEnabled = true; - - public MenuState(final Menu menu) { - this.menu = menu; - - resetGroup(); - } - - public void resetGroup() { - groupId = defaultGroupId; - groupCategory = defaultItemCategory; - groupOrder = defaultItemOrder; - groupCheckable = defaultItemCheckable; - groupVisible = defaultItemVisible; - groupEnabled = defaultItemEnabled; - } - - /** - * Called when the parser is pointing to a group tag. - */ - public void readGroup(AttributeSet attrs) { - TypedArray a = mContext.obtainStyledAttributes(attrs, - R.styleable.SherlockMenuGroup); - - groupId = a.getResourceId(R.styleable.SherlockMenuGroup_android_id, defaultGroupId); - groupCategory = a.getInt(R.styleable.SherlockMenuGroup_android_menuCategory, defaultItemCategory); - groupOrder = a.getInt(R.styleable.SherlockMenuGroup_android_orderInCategory, defaultItemOrder); - groupCheckable = a.getInt(R.styleable.SherlockMenuGroup_android_checkableBehavior, defaultItemCheckable); - groupVisible = a.getBoolean(R.styleable.SherlockMenuGroup_android_visible, defaultItemVisible); - groupEnabled = a.getBoolean(R.styleable.SherlockMenuGroup_android_enabled, defaultItemEnabled); - - a.recycle(); - } - - /** - * Called when the parser is pointing to an item tag. - */ - public void readItem(AttributeSet attrs) { - TypedArray a = mContext.obtainStyledAttributes(attrs, - R.styleable.SherlockMenuItem); - - // Inherit attributes from the group as default value - itemId = a.getResourceId(R.styleable.SherlockMenuItem_android_id, defaultItemId); - final int category = a.getInt(R.styleable.SherlockMenuItem_android_menuCategory, groupCategory); - final int order = a.getInt(R.styleable.SherlockMenuItem_android_orderInCategory, groupOrder); - itemCategoryOrder = (category & Menu.CATEGORY_MASK) | (order & Menu.USER_MASK); - itemTitle = a.getText(R.styleable.SherlockMenuItem_android_title); - itemTitleCondensed = a.getText(R.styleable.SherlockMenuItem_android_titleCondensed); - itemIconResId = a.getResourceId(R.styleable.SherlockMenuItem_android_icon, 0); - itemAlphabeticShortcut = - getShortcut(a.getString(R.styleable.SherlockMenuItem_android_alphabeticShortcut)); - itemNumericShortcut = - getShortcut(a.getString(R.styleable.SherlockMenuItem_android_numericShortcut)); - if (a.hasValue(R.styleable.SherlockMenuItem_android_checkable)) { - // Item has attribute checkable, use it - itemCheckable = a.getBoolean(R.styleable.SherlockMenuItem_android_checkable, false) ? 1 : 0; - } else { - // Item does not have attribute, use the group's (group can have one more state - // for checkable that represents the exclusive checkable) - itemCheckable = groupCheckable; - } - - itemChecked = a.getBoolean(R.styleable.SherlockMenuItem_android_checked, defaultItemChecked); - itemVisible = a.getBoolean(R.styleable.SherlockMenuItem_android_visible, groupVisible); - itemEnabled = a.getBoolean(R.styleable.SherlockMenuItem_android_enabled, groupEnabled); - - TypedValue value = new TypedValue(); - a.getValue(R.styleable.SherlockMenuItem_android_showAsAction, value); - itemShowAsAction = value.type == TypedValue.TYPE_INT_HEX ? value.data : -1; - - itemListenerMethodName = a.getString(R.styleable.SherlockMenuItem_android_onClick); - itemActionViewLayout = a.getResourceId(R.styleable.SherlockMenuItem_android_actionLayout, 0); - - // itemActionViewClassName = a.getString(R.styleable.SherlockMenuItem_android_actionViewClass); - value = new TypedValue(); - a.getValue(R.styleable.SherlockMenuItem_android_actionViewClass, value); - itemActionViewClassName = value.type == TypedValue.TYPE_STRING ? value.string.toString() : null; - - // itemActionProviderClassName = a.getString(R.styleable.SherlockMenuItem_android_actionProviderClass); - value = new TypedValue(); - a.getValue(R.styleable.SherlockMenuItem_android_actionProviderClass, value); - itemActionProviderClassName = value.type == TypedValue.TYPE_STRING ? value.string.toString() : null; - - final boolean hasActionProvider = itemActionProviderClassName != null; - if (hasActionProvider && itemActionViewLayout == 0 && itemActionViewClassName == null) { - itemActionProvider = newInstance(itemActionProviderClassName, - ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE, - mActionProviderConstructorArguments); - } else { - if (hasActionProvider) { - Log.w(LOG_TAG, "Ignoring attribute 'actionProviderClass'." - + " Action view already specified."); - } - itemActionProvider = null; - } - - a.recycle(); - - itemAdded = false; - } - - private char getShortcut(String shortcutString) { - if (shortcutString == null) { - return 0; - } else { - return shortcutString.charAt(0); - } - } - - private void setItem(MenuItem item) { - item.setChecked(itemChecked) - .setVisible(itemVisible) - .setEnabled(itemEnabled) - .setCheckable(itemCheckable >= 1) - .setTitleCondensed(itemTitleCondensed) - .setIcon(itemIconResId) - .setAlphabeticShortcut(itemAlphabeticShortcut) - .setNumericShortcut(itemNumericShortcut); - - if (itemShowAsAction >= 0) { - item.setShowAsAction(itemShowAsAction); - } - - if (itemListenerMethodName != null) { - if (mContext.isRestricted()) { - throw new IllegalStateException("The android:onClick attribute cannot " - + "be used within a restricted context"); - } - item.setOnMenuItemClickListener( - new InflatedOnMenuItemClickListener(mRealOwner, itemListenerMethodName)); - } - - if (itemCheckable >= 2) { - if (item instanceof MenuItemImpl) { - MenuItemImpl impl = (MenuItemImpl) item; - impl.setExclusiveCheckable(true); - } else { - menu.setGroupCheckable(groupId, true, true); - } - } - - boolean actionViewSpecified = false; - if (itemActionViewClassName != null) { - View actionView = (View) newInstance(itemActionViewClassName, - ACTION_VIEW_CONSTRUCTOR_SIGNATURE, mActionViewConstructorArguments); - item.setActionView(actionView); - actionViewSpecified = true; - } - if (itemActionViewLayout > 0) { - if (!actionViewSpecified) { - item.setActionView(itemActionViewLayout); - actionViewSpecified = true; - } else { - Log.w(LOG_TAG, "Ignoring attribute 'itemActionViewLayout'." - + " Action view already specified."); - } - } - if (itemActionProvider != null) { - item.setActionProvider(itemActionProvider); - } - } - - public void addItem() { - itemAdded = true; - setItem(menu.add(groupId, itemId, itemCategoryOrder, itemTitle)); - } - - public SubMenu addSubMenuItem() { - itemAdded = true; - SubMenu subMenu = menu.addSubMenu(groupId, itemId, itemCategoryOrder, itemTitle); - setItem(subMenu.getItem()); - return subMenu; - } - - public boolean hasAddedItem() { - return itemAdded; - } - - @SuppressWarnings("unchecked") - private T newInstance(String className, Class[] constructorSignature, - Object[] arguments) { - try { - Class clazz = mContext.getClassLoader().loadClass(className); - Constructor constructor = clazz.getConstructor(constructorSignature); - return (T) constructor.newInstance(arguments); - } catch (Exception e) { - Log.w(LOG_TAG, "Cannot instantiate class: " + className, e); - } - return null; - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/MenuItem.java b/actionbarsherlock/src/com/actionbarsherlock/view/MenuItem.java deleted file mode 100644 index 7fc3aa43..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/view/MenuItem.java +++ /dev/null @@ -1,598 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.View; - -/** - * Interface for direct access to a previously created menu item. - *

- * An Item is returned by calling one of the {@link android.view.Menu#add} - * methods. - *

- * For a feature set of specific menu types, see {@link Menu}. - * - *

- *

Developer Guides

- *

For information about creating menus, read the - * Menus developer guide.

- *
- */ -public interface MenuItem { - /* - * These should be kept in sync with attrs.xml enum constants for showAsAction - */ - /** Never show this item as a button in an Action Bar. */ - public static final int SHOW_AS_ACTION_NEVER = android.view.MenuItem.SHOW_AS_ACTION_NEVER; - /** Show this item as a button in an Action Bar if the system decides there is room for it. */ - public static final int SHOW_AS_ACTION_IF_ROOM = android.view.MenuItem.SHOW_AS_ACTION_IF_ROOM; - /** - * Always show this item as a button in an Action Bar. - * Use sparingly! If too many items are set to always show in the Action Bar it can - * crowd the Action Bar and degrade the user experience on devices with smaller screens. - * A good rule of thumb is to have no more than 2 items set to always show at a time. - */ - public static final int SHOW_AS_ACTION_ALWAYS = android.view.MenuItem.SHOW_AS_ACTION_ALWAYS; - - /** - * When this item is in the action bar, always show it with a text label even if - * it also has an icon specified. - */ - public static final int SHOW_AS_ACTION_WITH_TEXT = android.view.MenuItem.SHOW_AS_ACTION_WITH_TEXT; - - /** - * This item's action view collapses to a normal menu item. - * When expanded, the action view temporarily takes over - * a larger segment of its container. - */ - public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = android.view.MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW; - - /** - * Interface definition for a callback to be invoked when a menu item is - * clicked. - * - * @see Activity#onContextItemSelected(MenuItem) - * @see Activity#onOptionsItemSelected(MenuItem) - */ - public interface OnMenuItemClickListener { - /** - * Called when a menu item has been invoked. This is the first code - * that is executed; if it returns true, no other callbacks will be - * executed. - * - * @param item The menu item that was invoked. - * - * @return Return true to consume this click and prevent others from - * executing. - */ - public boolean onMenuItemClick(MenuItem item); - } - - /** - * Interface definition for a callback to be invoked when a menu item - * marked with {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} is - * expanded or collapsed. - * - * @see MenuItem#expandActionView() - * @see MenuItem#collapseActionView() - * @see MenuItem#setShowAsActionFlags(int) - */ - public interface OnActionExpandListener { - /** - * Called when a menu item with {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} - * is expanded. - * @param item Item that was expanded - * @return true if the item should expand, false if expansion should be suppressed. - */ - public boolean onMenuItemActionExpand(MenuItem item); - - /** - * Called when a menu item with {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} - * is collapsed. - * @param item Item that was collapsed - * @return true if the item should collapse, false if collapsing should be suppressed. - */ - public boolean onMenuItemActionCollapse(MenuItem item); - } - - /** - * Return the identifier for this menu item. The identifier can not - * be changed after the menu is created. - * - * @return The menu item's identifier. - */ - public int getItemId(); - - /** - * Return the group identifier that this menu item is part of. The group - * identifier can not be changed after the menu is created. - * - * @return The menu item's group identifier. - */ - public int getGroupId(); - - /** - * Return the category and order within the category of this item. This - * item will be shown before all items (within its category) that have - * order greater than this value. - *

- * An order integer contains the item's category (the upper bits of the - * integer; set by or/add the category with the order within the - * category) and the ordering of the item within that category (the - * lower bits). Example categories are {@link Menu#CATEGORY_SYSTEM}, - * {@link Menu#CATEGORY_SECONDARY}, {@link Menu#CATEGORY_ALTERNATIVE}, - * {@link Menu#CATEGORY_CONTAINER}. See {@link Menu} for a full list. - * - * @return The order of this item. - */ - public int getOrder(); - - /** - * Change the title associated with this item. - * - * @param title The new text to be displayed. - * @return This Item so additional setters can be called. - */ - public MenuItem setTitle(CharSequence title); - - /** - * Change the title associated with this item. - *

- * Some menu types do not sufficient space to show the full title, and - * instead a condensed title is preferred. See {@link Menu} for more - * information. - * - * @param title The resource id of the new text to be displayed. - * @return This Item so additional setters can be called. - * @see #setTitleCondensed(CharSequence) - */ - - public MenuItem setTitle(int title); - - /** - * Retrieve the current title of the item. - * - * @return The title. - */ - public CharSequence getTitle(); - - /** - * Change the condensed title associated with this item. The condensed - * title is used in situations where the normal title may be too long to - * be displayed. - * - * @param title The new text to be displayed as the condensed title. - * @return This Item so additional setters can be called. - */ - public MenuItem setTitleCondensed(CharSequence title); - - /** - * Retrieve the current condensed title of the item. If a condensed - * title was never set, it will return the normal title. - * - * @return The condensed title, if it exists. - * Otherwise the normal title. - */ - public CharSequence getTitleCondensed(); - - /** - * Change the icon associated with this item. This icon will not always be - * shown, so the title should be sufficient in describing this item. See - * {@link Menu} for the menu types that support icons. - * - * @param icon The new icon (as a Drawable) to be displayed. - * @return This Item so additional setters can be called. - */ - public MenuItem setIcon(Drawable icon); - - /** - * Change the icon associated with this item. This icon will not always be - * shown, so the title should be sufficient in describing this item. See - * {@link Menu} for the menu types that support icons. - *

- * This method will set the resource ID of the icon which will be used to - * lazily get the Drawable when this item is being shown. - * - * @param iconRes The new icon (as a resource ID) to be displayed. - * @return This Item so additional setters can be called. - */ - public MenuItem setIcon(int iconRes); - - /** - * Returns the icon for this item as a Drawable (getting it from resources if it hasn't been - * loaded before). - * - * @return The icon as a Drawable. - */ - public Drawable getIcon(); - - /** - * Change the Intent associated with this item. By default there is no - * Intent associated with a menu item. If you set one, and nothing - * else handles the item, then the default behavior will be to call - * {@link android.content.Context#startActivity} with the given Intent. - * - *

Note that setIntent() can not be used with the versions of - * {@link Menu#add} that take a Runnable, because {@link Runnable#run} - * does not return a value so there is no way to tell if it handled the - * item. In this case it is assumed that the Runnable always handles - * the item, and the intent will never be started. - * - * @see #getIntent - * @param intent The Intent to associated with the item. This Intent - * object is not copied, so be careful not to - * modify it later. - * @return This Item so additional setters can be called. - */ - public MenuItem setIntent(Intent intent); - - /** - * Return the Intent associated with this item. This returns a - * reference to the Intent which you can change as desired to modify - * what the Item is holding. - * - * @see #setIntent - * @return Returns the last value supplied to {@link #setIntent}, or - * null. - */ - public Intent getIntent(); - - /** - * Change both the numeric and alphabetic shortcut associated with this - * item. Note that the shortcut will be triggered when the key that - * generates the given character is pressed alone or along with with the alt - * key. Also note that case is not significant and that alphabetic shortcut - * characters will be displayed in lower case. - *

- * See {@link Menu} for the menu types that support shortcuts. - * - * @param numericChar The numeric shortcut key. This is the shortcut when - * using a numeric (e.g., 12-key) keyboard. - * @param alphaChar The alphabetic shortcut key. This is the shortcut when - * using a keyboard with alphabetic keys. - * @return This Item so additional setters can be called. - */ - public MenuItem setShortcut(char numericChar, char alphaChar); - - /** - * Change the numeric shortcut associated with this item. - *

- * See {@link Menu} for the menu types that support shortcuts. - * - * @param numericChar The numeric shortcut key. This is the shortcut when - * using a 12-key (numeric) keyboard. - * @return This Item so additional setters can be called. - */ - public MenuItem setNumericShortcut(char numericChar); - - /** - * Return the char for this menu item's numeric (12-key) shortcut. - * - * @return Numeric character to use as a shortcut. - */ - public char getNumericShortcut(); - - /** - * Change the alphabetic shortcut associated with this item. The shortcut - * will be triggered when the key that generates the given character is - * pressed alone or along with with the alt key. Case is not significant and - * shortcut characters will be displayed in lower case. Note that menu items - * with the characters '\b' or '\n' as shortcuts will get triggered by the - * Delete key or Carriage Return key, respectively. - *

- * See {@link Menu} for the menu types that support shortcuts. - * - * @param alphaChar The alphabetic shortcut key. This is the shortcut when - * using a keyboard with alphabetic keys. - * @return This Item so additional setters can be called. - */ - public MenuItem setAlphabeticShortcut(char alphaChar); - - /** - * Return the char for this menu item's alphabetic shortcut. - * - * @return Alphabetic character to use as a shortcut. - */ - public char getAlphabeticShortcut(); - - /** - * Control whether this item can display a check mark. Setting this does - * not actually display a check mark (see {@link #setChecked} for that); - * rather, it ensures there is room in the item in which to display a - * check mark. - *

- * See {@link Menu} for the menu types that support check marks. - * - * @param checkable Set to true to allow a check mark, false to - * disallow. The default is false. - * @see #setChecked - * @see #isCheckable - * @see Menu#setGroupCheckable - * @return This Item so additional setters can be called. - */ - public MenuItem setCheckable(boolean checkable); - - /** - * Return whether the item can currently display a check mark. - * - * @return If a check mark can be displayed, returns true. - * - * @see #setCheckable - */ - public boolean isCheckable(); - - /** - * Control whether this item is shown with a check mark. Note that you - * must first have enabled checking with {@link #setCheckable} or else - * the check mark will not appear. If this item is a member of a group that contains - * mutually-exclusive items (set via {@link Menu#setGroupCheckable(int, boolean, boolean)}, - * the other items in the group will be unchecked. - *

- * See {@link Menu} for the menu types that support check marks. - * - * @see #setCheckable - * @see #isChecked - * @see Menu#setGroupCheckable - * @param checked Set to true to display a check mark, false to hide - * it. The default value is false. - * @return This Item so additional setters can be called. - */ - public MenuItem setChecked(boolean checked); - - /** - * Return whether the item is currently displaying a check mark. - * - * @return If a check mark is displayed, returns true. - * - * @see #setChecked - */ - public boolean isChecked(); - - /** - * Sets the visibility of the menu item. Even if a menu item is not visible, - * it may still be invoked via its shortcut (to completely disable an item, - * set it to invisible and {@link #setEnabled(boolean) disabled}). - * - * @param visible If true then the item will be visible; if false it is - * hidden. - * @return This Item so additional setters can be called. - */ - public MenuItem setVisible(boolean visible); - - /** - * Return the visibility of the menu item. - * - * @return If true the item is visible; else it is hidden. - */ - public boolean isVisible(); - - /** - * Sets whether the menu item is enabled. Disabling a menu item will not - * allow it to be invoked via its shortcut. The menu item will still be - * visible. - * - * @param enabled If true then the item will be invokable; if false it is - * won't be invokable. - * @return This Item so additional setters can be called. - */ - public MenuItem setEnabled(boolean enabled); - - /** - * Return the enabled state of the menu item. - * - * @return If true the item is enabled and hence invokable; else it is not. - */ - public boolean isEnabled(); - - /** - * Check whether this item has an associated sub-menu. I.e. it is a - * sub-menu of another menu. - * - * @return If true this item has a menu; else it is a - * normal item. - */ - public boolean hasSubMenu(); - - /** - * Get the sub-menu to be invoked when this item is selected, if it has - * one. See {@link #hasSubMenu()}. - * - * @return The associated menu if there is one, else null - */ - public SubMenu getSubMenu(); - - /** - * Set a custom listener for invocation of this menu item. In most - * situations, it is more efficient and easier to use - * {@link Activity#onOptionsItemSelected(MenuItem)} or - * {@link Activity#onContextItemSelected(MenuItem)}. - * - * @param menuItemClickListener The object to receive invokations. - * @return This Item so additional setters can be called. - * @see Activity#onOptionsItemSelected(MenuItem) - * @see Activity#onContextItemSelected(MenuItem) - */ - public MenuItem setOnMenuItemClickListener(MenuItem.OnMenuItemClickListener menuItemClickListener); - - /** - * Gets the extra information linked to this menu item. This extra - * information is set by the View that added this menu item to the - * menu. - * - * @see OnCreateContextMenuListener - * @return The extra information linked to the View that added this - * menu item to the menu. This can be null. - */ - public ContextMenuInfo getMenuInfo(); - - /** - * Sets how this item should display in the presence of an Action Bar. - * The parameter actionEnum is a flag set. One of {@link #SHOW_AS_ACTION_ALWAYS}, - * {@link #SHOW_AS_ACTION_IF_ROOM}, or {@link #SHOW_AS_ACTION_NEVER} should - * be used, and you may optionally OR the value with {@link #SHOW_AS_ACTION_WITH_TEXT}. - * SHOW_AS_ACTION_WITH_TEXT requests that when the item is shown as an action, - * it should be shown with a text label. - * - * @param actionEnum How the item should display. One of - * {@link #SHOW_AS_ACTION_ALWAYS}, {@link #SHOW_AS_ACTION_IF_ROOM}, or - * {@link #SHOW_AS_ACTION_NEVER}. SHOW_AS_ACTION_NEVER is the default. - * - * @see android.app.ActionBar - * @see #setActionView(View) - */ - public void setShowAsAction(int actionEnum); - - /** - * Sets how this item should display in the presence of an Action Bar. - * The parameter actionEnum is a flag set. One of {@link #SHOW_AS_ACTION_ALWAYS}, - * {@link #SHOW_AS_ACTION_IF_ROOM}, or {@link #SHOW_AS_ACTION_NEVER} should - * be used, and you may optionally OR the value with {@link #SHOW_AS_ACTION_WITH_TEXT}. - * SHOW_AS_ACTION_WITH_TEXT requests that when the item is shown as an action, - * it should be shown with a text label. - * - *

Note: This method differs from {@link #setShowAsAction(int)} only in that it - * returns the current MenuItem instance for call chaining. - * - * @param actionEnum How the item should display. One of - * {@link #SHOW_AS_ACTION_ALWAYS}, {@link #SHOW_AS_ACTION_IF_ROOM}, or - * {@link #SHOW_AS_ACTION_NEVER}. SHOW_AS_ACTION_NEVER is the default. - * - * @see android.app.ActionBar - * @see #setActionView(View) - * @return This MenuItem instance for call chaining. - */ - public MenuItem setShowAsActionFlags(int actionEnum); - - /** - * Set an action view for this menu item. An action view will be displayed in place - * of an automatically generated menu item element in the UI when this item is shown - * as an action within a parent. - *

- * Note: Setting an action view overrides the action provider - * set via {@link #setActionProvider(ActionProvider)}. - *

- * - * @param view View to use for presenting this item to the user. - * @return This Item so additional setters can be called. - * - * @see #setShowAsAction(int) - */ - public MenuItem setActionView(View view); - - /** - * Set an action view for this menu item. An action view will be displayed in place - * of an automatically generated menu item element in the UI when this item is shown - * as an action within a parent. - *

- * Note: Setting an action view overrides the action provider - * set via {@link #setActionProvider(ActionProvider)}. - *

- * - * @param resId Layout resource to use for presenting this item to the user. - * @return This Item so additional setters can be called. - * - * @see #setShowAsAction(int) - */ - public MenuItem setActionView(int resId); - - /** - * Returns the currently set action view for this menu item. - * - * @return This item's action view - * - * @see #setActionView(View) - * @see #setShowAsAction(int) - */ - public View getActionView(); - - /** - * Sets the {@link ActionProvider} responsible for creating an action view if - * the item is placed on the action bar. The provider also provides a default - * action invoked if the item is placed in the overflow menu. - *

- * Note: Setting an action provider overrides the action view - * set via {@link #setActionView(int)} or {@link #setActionView(View)}. - *

- * - * @param actionProvider The action provider. - * @return This Item so additional setters can be called. - * - * @see ActionProvider - */ - public MenuItem setActionProvider(ActionProvider actionProvider); - - /** - * Gets the {@link ActionProvider}. - * - * @return The action provider. - * - * @see ActionProvider - * @see #setActionProvider(ActionProvider) - */ - public ActionProvider getActionProvider(); - - /** - * Expand the action view associated with this menu item. - * The menu item must have an action view set, as well as - * the showAsAction flag {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. - * If a listener has been set using {@link #setOnActionExpandListener(OnActionExpandListener)} - * it will have its {@link OnActionExpandListener#onMenuItemActionExpand(MenuItem)} - * method invoked. The listener may return false from this method to prevent expanding - * the action view. - * - * @return true if the action view was expanded, false otherwise. - */ - public boolean expandActionView(); - - /** - * Collapse the action view associated with this menu item. - * The menu item must have an action view set, as well as the showAsAction flag - * {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. If a listener has been set using - * {@link #setOnActionExpandListener(OnActionExpandListener)} it will have its - * {@link OnActionExpandListener#onMenuItemActionCollapse(MenuItem)} method invoked. - * The listener may return false from this method to prevent collapsing the action view. - * - * @return true if the action view was collapsed, false otherwise. - */ - public boolean collapseActionView(); - - /** - * Returns true if this menu item's action view has been expanded. - * - * @return true if the item's action view is expanded, false otherwise. - * - * @see #expandActionView() - * @see #collapseActionView() - * @see #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW - * @see OnActionExpandListener - */ - public boolean isActionViewExpanded(); - - /** - * Set an {@link OnActionExpandListener} on this menu item to be notified when - * the associated action view is expanded or collapsed. The menu item must - * be configured to expand or collapse its action view using the flag - * {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. - * - * @param listener Listener that will respond to expand/collapse events - * @return This menu item instance for call chaining - */ - public MenuItem setOnActionExpandListener(OnActionExpandListener listener); -} \ No newline at end of file diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/SubMenu.java b/actionbarsherlock/src/com/actionbarsherlock/view/SubMenu.java deleted file mode 100644 index 397fd1c2..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/view/SubMenu.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import android.graphics.drawable.Drawable; -import android.view.View; - -/** - * Subclass of {@link Menu} for sub menus. - *

- * Sub menus do not support item icons, or nested sub menus. - * - *

- *

Developer Guides

- *

For information about creating menus, read the - * Menus developer guide.

- *
- */ - -public interface SubMenu extends Menu { - /** - * Sets the submenu header's title to the title given in titleRes - * resource identifier. - * - * @param titleRes The string resource identifier used for the title. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setHeaderTitle(int titleRes); - - /** - * Sets the submenu header's title to the title given in title. - * - * @param title The character sequence used for the title. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setHeaderTitle(CharSequence title); - - /** - * Sets the submenu header's icon to the icon given in iconRes - * resource id. - * - * @param iconRes The resource identifier used for the icon. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setHeaderIcon(int iconRes); - - /** - * Sets the submenu header's icon to the icon given in icon - * {@link Drawable}. - * - * @param icon The {@link Drawable} used for the icon. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setHeaderIcon(Drawable icon); - - /** - * Sets the header of the submenu to the {@link View} given in - * view. This replaces the header title and icon (and those - * replace this). - * - * @param view The {@link View} used for the header. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setHeaderView(View view); - - /** - * Clears the header of the submenu. - */ - public void clearHeader(); - - /** - * Change the icon associated with this submenu's item in its parent menu. - * - * @see MenuItem#setIcon(int) - * @param iconRes The new icon (as a resource ID) to be displayed. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setIcon(int iconRes); - - /** - * Change the icon associated with this submenu's item in its parent menu. - * - * @see MenuItem#setIcon(Drawable) - * @param icon The new icon (as a Drawable) to be displayed. - * @return This SubMenu so additional setters can be called. - */ - public SubMenu setIcon(Drawable icon); - - /** - * Gets the {@link MenuItem} that represents this submenu in the parent - * menu. Use this for setting additional item attributes. - * - * @return The {@link MenuItem} that launches the submenu when invoked. - */ - public MenuItem getItem(); -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/view/Window.java b/actionbarsherlock/src/com/actionbarsherlock/view/Window.java deleted file mode 100644 index a340a429..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/view/Window.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * Copyright (C) 2011 Jake Wharton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.view; - -import android.content.Context; - -/** - *

Abstract base class for a top-level window look and behavior policy. An - * instance of this class should be used as the top-level view added to the - * window manager. It provides standard UI policies such as a background, title - * area, default key processing, etc.

- * - *

The only existing implementation of this abstract class is - * android.policy.PhoneWindow, which you should instantiate when needing a - * Window. Eventually that class will be refactored and a factory method added - * for creating Window instances without knowing about a particular - * implementation.

- */ -public abstract class Window extends android.view.Window { - public static final long FEATURE_ACTION_BAR = android.view.Window.FEATURE_ACTION_BAR; - public static final long FEATURE_ACTION_BAR_OVERLAY = android.view.Window.FEATURE_ACTION_BAR_OVERLAY; - public static final long FEATURE_ACTION_MODE_OVERLAY = android.view.Window.FEATURE_ACTION_MODE_OVERLAY; - public static final long FEATURE_NO_TITLE = android.view.Window.FEATURE_NO_TITLE; - public static final long FEATURE_PROGRESS = android.view.Window.FEATURE_PROGRESS; - public static final long FEATURE_INDETERMINATE_PROGRESS = android.view.Window.FEATURE_INDETERMINATE_PROGRESS; - - /** - * Create a new instance for a context. - * - * @param context Context. - */ - private Window(Context context) { - super(context); - } - - - public interface Callback { - /** - * Called when a panel's menu item has been selected by the user. - * - * @param featureId The panel that the menu is in. - * @param item The menu item that was selected. - * - * @return boolean Return true to finish processing of selection, or - * false to perform the normal menu handling (calling its - * Runnable or sending a Message to its target Handler). - */ - public boolean onMenuItemSelected(int featureId, MenuItem item); - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/widget/ActivityChooserModel.java b/actionbarsherlock/src/com/actionbarsherlock/widget/ActivityChooserModel.java deleted file mode 100644 index d7f110fc..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/widget/ActivityChooserModel.java +++ /dev/null @@ -1,1104 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.widget; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ResolveInfo; -import android.database.DataSetObservable; -import android.os.Handler; -import android.text.TextUtils; -import android.util.Log; -import android.util.Xml; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; - -/** - *

- * This class represents a data model for choosing a component for handing a - * given {@link Intent}. The model is responsible for querying the system for - * activities that can handle the given intent and order found activities - * based on historical data of previous choices. The historical data is stored - * in an application private file. If a client does not want to have persistent - * choice history the file can be omitted, thus the activities will be ordered - * based on historical usage for the current session. - *

- *

- * For each backing history file there is a singleton instance of this class. Thus, - * several clients that specify the same history file will share the same model. Note - * that if multiple clients are sharing the same model they should implement semantically - * equivalent functionality since setting the model intent will change the found - * activities and they may be inconsistent with the functionality of some of the clients. - * For example, choosing a share activity can be implemented by a single backing - * model and two different views for performing the selection. If however, one of the - * views is used for sharing but the other for importing, for example, then each - * view should be backed by a separate model. - *

- *

- * The way clients interact with this class is as follows: - *

- *

- *

- * 
- *  // Get a model and set it to a couple of clients with semantically similar function.
- *  ActivityChooserModel dataModel =
- *      ActivityChooserModel.get(context, "task_specific_history_file_name.xml");
- *
- *  ActivityChooserModelClient modelClient1 = getActivityChooserModelClient1();
- *  modelClient1.setActivityChooserModel(dataModel);
- *
- *  ActivityChooserModelClient modelClient2 = getActivityChooserModelClient2();
- *  modelClient2.setActivityChooserModel(dataModel);
- *
- *  // Set an intent to choose a an activity for.
- *  dataModel.setIntent(intent);
- * 
- * 
- * 

- *

- * Note: This class is thread safe. - *

- * - * @hide - */ -class ActivityChooserModel extends DataSetObservable { - - /** - * Client that utilizes an {@link ActivityChooserModel}. - */ - public interface ActivityChooserModelClient { - - /** - * Sets the {@link ActivityChooserModel}. - * - * @param dataModel The model. - */ - public void setActivityChooserModel(ActivityChooserModel dataModel); - } - - /** - * Defines a sorter that is responsible for sorting the activities - * based on the provided historical choices and an intent. - */ - public interface ActivitySorter { - - /** - * Sorts the activities in descending order of relevance - * based on previous history and an intent. - * - * @param intent The {@link Intent}. - * @param activities Activities to be sorted. - * @param historicalRecords Historical records. - */ - // This cannot be done by a simple comparator since an Activity weight - // is computed from history. Note that Activity implements Comparable. - public void sort(Intent intent, List activities, - List historicalRecords); - } - - /** - * Listener for choosing an activity. - */ - public interface OnChooseActivityListener { - - /** - * Called when an activity has been chosen. The client can decide whether - * an activity can be chosen and if so the caller of - * {@link ActivityChooserModel#chooseActivity(int)} will receive and {@link Intent} - * for launching it. - *

- * Note: Modifying the intent is not permitted and - * any changes to the latter will be ignored. - *

- * - * @param host The listener's host model. - * @param intent The intent for launching the chosen activity. - * @return Whether the intent is handled and should not be delivered to clients. - * - * @see ActivityChooserModel#chooseActivity(int) - */ - public boolean onChooseActivity(ActivityChooserModel host, Intent intent); - } - - /** - * Flag for selecting debug mode. - */ - private static final boolean DEBUG = false; - - /** - * Tag used for logging. - */ - private static final String LOG_TAG = ActivityChooserModel.class.getSimpleName(); - - /** - * The root tag in the history file. - */ - private static final String TAG_HISTORICAL_RECORDS = "historical-records"; - - /** - * The tag for a record in the history file. - */ - private static final String TAG_HISTORICAL_RECORD = "historical-record"; - - /** - * Attribute for the activity. - */ - private static final String ATTRIBUTE_ACTIVITY = "activity"; - - /** - * Attribute for the choice time. - */ - private static final String ATTRIBUTE_TIME = "time"; - - /** - * Attribute for the choice weight. - */ - private static final String ATTRIBUTE_WEIGHT = "weight"; - - /** - * The default name of the choice history file. - */ - public static final String DEFAULT_HISTORY_FILE_NAME = - "activity_choser_model_history.xml"; - - /** - * The default maximal length of the choice history. - */ - public static final int DEFAULT_HISTORY_MAX_LENGTH = 50; - - /** - * The amount with which to inflate a chosen activity when set as default. - */ - private static final int DEFAULT_ACTIVITY_INFLATION = 5; - - /** - * Default weight for a choice record. - */ - private static final float DEFAULT_HISTORICAL_RECORD_WEIGHT = 1.0f; - - /** - * The extension of the history file. - */ - private static final String HISTORY_FILE_EXTENSION = ".xml"; - - /** - * An invalid item index. - */ - private static final int INVALID_INDEX = -1; - - /** - * Lock to guard the model registry. - */ - private static final Object sRegistryLock = new Object(); - - /** - * This the registry for data models. - */ - private static final Map sDataModelRegistry = - new HashMap(); - - /** - * Lock for synchronizing on this instance. - */ - private final Object mInstanceLock = new Object(); - - /** - * List of activities that can handle the current intent. - */ - private final List mActivites = new ArrayList(); - - /** - * List with historical choice records. - */ - private final List mHistoricalRecords = new ArrayList(); - - /** - * Context for accessing resources. - */ - private final Context mContext; - - /** - * The name of the history file that backs this model. - */ - private final String mHistoryFileName; - - /** - * The intent for which a activity is being chosen. - */ - private Intent mIntent; - - /** - * The sorter for ordering activities based on intent and past choices. - */ - private ActivitySorter mActivitySorter = new DefaultSorter(); - - /** - * The maximal length of the choice history. - */ - private int mHistoryMaxSize = DEFAULT_HISTORY_MAX_LENGTH; - - /** - * Flag whether choice history can be read. In general many clients can - * share the same data model and {@link #readHistoricalData()} may be called - * by arbitrary of them any number of times. Therefore, this class guarantees - * that the very first read succeeds and subsequent reads can be performed - * only after a call to {@link #persistHistoricalData()} followed by change - * of the share records. - */ - private boolean mCanReadHistoricalData = true; - - /** - * Flag whether the choice history was read. This is used to enforce that - * before calling {@link #persistHistoricalData()} a call to - * {@link #persistHistoricalData()} has been made. This aims to avoid a - * scenario in which a choice history file exits, it is not read yet and - * it is overwritten. Note that always all historical records are read in - * full and the file is rewritten. This is necessary since we need to - * purge old records that are outside of the sliding window of past choices. - */ - private boolean mReadShareHistoryCalled = false; - - /** - * Flag whether the choice records have changed. In general many clients can - * share the same data model and {@link #persistHistoricalData()} may be called - * by arbitrary of them any number of times. Therefore, this class guarantees - * that choice history will be persisted only if it has changed. - */ - private boolean mHistoricalRecordsChanged = true; - - /** - * Hander for scheduling work on client tread. - */ - private final Handler mHandler = new Handler(); - - /** - * Policy for controlling how the model handles chosen activities. - */ - private OnChooseActivityListener mActivityChoserModelPolicy; - - /** - * Gets the data model backed by the contents of the provided file with historical data. - * Note that only one data model is backed by a given file, thus multiple calls with - * the same file name will return the same model instance. If no such instance is present - * it is created. - *

- * Note: To use the default historical data file clients should explicitly - * pass as file name {@link #DEFAULT_HISTORY_FILE_NAME}. If no persistence of the choice - * history is desired clients should pass null for the file name. In such - * case a new model is returned for each invocation. - *

- * - *

- * Always use difference historical data files for semantically different actions. - * For example, sharing is different from importing. - *

- * - * @param context Context for loading resources. - * @param historyFileName File name with choice history, null - * if the model should not be backed by a file. In this case the activities - * will be ordered only by data from the current session. - * - * @return The model. - */ - public static ActivityChooserModel get(Context context, String historyFileName) { - synchronized (sRegistryLock) { - ActivityChooserModel dataModel = sDataModelRegistry.get(historyFileName); - if (dataModel == null) { - dataModel = new ActivityChooserModel(context, historyFileName); - sDataModelRegistry.put(historyFileName, dataModel); - } - dataModel.readHistoricalData(); - return dataModel; - } - } - - /** - * Creates a new instance. - * - * @param context Context for loading resources. - * @param historyFileName The history XML file. - */ - private ActivityChooserModel(Context context, String historyFileName) { - mContext = context.getApplicationContext(); - if (!TextUtils.isEmpty(historyFileName) - && !historyFileName.endsWith(HISTORY_FILE_EXTENSION)) { - mHistoryFileName = historyFileName + HISTORY_FILE_EXTENSION; - } else { - mHistoryFileName = historyFileName; - } - } - - /** - * Sets an intent for which to choose a activity. - *

- * Note: Clients must set only semantically similar - * intents for each data model. - *

- * - * @param intent The intent. - */ - public void setIntent(Intent intent) { - synchronized (mInstanceLock) { - if (mIntent == intent) { - return; - } - mIntent = intent; - loadActivitiesLocked(); - } - } - - /** - * Gets the intent for which a activity is being chosen. - * - * @return The intent. - */ - public Intent getIntent() { - synchronized (mInstanceLock) { - return mIntent; - } - } - - /** - * Gets the number of activities that can handle the intent. - * - * @return The activity count. - * - * @see #setIntent(Intent) - */ - public int getActivityCount() { - synchronized (mInstanceLock) { - return mActivites.size(); - } - } - - /** - * Gets an activity at a given index. - * - * @return The activity. - * - * @see ActivityResolveInfo - * @see #setIntent(Intent) - */ - public ResolveInfo getActivity(int index) { - synchronized (mInstanceLock) { - return mActivites.get(index).resolveInfo; - } - } - - /** - * Gets the index of a the given activity. - * - * @param activity The activity index. - * - * @return The index if found, -1 otherwise. - */ - public int getActivityIndex(ResolveInfo activity) { - List activities = mActivites; - final int activityCount = activities.size(); - for (int i = 0; i < activityCount; i++) { - ActivityResolveInfo currentActivity = activities.get(i); - if (currentActivity.resolveInfo == activity) { - return i; - } - } - return INVALID_INDEX; - } - - /** - * Chooses a activity to handle the current intent. This will result in - * adding a historical record for that action and construct intent with - * its component name set such that it can be immediately started by the - * client. - *

- * Note: By calling this method the client guarantees - * that the returned intent will be started. This intent is returned to - * the client solely to let additional customization before the start. - *

- * - * @return An {@link Intent} for launching the activity or null if the - * policy has consumed the intent. - * - * @see HistoricalRecord - * @see OnChooseActivityListener - */ - public Intent chooseActivity(int index) { - ActivityResolveInfo chosenActivity = mActivites.get(index); - - ComponentName chosenName = new ComponentName( - chosenActivity.resolveInfo.activityInfo.packageName, - chosenActivity.resolveInfo.activityInfo.name); - - Intent choiceIntent = new Intent(mIntent); - choiceIntent.setComponent(chosenName); - - if (mActivityChoserModelPolicy != null) { - // Do not allow the policy to change the intent. - Intent choiceIntentCopy = new Intent(choiceIntent); - final boolean handled = mActivityChoserModelPolicy.onChooseActivity(this, - choiceIntentCopy); - if (handled) { - return null; - } - } - - HistoricalRecord historicalRecord = new HistoricalRecord(chosenName, - System.currentTimeMillis(), DEFAULT_HISTORICAL_RECORD_WEIGHT); - addHisoricalRecord(historicalRecord); - - return choiceIntent; - } - - /** - * Sets the listener for choosing an activity. - * - * @param listener The listener. - */ - public void setOnChooseActivityListener(OnChooseActivityListener listener) { - mActivityChoserModelPolicy = listener; - } - - /** - * Gets the default activity, The default activity is defined as the one - * with highest rank i.e. the first one in the list of activities that can - * handle the intent. - * - * @return The default activity, null id not activities. - * - * @see #getActivity(int) - */ - public ResolveInfo getDefaultActivity() { - synchronized (mInstanceLock) { - if (!mActivites.isEmpty()) { - return mActivites.get(0).resolveInfo; - } - } - return null; - } - - /** - * Sets the default activity. The default activity is set by adding a - * historical record with weight high enough that this activity will - * become the highest ranked. Such a strategy guarantees that the default - * will eventually change if not used. Also the weight of the record for - * setting a default is inflated with a constant amount to guarantee that - * it will stay as default for awhile. - * - * @param index The index of the activity to set as default. - */ - public void setDefaultActivity(int index) { - ActivityResolveInfo newDefaultActivity = mActivites.get(index); - ActivityResolveInfo oldDefaultActivity = mActivites.get(0); - - final float weight; - if (oldDefaultActivity != null) { - // Add a record with weight enough to boost the chosen at the top. - weight = oldDefaultActivity.weight - newDefaultActivity.weight - + DEFAULT_ACTIVITY_INFLATION; - } else { - weight = DEFAULT_HISTORICAL_RECORD_WEIGHT; - } - - ComponentName defaultName = new ComponentName( - newDefaultActivity.resolveInfo.activityInfo.packageName, - newDefaultActivity.resolveInfo.activityInfo.name); - HistoricalRecord historicalRecord = new HistoricalRecord(defaultName, - System.currentTimeMillis(), weight); - addHisoricalRecord(historicalRecord); - } - - /** - * Reads the history data from the backing file if the latter - * was provided. Calling this method more than once before a call - * to {@link #persistHistoricalData()} has been made has no effect. - *

- * Note: Historical data is read asynchronously and - * as soon as the reading is completed any registered - * {@link DataSetObserver}s will be notified. Also no historical - * data is read until this method is invoked. - *

- */ - private void readHistoricalData() { - synchronized (mInstanceLock) { - if (!mCanReadHistoricalData || !mHistoricalRecordsChanged) { - return; - } - mCanReadHistoricalData = false; - mReadShareHistoryCalled = true; - if (!TextUtils.isEmpty(mHistoryFileName)) { - /*AsyncTask.*/SERIAL_EXECUTOR.execute(new HistoryLoader()); - } - } - } - - private static final Executor SERIAL_EXECUTOR = Executors.newSingleThreadExecutor(); - - /** - * Persists the history data to the backing file if the latter - * was provided. Calling this method before a call to {@link #readHistoricalData()} - * throws an exception. Calling this method more than one without choosing an - * activity has not effect. - * - * @throws IllegalStateException If this method is called before a call to - * {@link #readHistoricalData()}. - */ - private void persistHistoricalData() { - synchronized (mInstanceLock) { - if (!mReadShareHistoryCalled) { - throw new IllegalStateException("No preceding call to #readHistoricalData"); - } - if (!mHistoricalRecordsChanged) { - return; - } - mHistoricalRecordsChanged = false; - mCanReadHistoricalData = true; - if (!TextUtils.isEmpty(mHistoryFileName)) { - /*AsyncTask.*/SERIAL_EXECUTOR.execute(new HistoryPersister()); - } - } - } - - /** - * Sets the sorter for ordering activities based on historical data and an intent. - * - * @param activitySorter The sorter. - * - * @see ActivitySorter - */ - public void setActivitySorter(ActivitySorter activitySorter) { - synchronized (mInstanceLock) { - if (mActivitySorter == activitySorter) { - return; - } - mActivitySorter = activitySorter; - sortActivities(); - } - } - - /** - * Sorts the activities based on history and an intent. If - * a sorter is not specified this a default implementation is used. - * - * @see #setActivitySorter(ActivitySorter) - */ - private void sortActivities() { - synchronized (mInstanceLock) { - if (mActivitySorter != null && !mActivites.isEmpty()) { - mActivitySorter.sort(mIntent, mActivites, - Collections.unmodifiableList(mHistoricalRecords)); - notifyChanged(); - } - } - } - - /** - * Sets the maximal size of the historical data. Defaults to - * {@link #DEFAULT_HISTORY_MAX_LENGTH} - *

- * Note: Setting this property will immediately - * enforce the specified max history size by dropping enough old - * historical records to enforce the desired size. Thus, any - * records that exceed the history size will be discarded and - * irreversibly lost. - *

- * - * @param historyMaxSize The max history size. - */ - public void setHistoryMaxSize(int historyMaxSize) { - synchronized (mInstanceLock) { - if (mHistoryMaxSize == historyMaxSize) { - return; - } - mHistoryMaxSize = historyMaxSize; - pruneExcessiveHistoricalRecordsLocked(); - sortActivities(); - } - } - - /** - * Gets the history max size. - * - * @return The history max size. - */ - public int getHistoryMaxSize() { - synchronized (mInstanceLock) { - return mHistoryMaxSize; - } - } - - /** - * Gets the history size. - * - * @return The history size. - */ - public int getHistorySize() { - synchronized (mInstanceLock) { - return mHistoricalRecords.size(); - } - } - - /** - * Adds a historical record. - * - * @param historicalRecord The record to add. - * @return True if the record was added. - */ - private boolean addHisoricalRecord(HistoricalRecord historicalRecord) { - synchronized (mInstanceLock) { - final boolean added = mHistoricalRecords.add(historicalRecord); - if (added) { - mHistoricalRecordsChanged = true; - pruneExcessiveHistoricalRecordsLocked(); - persistHistoricalData(); - sortActivities(); - } - return added; - } - } - - /** - * Prunes older excessive records to guarantee {@link #mHistoryMaxSize}. - */ - private void pruneExcessiveHistoricalRecordsLocked() { - List choiceRecords = mHistoricalRecords; - final int pruneCount = choiceRecords.size() - mHistoryMaxSize; - if (pruneCount <= 0) { - return; - } - mHistoricalRecordsChanged = true; - for (int i = 0; i < pruneCount; i++) { - HistoricalRecord prunedRecord = choiceRecords.remove(0); - if (DEBUG) { - Log.i(LOG_TAG, "Pruned: " + prunedRecord); - } - } - } - - /** - * Loads the activities. - */ - private void loadActivitiesLocked() { - mActivites.clear(); - if (mIntent != null) { - List resolveInfos = - mContext.getPackageManager().queryIntentActivities(mIntent, 0); - final int resolveInfoCount = resolveInfos.size(); - for (int i = 0; i < resolveInfoCount; i++) { - ResolveInfo resolveInfo = resolveInfos.get(i); - mActivites.add(new ActivityResolveInfo(resolveInfo)); - } - sortActivities(); - } else { - notifyChanged(); - } - } - - /** - * Represents a record in the history. - */ - public final static class HistoricalRecord { - - /** - * The activity name. - */ - public final ComponentName activity; - - /** - * The choice time. - */ - public final long time; - - /** - * The record weight. - */ - public final float weight; - - /** - * Creates a new instance. - * - * @param activityName The activity component name flattened to string. - * @param time The time the activity was chosen. - * @param weight The weight of the record. - */ - public HistoricalRecord(String activityName, long time, float weight) { - this(ComponentName.unflattenFromString(activityName), time, weight); - } - - /** - * Creates a new instance. - * - * @param activityName The activity name. - * @param time The time the activity was chosen. - * @param weight The weight of the record. - */ - public HistoricalRecord(ComponentName activityName, long time, float weight) { - this.activity = activityName; - this.time = time; - this.weight = weight; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((activity == null) ? 0 : activity.hashCode()); - result = prime * result + (int) (time ^ (time >>> 32)); - result = prime * result + Float.floatToIntBits(weight); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - HistoricalRecord other = (HistoricalRecord) obj; - if (activity == null) { - if (other.activity != null) { - return false; - } - } else if (!activity.equals(other.activity)) { - return false; - } - if (time != other.time) { - return false; - } - if (Float.floatToIntBits(weight) != Float.floatToIntBits(other.weight)) { - return false; - } - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("["); - builder.append("; activity:").append(activity); - builder.append("; time:").append(time); - builder.append("; weight:").append(new BigDecimal(weight)); - builder.append("]"); - return builder.toString(); - } - } - - /** - * Represents an activity. - */ - public final class ActivityResolveInfo implements Comparable { - - /** - * The {@link ResolveInfo} of the activity. - */ - public final ResolveInfo resolveInfo; - - /** - * Weight of the activity. Useful for sorting. - */ - public float weight; - - /** - * Creates a new instance. - * - * @param resolveInfo activity {@link ResolveInfo}. - */ - public ActivityResolveInfo(ResolveInfo resolveInfo) { - this.resolveInfo = resolveInfo; - } - - @Override - public int hashCode() { - return 31 + Float.floatToIntBits(weight); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - ActivityResolveInfo other = (ActivityResolveInfo) obj; - if (Float.floatToIntBits(weight) != Float.floatToIntBits(other.weight)) { - return false; - } - return true; - } - - public int compareTo(ActivityResolveInfo another) { - return Float.floatToIntBits(another.weight) - Float.floatToIntBits(weight); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("["); - builder.append("resolveInfo:").append(resolveInfo.toString()); - builder.append("; weight:").append(new BigDecimal(weight)); - builder.append("]"); - return builder.toString(); - } - } - - /** - * Default activity sorter implementation. - */ - private final class DefaultSorter implements ActivitySorter { - private static final float WEIGHT_DECAY_COEFFICIENT = 0.95f; - - private final Map mPackageNameToActivityMap = - new HashMap(); - - public void sort(Intent intent, List activities, - List historicalRecords) { - Map packageNameToActivityMap = - mPackageNameToActivityMap; - packageNameToActivityMap.clear(); - - final int activityCount = activities.size(); - for (int i = 0; i < activityCount; i++) { - ActivityResolveInfo activity = activities.get(i); - activity.weight = 0.0f; - String packageName = activity.resolveInfo.activityInfo.packageName; - packageNameToActivityMap.put(packageName, activity); - } - - final int lastShareIndex = historicalRecords.size() - 1; - float nextRecordWeight = 1; - for (int i = lastShareIndex; i >= 0; i--) { - HistoricalRecord historicalRecord = historicalRecords.get(i); - String packageName = historicalRecord.activity.getPackageName(); - ActivityResolveInfo activity = packageNameToActivityMap.get(packageName); - if (activity != null) { - activity.weight += historicalRecord.weight * nextRecordWeight; - nextRecordWeight = nextRecordWeight * WEIGHT_DECAY_COEFFICIENT; - } - } - - Collections.sort(activities); - - if (DEBUG) { - for (int i = 0; i < activityCount; i++) { - Log.i(LOG_TAG, "Sorted: " + activities.get(i)); - } - } - } - } - - /** - * Command for reading the historical records from a file off the UI thread. - */ - private final class HistoryLoader implements Runnable { - - public void run() { - FileInputStream fis = null; - try { - fis = mContext.openFileInput(mHistoryFileName); - } catch (FileNotFoundException fnfe) { - if (DEBUG) { - Log.i(LOG_TAG, "Could not open historical records file: " + mHistoryFileName); - } - return; - } - try { - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(fis, null); - - int type = XmlPullParser.START_DOCUMENT; - while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) { - type = parser.next(); - } - - if (!TAG_HISTORICAL_RECORDS.equals(parser.getName())) { - throw new XmlPullParserException("Share records file does not start with " - + TAG_HISTORICAL_RECORDS + " tag."); - } - - List readRecords = new ArrayList(); - - while (true) { - type = parser.next(); - if (type == XmlPullParser.END_DOCUMENT) { - break; - } - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - String nodeName = parser.getName(); - if (!TAG_HISTORICAL_RECORD.equals(nodeName)) { - throw new XmlPullParserException("Share records file not well-formed."); - } - - String activity = parser.getAttributeValue(null, ATTRIBUTE_ACTIVITY); - final long time = - Long.parseLong(parser.getAttributeValue(null, ATTRIBUTE_TIME)); - final float weight = - Float.parseFloat(parser.getAttributeValue(null, ATTRIBUTE_WEIGHT)); - - HistoricalRecord readRecord = new HistoricalRecord(activity, time, - weight); - readRecords.add(readRecord); - - if (DEBUG) { - Log.i(LOG_TAG, "Read " + readRecord.toString()); - } - } - - if (DEBUG) { - Log.i(LOG_TAG, "Read " + readRecords.size() + " historical records."); - } - - synchronized (mInstanceLock) { - Set uniqueShareRecords = - new LinkedHashSet(readRecords); - - // Make sure no duplicates. Example: Read a file with - // one record, add one record, persist the two records, - // add a record, read the persisted records - the - // read two records should not be added again. - List historicalRecords = mHistoricalRecords; - final int historicalRecordsCount = historicalRecords.size(); - for (int i = historicalRecordsCount - 1; i >= 0; i--) { - HistoricalRecord historicalRecord = historicalRecords.get(i); - uniqueShareRecords.add(historicalRecord); - } - - if (historicalRecords.size() == uniqueShareRecords.size()) { - return; - } - - // Make sure the oldest records go to the end. - historicalRecords.clear(); - historicalRecords.addAll(uniqueShareRecords); - - mHistoricalRecordsChanged = true; - - // Do this on the client thread since the client may be on the UI - // thread, wait for data changes which happen during sorting, and - // perform UI modification based on the data change. - mHandler.post(new Runnable() { - public void run() { - pruneExcessiveHistoricalRecordsLocked(); - sortActivities(); - } - }); - } - } catch (XmlPullParserException xppe) { - Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, xppe); - } catch (IOException ioe) { - Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, ioe); - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException ioe) { - /* ignore */ - } - } - } - } - } - - /** - * Command for persisting the historical records to a file off the UI thread. - */ - private final class HistoryPersister implements Runnable { - - public void run() { - FileOutputStream fos = null; - List records = null; - - synchronized (mInstanceLock) { - records = new ArrayList(mHistoricalRecords); - } - - try { - fos = mContext.openFileOutput(mHistoryFileName, Context.MODE_PRIVATE); - } catch (FileNotFoundException fnfe) { - Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, fnfe); - return; - } - - XmlSerializer serializer = Xml.newSerializer(); - - try { - serializer.setOutput(fos, null); - serializer.startDocument("UTF-8", true); - serializer.startTag(null, TAG_HISTORICAL_RECORDS); - - final int recordCount = records.size(); - for (int i = 0; i < recordCount; i++) { - HistoricalRecord record = records.remove(0); - serializer.startTag(null, TAG_HISTORICAL_RECORD); - serializer.attribute(null, ATTRIBUTE_ACTIVITY, record.activity.flattenToString()); - serializer.attribute(null, ATTRIBUTE_TIME, String.valueOf(record.time)); - serializer.attribute(null, ATTRIBUTE_WEIGHT, String.valueOf(record.weight)); - serializer.endTag(null, TAG_HISTORICAL_RECORD); - if (DEBUG) { - Log.i(LOG_TAG, "Wrote " + record.toString()); - } - } - - serializer.endTag(null, TAG_HISTORICAL_RECORDS); - serializer.endDocument(); - - if (DEBUG) { - Log.i(LOG_TAG, "Wrote " + recordCount + " historical records."); - } - } catch (IllegalArgumentException iae) { - Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, iae); - } catch (IllegalStateException ise) { - Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, ise); - } catch (IOException ioe) { - Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, ioe); - } finally { - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - /* ignore */ - } - } - } - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/widget/ActivityChooserView.java b/actionbarsherlock/src/com/actionbarsherlock/widget/ActivityChooserView.java deleted file mode 100644 index e19ea9e9..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/widget/ActivityChooserView.java +++ /dev/null @@ -1,827 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.widget; - -import android.os.Build; -import com.actionbarsherlock.R; -import com.actionbarsherlock.internal.widget.IcsLinearLayout; -import com.actionbarsherlock.internal.widget.IcsListPopupWindow; -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.widget.ActivityChooserModel.ActivityChooserModelClient; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.database.DataSetObserver; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.view.ViewTreeObserver.OnGlobalLayoutListener; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.PopupWindow; -import android.widget.TextView; - -/** - * This class is a view for choosing an activity for handling a given {@link Intent}. - *

- * The view is composed of two adjacent buttons: - *

    - *
  • - * The left button is an immediate action and allows one click activity choosing. - * Tapping this button immediately executes the intent without requiring any further - * user input. Long press on this button shows a popup for changing the default - * activity. - *
  • - *
  • - * The right button is an overflow action and provides an optimized menu - * of additional activities. Tapping this button shows a popup anchored to this - * view, listing the most frequently used activities. This list is initially - * limited to a small number of items in frequency used order. The last item, - * "Show all..." serves as an affordance to display all available activities. - *
  • - *
- *

- * - * @hide - */ -class ActivityChooserView extends ViewGroup implements ActivityChooserModelClient { - - /** - * An adapter for displaying the activities in an {@link AdapterView}. - */ - private final ActivityChooserViewAdapter mAdapter; - - /** - * Implementation of various interfaces to avoid publishing them in the APIs. - */ - private final Callbacks mCallbacks; - - /** - * The content of this view. - */ - private final IcsLinearLayout mActivityChooserContent; - - /** - * Stores the background drawable to allow hiding and latter showing. - */ - private final Drawable mActivityChooserContentBackground; - - /** - * The expand activities action button; - */ - private final FrameLayout mExpandActivityOverflowButton; - - /** - * The image for the expand activities action button; - */ - private final ImageView mExpandActivityOverflowButtonImage; - - /** - * The default activities action button; - */ - private final FrameLayout mDefaultActivityButton; - - /** - * The image for the default activities action button; - */ - private final ImageView mDefaultActivityButtonImage; - - /** - * The maximal width of the list popup. - */ - private final int mListPopupMaxWidth; - - /** - * The ActionProvider hosting this view, if applicable. - */ - ActionProvider mProvider; - - /** - * Observer for the model data. - */ - private final DataSetObserver mModelDataSetOberver = new DataSetObserver() { - - @Override - public void onChanged() { - super.onChanged(); - mAdapter.notifyDataSetChanged(); - } - @Override - public void onInvalidated() { - super.onInvalidated(); - mAdapter.notifyDataSetInvalidated(); - } - }; - - private final OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - if (isShowingPopup()) { - if (!isShown()) { - getListPopupWindow().dismiss(); - } else { - getListPopupWindow().show(); - if (mProvider != null) { - mProvider.subUiVisibilityChanged(true); - } - } - } - } - }; - - /** - * Popup window for showing the activity overflow list. - */ - private IcsListPopupWindow mListPopupWindow; - - /** - * Listener for the dismissal of the popup/alert. - */ - private PopupWindow.OnDismissListener mOnDismissListener; - - /** - * Flag whether a default activity currently being selected. - */ - private boolean mIsSelectingDefaultActivity; - - /** - * The count of activities in the popup. - */ - private int mInitialActivityCount = ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT; - - /** - * Flag whether this view is attached to a window. - */ - private boolean mIsAttachedToWindow; - - /** - * String resource for formatting content description of the default target. - */ - private int mDefaultActionButtonContentDescription; - - private final Context mContext; - - /** - * Create a new instance. - * - * @param context The application environment. - */ - public ActivityChooserView(Context context) { - this(context, null); - } - - /** - * Create a new instance. - * - * @param context The application environment. - * @param attrs A collection of attributes. - */ - public ActivityChooserView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - /** - * Create a new instance. - * - * @param context The application environment. - * @param attrs A collection of attributes. - * @param defStyle The default style to apply to this view. - */ - public ActivityChooserView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - mContext = context; - - TypedArray attributesArray = context.obtainStyledAttributes(attrs, - R.styleable.SherlockActivityChooserView, defStyle, 0); - - mInitialActivityCount = attributesArray.getInt( - R.styleable.SherlockActivityChooserView_initialActivityCount, - ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT); - - Drawable expandActivityOverflowButtonDrawable = attributesArray.getDrawable( - R.styleable.SherlockActivityChooserView_expandActivityOverflowButtonDrawable); - - attributesArray.recycle(); - - LayoutInflater inflater = LayoutInflater.from(mContext); - inflater.inflate(R.layout.abs__activity_chooser_view, this, true); - - mCallbacks = new Callbacks(); - - mActivityChooserContent = (IcsLinearLayout) findViewById(R.id.abs__activity_chooser_view_content); - mActivityChooserContentBackground = mActivityChooserContent.getBackground(); - - mDefaultActivityButton = (FrameLayout) findViewById(R.id.abs__default_activity_button); - mDefaultActivityButton.setOnClickListener(mCallbacks); - mDefaultActivityButton.setOnLongClickListener(mCallbacks); - mDefaultActivityButtonImage = (ImageView) mDefaultActivityButton.findViewById(R.id.abs__image); - - mExpandActivityOverflowButton = (FrameLayout) findViewById(R.id.abs__expand_activities_button); - mExpandActivityOverflowButton.setOnClickListener(mCallbacks); - mExpandActivityOverflowButtonImage = - (ImageView) mExpandActivityOverflowButton.findViewById(R.id.abs__image); - mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable); - - mAdapter = new ActivityChooserViewAdapter(); - mAdapter.registerDataSetObserver(new DataSetObserver() { - @Override - public void onChanged() { - super.onChanged(); - updateAppearance(); - } - }); - - Resources resources = context.getResources(); - mListPopupMaxWidth = Math.max(resources.getDisplayMetrics().widthPixels / 2, - resources.getDimensionPixelSize(R.dimen.abs__config_prefDialogWidth)); - } - - /** - * {@inheritDoc} - */ - public void setActivityChooserModel(ActivityChooserModel dataModel) { - mAdapter.setDataModel(dataModel); - if (isShowingPopup()) { - dismissPopup(); - showPopup(); - } - } - - /** - * Sets the background for the button that expands the activity - * overflow list. - * - * Note: Clients would like to set this drawable - * as a clue about the action the chosen activity will perform. For - * example, if a share activity is to be chosen the drawable should - * give a clue that sharing is to be performed. - * - * @param drawable The drawable. - */ - public void setExpandActivityOverflowButtonDrawable(Drawable drawable) { - mExpandActivityOverflowButtonImage.setImageDrawable(drawable); - } - - /** - * Sets the content description for the button that expands the activity - * overflow list. - * - * description as a clue about the action performed by the button. - * For example, if a share activity is to be chosen the content - * description should be something like "Share with". - * - * @param resourceId The content description resource id. - */ - public void setExpandActivityOverflowButtonContentDescription(int resourceId) { - CharSequence contentDescription = mContext.getString(resourceId); - mExpandActivityOverflowButtonImage.setContentDescription(contentDescription); - } - - /** - * Set the provider hosting this view, if applicable. - * @hide Internal use only - */ - public void setProvider(ActionProvider provider) { - mProvider = provider; - } - - /** - * Shows the popup window with activities. - * - * @return True if the popup was shown, false if already showing. - */ - public boolean showPopup() { - if (isShowingPopup() || !mIsAttachedToWindow) { - return false; - } - mIsSelectingDefaultActivity = false; - showPopupUnchecked(mInitialActivityCount); - return true; - } - - /** - * Shows the popup no matter if it was already showing. - * - * @param maxActivityCount The max number of activities to display. - */ - private void showPopupUnchecked(int maxActivityCount) { - if (mAdapter.getDataModel() == null) { - throw new IllegalStateException("No data model. Did you call #setDataModel?"); - } - - getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener); - - final boolean defaultActivityButtonShown = - mDefaultActivityButton.getVisibility() == VISIBLE; - - final int activityCount = mAdapter.getActivityCount(); - final int maxActivityCountOffset = defaultActivityButtonShown ? 1 : 0; - if (maxActivityCount != ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED - && activityCount > maxActivityCount + maxActivityCountOffset) { - mAdapter.setShowFooterView(true); - mAdapter.setMaxActivityCount(maxActivityCount - 1); - } else { - mAdapter.setShowFooterView(false); - mAdapter.setMaxActivityCount(maxActivityCount); - } - - IcsListPopupWindow popupWindow = getListPopupWindow(); - if (!popupWindow.isShowing()) { - if (mIsSelectingDefaultActivity || !defaultActivityButtonShown) { - mAdapter.setShowDefaultActivity(true, defaultActivityButtonShown); - } else { - mAdapter.setShowDefaultActivity(false, false); - } - final int contentWidth = Math.min(mAdapter.measureContentWidth(), mListPopupMaxWidth); - popupWindow.setContentWidth(contentWidth); - popupWindow.show(); - if (mProvider != null) { - mProvider.subUiVisibilityChanged(true); - } - popupWindow.getListView().setContentDescription(mContext.getString( - R.string.abs__activitychooserview_choose_application)); - } - } - - /** - * Dismisses the popup window with activities. - * - * @return True if dismissed, false if already dismissed. - */ - public boolean dismissPopup() { - if (isShowingPopup()) { - getListPopupWindow().dismiss(); - ViewTreeObserver viewTreeObserver = getViewTreeObserver(); - if (viewTreeObserver.isAlive()) { - viewTreeObserver.removeGlobalOnLayoutListener(mOnGlobalLayoutListener); - } - } - return true; - } - - /** - * Gets whether the popup window with activities is shown. - * - * @return True if the popup is shown. - */ - public boolean isShowingPopup() { - return getListPopupWindow().isShowing(); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - ActivityChooserModel dataModel = mAdapter.getDataModel(); - if (dataModel != null) { - dataModel.registerObserver(mModelDataSetOberver); - } - mIsAttachedToWindow = true; - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - ActivityChooserModel dataModel = mAdapter.getDataModel(); - if (dataModel != null) { - try { - dataModel.unregisterObserver(mModelDataSetOberver); - } catch (IllegalStateException e) { - //Oh, well... fixes issue #557 - } - } - ViewTreeObserver viewTreeObserver = getViewTreeObserver(); - if (viewTreeObserver.isAlive()) { - viewTreeObserver.removeGlobalOnLayoutListener(mOnGlobalLayoutListener); - } - mIsAttachedToWindow = false; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - View child = mActivityChooserContent; - // If the default action is not visible we want to be as tall as the - // ActionBar so if this widget is used in the latter it will look as - // a normal action button. - if (mDefaultActivityButton.getVisibility() != VISIBLE) { - heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec), - MeasureSpec.EXACTLY); - } - measureChild(child, widthMeasureSpec, heightMeasureSpec); - setMeasuredDimension(child.getMeasuredWidth(), child.getMeasuredHeight()); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - mActivityChooserContent.layout(0, 0, right - left, bottom - top); - if (getListPopupWindow().isShowing()) { - showPopupUnchecked(mAdapter.getMaxActivityCount()); - } else { - dismissPopup(); - } - } - - public ActivityChooserModel getDataModel() { - return mAdapter.getDataModel(); - } - - /** - * Sets a listener to receive a callback when the popup is dismissed. - * - * @param listener The listener to be notified. - */ - public void setOnDismissListener(PopupWindow.OnDismissListener listener) { - mOnDismissListener = listener; - } - - /** - * Sets the initial count of items shown in the activities popup - * i.e. the items before the popup is expanded. This is an upper - * bound since it is not guaranteed that such number of intent - * handlers exist. - * - * @param itemCount The initial popup item count. - */ - public void setInitialActivityCount(int itemCount) { - mInitialActivityCount = itemCount; - } - - /** - * Sets a content description of the default action button. This - * resource should be a string taking one formatting argument and - * will be used for formatting the content description of the button - * dynamically as the default target changes. For example, a resource - * pointing to the string "share with %1$s" will result in a content - * description "share with Bluetooth" for the Bluetooth activity. - * - * @param resourceId The resource id. - */ - public void setDefaultActionButtonContentDescription(int resourceId) { - mDefaultActionButtonContentDescription = resourceId; - } - - /** - * Gets the list popup window which is lazily initialized. - * - * @return The popup. - */ - private IcsListPopupWindow getListPopupWindow() { - if (mListPopupWindow == null) { - mListPopupWindow = new IcsListPopupWindow(getContext()); - mListPopupWindow.setAdapter(mAdapter); - mListPopupWindow.setAnchorView(ActivityChooserView.this); - mListPopupWindow.setModal(true); - mListPopupWindow.setOnItemClickListener(mCallbacks); - mListPopupWindow.setOnDismissListener(mCallbacks); - } - return mListPopupWindow; - } - - /** - * Updates the buttons state. - */ - private void updateAppearance() { - // Expand overflow button. - if (mAdapter.getCount() > 0) { - mExpandActivityOverflowButton.setEnabled(true); - } else { - mExpandActivityOverflowButton.setEnabled(false); - } - // Default activity button. - final int activityCount = mAdapter.getActivityCount(); - final int historySize = mAdapter.getHistorySize(); - if (activityCount > 0 && historySize > 0) { - mDefaultActivityButton.setVisibility(VISIBLE); - ResolveInfo activity = mAdapter.getDefaultActivity(); - PackageManager packageManager = mContext.getPackageManager(); - mDefaultActivityButtonImage.setImageDrawable(activity.loadIcon(packageManager)); - if (mDefaultActionButtonContentDescription != 0) { - CharSequence label = activity.loadLabel(packageManager); - String contentDescription = mContext.getString( - mDefaultActionButtonContentDescription, label); - mDefaultActivityButton.setContentDescription(contentDescription); - } - } else { - mDefaultActivityButton.setVisibility(View.GONE); - } - // Activity chooser content. - if (mDefaultActivityButton.getVisibility() == VISIBLE) { - mActivityChooserContent.setBackgroundDrawable(mActivityChooserContentBackground); - } else { - mActivityChooserContent.setBackgroundDrawable(null); - mActivityChooserContent.setPadding(0, 0, 0, 0); - } - } - - /** - * Interface implementation to avoid publishing them in the APIs. - */ - private class Callbacks implements AdapterView.OnItemClickListener, - View.OnClickListener, View.OnLongClickListener, PopupWindow.OnDismissListener { - - // AdapterView#OnItemClickListener - public void onItemClick(AdapterView parent, View view, int position, long id) { - ActivityChooserViewAdapter adapter = (ActivityChooserViewAdapter) parent.getAdapter(); - final int itemViewType = adapter.getItemViewType(position); - switch (itemViewType) { - case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_FOOTER: { - showPopupUnchecked(ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_UNLIMITED); - } break; - case ActivityChooserViewAdapter.ITEM_VIEW_TYPE_ACTIVITY: { - dismissPopup(); - if (mIsSelectingDefaultActivity) { - // The item at position zero is the default already. - if (position > 0) { - mAdapter.getDataModel().setDefaultActivity(position); - } - } else { - // If the default target is not shown in the list, the first - // item in the model is default action => adjust index - position = mAdapter.getShowDefaultActivity() ? position : position + 1; - Intent launchIntent = mAdapter.getDataModel().chooseActivity(position); - if (launchIntent != null) { - mContext.startActivity(launchIntent); - } - } - } break; - default: - throw new IllegalArgumentException(); - } - } - - // View.OnClickListener - public void onClick(View view) { - if (view == mDefaultActivityButton) { - dismissPopup(); - ResolveInfo defaultActivity = mAdapter.getDefaultActivity(); - final int index = mAdapter.getDataModel().getActivityIndex(defaultActivity); - Intent launchIntent = mAdapter.getDataModel().chooseActivity(index); - if (launchIntent != null) { - mContext.startActivity(launchIntent); - } - } else if (view == mExpandActivityOverflowButton) { - mIsSelectingDefaultActivity = false; - showPopupUnchecked(mInitialActivityCount); - } else { - throw new IllegalArgumentException(); - } - } - - // OnLongClickListener#onLongClick - @Override - public boolean onLongClick(View view) { - if (view == mDefaultActivityButton) { - if (mAdapter.getCount() > 0) { - mIsSelectingDefaultActivity = true; - showPopupUnchecked(mInitialActivityCount); - } - } else { - throw new IllegalArgumentException(); - } - return true; - } - - // PopUpWindow.OnDismissListener#onDismiss - public void onDismiss() { - notifyOnDismissListener(); - if (mProvider != null) { - mProvider.subUiVisibilityChanged(false); - } - } - - private void notifyOnDismissListener() { - if (mOnDismissListener != null) { - mOnDismissListener.onDismiss(); - } - } - } - - private static class SetActivated { - public static void invoke(View view, boolean activated) { - view.setActivated(activated); - } - } - - private static final boolean IS_HONEYCOMB = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; - - /** - * Adapter for backing the list of activities shown in the popup. - */ - private class ActivityChooserViewAdapter extends BaseAdapter { - - public static final int MAX_ACTIVITY_COUNT_UNLIMITED = Integer.MAX_VALUE; - - public static final int MAX_ACTIVITY_COUNT_DEFAULT = 4; - - private static final int ITEM_VIEW_TYPE_ACTIVITY = 0; - - private static final int ITEM_VIEW_TYPE_FOOTER = 1; - - private static final int ITEM_VIEW_TYPE_COUNT = 3; - - private ActivityChooserModel mDataModel; - - private int mMaxActivityCount = MAX_ACTIVITY_COUNT_DEFAULT; - - private boolean mShowDefaultActivity; - - private boolean mHighlightDefaultActivity; - - private boolean mShowFooterView; - - public void setDataModel(ActivityChooserModel dataModel) { - ActivityChooserModel oldDataModel = mAdapter.getDataModel(); - if (oldDataModel != null && isShown()) { - try { - oldDataModel.unregisterObserver(mModelDataSetOberver); - } catch (IllegalStateException e) { - //Oh, well... fixes issue #557 - } - } - mDataModel = dataModel; - if (dataModel != null && isShown()) { - dataModel.registerObserver(mModelDataSetOberver); - } - notifyDataSetChanged(); - } - - @Override - public int getItemViewType(int position) { - if (mShowFooterView && position == getCount() - 1) { - return ITEM_VIEW_TYPE_FOOTER; - } else { - return ITEM_VIEW_TYPE_ACTIVITY; - } - } - - @Override - public int getViewTypeCount() { - return ITEM_VIEW_TYPE_COUNT; - } - - public int getCount() { - int count = 0; - int activityCount = mDataModel.getActivityCount(); - if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) { - activityCount--; - } - count = Math.min(activityCount, mMaxActivityCount); - if (mShowFooterView) { - count++; - } - return count; - } - - public Object getItem(int position) { - final int itemViewType = getItemViewType(position); - switch (itemViewType) { - case ITEM_VIEW_TYPE_FOOTER: - return null; - case ITEM_VIEW_TYPE_ACTIVITY: - if (!mShowDefaultActivity && mDataModel.getDefaultActivity() != null) { - position++; - } - return mDataModel.getActivity(position); - default: - throw new IllegalArgumentException(); - } - } - - public long getItemId(int position) { - return position; - } - - public View getView(int position, View convertView, ViewGroup parent) { - final int itemViewType = getItemViewType(position); - switch (itemViewType) { - case ITEM_VIEW_TYPE_FOOTER: - if (convertView == null || convertView.getId() != ITEM_VIEW_TYPE_FOOTER) { - convertView = LayoutInflater.from(getContext()).inflate( - R.layout.abs__activity_chooser_view_list_item, parent, false); - convertView.setId(ITEM_VIEW_TYPE_FOOTER); - TextView titleView = (TextView) convertView.findViewById(R.id.abs__title); - titleView.setText(mContext.getString( - R.string.abs__activity_chooser_view_see_all)); - } - return convertView; - case ITEM_VIEW_TYPE_ACTIVITY: - if (convertView == null || convertView.getId() != R.id.abs__list_item) { - convertView = LayoutInflater.from(getContext()).inflate( - R.layout.abs__activity_chooser_view_list_item, parent, false); - } - PackageManager packageManager = mContext.getPackageManager(); - // Set the icon - ImageView iconView = (ImageView) convertView.findViewById(R.id.abs__icon); - ResolveInfo activity = (ResolveInfo) getItem(position); - iconView.setImageDrawable(activity.loadIcon(packageManager)); - // Set the title. - TextView titleView = (TextView) convertView.findViewById(R.id.abs__title); - titleView.setText(activity.loadLabel(packageManager)); - if (IS_HONEYCOMB) { - // Highlight the default. - if (mShowDefaultActivity && position == 0 && mHighlightDefaultActivity) { - SetActivated.invoke(convertView, true); - } else { - SetActivated.invoke(convertView, false); - } - } - return convertView; - default: - throw new IllegalArgumentException(); - } - } - - public int measureContentWidth() { - // The user may have specified some of the target not to be shown but we - // want to measure all of them since after expansion they should fit. - final int oldMaxActivityCount = mMaxActivityCount; - mMaxActivityCount = MAX_ACTIVITY_COUNT_UNLIMITED; - - int contentWidth = 0; - View itemView = null; - - final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - final int count = getCount(); - - for (int i = 0; i < count; i++) { - itemView = getView(i, itemView, null); - itemView.measure(widthMeasureSpec, heightMeasureSpec); - contentWidth = Math.max(contentWidth, itemView.getMeasuredWidth()); - } - - mMaxActivityCount = oldMaxActivityCount; - - return contentWidth; - } - - public void setMaxActivityCount(int maxActivityCount) { - if (mMaxActivityCount != maxActivityCount) { - mMaxActivityCount = maxActivityCount; - notifyDataSetChanged(); - } - } - - public ResolveInfo getDefaultActivity() { - return mDataModel.getDefaultActivity(); - } - - public void setShowFooterView(boolean showFooterView) { - if (mShowFooterView != showFooterView) { - mShowFooterView = showFooterView; - notifyDataSetChanged(); - } - } - - public int getActivityCount() { - return mDataModel.getActivityCount(); - } - - public int getHistorySize() { - return mDataModel.getHistorySize(); - } - - public int getMaxActivityCount() { - return mMaxActivityCount; - } - - public ActivityChooserModel getDataModel() { - return mDataModel; - } - - public void setShowDefaultActivity(boolean showDefaultActivity, - boolean highlightDefaultActivity) { - if (mShowDefaultActivity != showDefaultActivity - || mHighlightDefaultActivity != highlightDefaultActivity) { - mShowDefaultActivity = showDefaultActivity; - mHighlightDefaultActivity = highlightDefaultActivity; - notifyDataSetChanged(); - } - } - - public boolean getShowDefaultActivity() { - return mShowDefaultActivity; - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/widget/SearchView.java b/actionbarsherlock/src/com/actionbarsherlock/widget/SearchView.java deleted file mode 100644 index c9e7897d..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/widget/SearchView.java +++ /dev/null @@ -1,1811 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.widget; - -import android.app.PendingIntent; -import android.app.SearchManager; -import android.app.SearchableInfo; -import android.content.ActivityNotFoundException; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.database.Cursor; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.ResultReceiver; -import android.speech.RecognizerIntent; -import android.support.v4.view.KeyEventCompat; -import android.support.v4.widget.CursorAdapter; -import android.text.Editable; -import android.text.InputType; -import android.text.Spannable; -import android.text.SpannableStringBuilder; -import android.text.TextUtils; -import android.text.TextWatcher; -import android.text.style.ImageSpan; -import android.util.AttributeSet; -import android.util.Log; -import android.util.TypedValue; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewTreeObserver; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.AdapterView.OnItemSelectedListener; -import android.widget.AutoCompleteTextView; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.TextView.OnEditorActionListener; -import com.actionbarsherlock.R; -import com.actionbarsherlock.view.CollapsibleActionView; - -import java.lang.reflect.Method; -import java.util.WeakHashMap; - -import static com.actionbarsherlock.widget.SuggestionsAdapter.getColumnString; - -/** - * A widget that provides a user interface for the user to enter a search query and submit a request - * to a search provider. Shows a list of query suggestions or results, if available, and allows the - * user to pick a suggestion or result to launch into. - * - *

- * When the SearchView is used in an ActionBar as an action view for a collapsible menu item, it - * needs to be set to iconified by default using {@link #setIconifiedByDefault(boolean) - * setIconifiedByDefault(true)}. This is the default, so nothing needs to be done. - *

- *

- * If you want the search field to always be visible, then call setIconifiedByDefault(false). - *

- * - *
- *

Developer Guides

- *

For information about using {@code SearchView}, read the - * Search developer guide.

- *
- * - * @see android.view.MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW - * @attr ref android.R.styleable#SearchView_iconifiedByDefault - * @attr ref android.R.styleable#SearchView_imeOptions - * @attr ref android.R.styleable#SearchView_inputType - * @attr ref android.R.styleable#SearchView_maxWidth - * @attr ref android.R.styleable#SearchView_queryHint - */ -public class SearchView extends LinearLayout implements CollapsibleActionView { - - private static final boolean DBG = false; - private static final String LOG_TAG = "SearchView"; - - /** - * Private constant for removing the microphone in the keyboard. - */ - private static final String IME_OPTION_NO_MICROPHONE = "nm"; - - private OnQueryTextListener mOnQueryChangeListener; - private OnCloseListener mOnCloseListener; - private OnFocusChangeListener mOnQueryTextFocusChangeListener; - private OnSuggestionListener mOnSuggestionListener; - private OnClickListener mOnSearchClickListener; - - private boolean mIconifiedByDefault; - private boolean mIconified; - private CursorAdapter mSuggestionsAdapter; - private View mSearchButton; - private View mSubmitButton; - private View mSearchPlate; - private View mSubmitArea; - private ImageView mCloseButton; - private View mSearchEditFrame; - private View mVoiceButton; - private SearchAutoComplete mQueryTextView; - private View mDropDownAnchor; - private ImageView mSearchHintIcon; - private boolean mSubmitButtonEnabled; - private CharSequence mQueryHint; - private boolean mQueryRefinement; - private boolean mClearingFocus; - private int mMaxWidth; - private boolean mVoiceButtonEnabled; - private CharSequence mOldQueryText; - private CharSequence mUserQuery; - private boolean mExpandedInActionView; - private int mCollapsedImeOptions; - - private SearchableInfo mSearchable; - private Bundle mAppSearchData; - - /* - * SearchView can be set expanded before the IME is ready to be shown during - * initial UI setup. The show operation is asynchronous to account for this. - */ - private Runnable mShowImeRunnable = new Runnable() { - public void run() { - InputMethodManager imm = (InputMethodManager) - getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - - if (imm != null) { - showSoftInputUnchecked(SearchView.this, imm, 0); - } - } - }; - - private Runnable mUpdateDrawableStateRunnable = new Runnable() { - public void run() { - updateFocusedState(); - } - }; - - private Runnable mReleaseCursorRunnable = new Runnable() { - public void run() { - if (mSuggestionsAdapter != null && mSuggestionsAdapter instanceof SuggestionsAdapter) { - mSuggestionsAdapter.changeCursor(null); - } - } - }; - - // For voice searching - private final Intent mVoiceWebSearchIntent; - private final Intent mVoiceAppSearchIntent; - - // A weak map of drawables we've gotten from other packages, so we don't load them - // more than once. - private final WeakHashMap mOutsideDrawablesCache = - new WeakHashMap(); - - /** - * Callbacks for changes to the query text. - */ - public interface OnQueryTextListener { - - /** - * Called when the user submits the query. This could be due to a key press on the - * keyboard or due to pressing a submit button. - * The listener can override the standard behavior by returning true - * to indicate that it has handled the submit request. Otherwise return false to - * let the SearchView handle the submission by launching any associated intent. - * - * @param query the query text that is to be submitted - * - * @return true if the query has been handled by the listener, false to let the - * SearchView perform the default action. - */ - boolean onQueryTextSubmit(String query); - - /** - * Called when the query text is changed by the user. - * - * @param newText the new content of the query text field. - * - * @return false if the SearchView should perform the default action of showing any - * suggestions if available, true if the action was handled by the listener. - */ - boolean onQueryTextChange(String newText); - } - - public interface OnCloseListener { - - /** - * The user is attempting to close the SearchView. - * - * @return true if the listener wants to override the default behavior of clearing the - * text field and dismissing it, false otherwise. - */ - boolean onClose(); - } - - /** - * Callback interface for selection events on suggestions. These callbacks - * are only relevant when a SearchableInfo has been specified by {@link #setSearchableInfo}. - */ - public interface OnSuggestionListener { - - /** - * Called when a suggestion was selected by navigating to it. - * @param position the absolute position in the list of suggestions. - * - * @return true if the listener handles the event and wants to override the default - * behavior of possibly rewriting the query based on the selected item, false otherwise. - */ - boolean onSuggestionSelect(int position); - - /** - * Called when a suggestion was clicked. - * @param position the absolute position of the clicked item in the list of suggestions. - * - * @return true if the listener handles the event and wants to override the default - * behavior of launching any intent or submitting a search query specified on that item. - * Return false otherwise. - */ - boolean onSuggestionClick(int position); - } - - public SearchView(Context context) { - this(context, null); - } - - public SearchView(Context context, AttributeSet attrs) { - super(context, attrs); - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { - throw new IllegalStateException("SearchView is API 8+ only."); - } - - LayoutInflater inflater = (LayoutInflater) context - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - inflater.inflate(R.layout.abs__search_view, this, true); - - mSearchButton = findViewById(R.id.abs__search_button); - mQueryTextView = (SearchAutoComplete) findViewById(R.id.abs__search_src_text); - mQueryTextView.setSearchView(this); - - mSearchEditFrame = findViewById(R.id.abs__search_edit_frame); - mSearchPlate = findViewById(R.id.abs__search_plate); - mSubmitArea = findViewById(R.id.abs__submit_area); - mSubmitButton = findViewById(R.id.abs__search_go_btn); - mCloseButton = (ImageView) findViewById(R.id.abs__search_close_btn); - mVoiceButton = findViewById(R.id.abs__search_voice_btn); - mSearchHintIcon = (ImageView) findViewById(R.id.abs__search_mag_icon); - - mSearchButton.setOnClickListener(mOnClickListener); - mCloseButton.setOnClickListener(mOnClickListener); - mSubmitButton.setOnClickListener(mOnClickListener); - mVoiceButton.setOnClickListener(mOnClickListener); - mQueryTextView.setOnClickListener(mOnClickListener); - - mQueryTextView.addTextChangedListener(mTextWatcher); - mQueryTextView.setOnEditorActionListener(mOnEditorActionListener); - mQueryTextView.setOnItemClickListener(mOnItemClickListener); - mQueryTextView.setOnItemSelectedListener(mOnItemSelectedListener); - mQueryTextView.setOnKeyListener(mTextKeyListener); - // Inform any listener of focus changes - mQueryTextView.setOnFocusChangeListener(new OnFocusChangeListener() { - - public void onFocusChange(View v, boolean hasFocus) { - if (mOnQueryTextFocusChangeListener != null) { - mOnQueryTextFocusChangeListener.onFocusChange(SearchView.this, hasFocus); - } - } - }); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockSearchView, 0, 0); - setIconifiedByDefault(a.getBoolean(R.styleable.SherlockSearchView_iconifiedByDefault, true)); - int maxWidth = a.getDimensionPixelSize(R.styleable.SherlockSearchView_android_maxWidth, -1); - if (maxWidth != -1) { - setMaxWidth(maxWidth); - } - CharSequence queryHint = a.getText(R.styleable.SherlockSearchView_queryHint); - if (!TextUtils.isEmpty(queryHint)) { - setQueryHint(queryHint); - } - int imeOptions = a.getInt(R.styleable.SherlockSearchView_android_imeOptions, -1); - if (imeOptions != -1) { - setImeOptions(imeOptions); - } - int inputType = a.getInt(R.styleable.SherlockSearchView_android_inputType, -1); - if (inputType != -1) { - setInputType(inputType); - } - - a.recycle(); - - boolean focusable = true; - - a = context.obtainStyledAttributes(attrs, R.styleable.SherlockView, 0, 0); - focusable = a.getBoolean(R.styleable.SherlockView_android_focusable, focusable); - a.recycle(); - setFocusable(focusable); - - // Save voice intent for later queries/launching - mVoiceWebSearchIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH); - mVoiceWebSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mVoiceWebSearchIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, - RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH); - - mVoiceAppSearchIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); - mVoiceAppSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - - mDropDownAnchor = findViewById(mQueryTextView.getDropDownAnchor()); - if (mDropDownAnchor != null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - mDropDownAnchor.addOnLayoutChangeListener(new OnLayoutChangeListener() { - @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, - int oldLeft, int oldTop, int oldRight, int oldBottom) { - adjustDropDownSizeAndPosition(); - } - }); - } else { - mDropDownAnchor.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override public void onGlobalLayout() { - adjustDropDownSizeAndPosition(); - } - }); - } - } - - updateViewsVisibility(mIconifiedByDefault); - updateQueryHint(); - } - - /** - * Sets the SearchableInfo for this SearchView. Properties in the SearchableInfo are used - * to display labels, hints, suggestions, create intents for launching search results screens - * and controlling other affordances such as a voice button. - * - * @param searchable a SearchableInfo can be retrieved from the SearchManager, for a specific - * activity or a global search provider. - */ - public void setSearchableInfo(SearchableInfo searchable) { - mSearchable = searchable; - if (mSearchable != null) { - updateSearchAutoComplete(); - updateQueryHint(); - } - // Cache the voice search capability - mVoiceButtonEnabled = hasVoiceSearch(); - - if (mVoiceButtonEnabled) { - // Disable the microphone on the keyboard, as a mic is displayed near the text box - // TODO: use imeOptions to disable voice input when the new API will be available - mQueryTextView.setPrivateImeOptions(IME_OPTION_NO_MICROPHONE); - } - updateViewsVisibility(isIconified()); - } - - /** - * Sets the APP_DATA for legacy SearchDialog use. - * @param appSearchData bundle provided by the app when launching the search dialog - * @hide - */ - public void setAppSearchData(Bundle appSearchData) { - mAppSearchData = appSearchData; - } - - /** - * Sets the IME options on the query text field. - * - * @see TextView#setImeOptions(int) - * @param imeOptions the options to set on the query text field - * - * @attr ref android.R.styleable#SearchView_imeOptions - */ - public void setImeOptions(int imeOptions) { - mQueryTextView.setImeOptions(imeOptions); - } - - /** - * Returns the IME options set on the query text field. - * @return the ime options - * @see TextView#setImeOptions(int) - * - * @attr ref android.R.styleable#SearchView_imeOptions - */ - public int getImeOptions() { - return mQueryTextView.getImeOptions(); - } - - /** - * Sets the input type on the query text field. - * - * @see TextView#setInputType(int) - * @param inputType the input type to set on the query text field - * - * @attr ref android.R.styleable#SearchView_inputType - */ - public void setInputType(int inputType) { - mQueryTextView.setInputType(inputType); - } - - /** - * Returns the input type set on the query text field. - * @return the input type - * - * @attr ref android.R.styleable#SearchView_inputType - */ - public int getInputType() { - return mQueryTextView.getInputType(); - } - - /** @hide */ - @Override - public boolean requestFocus(int direction, Rect previouslyFocusedRect) { - // Don't accept focus if in the middle of clearing focus - if (mClearingFocus) return false; - // Check if SearchView is focusable. - if (!isFocusable()) return false; - // If it is not iconified, then give the focus to the text field - if (!isIconified()) { - boolean result = mQueryTextView.requestFocus(direction, previouslyFocusedRect); - if (result) { - updateViewsVisibility(false); - } - return result; - } else { - return super.requestFocus(direction, previouslyFocusedRect); - } - } - - /** @hide */ - @Override - public void clearFocus() { - mClearingFocus = true; - setImeVisibility(false); - super.clearFocus(); - mQueryTextView.clearFocus(); - mClearingFocus = false; - } - - /** - * Sets a listener for user actions within the SearchView. - * - * @param listener the listener object that receives callbacks when the user performs - * actions in the SearchView such as clicking on buttons or typing a query. - */ - public void setOnQueryTextListener(OnQueryTextListener listener) { - mOnQueryChangeListener = listener; - } - - /** - * Sets a listener to inform when the user closes the SearchView. - * - * @param listener the listener to call when the user closes the SearchView. - */ - public void setOnCloseListener(OnCloseListener listener) { - mOnCloseListener = listener; - } - - /** - * Sets a listener to inform when the focus of the query text field changes. - * - * @param listener the listener to inform of focus changes. - */ - public void setOnQueryTextFocusChangeListener(OnFocusChangeListener listener) { - mOnQueryTextFocusChangeListener = listener; - } - - /** - * Sets a listener to inform when a suggestion is focused or clicked. - * - * @param listener the listener to inform of suggestion selection events. - */ - public void setOnSuggestionListener(OnSuggestionListener listener) { - mOnSuggestionListener = listener; - } - - /** - * Sets a listener to inform when the search button is pressed. This is only - * relevant when the text field is not visible by default. Calling {@link #setIconified - * setIconified(false)} can also cause this listener to be informed. - * - * @param listener the listener to inform when the search button is clicked or - * the text field is programmatically de-iconified. - */ - public void setOnSearchClickListener(OnClickListener listener) { - mOnSearchClickListener = listener; - } - - /** - * Returns the query string currently in the text field. - * - * @return the query string - */ - public CharSequence getQuery() { - return mQueryTextView.getText(); - } - - /** - * Sets a query string in the text field and optionally submits the query as well. - * - * @param query the query string. This replaces any query text already present in the - * text field. - * @param submit whether to submit the query right now or only update the contents of - * text field. - */ - public void setQuery(CharSequence query, boolean submit) { - mQueryTextView.setText(query); - if (query != null) { - mQueryTextView.setSelection(mQueryTextView.length()); - mUserQuery = query; - } - - // If the query is not empty and submit is requested, submit the query - if (submit && !TextUtils.isEmpty(query)) { - onSubmitQuery(); - } - } - - /** - * Sets the hint text to display in the query text field. This overrides any hint specified - * in the SearchableInfo. - * - * @param hint the hint text to display - * - * @attr ref android.R.styleable#SearchView_queryHint - */ - public void setQueryHint(CharSequence hint) { - mQueryHint = hint; - updateQueryHint(); - } - - /** - * Gets the hint text to display in the query text field. - * @return the query hint text, if specified, null otherwise. - * - * @attr ref android.R.styleable#SearchView_queryHint - */ - public CharSequence getQueryHint() { - if (mQueryHint != null) { - return mQueryHint; - } else if (mSearchable != null) { - CharSequence hint = null; - int hintId = mSearchable.getHintId(); - if (hintId != 0) { - hint = getContext().getString(hintId); - } - return hint; - } - return null; - } - - /** - * Sets the default or resting state of the search field. If true, a single search icon is - * shown by default and expands to show the text field and other buttons when pressed. Also, - * if the default state is iconified, then it collapses to that state when the close button - * is pressed. Changes to this property will take effect immediately. - * - *

The default value is true.

- * - * @param iconified whether the search field should be iconified by default - * - * @attr ref android.R.styleable#SearchView_iconifiedByDefault - */ - public void setIconifiedByDefault(boolean iconified) { - if (mIconifiedByDefault == iconified) return; - mIconifiedByDefault = iconified; - updateViewsVisibility(iconified); - updateQueryHint(); - } - - /** - * Returns the default iconified state of the search field. - * @return - * - * @attr ref android.R.styleable#SearchView_iconifiedByDefault - */ - public boolean isIconfiedByDefault() { - return mIconifiedByDefault; - } - - /** - * Iconifies or expands the SearchView. Any query text is cleared when iconified. This is - * a temporary state and does not override the default iconified state set by - * {@link #setIconifiedByDefault(boolean)}. If the default state is iconified, then - * a false here will only be valid until the user closes the field. And if the default - * state is expanded, then a true here will only clear the text field and not close it. - * - * @param iconify a true value will collapse the SearchView to an icon, while a false will - * expand it. - */ - public void setIconified(boolean iconify) { - if (iconify) { - onCloseClicked(); - } else { - onSearchClicked(); - } - } - - /** - * Returns the current iconified state of the SearchView. - * - * @return true if the SearchView is currently iconified, false if the search field is - * fully visible. - */ - public boolean isIconified() { - return mIconified; - } - - /** - * Enables showing a submit button when the query is non-empty. In cases where the SearchView - * is being used to filter the contents of the current activity and doesn't launch a separate - * results activity, then the submit button should be disabled. - * - * @param enabled true to show a submit button for submitting queries, false if a submit - * button is not required. - */ - public void setSubmitButtonEnabled(boolean enabled) { - mSubmitButtonEnabled = enabled; - updateViewsVisibility(isIconified()); - } - - /** - * Returns whether the submit button is enabled when necessary or never displayed. - * - * @return whether the submit button is enabled automatically when necessary - */ - public boolean isSubmitButtonEnabled() { - return mSubmitButtonEnabled; - } - - /** - * Specifies if a query refinement button should be displayed alongside each suggestion - * or if it should depend on the flags set in the individual items retrieved from the - * suggestions provider. Clicking on the query refinement button will replace the text - * in the query text field with the text from the suggestion. This flag only takes effect - * if a SearchableInfo has been specified with {@link #setSearchableInfo(SearchableInfo)} - * and not when using a custom adapter. - * - * @param enable true if all items should have a query refinement button, false if only - * those items that have a query refinement flag set should have the button. - * - * @see SearchManager#SUGGEST_COLUMN_FLAGS - * @see SearchManager#FLAG_QUERY_REFINEMENT - */ - public void setQueryRefinementEnabled(boolean enable) { - mQueryRefinement = enable; - if (mSuggestionsAdapter instanceof SuggestionsAdapter) { - ((SuggestionsAdapter) mSuggestionsAdapter).setQueryRefinement( - enable ? SuggestionsAdapter.REFINE_ALL : SuggestionsAdapter.REFINE_BY_ENTRY); - } - } - - /** - * Returns whether query refinement is enabled for all items or only specific ones. - * @return true if enabled for all items, false otherwise. - */ - public boolean isQueryRefinementEnabled() { - return mQueryRefinement; - } - - /** - * You can set a custom adapter if you wish. Otherwise the default adapter is used to - * display the suggestions from the suggestions provider associated with the SearchableInfo. - * - * @see #setSearchableInfo(SearchableInfo) - */ - public void setSuggestionsAdapter(CursorAdapter adapter) { - mSuggestionsAdapter = adapter; - - mQueryTextView.setAdapter(mSuggestionsAdapter); - } - - /** - * Returns the adapter used for suggestions, if any. - * @return the suggestions adapter - */ - public CursorAdapter getSuggestionsAdapter() { - return mSuggestionsAdapter; - } - - /** - * Makes the view at most this many pixels wide - * - * @attr ref android.R.styleable#SearchView_maxWidth - */ - public void setMaxWidth(int maxpixels) { - mMaxWidth = maxpixels; - - requestLayout(); - } - - /** - * Gets the specified maximum width in pixels, if set. Returns zero if - * no maximum width was specified. - * @return the maximum width of the view - * - * @attr ref android.R.styleable#SearchView_maxWidth - */ - public int getMaxWidth() { - return mMaxWidth; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // Let the standard measurements take effect in iconified state. - if (isIconified()) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - return; - } - - int widthMode = MeasureSpec.getMode(widthMeasureSpec); - int width = MeasureSpec.getSize(widthMeasureSpec); - - switch (widthMode) { - case MeasureSpec.AT_MOST: - // If there is an upper limit, don't exceed maximum width (explicit or implicit) - if (mMaxWidth > 0) { - width = Math.min(mMaxWidth, width); - } else { - width = Math.min(getPreferredWidth(), width); - } - break; - case MeasureSpec.EXACTLY: - // If an exact width is specified, still don't exceed any specified maximum width - if (mMaxWidth > 0) { - width = Math.min(mMaxWidth, width); - } - break; - case MeasureSpec.UNSPECIFIED: - // Use maximum width, if specified, else preferred width - width = mMaxWidth > 0 ? mMaxWidth : getPreferredWidth(); - break; - } - widthMode = MeasureSpec.EXACTLY; - super.onMeasure(MeasureSpec.makeMeasureSpec(width, widthMode), heightMeasureSpec); - } - - private int getPreferredWidth() { - return getContext().getResources() - .getDimensionPixelSize(R.dimen.abs__search_view_preferred_width); - } - - private void updateViewsVisibility(final boolean collapsed) { - mIconified = collapsed; - // Visibility of views that are visible when collapsed - final int visCollapsed = collapsed ? VISIBLE : GONE; - // Is there text in the query - final boolean hasText = !TextUtils.isEmpty(mQueryTextView.getText()); - - mSearchButton.setVisibility(visCollapsed); - updateSubmitButton(hasText); - mSearchEditFrame.setVisibility(collapsed ? GONE : VISIBLE); - mSearchHintIcon.setVisibility(mIconifiedByDefault ? GONE : VISIBLE); - updateCloseButton(); - updateVoiceButton(!hasText); - updateSubmitArea(); - } - - private boolean hasVoiceSearch() { - if (mSearchable != null && mSearchable.getVoiceSearchEnabled()) { - Intent testIntent = null; - if (mSearchable.getVoiceSearchLaunchWebSearch()) { - testIntent = mVoiceWebSearchIntent; - } else if (mSearchable.getVoiceSearchLaunchRecognizer()) { - testIntent = mVoiceAppSearchIntent; - } - if (testIntent != null) { - ResolveInfo ri = getContext().getPackageManager().resolveActivity(testIntent, - PackageManager.MATCH_DEFAULT_ONLY); - return ri != null; - } - } - return false; - } - - private boolean isSubmitAreaEnabled() { - return (mSubmitButtonEnabled || mVoiceButtonEnabled) && !isIconified(); - } - - private void updateSubmitButton(boolean hasText) { - int visibility = GONE; - if (mSubmitButtonEnabled && isSubmitAreaEnabled() && hasFocus() - && (hasText || !mVoiceButtonEnabled)) { - visibility = VISIBLE; - } - mSubmitButton.setVisibility(visibility); - } - - private void updateSubmitArea() { - int visibility = GONE; - if (isSubmitAreaEnabled() - && (mSubmitButton.getVisibility() == VISIBLE - || mVoiceButton.getVisibility() == VISIBLE)) { - visibility = VISIBLE; - } - mSubmitArea.setVisibility(visibility); - } - - private void updateCloseButton() { - final boolean hasText = !TextUtils.isEmpty(mQueryTextView.getText()); - // Should we show the close button? It is not shown if there's no focus, - // field is not iconified by default and there is no text in it. - final boolean showClose = hasText || (mIconifiedByDefault && !mExpandedInActionView); - mCloseButton.setVisibility(showClose ? VISIBLE : GONE); - mCloseButton.getDrawable().setState(hasText ? ENABLED_STATE_SET : EMPTY_STATE_SET); - } - - private void postUpdateFocusedState() { - post(mUpdateDrawableStateRunnable); - } - - private void updateFocusedState() { - boolean focused = mQueryTextView.hasFocus(); - mSearchPlate.getBackground().setState(focused ? FOCUSED_STATE_SET : EMPTY_STATE_SET); - mSubmitArea.getBackground().setState(focused ? FOCUSED_STATE_SET : EMPTY_STATE_SET); - invalidate(); - } - - @Override - protected void onDetachedFromWindow() { - removeCallbacks(mUpdateDrawableStateRunnable); - post(mReleaseCursorRunnable); - super.onDetachedFromWindow(); - } - - private void setImeVisibility(final boolean visible) { - if (visible) { - post(mShowImeRunnable); - } else { - removeCallbacks(mShowImeRunnable); - InputMethodManager imm = (InputMethodManager) - getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - - if (imm != null) { - imm.hideSoftInputFromWindow(getWindowToken(), 0); - } - } - } - - /** - * Called by the SuggestionsAdapter - * @hide - */ - /* package */void onQueryRefine(CharSequence queryText) { - setQuery(queryText); - } - - private final OnClickListener mOnClickListener = new OnClickListener() { - - public void onClick(View v) { - if (v == mSearchButton) { - onSearchClicked(); - } else if (v == mCloseButton) { - onCloseClicked(); - } else if (v == mSubmitButton) { - onSubmitQuery(); - } else if (v == mVoiceButton) { - onVoiceClicked(); - } else if (v == mQueryTextView) { - forceSuggestionQuery(); - } - } - }; - - /** - * Handles the key down event for dealing with action keys. - * - * @param keyCode This is the keycode of the typed key, and is the same value as - * found in the KeyEvent parameter. - * @param event The complete event record for the typed key - * - * @return true if the event was handled here, or false if not. - */ - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (mSearchable == null) { - return false; - } - - // if it's an action specified by the searchable activity, launch the - // entered query with the action key - // TODO SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode); - // TODO if ((actionKey != null) && (actionKey.getQueryActionMsg() != null)) { - // TODO launchQuerySearch(keyCode, actionKey.getQueryActionMsg(), mQueryTextView.getText() - // TODO .toString()); - // TODO return true; - // TODO } - - return super.onKeyDown(keyCode, event); - } - - /** - * React to the user typing "enter" or other hardwired keys while typing in - * the search box. This handles these special keys while the edit box has - * focus. - */ - View.OnKeyListener mTextKeyListener = new View.OnKeyListener() { - public boolean onKey(View v, int keyCode, KeyEvent event) { - // guard against possible race conditions - if (mSearchable == null) { - return false; - } - - if (DBG) { - Log.d(LOG_TAG, "mTextListener.onKey(" + keyCode + "," + event + "), selection: " - + mQueryTextView.getListSelection()); - } - - // If a suggestion is selected, handle enter, search key, and action keys - // as presses on the selected suggestion - if (mQueryTextView.isPopupShowing() - && mQueryTextView.getListSelection() != ListView.INVALID_POSITION) { - return onSuggestionsKey(v, keyCode, event); - } - - // If there is text in the query box, handle enter, and action keys - // The search key is handled by the dialog's onKeyDown(). - if (!mQueryTextView.isEmpty() && KeyEventCompat.hasNoModifiers(event)) { - if (event.getAction() == KeyEvent.ACTION_UP) { - if (keyCode == KeyEvent.KEYCODE_ENTER) { - v.cancelLongPress(); - - // Launch as a regular search. - launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null, mQueryTextView.getText() - .toString()); - return true; - } - } - if (event.getAction() == KeyEvent.ACTION_DOWN) { - // TODO SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode); - // TODO if ((actionKey != null) && (actionKey.getQueryActionMsg() != null)) { - // TODO launchQuerySearch(keyCode, actionKey.getQueryActionMsg(), mQueryTextView - // TODO .getText().toString()); - // TODO return true; - // TODO } - } - } - return false; - } - }; - - /** - * React to the user typing while in the suggestions list. First, check for - * action keys. If not handled, try refocusing regular characters into the - * EditText. - */ - private boolean onSuggestionsKey(View v, int keyCode, KeyEvent event) { - // guard against possible race conditions (late arrival after dismiss) - if (mSearchable == null) { - return false; - } - if (mSuggestionsAdapter == null) { - return false; - } - if (event.getAction() == KeyEvent.ACTION_DOWN && KeyEventCompat.hasNoModifiers(event)) { - // First, check for enter or search (both of which we'll treat as a - // "click") - if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_SEARCH - || keyCode == KeyEvent.KEYCODE_TAB) { - int position = mQueryTextView.getListSelection(); - return onItemClicked(position, KeyEvent.KEYCODE_UNKNOWN, null); - } - - // Next, check for left/right moves, which we use to "return" the - // user to the edit view - if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { - // give "focus" to text editor, with cursor at the beginning if - // left key, at end if right key - // TODO: Reverse left/right for right-to-left languages, e.g. - // Arabic - int selPoint = (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) ? 0 : mQueryTextView - .length(); - mQueryTextView.setSelection(selPoint); - mQueryTextView.setListSelection(0); - mQueryTextView.clearListSelection(); - ensureImeVisible(mQueryTextView, true); - - return true; - } - - // Next, check for an "up and out" move - if (keyCode == KeyEvent.KEYCODE_DPAD_UP && 0 == mQueryTextView.getListSelection()) { - // TODO: restoreUserQuery(); - // let ACTV complete the move - return false; - } - - // Next, check for an "action key" - // TODO SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode); - // TODO if ((actionKey != null) - // TODO && ((actionKey.getSuggestActionMsg() != null) || (actionKey - // TODO .getSuggestActionMsgColumn() != null))) { - // TODO // launch suggestion using action key column - // TODO int position = mQueryTextView.getListSelection(); - // TODO if (position != ListView.INVALID_POSITION) { - // TODO Cursor c = mSuggestionsAdapter.getCursor(); - // TODO if (c.moveToPosition(position)) { - // TODO final String actionMsg = getActionKeyMessage(c, actionKey); - // TODO if (actionMsg != null && (actionMsg.length() > 0)) { - // TODO return onItemClicked(position, keyCode, actionMsg); - // TODO } - // TODO } - // TODO } - // TODO } - } - return false; - } - - /** - * For a given suggestion and a given cursor row, get the action message. If - * not provided by the specific row/column, also check for a single - * definition (for the action key). - * - * @param c The cursor providing suggestions - * @param actionKey The actionkey record being examined - * - * @return Returns a string, or null if no action key message for this - * suggestion - */ - // TODO private static String getActionKeyMessage(Cursor c, SearchableInfo.ActionKeyInfo actionKey) { - // TODO String result = null; - // TODO // check first in the cursor data, for a suggestion-specific message - // TODO final String column = actionKey.getSuggestActionMsgColumn(); - // TODO if (column != null) { - // TODO result = SuggestionsAdapter.getColumnString(c, column); - // TODO } - // TODO // If the cursor didn't give us a message, see if there's a single - // TODO // message defined - // TODO // for the actionkey (for all suggestions) - // TODO if (result == null) { - // TODO result = actionKey.getSuggestActionMsg(); - // TODO } - // TODO return result; - // TODO } - - private int getSearchIconId() { - TypedValue outValue = new TypedValue(); - getContext().getTheme().resolveAttribute(R.attr.searchViewSearchIcon, - outValue, true); - return outValue.resourceId; - } - - private CharSequence getDecoratedHint(CharSequence hintText) { - // If the field is always expanded, then don't add the search icon to the hint - if (!mIconifiedByDefault) return hintText; - - SpannableStringBuilder ssb = new SpannableStringBuilder(" "); // for the icon - ssb.append(hintText); - Drawable searchIcon = getContext().getResources().getDrawable(getSearchIconId()); - int textSize = (int) (mQueryTextView.getTextSize() * 1.25); - searchIcon.setBounds(0, 0, textSize, textSize); - ssb.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - return ssb; - } - - private void updateQueryHint() { - if (mQueryHint != null) { - mQueryTextView.setHint(getDecoratedHint(mQueryHint)); - } else if (mSearchable != null) { - CharSequence hint = null; - int hintId = mSearchable.getHintId(); - if (hintId != 0) { - hint = getContext().getString(hintId); - } - if (hint != null) { - mQueryTextView.setHint(getDecoratedHint(hint)); - } - } else { - mQueryTextView.setHint(getDecoratedHint("")); - } - } - - /** - * Updates the auto-complete text view. - */ - private void updateSearchAutoComplete() { - // TODO mQueryTextView.setDropDownAnimationStyle(0); // no animation - mQueryTextView.setThreshold(mSearchable.getSuggestThreshold()); - mQueryTextView.setImeOptions(mSearchable.getImeOptions()); - int inputType = mSearchable.getInputType(); - // We only touch this if the input type is set up for text (which it almost certainly - // should be, in the case of search!) - if ((inputType & InputType.TYPE_MASK_CLASS) == InputType.TYPE_CLASS_TEXT) { - // The existence of a suggestions authority is the proxy for "suggestions - // are available here" - inputType &= ~InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE; - if (mSearchable.getSuggestAuthority() != null) { - inputType |= InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE; - // TYPE_TEXT_FLAG_AUTO_COMPLETE means that the text editor is performing - // auto-completion based on its own semantics, which it will present to the user - // as they type. This generally means that the input method should not show its - // own candidates, and the spell checker should not be in action. The text editor - // supplies its candidates by calling InputMethodManager.displayCompletions(), - // which in turn will call InputMethodSession.displayCompletions(). - inputType |= InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS; - } - } - mQueryTextView.setInputType(inputType); - if (mSuggestionsAdapter != null) { - mSuggestionsAdapter.changeCursor(null); - } - // attach the suggestions adapter, if suggestions are available - // The existence of a suggestions authority is the proxy for "suggestions available here" - if (mSearchable.getSuggestAuthority() != null) { - mSuggestionsAdapter = new SuggestionsAdapter(getContext(), - this, mSearchable, mOutsideDrawablesCache); - mQueryTextView.setAdapter(mSuggestionsAdapter); - ((SuggestionsAdapter) mSuggestionsAdapter).setQueryRefinement( - mQueryRefinement ? SuggestionsAdapter.REFINE_ALL - : SuggestionsAdapter.REFINE_BY_ENTRY); - } - } - - /** - * Update the visibility of the voice button. There are actually two voice search modes, - * either of which will activate the button. - * @param empty whether the search query text field is empty. If it is, then the other - * criteria apply to make the voice button visible. - */ - private void updateVoiceButton(boolean empty) { - int visibility = GONE; - if (mVoiceButtonEnabled && !isIconified() && empty) { - visibility = VISIBLE; - mSubmitButton.setVisibility(GONE); - } - mVoiceButton.setVisibility(visibility); - } - - private final OnEditorActionListener mOnEditorActionListener = new OnEditorActionListener() { - - /** - * Called when the input method default action key is pressed. - */ - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - onSubmitQuery(); - return true; - } - }; - - private void onTextChanged(CharSequence newText) { - CharSequence text = mQueryTextView.getText(); - mUserQuery = text; - boolean hasText = !TextUtils.isEmpty(text); - updateSubmitButton(hasText); - updateVoiceButton(!hasText); - updateCloseButton(); - updateSubmitArea(); - if (mOnQueryChangeListener != null && !TextUtils.equals(newText, mOldQueryText)) { - mOnQueryChangeListener.onQueryTextChange(newText.toString()); - } - mOldQueryText = newText.toString(); - } - - private void onSubmitQuery() { - CharSequence query = mQueryTextView.getText(); - if (query != null && TextUtils.getTrimmedLength(query) > 0) { - if (mOnQueryChangeListener == null - || !mOnQueryChangeListener.onQueryTextSubmit(query.toString())) { - if (mSearchable != null) { - launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null, query.toString()); - setImeVisibility(false); - } - dismissSuggestions(); - } - } - } - - private void dismissSuggestions() { - mQueryTextView.dismissDropDown(); - } - - private void onCloseClicked() { - CharSequence text = mQueryTextView.getText(); - if (TextUtils.isEmpty(text)) { - if (mIconifiedByDefault) { - // If the app doesn't override the close behavior - if (mOnCloseListener == null || !mOnCloseListener.onClose()) { - // hide the keyboard and remove focus - clearFocus(); - // collapse the search field - updateViewsVisibility(true); - } - } - } else { - mQueryTextView.setText(""); - mQueryTextView.requestFocus(); - setImeVisibility(true); - } - - } - - private void onSearchClicked() { - updateViewsVisibility(false); - mQueryTextView.requestFocus(); - setImeVisibility(true); - if (mOnSearchClickListener != null) { - mOnSearchClickListener.onClick(this); - } - } - - private void onVoiceClicked() { - // guard against possible race conditions - if (mSearchable == null) { - return; - } - SearchableInfo searchable = mSearchable; - try { - if (searchable.getVoiceSearchLaunchWebSearch()) { - Intent webSearchIntent = createVoiceWebSearchIntent(mVoiceWebSearchIntent, - searchable); - getContext().startActivity(webSearchIntent); - } else if (searchable.getVoiceSearchLaunchRecognizer()) { - Intent appSearchIntent = createVoiceAppSearchIntent(mVoiceAppSearchIntent, - searchable); - getContext().startActivity(appSearchIntent); - } - } catch (ActivityNotFoundException e) { - // Should not happen, since we check the availability of - // voice search before showing the button. But just in case... - Log.w(LOG_TAG, "Could not find voice search activity"); - } - } - - void onTextFocusChanged() { - updateViewsVisibility(isIconified()); - // Delayed update to make sure that the focus has settled down and window focus changes - // don't affect it. A synchronous update was not working. - postUpdateFocusedState(); - if (mQueryTextView.hasFocus()) { - forceSuggestionQuery(); - } - } - - @Override - public void onWindowFocusChanged(boolean hasWindowFocus) { - super.onWindowFocusChanged(hasWindowFocus); - - postUpdateFocusedState(); - } - - /** - * {@inheritDoc} - */ - @Override - public void onActionViewCollapsed() { - clearFocus(); - updateViewsVisibility(true); - mQueryTextView.setImeOptions(mCollapsedImeOptions); - mExpandedInActionView = false; - } - - /** - * {@inheritDoc} - */ - @Override - public void onActionViewExpanded() { - if (mExpandedInActionView) return; - - mExpandedInActionView = true; - mCollapsedImeOptions = mQueryTextView.getImeOptions(); - mQueryTextView.setImeOptions(mCollapsedImeOptions | EditorInfo.IME_FLAG_NO_FULLSCREEN); - mQueryTextView.setText(""); - setIconified(false); - } - - @Override - public void onInitializeAccessibilityEvent(AccessibilityEvent event) { - super.onInitializeAccessibilityEvent(event); - event.setClassName(SearchView.class.getName()); - } - - @Override - public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { - super.onInitializeAccessibilityNodeInfo(info); - info.setClassName(SearchView.class.getName()); - } - - private void adjustDropDownSizeAndPosition() { - if (mDropDownAnchor.getWidth() > 1) { - Resources res = getContext().getResources(); - int anchorPadding = mSearchPlate.getPaddingLeft(); - Rect dropDownPadding = new Rect(); - int iconOffset = mIconifiedByDefault - ? res.getDimensionPixelSize(R.dimen.abs__dropdownitem_icon_width) - + res.getDimensionPixelSize(R.dimen.abs__dropdownitem_text_padding_left) - : 0; - mQueryTextView.getDropDownBackground().getPadding(dropDownPadding); - mQueryTextView.setDropDownHorizontalOffset(-(dropDownPadding.left + iconOffset) - + anchorPadding); - mQueryTextView.setDropDownWidth(mDropDownAnchor.getWidth() + dropDownPadding.left - + dropDownPadding.right + iconOffset - (anchorPadding)); - } - } - - private boolean onItemClicked(int position, int actionKey, String actionMsg) { - if (mOnSuggestionListener == null - || !mOnSuggestionListener.onSuggestionClick(position)) { - launchSuggestion(position, KeyEvent.KEYCODE_UNKNOWN, null); - setImeVisibility(false); - dismissSuggestions(); - return true; - } - return false; - } - - private boolean onItemSelected(int position) { - if (mOnSuggestionListener == null - || !mOnSuggestionListener.onSuggestionSelect(position)) { - rewriteQueryFromSuggestion(position); - return true; - } - return false; - } - - private final OnItemClickListener mOnItemClickListener = new OnItemClickListener() { - - /** - * Implements OnItemClickListener - */ - public void onItemClick(AdapterView parent, View view, int position, long id) { - if (DBG) Log.d(LOG_TAG, "onItemClick() position " + position); - onItemClicked(position, KeyEvent.KEYCODE_UNKNOWN, null); - } - }; - - private final OnItemSelectedListener mOnItemSelectedListener = new OnItemSelectedListener() { - - /** - * Implements OnItemSelectedListener - */ - public void onItemSelected(AdapterView parent, View view, int position, long id) { - if (DBG) Log.d(LOG_TAG, "onItemSelected() position " + position); - SearchView.this.onItemSelected(position); - } - - /** - * Implements OnItemSelectedListener - */ - public void onNothingSelected(AdapterView parent) { - if (DBG) - Log.d(LOG_TAG, "onNothingSelected()"); - } - }; - - /** - * Query rewriting. - */ - private void rewriteQueryFromSuggestion(int position) { - CharSequence oldQuery = mQueryTextView.getText(); - Cursor c = mSuggestionsAdapter.getCursor(); - if (c == null) { - return; - } - if (c.moveToPosition(position)) { - // Get the new query from the suggestion. - CharSequence newQuery = mSuggestionsAdapter.convertToString(c); - if (newQuery != null) { - // The suggestion rewrites the query. - // Update the text field, without getting new suggestions. - setQuery(newQuery); - } else { - // The suggestion does not rewrite the query, restore the user's query. - setQuery(oldQuery); - } - } else { - // We got a bad position, restore the user's query. - setQuery(oldQuery); - } - } - - /** - * Launches an intent based on a suggestion. - * - * @param position The index of the suggestion to create the intent from. - * @param actionKey The key code of the action key that was pressed, - * or {@link KeyEvent#KEYCODE_UNKNOWN} if none. - * @param actionMsg The message for the action key that was pressed, - * or null if none. - * @return true if a successful launch, false if could not (e.g. bad position). - */ - private boolean launchSuggestion(int position, int actionKey, String actionMsg) { - Cursor c = mSuggestionsAdapter.getCursor(); - if ((c != null) && c.moveToPosition(position)) { - - Intent intent = createIntentFromSuggestion(c, actionKey, actionMsg); - - // launch the intent - launchIntent(intent); - - return true; - } - return false; - } - - /** - * Launches an intent, including any special intent handling. - */ - private void launchIntent(Intent intent) { - if (intent == null) { - return; - } - try { - // If the intent was created from a suggestion, it will always have an explicit - // component here. - getContext().startActivity(intent); - } catch (RuntimeException ex) { - Log.e(LOG_TAG, "Failed launch activity: " + intent, ex); - } - } - - /** - * Sets the text in the query box, without updating the suggestions. - */ - private void setQuery(CharSequence query) { - setText(mQueryTextView, query, true); - // Move the cursor to the end - mQueryTextView.setSelection(TextUtils.isEmpty(query) ? 0 : query.length()); - } - - private void launchQuerySearch(int actionKey, String actionMsg, String query) { - String action = Intent.ACTION_SEARCH; - Intent intent = createIntent(action, null, null, query, actionKey, actionMsg); - getContext().startActivity(intent); - } - - /** - * Constructs an intent from the given information and the search dialog state. - * - * @param action Intent action. - * @param data Intent data, or null. - * @param extraData Data for {@link SearchManager#EXTRA_DATA_KEY} or null. - * @param query Intent query, or null. - * @param actionKey The key code of the action key that was pressed, - * or {@link KeyEvent#KEYCODE_UNKNOWN} if none. - * @param actionMsg The message for the action key that was pressed, - * or null if none. - * @return The intent. - */ - private Intent createIntent(String action, Uri data, String extraData, String query, - int actionKey, String actionMsg) { - // Now build the Intent - Intent intent = new Intent(action); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - // We need CLEAR_TOP to avoid reusing an old task that has other activities - // on top of the one we want. We don't want to do this in in-app search though, - // as it can be destructive to the activity stack. - if (data != null) { - intent.setData(data); - } - intent.putExtra(SearchManager.USER_QUERY, mUserQuery); - if (query != null) { - intent.putExtra(SearchManager.QUERY, query); - } - if (extraData != null) { - intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData); - } - if (mAppSearchData != null) { - intent.putExtra(SearchManager.APP_DATA, mAppSearchData); - } - if (actionKey != KeyEvent.KEYCODE_UNKNOWN) { - intent.putExtra(SearchManager.ACTION_KEY, actionKey); - intent.putExtra(SearchManager.ACTION_MSG, actionMsg); - } - intent.setComponent(mSearchable.getSearchActivity()); - return intent; - } - - /** - * Create and return an Intent that can launch the voice search activity for web search. - */ - private Intent createVoiceWebSearchIntent(Intent baseIntent, SearchableInfo searchable) { - Intent voiceIntent = new Intent(baseIntent); - ComponentName searchActivity = searchable.getSearchActivity(); - voiceIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, searchActivity == null ? null - : searchActivity.flattenToShortString()); - return voiceIntent; - } - - /** - * Create and return an Intent that can launch the voice search activity, perform a specific - * voice transcription, and forward the results to the searchable activity. - * - * @param baseIntent The voice app search intent to start from - * @return A completely-configured intent ready to send to the voice search activity - */ - private Intent createVoiceAppSearchIntent(Intent baseIntent, SearchableInfo searchable) { - ComponentName searchActivity = searchable.getSearchActivity(); - - // create the necessary intent to set up a search-and-forward operation - // in the voice search system. We have to keep the bundle separate, - // because it becomes immutable once it enters the PendingIntent - Intent queryIntent = new Intent(Intent.ACTION_SEARCH); - queryIntent.setComponent(searchActivity); - PendingIntent pending = PendingIntent.getActivity(getContext(), 0, queryIntent, - PendingIntent.FLAG_ONE_SHOT); - - // Now set up the bundle that will be inserted into the pending intent - // when it's time to do the search. We always build it here (even if empty) - // because the voice search activity will always need to insert "QUERY" into - // it anyway. - Bundle queryExtras = new Bundle(); - - // Now build the intent to launch the voice search. Add all necessary - // extras to launch the voice recognizer, and then all the necessary extras - // to forward the results to the searchable activity - Intent voiceIntent = new Intent(baseIntent); - - // Add all of the configuration options supplied by the searchable's metadata - String languageModel = RecognizerIntent.LANGUAGE_MODEL_FREE_FORM; - String prompt = null; - String language = null; - int maxResults = 1; - - Resources resources = getResources(); - if (searchable.getVoiceLanguageModeId() != 0) { - languageModel = resources.getString(searchable.getVoiceLanguageModeId()); - } - if (searchable.getVoicePromptTextId() != 0) { - prompt = resources.getString(searchable.getVoicePromptTextId()); - } - if (searchable.getVoiceLanguageId() != 0) { - language = resources.getString(searchable.getVoiceLanguageId()); - } - if (searchable.getVoiceMaxResults() != 0) { - maxResults = searchable.getVoiceMaxResults(); - } - voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, languageModel); - voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt); - voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language); - voiceIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, maxResults); - voiceIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, searchActivity == null ? null - : searchActivity.flattenToShortString()); - - // Add the values that configure forwarding the results - voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT, pending); - voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT_BUNDLE, queryExtras); - - return voiceIntent; - } - - /** - * When a particular suggestion has been selected, perform the various lookups required - * to use the suggestion. This includes checking the cursor for suggestion-specific data, - * and/or falling back to the XML for defaults; It also creates REST style Uri data when - * the suggestion includes a data id. - * - * @param c The suggestions cursor, moved to the row of the user's selection - * @param actionKey The key code of the action key that was pressed, - * or {@link KeyEvent#KEYCODE_UNKNOWN} if none. - * @param actionMsg The message for the action key that was pressed, - * or null if none. - * @return An intent for the suggestion at the cursor's position. - */ - private Intent createIntentFromSuggestion(Cursor c, int actionKey, String actionMsg) { - try { - // use specific action if supplied, or default action if supplied, or fixed default - String action = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_ACTION); - - if (action == null) { - action = mSearchable.getSuggestIntentAction(); - } - if (action == null) { - action = Intent.ACTION_SEARCH; - } - - // use specific data if supplied, or default data if supplied - String data = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_DATA); - if (data == null) { - data = mSearchable.getSuggestIntentData(); - } - // then, if an ID was provided, append it. - if (data != null) { - String id = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID); - if (id != null) { - data = data + "/" + Uri.encode(id); - } - } - Uri dataUri = (data == null) ? null : Uri.parse(data); - - String query = getColumnString(c, SearchManager.SUGGEST_COLUMN_QUERY); - String extraData = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA); - - return createIntent(action, dataUri, extraData, query, actionKey, actionMsg); - } catch (RuntimeException e ) { - int rowNum; - try { // be really paranoid now - rowNum = c.getPosition(); - } catch (RuntimeException e2 ) { - rowNum = -1; - } - Log.w(LOG_TAG, "Search suggestions cursor at row " + rowNum + - " returned exception.", e); - return null; - } - } - - private void forceSuggestionQuery() { - try { - Method before = SearchAutoComplete.class.getMethod("doBeforeTextChanged"); - Method after = SearchAutoComplete.class.getMethod("doAfterTextChanged"); - before.setAccessible(true); - after.setAccessible(true); - before.invoke(mQueryTextView); - after.invoke(mQueryTextView); - } catch (Exception e) { - // Oh well... - } - } - - static boolean isLandscapeMode(Context context) { - return context.getResources().getConfiguration().orientation - == Configuration.ORIENTATION_LANDSCAPE; - } - - /** - * Callback to watch the text field for empty/non-empty - */ - private TextWatcher mTextWatcher = new TextWatcher() { - - public void beforeTextChanged(CharSequence s, int start, int before, int after) { } - - public void onTextChanged(CharSequence s, int start, - int before, int after) { - SearchView.this.onTextChanged(s); - } - - public void afterTextChanged(Editable s) { - } - }; - - /** - * Local subclass for AutoCompleteTextView. - * @hide - */ - public static class SearchAutoComplete extends AutoCompleteTextView { - - private int mThreshold; - private SearchView mSearchView; - - public SearchAutoComplete(Context context) { - super(context); - mThreshold = getThreshold(); - } - - public SearchAutoComplete(Context context, AttributeSet attrs) { - super(context, attrs); - mThreshold = getThreshold(); - } - - public SearchAutoComplete(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - mThreshold = getThreshold(); - } - - void setSearchView(SearchView searchView) { - mSearchView = searchView; - } - - @Override - public void setThreshold(int threshold) { - super.setThreshold(threshold); - mThreshold = threshold; - } - - /** - * Returns true if the text field is empty, or contains only whitespace. - */ - private boolean isEmpty() { - return TextUtils.getTrimmedLength(getText()) == 0; - } - - /** - * We override this method to avoid replacing the query box text when a - * suggestion is clicked. - */ - @Override - protected void replaceText(CharSequence text) { - } - - /** - * We override this method to avoid an extra onItemClick being called on - * the drop-down's OnItemClickListener by - * {@link AutoCompleteTextView#onKeyUp(int, KeyEvent)} when an item is - * clicked with the trackball. - */ - @Override - public void performCompletion() { - } - - /** - * We override this method to be sure and show the soft keyboard if - * appropriate when the TextView has focus. - */ - @Override - public void onWindowFocusChanged(boolean hasWindowFocus) { - super.onWindowFocusChanged(hasWindowFocus); - - if (hasWindowFocus && mSearchView.hasFocus() && getVisibility() == VISIBLE) { - InputMethodManager inputManager = (InputMethodManager) getContext() - .getSystemService(Context.INPUT_METHOD_SERVICE); - inputManager.showSoftInput(this, 0); - // If in landscape mode, then make sure that - // the ime is in front of the dropdown. - if (isLandscapeMode(getContext())) { - ensureImeVisible(this, true); - } - } - } - - @Override - protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { - super.onFocusChanged(focused, direction, previouslyFocusedRect); - mSearchView.onTextFocusChanged(); - } - - /** - * We override this method so that we can allow a threshold of zero, - * which ACTV does not. - */ - @Override - public boolean enoughToFilter() { - return mThreshold <= 0 || super.enoughToFilter(); - } - - @Override - public boolean onKeyPreIme(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - // special case for the back key, we do not even try to send it - // to the drop down list but instead, consume it immediately - if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { - KeyEvent.DispatcherState state = getKeyDispatcherState(); - if (state != null) { - state.startTracking(event, this); - } - return true; - } else if (event.getAction() == KeyEvent.ACTION_UP) { - KeyEvent.DispatcherState state = getKeyDispatcherState(); - if (state != null) { - state.handleUpEvent(event); - } - if (event.isTracking() && !event.isCanceled()) { - mSearchView.clearFocus(); - mSearchView.setImeVisibility(false); - return true; - } - } - } - return super.onKeyPreIme(keyCode, event); - } - - } - - private static void ensureImeVisible(AutoCompleteTextView view, boolean visible) { - try { - Method method = AutoCompleteTextView.class.getMethod("ensureImeVisible", boolean.class); - method.setAccessible(true); - method.invoke(view, visible); - } catch (Exception e) { - //Oh well... - } - } - - private static void showSoftInputUnchecked(View view, InputMethodManager imm, int flags) { - try { - Method method = imm.getClass().getMethod("showSoftInputUnchecked", int.class, ResultReceiver.class); - method.setAccessible(true); - method.invoke(imm, flags, null); - } catch (Exception e) { - //Fallback to public API which hopefully does mostly the same thing - imm.showSoftInput(view, flags); - } - } - - private static void setText(AutoCompleteTextView view, CharSequence text, boolean filter) { - try { - Method method = AutoCompleteTextView.class.getMethod("setText", CharSequence.class, boolean.class); - method.setAccessible(true); - method.invoke(view, text, filter); - } catch (Exception e) { - //Fallback to public API which hopefully does mostly the same thing - view.setText(text); - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/widget/ShareActionProvider.java b/actionbarsherlock/src/com/actionbarsherlock/widget/ShareActionProvider.java deleted file mode 100644 index 83e9f0ca..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/widget/ShareActionProvider.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.widget; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.graphics.drawable.Drawable; -import android.util.TypedValue; -import android.view.View; - -import com.actionbarsherlock.R; -import com.actionbarsherlock.view.ActionProvider; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.MenuItem.OnMenuItemClickListener; -import com.actionbarsherlock.view.SubMenu; -import com.actionbarsherlock.widget.ActivityChooserModel.OnChooseActivityListener; - -/** - * This is a provider for a share action. It is responsible for creating views - * that enable data sharing and also to show a sub menu with sharing activities - * if the hosting item is placed on the overflow menu. - *

- * Here is how to use the action provider with custom backing file in a {@link MenuItem}: - *

- *

- *

- * 
- *  // In Activity#onCreateOptionsMenu
- *  public boolean onCreateOptionsMenu(Menu menu) {
- *      // Get the menu item.
- *      MenuItem menuItem = menu.findItem(R.id.my_menu_item);
- *      // Get the provider and hold onto it to set/change the share intent.
- *      mShareActionProvider = (ShareActionProvider) menuItem.getActionProvider();
- *      // Set history different from the default before getting the action
- *      // view since a call to {@link MenuItem#getActionView() MenuItem.getActionView()} calls
- *      // {@link ActionProvider#onCreateActionView()} which uses the backing file name. Omit this
- *      // line if using the default share history file is desired.
- *      mShareActionProvider.setShareHistoryFileName("custom_share_history.xml");
- *      . . .
- *  }
- *
- *  // Somewhere in the application.
- *  public void doShare(Intent shareIntent) {
- *      // When you want to share set the share intent.
- *      mShareActionProvider.setShareIntent(shareIntent);
- *  }
- * 
- * - *

- *

- * Note: While the sample snippet demonstrates how to use this provider - * in the context of a menu item, the use of the provider is not limited to menu items. - *

- * - * @see ActionProvider - */ -public class ShareActionProvider extends ActionProvider { - - /** - * Listener for the event of selecting a share target. - */ - public interface OnShareTargetSelectedListener { - - /** - * Called when a share target has been selected. The client can - * decide whether to handle the intent or rely on the default - * behavior which is launching it. - *

- * Note: Modifying the intent is not permitted and - * any changes to the latter will be ignored. - *

- * - * @param source The source of the notification. - * @param intent The intent for launching the chosen share target. - * @return Whether the client has handled the intent. - */ - public boolean onShareTargetSelected(ShareActionProvider source, Intent intent); - } - - /** - * The default for the maximal number of activities shown in the sub-menu. - */ - private static final int DEFAULT_INITIAL_ACTIVITY_COUNT = 4; - - /** - * The the maximum number activities shown in the sub-menu. - */ - private int mMaxShownActivityCount = DEFAULT_INITIAL_ACTIVITY_COUNT; - - /** - * Listener for handling menu item clicks. - */ - private final ShareMenuItemOnMenuItemClickListener mOnMenuItemClickListener = - new ShareMenuItemOnMenuItemClickListener(); - - /** - * The default name for storing share history. - */ - public static final String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml"; - - /** - * Context for accessing resources. - */ - private final Context mContext; - - /** - * The name of the file with share history data. - */ - private String mShareHistoryFileName = DEFAULT_SHARE_HISTORY_FILE_NAME; - - private OnShareTargetSelectedListener mOnShareTargetSelectedListener; - - private OnChooseActivityListener mOnChooseActivityListener; - - /** - * Creates a new instance. - * - * @param context Context for accessing resources. - */ - public ShareActionProvider(Context context) { - super(context); - mContext = context; - } - - /** - * Sets a listener to be notified when a share target has been selected. - * The listener can optionally decide to handle the selection and - * not rely on the default behavior which is to launch the activity. - *

- * Note: If you choose the backing share history file - * you will still be notified in this callback. - *

- * @param listener The listener. - */ - public void setOnShareTargetSelectedListener(OnShareTargetSelectedListener listener) { - mOnShareTargetSelectedListener = listener; - setActivityChooserPolicyIfNeeded(); - } - - /** - * {@inheritDoc} - */ - @Override - public View onCreateActionView() { - // Create the view and set its data model. - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); - ActivityChooserView activityChooserView = new ActivityChooserView(mContext); - activityChooserView.setActivityChooserModel(dataModel); - - // Lookup and set the expand action icon. - TypedValue outTypedValue = new TypedValue(); - mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true); - Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId); - activityChooserView.setExpandActivityOverflowButtonDrawable(drawable); - activityChooserView.setProvider(this); - - // Set content description. - activityChooserView.setDefaultActionButtonContentDescription( - R.string.abs__shareactionprovider_share_with_application); - activityChooserView.setExpandActivityOverflowButtonContentDescription( - R.string.abs__shareactionprovider_share_with); - - return activityChooserView; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean hasSubMenu() { - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public void onPrepareSubMenu(SubMenu subMenu) { - // Clear since the order of items may change. - subMenu.clear(); - - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); - PackageManager packageManager = mContext.getPackageManager(); - - final int expandedActivityCount = dataModel.getActivityCount(); - final int collapsedActivityCount = Math.min(expandedActivityCount, mMaxShownActivityCount); - - // Populate the sub-menu with a sub set of the activities. - for (int i = 0; i < collapsedActivityCount; i++) { - ResolveInfo activity = dataModel.getActivity(i); - subMenu.add(0, i, i, activity.loadLabel(packageManager)) - .setIcon(activity.loadIcon(packageManager)) - .setOnMenuItemClickListener(mOnMenuItemClickListener); - } - - if (collapsedActivityCount < expandedActivityCount) { - // Add a sub-menu for showing all activities as a list item. - SubMenu expandedSubMenu = subMenu.addSubMenu(Menu.NONE, collapsedActivityCount, - collapsedActivityCount, - mContext.getString(R.string.abs__activity_chooser_view_see_all)); - for (int i = 0; i < expandedActivityCount; i++) { - ResolveInfo activity = dataModel.getActivity(i); - expandedSubMenu.add(0, i, i, activity.loadLabel(packageManager)) - .setIcon(activity.loadIcon(packageManager)) - .setOnMenuItemClickListener(mOnMenuItemClickListener); - } - } - } - - /** - * Sets the file name of a file for persisting the share history which - * history will be used for ordering share targets. This file will be used - * for all view created by {@link #onCreateActionView()}. Defaults to - * {@link #DEFAULT_SHARE_HISTORY_FILE_NAME}. Set to null - * if share history should not be persisted between sessions. - *

- * Note: The history file name can be set any time, however - * only the action views created by {@link #onCreateActionView()} after setting - * the file name will be backed by the provided file. - *

- * - * @param shareHistoryFile The share history file name. - */ - public void setShareHistoryFileName(String shareHistoryFile) { - mShareHistoryFileName = shareHistoryFile; - setActivityChooserPolicyIfNeeded(); - } - - /** - * Sets an intent with information about the share action. Here is a - * sample for constructing a share intent: - *

- *

-     * 
-     *  Intent shareIntent = new Intent(Intent.ACTION_SEND);
-     *  shareIntent.setType("image/*");
-     *  Uri uri = Uri.fromFile(new File(getFilesDir(), "foo.jpg"));
-     *  shareIntent.putExtra(Intent.EXTRA_STREAM, uri.toString());
-     * 
- * - *

- * - * @param shareIntent The share intent. - * - * @see Intent#ACTION_SEND - * @see Intent#ACTION_SEND_MULTIPLE - */ - public void setShareIntent(Intent shareIntent) { - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, - mShareHistoryFileName); - dataModel.setIntent(shareIntent); - } - - /** - * Reusable listener for handling share item clicks. - */ - private class ShareMenuItemOnMenuItemClickListener implements OnMenuItemClickListener { - @Override - public boolean onMenuItemClick(MenuItem item) { - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, - mShareHistoryFileName); - final int itemId = item.getItemId(); - Intent launchIntent = dataModel.chooseActivity(itemId); - if (launchIntent != null) { - mContext.startActivity(launchIntent); - } - return true; - } - } - - /** - * Set the activity chooser policy of the model backed by the current - * share history file if needed which is if there is a registered callback. - */ - private void setActivityChooserPolicyIfNeeded() { - if (mOnShareTargetSelectedListener == null) { - return; - } - if (mOnChooseActivityListener == null) { - mOnChooseActivityListener = new ShareAcitivityChooserModelPolicy(); - } - ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); - dataModel.setOnChooseActivityListener(mOnChooseActivityListener); - } - - /** - * Policy that delegates to the {@link OnShareTargetSelectedListener}, if such. - */ - private class ShareAcitivityChooserModelPolicy implements OnChooseActivityListener { - @Override - public boolean onChooseActivity(ActivityChooserModel host, Intent intent) { - if (mOnShareTargetSelectedListener != null) { - return mOnShareTargetSelectedListener.onShareTargetSelected( - ShareActionProvider.this, intent); - } - return false; - } - } -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/widget/SuggestionsAdapter.java b/actionbarsherlock/src/com/actionbarsherlock/widget/SuggestionsAdapter.java deleted file mode 100644 index bd5cbd71..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/widget/SuggestionsAdapter.java +++ /dev/null @@ -1,733 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.actionbarsherlock.widget; - -import android.app.SearchManager; -import android.app.SearchableInfo; -import android.content.ComponentName; -import android.content.ContentResolver; -import android.content.Context; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.ColorStateList; -import android.content.res.Resources; -import android.database.Cursor; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Bundle; -import android.support.v4.widget.ResourceCursorAdapter; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.TextUtils; -import android.text.style.TextAppearanceSpan; -import android.util.Log; -import android.util.TypedValue; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; -import com.actionbarsherlock.R; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.WeakHashMap; - -/** - * Provides the contents for the suggestion drop-down list. - * - * @hide - */ -class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListener { - - private static final boolean DBG = false; - private static final String LOG_TAG = "SuggestionsAdapter"; - private static final int QUERY_LIMIT = 50; - - static final int REFINE_NONE = 0; - static final int REFINE_BY_ENTRY = 1; - static final int REFINE_ALL = 2; - - private SearchManager mSearchManager; - private SearchView mSearchView; - private Context mProviderContext; - private WeakHashMap mOutsideDrawablesCache; - private boolean mClosed = false; - private int mQueryRefinement = REFINE_BY_ENTRY; - - // URL color - private ColorStateList mUrlColor; - - static final int INVALID_INDEX = -1; - - // Cached column indexes, updated when the cursor changes. - private int mText1Col = INVALID_INDEX; - private int mText2Col = INVALID_INDEX; - private int mText2UrlCol = INVALID_INDEX; - private int mIconName1Col = INVALID_INDEX; - private int mIconName2Col = INVALID_INDEX; - private int mFlagsCol = INVALID_INDEX; - - // private final Runnable mStartSpinnerRunnable; - // private final Runnable mStopSpinnerRunnable; - - /** - * The amount of time we delay in the filter when the user presses the delete key. - */ - //private static final long DELETE_KEY_POST_DELAY = 500L; - - public SuggestionsAdapter(Context context, SearchView searchView, - SearchableInfo mSearchable, WeakHashMap outsideDrawablesCache) { - super(context, - R.layout.abs__search_dropdown_item_icons_2line, - null, // no initial cursor - true); // auto-requery - mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); - mProviderContext = mContext; - mSearchView = searchView; - - mOutsideDrawablesCache = outsideDrawablesCache; - - // mStartSpinnerRunnable = new Runnable() { - // public void run() { - // // mSearchView.setWorking(true); // TODO: - // } - // }; - // - // mStopSpinnerRunnable = new Runnable() { - // public void run() { - // // mSearchView.setWorking(false); // TODO: - // } - // }; - - // delay 500ms when deleting -// TODO getFilter().setDelayer(new Filter.Delayer() { -// -// private int mPreviousLength = 0; -// -// public long getPostingDelay(CharSequence constraint) { -// if (constraint == null) return 0; -// -// long delay = constraint.length() < mPreviousLength ? DELETE_KEY_POST_DELAY : 0; -// mPreviousLength = constraint.length(); -// return delay; -// } -// }); - } - - /** - * Enables query refinement for all suggestions. This means that an additional icon - * will be shown for each entry. When clicked, the suggested text on that line will be - * copied to the query text field. - *

- * - * @param refineWhat which queries to refine. Possible values are {@link #REFINE_NONE}, - * {@link #REFINE_BY_ENTRY}, and {@link #REFINE_ALL}. - */ - public void setQueryRefinement(int refineWhat) { - mQueryRefinement = refineWhat; - } - - /** - * Returns the current query refinement preference. - * @return value of query refinement preference - */ - public int getQueryRefinement() { - return mQueryRefinement; - } - - /** - * Overridden to always return false, since we cannot be sure that - * suggestion sources return stable IDs. - */ - @Override - public boolean hasStableIds() { - return false; - } - - /** - * Use the search suggestions provider to obtain a live cursor. This will be called - * in a worker thread, so it's OK if the query is slow (e.g. round trip for suggestions). - * The results will be processed in the UI thread and changeCursor() will be called. - */ - @Override - public Cursor runQueryOnBackgroundThread(CharSequence constraint) { - if (DBG) Log.d(LOG_TAG, "runQueryOnBackgroundThread(" + constraint + ")"); - String query = (constraint == null) ? "" : constraint.toString(); - /** - * for in app search we show the progress spinner until the cursor is returned with - * the results. - */ - Cursor cursor = null; - if (mSearchView.getVisibility() != View.VISIBLE - || mSearchView.getWindowVisibility() != View.VISIBLE) { - return null; - } - //mSearchView.getWindow().getDecorView().post(mStartSpinnerRunnable); // TODO: - try { - cursor = getSuggestions(query, QUERY_LIMIT); - // trigger fill window so the spinner stays up until the results are copied over and - // closer to being ready - if (cursor != null) { - cursor.getCount(); - return cursor; - } - } catch (RuntimeException e) { - Log.w(LOG_TAG, "Search suggestions query threw an exception.", e); - } - // If cursor is null or an exception was thrown, stop the spinner and return null. - // changeCursor doesn't get called if cursor is null - // mSearchView.getWindow().getDecorView().post(mStopSpinnerRunnable); // TODO: - return null; - } - - public Cursor getSuggestions(String query, int limit) { - Uri.Builder uriBuilder = new Uri.Builder() - .scheme(ContentResolver.SCHEME_CONTENT) - .query("") // TODO: Remove, workaround for a bug in Uri.writeToParcel() - .fragment(""); // TODO: Remove, workaround for a bug in Uri.writeToParcel() - - // append standard suggestion query path - uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY); - - // inject query, either as selection args or inline - uriBuilder.appendPath(query); - - if (limit > 0) { - uriBuilder.appendQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT, String.valueOf(limit)); - } - - Uri uri = uriBuilder.build(); - - // finally, make the query - return mContext.getContentResolver().query(uri, null, null, null, null); - } - - public void close() { - if (DBG) Log.d(LOG_TAG, "close()"); - changeCursor(null); - mClosed = true; - } - - @Override - public void notifyDataSetChanged() { - if (DBG) Log.d(LOG_TAG, "notifyDataSetChanged"); - super.notifyDataSetChanged(); - - // mSearchView.onDataSetChanged(); // TODO: - - updateSpinnerState(getCursor()); - } - - @Override - public void notifyDataSetInvalidated() { - if (DBG) Log.d(LOG_TAG, "notifyDataSetInvalidated"); - super.notifyDataSetInvalidated(); - - updateSpinnerState(getCursor()); - } - - private void updateSpinnerState(Cursor cursor) { - Bundle extras = cursor != null ? cursor.getExtras() : null; - if (DBG) { - Log.d(LOG_TAG, "updateSpinnerState - extra = " - + (extras != null - ? extras.getBoolean(SearchManager.CURSOR_EXTRA_KEY_IN_PROGRESS) - : null)); - } - // Check if the Cursor indicates that the query is not complete and show the spinner - if (extras != null - && extras.getBoolean(SearchManager.CURSOR_EXTRA_KEY_IN_PROGRESS)) { - // mSearchView.getWindow().getDecorView().post(mStartSpinnerRunnable); // TODO: - return; - } - // If cursor is null or is done, stop the spinner - // mSearchView.getWindow().getDecorView().post(mStopSpinnerRunnable); // TODO: - } - - /** - * Cache columns. - */ - @Override - public void changeCursor(Cursor c) { - if (DBG) Log.d(LOG_TAG, "changeCursor(" + c + ")"); - - if (mClosed) { - Log.w(LOG_TAG, "Tried to change cursor after adapter was closed."); - if (c != null) c.close(); - return; - } - - try { - super.changeCursor(c); - - if (c != null) { - mText1Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1); - mText2Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2); - mText2UrlCol = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2_URL); - mIconName1Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1); - mIconName2Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_2); - mFlagsCol = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_FLAGS); - } - } catch (Exception e) { - Log.e(LOG_TAG, "error changing cursor and caching columns", e); - } - } - - /** - * Tags the view with cached child view look-ups. - */ - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - View v = super.newView(context, cursor, parent); - v.setTag(new ChildViewCache(v)); - return v; - } - - /** - * Cache of the child views of drop-drown list items, to avoid looking up the children - * each time the contents of a list item are changed. - */ - private final static class ChildViewCache { - public final TextView mText1; - public final TextView mText2; - public final ImageView mIcon1; - public final ImageView mIcon2; - public final ImageView mIconRefine; - - public ChildViewCache(View v) { - mText1 = (TextView) v.findViewById(android.R.id.text1); - mText2 = (TextView) v.findViewById(android.R.id.text2); - mIcon1 = (ImageView) v.findViewById(android.R.id.icon1); - mIcon2 = (ImageView) v.findViewById(android.R.id.icon2); - mIconRefine = (ImageView) v.findViewById(R.id.edit_query); - } - } - - @Override - public void bindView(View view, Context context, Cursor cursor) { - ChildViewCache views = (ChildViewCache) view.getTag(); - - int flags = 0; - if (mFlagsCol != INVALID_INDEX) { - flags = cursor.getInt(mFlagsCol); - } - if (views.mText1 != null) { - String text1 = getStringOrNull(cursor, mText1Col); - setViewText(views.mText1, text1); - } - if (views.mText2 != null) { - // First check TEXT_2_URL - CharSequence text2 = getStringOrNull(cursor, mText2UrlCol); - if (text2 != null) { - text2 = formatUrl(text2); - } else { - text2 = getStringOrNull(cursor, mText2Col); - } - - // If no second line of text is indicated, allow the first line of text - // to be up to two lines if it wants to be. - if (TextUtils.isEmpty(text2)) { - if (views.mText1 != null) { - views.mText1.setSingleLine(false); - views.mText1.setMaxLines(2); - } - } else { - if (views.mText1 != null) { - views.mText1.setSingleLine(true); - views.mText1.setMaxLines(1); - } - } - setViewText(views.mText2, text2); - } - - if (views.mIcon1 != null) { - setViewDrawable(views.mIcon1, getIcon1(cursor), View.INVISIBLE); - } - if (views.mIcon2 != null) { - setViewDrawable(views.mIcon2, getIcon2(cursor), View.GONE); - } - if (mQueryRefinement == REFINE_ALL - || (mQueryRefinement == REFINE_BY_ENTRY - && (flags & SearchManager.FLAG_QUERY_REFINEMENT) != 0)) { - views.mIconRefine.setVisibility(View.VISIBLE); - views.mIconRefine.setTag(views.mText1.getText()); - views.mIconRefine.setOnClickListener(this); - } else { - views.mIconRefine.setVisibility(View.GONE); - } - } - - public void onClick(View v) { - Object tag = v.getTag(); - if (tag instanceof CharSequence) { - mSearchView.onQueryRefine((CharSequence) tag); - } - } - - private CharSequence formatUrl(CharSequence url) { - if (mUrlColor == null) { - // Lazily get the URL color from the current theme. - TypedValue colorValue = new TypedValue(); - mContext.getTheme().resolveAttribute(R.attr.textColorSearchUrl, colorValue, true); - mUrlColor = mContext.getResources().getColorStateList(colorValue.resourceId); - } - - SpannableString text = new SpannableString(url); - text.setSpan(new TextAppearanceSpan(null, 0, 0, mUrlColor, null), - 0, url.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - return text; - } - - private void setViewText(TextView v, CharSequence text) { - // Set the text even if it's null, since we need to clear any previous text. - v.setText(text); - - if (TextUtils.isEmpty(text)) { - v.setVisibility(View.GONE); - } else { - v.setVisibility(View.VISIBLE); - } - } - - private Drawable getIcon1(Cursor cursor) { - if (mIconName1Col == INVALID_INDEX) { - return null; - } - String value = cursor.getString(mIconName1Col); - Drawable drawable = getDrawableFromResourceValue(value); - if (drawable != null) { - return drawable; - } - return getDefaultIcon1(cursor); - } - - private Drawable getIcon2(Cursor cursor) { - if (mIconName2Col == INVALID_INDEX) { - return null; - } - String value = cursor.getString(mIconName2Col); - return getDrawableFromResourceValue(value); - } - - /** - * Sets the drawable in an image view, makes sure the view is only visible if there - * is a drawable. - */ - private void setViewDrawable(ImageView v, Drawable drawable, int nullVisibility) { - // Set the icon even if the drawable is null, since we need to clear any - // previous icon. - v.setImageDrawable(drawable); - - if (drawable == null) { - v.setVisibility(nullVisibility); - } else { - v.setVisibility(View.VISIBLE); - - // This is a hack to get any animated drawables (like a 'working' spinner) - // to animate. You have to setVisible true on an AnimationDrawable to get - // it to start animating, but it must first have been false or else the - // call to setVisible will be ineffective. We need to clear up the story - // about animated drawables in the future, see http://b/1878430. - drawable.setVisible(false, false); - drawable.setVisible(true, false); - } - } - - /** - * Gets the text to show in the query field when a suggestion is selected. - * - * @param cursor The Cursor to read the suggestion data from. The Cursor should already - * be moved to the suggestion that is to be read from. - * @return The text to show, or null if the query should not be - * changed when selecting this suggestion. - */ - @Override - public CharSequence convertToString(Cursor cursor) { - if (cursor == null) { - return null; - } - - String query = getColumnString(cursor, SearchManager.SUGGEST_COLUMN_QUERY); - if (query != null) { - return query; - } - - return null; - } - - /** - * This method is overridden purely to provide a bit of protection against - * flaky content providers. - * - * @see android.widget.ListAdapter#getView(int, View, ViewGroup) - */ - @Override - public View getView(int position, View convertView, ViewGroup parent) { - try { - return super.getView(position, convertView, parent); - } catch (RuntimeException e) { - Log.w(LOG_TAG, "Search suggestions cursor threw exception.", e); - // Put exception string in item title - View v = newView(mContext, mCursor, parent); - if (v != null) { - ChildViewCache views = (ChildViewCache) v.getTag(); - TextView tv = views.mText1; - tv.setText(e.toString()); - } - return v; - } - } - - /** - * Gets a drawable given a value provided by a suggestion provider. - * - * This value could be just the string value of a resource id - * (e.g., "2130837524"), in which case we will try to retrieve a drawable from - * the provider's resources. If the value is not an integer, it is - * treated as a Uri and opened with - * {@link ContentResolver#openOutputStream(android.net.Uri, String)}. - * - * All resources and URIs are read using the suggestion provider's context. - * - * If the string is not formatted as expected, or no drawable can be found for - * the provided value, this method returns null. - * - * @param drawableId a string like "2130837524", - * "android.resource://com.android.alarmclock/2130837524", - * or "content://contacts/photos/253". - * @return a Drawable, or null if none found - */ - private Drawable getDrawableFromResourceValue(String drawableId) { - if (drawableId == null || drawableId.length() == 0 || "0".equals(drawableId)) { - return null; - } - try { - // First, see if it's just an integer - int resourceId = Integer.parseInt(drawableId); - // It's an int, look for it in the cache - String drawableUri = ContentResolver.SCHEME_ANDROID_RESOURCE - + "://" + mProviderContext.getPackageName() + "/" + resourceId; - // Must use URI as cache key, since ints are app-specific - Drawable drawable = checkIconCache(drawableUri); - if (drawable != null) { - return drawable; - } - // Not cached, find it by resource ID - drawable = mProviderContext.getResources().getDrawable(resourceId); - // Stick it in the cache, using the URI as key - storeInIconCache(drawableUri, drawable); - return drawable; - } catch (NumberFormatException nfe) { - // It's not an integer, use it as a URI - Drawable drawable = checkIconCache(drawableId); - if (drawable != null) { - return drawable; - } - Uri uri = Uri.parse(drawableId); - drawable = getDrawable(uri); - storeInIconCache(drawableId, drawable); - return drawable; - } catch (Resources.NotFoundException nfe) { - // It was an integer, but it couldn't be found, bail out - Log.w(LOG_TAG, "Icon resource not found: " + drawableId); - return null; - } - } - - /** - * Gets a drawable by URI, without using the cache. - * - * @return A drawable, or {@code null} if the drawable could not be loaded. - */ - private Drawable getDrawable(Uri uri) { - try { - String scheme = uri.getScheme(); - if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) { - // Load drawables through Resources, to get the source density information - try { - return getTheDrawable(uri); - } catch (Resources.NotFoundException ex) { - throw new FileNotFoundException("Resource does not exist: " + uri); - } - } else { - // Let the ContentResolver handle content and file URIs. - InputStream stream = mProviderContext.getContentResolver().openInputStream(uri); - if (stream == null) { - throw new FileNotFoundException("Failed to open " + uri); - } - try { - return Drawable.createFromStream(stream, null); - } finally { - try { - stream.close(); - } catch (IOException ex) { - Log.e(LOG_TAG, "Error closing icon stream for " + uri, ex); - } - } - } - } catch (FileNotFoundException fnfe) { - Log.w(LOG_TAG, "Icon not found: " + uri + ", " + fnfe.getMessage()); - return null; - } - } - - public Drawable getTheDrawable(Uri uri) throws FileNotFoundException { - String authority = uri.getAuthority(); - Resources r; - if (TextUtils.isEmpty(authority)) { - throw new FileNotFoundException("No authority: " + uri); - } else { - try { - r = mContext.getPackageManager().getResourcesForApplication(authority); - } catch (NameNotFoundException ex) { - throw new FileNotFoundException("No package found for authority: " + uri); - } - } - List path = uri.getPathSegments(); - if (path == null) { - throw new FileNotFoundException("No path: " + uri); - } - int len = path.size(); - int id; - if (len == 1) { - try { - id = Integer.parseInt(path.get(0)); - } catch (NumberFormatException e) { - throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); - } - } else if (len == 2) { - id = r.getIdentifier(path.get(1), path.get(0), authority); - } else { - throw new FileNotFoundException("More than two path segments: " + uri); - } - if (id == 0) { - throw new FileNotFoundException("No resource found for: " + uri); - } - return r.getDrawable(id); - } - - private Drawable checkIconCache(String resourceUri) { - Drawable.ConstantState cached = mOutsideDrawablesCache.get(resourceUri); - if (cached == null) { - return null; - } - if (DBG) Log.d(LOG_TAG, "Found icon in cache: " + resourceUri); - return cached.newDrawable(); - } - - private void storeInIconCache(String resourceUri, Drawable drawable) { - if (drawable != null) { - mOutsideDrawablesCache.put(resourceUri, drawable.getConstantState()); - } - } - - /** - * Gets the left-hand side icon that will be used for the current suggestion - * if the suggestion contains an icon column but no icon or a broken icon. - * - * @param cursor A cursor positioned at the current suggestion. - * @return A non-null drawable. - */ - private Drawable getDefaultIcon1(Cursor cursor) { - // Fall back to a default icon - return mContext.getPackageManager().getDefaultActivityIcon(); - } - - /** - * Gets the activity or application icon for an activity. - * Uses the local icon cache for fast repeated lookups. - * - * @param component Name of an activity. - * @return A drawable, or {@code null} if neither the activity nor the application - * has an icon set. - */ - private Drawable getActivityIconWithCache(ComponentName component) { - // First check the icon cache - String componentIconKey = component.flattenToShortString(); - // Using containsKey() since we also store null values. - if (mOutsideDrawablesCache.containsKey(componentIconKey)) { - Drawable.ConstantState cached = mOutsideDrawablesCache.get(componentIconKey); - return cached == null ? null : cached.newDrawable(mProviderContext.getResources()); - } - // Then try the activity or application icon - Drawable drawable = getActivityIcon(component); - // Stick it in the cache so we don't do this lookup again. - Drawable.ConstantState toCache = drawable == null ? null : drawable.getConstantState(); - mOutsideDrawablesCache.put(componentIconKey, toCache); - return drawable; - } - - /** - * Gets the activity or application icon for an activity. - * - * @param component Name of an activity. - * @return A drawable, or {@code null} if neither the acitivy or the application - * have an icon set. - */ - private Drawable getActivityIcon(ComponentName component) { - PackageManager pm = mContext.getPackageManager(); - final ActivityInfo activityInfo; - try { - activityInfo = pm.getActivityInfo(component, PackageManager.GET_META_DATA); - } catch (NameNotFoundException ex) { - Log.w(LOG_TAG, ex.toString()); - return null; - } - int iconId = activityInfo.getIconResource(); - if (iconId == 0) return null; - String pkg = component.getPackageName(); - Drawable drawable = pm.getDrawable(pkg, iconId, activityInfo.applicationInfo); - if (drawable == null) { - Log.w(LOG_TAG, "Invalid icon resource " + iconId + " for " - + component.flattenToShortString()); - return null; - } - return drawable; - } - - /** - * Gets the value of a string column by name. - * - * @param cursor Cursor to read the value from. - * @param columnName The name of the column to read. - * @return The value of the given column, or null - * if the cursor does not contain the given column. - */ - public static String getColumnString(Cursor cursor, String columnName) { - int col = cursor.getColumnIndex(columnName); - return getStringOrNull(cursor, col); - } - - private static String getStringOrNull(Cursor cursor, int col) { - if (col == INVALID_INDEX) { - return null; - } - try { - return cursor.getString(col); - } catch (Exception e) { - Log.e(LOG_TAG, - "unexpected error retrieving valid column from cursor, " - + "did the remote process die?", e); - return null; - } - } -} diff --git a/actionbarsherlock/test/com/actionbarsherlock/internal/ManifestParsingTest.java b/actionbarsherlock/test/com/actionbarsherlock/internal/ManifestParsingTest.java deleted file mode 100644 index 47475c57..00000000 --- a/actionbarsherlock/test/com/actionbarsherlock/internal/ManifestParsingTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.actionbarsherlock.internal; - -import org.junit.Test; - -import static com.actionbarsherlock.internal.ActionBarSherlockCompat.cleanActivityName; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; - -public class ManifestParsingTest { - @Test - public void testFullyQualifiedClassName() { - String expected = "com.other.package.SomeClass"; - String actual = cleanActivityName("com.jakewharton.test", "com.other.package.SomeClass"); - assertThat(expected, equalTo(actual)); - } - - @Test - public void testFullyQualifiedClassNameSamePackage() { - String expected = "com.jakewharton.test.SomeClass"; - String actual = cleanActivityName("com.jakewharton.test", "com.jakewharton.test.SomeClass"); - assertThat(expected, equalTo(actual)); - } - - @Test - public void testUnqualifiedClassName() { - String expected = "com.jakewharton.test.SomeClass"; - String actual = cleanActivityName("com.jakewharton.test", "SomeClass"); - assertThat(expected, equalTo(actual)); - } - - @Test - public void testRelativeClassName() { - String expected = "com.jakewharton.test.ui.SomeClass"; - String actual = cleanActivityName("com.jakewharton.test", ".ui.SomeClass"); - assertThat(expected, equalTo(actual)); - } -} \ No newline at end of file diff --git a/project.properties b/project.properties index 7daaa0e9..d476196b 100644 --- a/project.properties +++ b/project.properties @@ -9,4 +9,4 @@ # Project target. target=android-14 -android.library.reference.1=actionbarsherlock +android.library.reference.1=actionbarsherlock/library diff --git a/setup_env.sh b/setup_env.sh index a915d9d2..78babf13 100755 --- a/setup_env.sh +++ b/setup_env.sh @@ -1,6 +1,9 @@ #!/bin/bash -android update project -p actionbarsherlock +git submodule init +git submodule update +android update project -p actionbarsherlock/library android update project -p . +cp third_party/android-support-library/android-support-v4.jar actionbarsherlock/library/libs/android-support-v4.jar cd tests android update test-project -m .. -p . -- 2.11.0

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 X9Df(GyQW>hf43jgw9-?^liL3Qe0D - - - 4.0.0 - - actionbarsherlock - ActionBarSherlock - apklib - - - com.actionbarsherlock - parent - 4.2.0 - ../pom.xml - - - - - com.google.android - android - provided - - - com.google.android - support-v4 - - - - junit - junit - test - - - - - src - test - - - - com.jayway.maven.plugins.android.generation2 - android-maven-plugin - true - - ignored - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - true - - - - - com.google.code.maven-replacer-plugin - maven-replacer-plugin - 1.4.0 - - - process-sources - - replace - - - - - false - target/generated-sources/r/com/actionbarsherlock/R.java - target/generated-sources/r/com/actionbarsherlock/R.java - false - static final int - static int - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - - ../checkstyle.xml - - - - verify - - checkstyle - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.7 - - - package - - attach-artifact - - - - - jar - ${project.build.directory}/${project.build.finalName}.jar - - - - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - com.google.code.maven-replacer-plugin - maven-replacer-plugin - [1.4.0,) - - replace - - - - - - - - - - - - - - diff --git a/actionbarsherlock/proguard-project.txt b/actionbarsherlock/proguard-project.txt deleted file mode 100644 index f2fe1559..00000000 --- a/actionbarsherlock/proguard-project.txt +++ /dev/null @@ -1,20 +0,0 @@ -# To enable ProGuard in your project, edit project.properties -# to define the proguard.config property as described in that file. -# -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in ${sdk.dir}/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/actionbarsherlock/project.properties b/actionbarsherlock/project.properties deleted file mode 100644 index 5ca7d624..00000000 --- a/actionbarsherlock/project.properties +++ /dev/null @@ -1,12 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "ant.properties", and override values to adapt the script to your -# project structure. - -android.library=true -# Project target. -target=android-14 diff --git a/actionbarsherlock/res/color/abs__primary_text_disable_only_holo_dark.xml b/actionbarsherlock/res/color/abs__primary_text_disable_only_holo_dark.xml deleted file mode 100644 index ea7459aa..00000000 --- a/actionbarsherlock/res/color/abs__primary_text_disable_only_holo_dark.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/actionbarsherlock/res/color/abs__primary_text_disable_only_holo_light.xml b/actionbarsherlock/res/color/abs__primary_text_disable_only_holo_light.xml deleted file mode 100644 index 0edb33b4..00000000 --- a/actionbarsherlock/res/color/abs__primary_text_disable_only_holo_light.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - diff --git a/actionbarsherlock/res/color/abs__primary_text_holo_dark.xml b/actionbarsherlock/res/color/abs__primary_text_holo_dark.xml deleted file mode 100644 index 2bcfd0b6..00000000 --- a/actionbarsherlock/res/color/abs__primary_text_holo_dark.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - diff --git a/actionbarsherlock/res/color/abs__primary_text_holo_light.xml b/actionbarsherlock/res/color/abs__primary_text_holo_light.xml deleted file mode 100644 index 198384fe..00000000 --- a/actionbarsherlock/res/color/abs__primary_text_holo_light.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_solid_dark_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_solid_dark_holo.9.png deleted file mode 100644 index 769463b369a5185ba2d2fdf26abf058086ebcd08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^S!aZFaLn02py|Iz^fCC51!MDwC ze!c%VXGhEQ)_dJsezHtpNMD|7Dac@a*_ZJyulFV2w{5C|YCbaz5)ZX-3ak0tIJ#lm tp_aeGY*)k&iW*FhzahTiJD1r}=BlLiI{(TJ=>e@^@O1TaS?83{1OUpzopr0A6)2vH$=8 diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_solid_light_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_solid_light_holo.9.png deleted file mode 100644 index 73050476e77aa798919b829a5566973e231f9d49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^S!aZFaLn02py|Iz^fCC51!MFRR zxpqaJ>-4UOe6iPKwm$=BLD{Wo!i)yScSSDT-Jo*!N?wFe;-MB!VKtu_20%tEPqwzt q4f{lgTEQ5`;-9UxjMeKCf^DQ_uhd?;-Btm#g2B_(&t;ucLK6V6dokDm diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_transparent_dark_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_transparent_dark_holo.9.png deleted file mode 100644 index 712a551ece87b2544433ac982382a087e7f1731d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^S{5)M8Ln02py}Xf^L4oIp!}}xu zHrx6hVG;aws8xB@i!KMDZA_cCWy>wsRQS4KRST!En$HY_#6vK~{lt8cLjun}a%VT6 c)z9eScC>M27UGHi05qAw)78&qol`;+0QSr+Bme*a diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_transparent_light_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__ab_bottom_transparent_light_holo.9.png deleted file mode 100644 index bf3b9438b16543294498ba27e51d4e878c8ead5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^Sd_7$pLn02py}Xh4fCCS+;oB*H z(}QQZt5vXQMa=PTZk@YrXXvE3+ofW5$)(cU#3WF_jrSY!c@8l>`*HAE!gKCvr?`99 W=bm|#aNiDSFoUP7pUXO@geCw#94y)Z diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ab_share_pack_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__ab_share_pack_holo_dark.9.png deleted file mode 100644 index 81b87b86c959a98c478177270c979763831ebf66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2863 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 N002ovPDHLkV1kHdRS^IH diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ab_share_pack_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__ab_share_pack_holo_light.9.png deleted file mode 100644 index 8fc83e22efde5509c563c97a836d869d05ff5dc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2859 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 JPDHLkV1neRPs;!R diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ab_solid_dark_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__ab_solid_dark_holo.9.png deleted file mode 100644 index cbbaec588ec98bbc8a518a9ab5a9c469482341ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SB0XIkLn02py}Xe3KmgB?fcJu8 z^Zp*+-L#E6MBZg;W9F9wttxZ4PHc?!oG~+pYe(tbxxSpjYCbaz5)ZY&8G8*Bq7ylO npZ&2~Yqrog$!|3Wm+fFU5UE)t_U_Fapd}2Ru6{1-oD!M-^V;Vpy{TG>rs2jRbt|WpWjh#Ji#?9Gi^wblTEgJz>gTe~DWM4fZg4bX diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ab_stacked_transparent_dark_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__ab_stacked_transparent_dark_holo.9.png deleted file mode 100644 index 1e39572224b24a81ed4d73923280ba2724dbaf6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^Sf;?RuLn02py|Iy(L4oIp!})_Q zZ}wlfoYKNk`|wbZR*CB+2cd0Do4#G+S+1#YsD)El&1Z%|BAjt`!_S2)TNKYc{m-!5 f_v_(jT(cfAPEEXE)c4^Y$T|j3S3j3^P6 diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ab_stacked_transparent_light_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__ab_stacked_transparent_light_holo.9.png deleted file mode 100644 index a16db853e94af78c0739d9b89b578e2a8021c856..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^Sd^}woLn02py|j?`fP(zopr08IHUH2?qr diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ab_transparent_dark_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__ab_transparent_dark_holo.9.png deleted file mode 100644 index 0eff695d82911a73874d871f3a7b23b71dd8ab44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^Sl001;Ln02py?l}LfC5j;!{`N< zEvnsL$t-6rWU%$psDGg1|4DLDj`q~RzPqNgR|nl=*Rt6dx_ol~p-I||JQ4;82O1ce y*`SQyBHQ|!3>bf({j~je;Zla%ZD->HG+$+yO5M3zoXrBXjlt8^&t;ucLK6T4R5w)s diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ab_transparent_light_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__ab_transparent_light_holo.9.png deleted file mode 100644 index 219b170fa67aa2ef8e0b11ebff90c1629ba7e97a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SB0OCjLn02py?l|AL4l*?;q8?- zrB_<6lUu~-<@8GYocm9fskyGHQx2!G9uAwU_k&&MlS%_4GaHYDLBatTBRp}nY76HL mkjg^D5fnx&0glSHJj>3%>1Jqp^q#PeS;bnL@oAJ;NJ=s*Cb_P#ZKbLh* G2~7YBfgFPX diff --git a/actionbarsherlock/res/drawable-hdpi/abs__btn_cab_done_pressed_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__btn_cab_done_pressed_holo_dark.9.png deleted file mode 100644 index 66adffed632f0f6267afe6dc2f518adb6a83ca4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Qo!3HFq_#{<Lb diff --git a/actionbarsherlock/res/drawable-hdpi/abs__cab_background_bottom_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__cab_background_bottom_holo_dark.9.png deleted file mode 100644 index 1d836f65a1fffea301e9cf36770b21b48b3b8132..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SVmw_OLn02py|R(B!9jra;>r_8 z?%b*io|Yn;UGT9};ZTu}!9}%xc^%IgtXD4oJ@0X-F7B%4f|j+c$=0hv54CU#tNF|@ sNQ5wMgi8eI0r?xYZ}@0_Yf6jsMX$B_pXOhT0oudh>FVdQ&MBb@0DzD;x&QzG diff --git a/actionbarsherlock/res/drawable-hdpi/abs__cab_background_bottom_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__cab_background_bottom_holo_light.9.png deleted file mode 100644 index 5818666d4e64b93da73bc3d6dc2764bcb500359c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SB0OCjLn02py|R(>fCCT9!M7)Q zv diff --git a/actionbarsherlock/res/drawable-hdpi/abs__cab_background_top_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__cab_background_top_holo_dark.9.png deleted file mode 100644 index 564fb34b4308750b6922f320e9e114b080ecd538..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SqC8z3Ln02py}XdO!9jra;!2L@ z<=I|~`ucZlc5hPnsi>TGwM)Is^N?0TPy5{UQpwgqqAoKG5)ZX-3ak0R7;B{1mWZ}( p*lxaUe)ue*Z}vC-G%ee~_}P|!&DqTD7lF1gc)I$ztaD0e0st(KG%NrB diff --git a/actionbarsherlock/res/drawable-hdpi/abs__cab_background_top_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__cab_background_top_holo_light.9.png deleted file mode 100644 index ae21b760fb1ebecac3389164251b0fa14f580f5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SqC8z3Ln02py>gKAfB^?4dC zy{Qwe+I<(;Zrk3}qFy7o$Hqotreyxi(D>i`gF-*@tj&^T;Xws!Omj@dZ?l#4Y_?*} ivA^-x{8q}NM@;fbHo20HF^oW47(8A5T-G@yGywny6)bE3 diff --git a/actionbarsherlock/res/drawable-hdpi/abs__dialog_full_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__dialog_full_holo_dark.9.png deleted file mode 100644 index 79e56f522b2837bd9f579b28f037ad5eafaaee8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1414 zcmV;11$p|3P)cSnqT^=WQ7*OFqW%ysfqGq3fLYCng$eebY1E zq0h)!qMt>^T{!1KLrdv5=!(bMwnfb7mMF4BgVA@!3k##^X|etG%o8VLfn)&kp1$5* zAHx|3EF9@?)w)=}!OothSF(h}LSVs2n}u~V8rR2gA&m?6GFm9LT5i!5ovh2$`aOLf zDMwpCv(UIN+s(qhT71rU;E=VYR%2(wIy9)U9BqNMU?EvKj~0!zxmxOREjkZzh+iq_n}2*GaEP(@ILD!5 zWBguqUH^M`clY;tz5a@wsI&tR0g7j89WEv$&WS`s3jmAj>+65+@9$R+4-crSDsl+t zoXD~ai^by4tE;Qe>-G9CHN@f2j4rXz#$jzQA^^+B$H$Mix3`1-5a+ZsO@p#5Q53}= z0G4QnFC7vyL_!;@%<@Jv>_k)mSUx>Hz18n=PE3d}%kYsC@*I)N0NNv^lI%s;wg9j! z%knLLgEIoQ+bysY63^&#(^_eOc(NT6QxTdoZI(#S<~ro`ne!tS(gH7T&zUX-UZRk7 zy|5!F77`FowzZg?X(M)KAw}<4SRP51e8qZ>m)V;$Z3?tS#CiaZ^hhEi?U_=yRh(%c zcGk9kwMUBGYjYt@pHyCSltyExNUHHFevMy@-l#r~QEjQ;(4?Q~r4samHh{FF{bU7StYxgeBAZQ`6E7N`VLYGS_ z;oj>aHT`D+d1$*FJhVBd!G+`uf(ywR1Q(Js2reXN5G)~C&xiARXWFDHmGF81Z6U>K z;#g%)oXa8RP+ENtZO$MZBP0)Pm&4Jv?h_KbHF>VdnKo?a-t;CVB(9^gh389`0#_~3 z>r7%ovdX{d8amFjk%uF>Vp~*9sp-GKg_vAO(?{&AZLdjA|Mdo3?oA8H>)1>mc|==# zB~EQxV&cD40$n%8&w#s-rjOWJ+ddiIQXYxR!^y#)tE&3)24CJ80l~J_MCXPu>Ml3AI+9BHcJ4%0r(Kw z@2dYHj4#nGKH!fqjRVUuh**Aw_CvMrs{b>Lm!YwzO4di>6N@*}Phg5Tw&B1fy2S@v zNaMh=r`Sx3>1SxA8q+hl==5I;NtblfC(XkF^KkH7ZKuDGcq0~@mC!ryi=K7WXgde? zOwz>rq{P&!A!(hIr~D!&pe-W#G7`?LQYh|`P7hzs(O!weT#2|xih3m$l64(P7wFd8 z$(YnkvI-Blh{l8EAha{kf+|%%mTX6hk;YCcRo{6`6g>|oKBz>Tb24JLyVyI4p!izS z!8wv9b%$RIiIZ@y?B&nGjRPyvaF~-xlb-U|=!P~^8?n&FNw@wIvQA!p;xDy1AK0dR zu~CaAl^btMM>A?9->NQ&|AnVmzdt!!WF>xutSl`;$84s2a_=ari#ecl- zo|KSyJXTD=1$2JI1Ql!6el7Y8-dCZ-i%gs^mMBu<;eLzP8a;YIXA&Hxi>7JtAFa#2 UvCQ(L;{X5v07*qoM6N<$g1g$KMgRZ+ diff --git a/actionbarsherlock/res/drawable-hdpi/abs__dialog_full_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__dialog_full_holo_light.9.png deleted file mode 100644 index e029f210b9a81ed4765d31e90b6e49dc8aa37bed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1537 zcmV+c2LAbpP)P*hY@RCILOyI+)4*Y%ioMH6eaT8-v42qXrI z0|4iGEk=d4Xm52^#H?WUz%bBygG}I|;L!cJM*+u%I9T*&&%x@0sx#0Qk0mTmeRX1h$MIxNMY&% zsz{Hz01C^N@8p~dFgXbIRub%{CUOKKzAQ3rfl0r3M&j^DZL~BnC0R+zNTfH*0>l>% z6xe!^4oO*vg0sbY%(i4Znw@-;nUbs&1zN~PIe02zy)Qcz&8uA?+OU=`?e2Zs5}uJN0M*6C#a{)YX?>^k&iO8v%U{pV&i+9YXUL@sAe1fQs10%V6ikBo z^7Qod_s{$xhgN}Tci-i5`3pX{;N4;1Au(Bm7x@)z#1I9LmdL~RrF4uC5rsHs>tE+w zbjvJ)LKv+{MYbuBrU=TBLj=6Xm=@t7;baF+QjNr0K02$09MPPz_Q^dZ5CLh8#Oov4 z0!TsP8|Jz<^->fRi@r;w5OrSCkw6L?N(J|#V;?nA78HxV{Q97DD=gWeOHxKs4U)p3 zSoD>;waz;geHn?ahed6Tq%7rduPgn zV$nDE$&ajtWS5-`4=n>hvFJNE&bxxNGnt2!k)T-g9UO0!_0BFb6cm%bLuC>qYeBK* zyN@VHxuTkNE#cFa@PaJz!! z*)p0eo;YjAyoc}Lcn`@)ql2XA#Le!l%y)3C`#|D`qk*LC#Leoh&{v9irz@IDt(4j|E-ey3YJCdAoj z17Q35`nvale)TKB+I=4%AAxk%w!OMGAf++t+Mb@Cemp-vW4j&J%V|A%#TR&cd&9%S z1Mctdf1tZ-6W>Id5JKwGXhvG!+}wOSKR^Gos;Zyq!S}5X*>+05G4|7V9G{hQ?!VjH z+iw8YkTX)YMrymYx~{`?w$U_yh$q-O1#m*zu<(hQDx}lJ70s)V5Io{ZN7v2rMwVC7 zhTm_2@1*&pTK&uP8_~o&lye*5+om^+1{h zqafFH?O0X{OUO1M^YAPb=F`bd6<0LB=s!LE=ilN39Gach?DYt$CL6UhXTc;$2zpT2dqqQrIZWT*_yH->_|IcgE|Y&S_AJ4lX{3 zlIkT6RWeyS^JtZ1q^3@yK=Cm?J&*-y*C;dpYgTSF&bztX%>V7a(kL+ra#JUT-|=or zs-McUNbE?uO3e#!@v#wf-Fu%ryG^`~69lNs`%MmnTRbrM$471B$+eE{K4hK$mCQ9h-Z$E`tJc<=E)8`p?U8s&`700000NkvXXu0mjfb2aWW diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_ab_back_holo_dark.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_ab_back_holo_dark.png deleted file mode 100644 index 897a1c11a06923f0ee630a3ec44b40118c1fa4d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 602 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1rX+877l!}s{b%+Ad7K3vkswhI zFm^kcZ3hx8D{xE)(qO#|6+TOsF)%PDdAc};Se)*?;+-wxD8l++z18QgepiI9o*=R4AA9|r|3}>uTm;M6YILUxmVi!uBjgaN)~;(wEWpmNk!cW z(d%Z<{E>P~YK!lT=8FgRsYuTJwQ$0$u+I~@?rdLb^6_f+5jpHV#tRQqPS1ijb30F2_W#pYUFO#_XV=?h zOHP?#2^DqDa diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_ab_back_holo_light.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_ab_back_holo_light.png deleted file mode 100644 index 0c89f71407e8d51f92ff6a10b1ae40ec902aa04e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 546 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1rX+877l!}s{b%+Ad7K3vkswhI zFm^kcZ3hx8D{xE)(qO#|6+TOsF)%P{dAc};Se%}E<)W9gqsXz3_j5LNPFu1pO1DK} z+N#=yeg8w_ofMzAMJao1SUGXl-8U7Joy@GYEX@zknfd?wSxaLcYqyHhr&soQ-EO{p zw!~UfNcQJK)l+|B(yvWaZRmKvsC8=g<+E=!6%t;!XnxPxBUZuOVKlwt*0FipR-Y02 zmCh$xWIQ?dubRMH%k4r1TjlOEFztJ(`Lu4f+1J+&0<|T}CPeP?x_?Pcpm5>hNwa5M zzkQR1sjpY$)<2WmGuJ)*zvffcmaNUK`~10Vr~dw8eVc_z%*|+OqxE^sCGQ0OTrOO6 z<>J@Zf0Ym33CMeTp!xW+<7NU=B(%1ExnpuV-^$?oQTEn-hjMN&=46?A$U{|X$JUzr zjr;q)=$3Bvc`c`@@Ze;4?7{TSRWGgUnXHd<-`o)9JVUa&78r!8C9V-ADTyViR>?)F zK#IZ0z|c_Fz+BhBFvQT<%Fw{d$P~!6GB7Z{-*6d4LvDUbW?Cg~4NgrK`9KYlARB`7 r(@M${i&7aJQ}UBi6+Ckj(^G>|6H_V+Po~-c6)||a`njxgN@xNAF&x-_ diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_cab_done_holo_dark.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_cab_done_holo_dark.png deleted file mode 100644 index d8662e3f0fdae62cdee68c184a30fa9e421dc338..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 713 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}trX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfizez!?|}o;S3Cn7d>4ZLn02pop#z!+EApeUwz>goe2TrwSq2J zirU3kvaXhOUTIG}?do{Paly7dd_m%&JI?q_-onB2%KO8{j^-Q>wzNlYp6R5&dH;Rm z|KbvtPbZZ7*R_9QUBqkhp({MdL+G`PeiKVkcC&4Y!{nAd6Z!S-oqj3U!mzMkIqyf? zf)_G(nEp@p{`aZ-I!9g5h7aq1927O&FPT&GvG@NuQA5$TGve!iOqW^IxiY{>!{pzO z!{3V<)Sk6$zkBfg;!caFvF0E2Z#WAV9{aHQL)vPusEmizHw=GVH2J}B^#kKc_ZNxM zzDF#RGe0;TaIo&I-m~b0*sP8To$2@Yde+QKc8kg_`XHU5q@;HFk@ug+O{X5aZ~nk~ zjknIKwfM~0Z^b864VUMM@zwGAdYt)v<(Nz4IlImB@8#qJ%zn(A@Z29bd}4MpKn$sTM506307QmPCTFYr(@#O zpZ-(V%YE!?30QE(DXivDMdI0PFM+AKOT1>hnX-6tX;O6(d#2d)iSBZ_kN7m7WzTRr zzEA`h)2bz|5hW>!C8<`)MX5lF!N|bSP}jgh*T6i)(9Fuf$jaCl$hI;t2>JhQGm3`X z{FKbJN)!#IR;K1a1kqq?mJtlpAPKS|I6tkVJh3R1!7(L2DOJHUH!(dmC^a#qvhZZ8 Q4Nwt-r>mdKI;Vst0K3d3fB*mh diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_cab_done_holo_light.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_cab_done_holo_light.png deleted file mode 100644 index ed03f620f8ef9e969d0471ab76329038e25c9f0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 737 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}trX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfizez!?|}o;S3CnFFjoxLn02py%z6(IY8q0$M=`{k_{&Q=;t<2 zt8!*r>&D`|W2$+>pS=eAb}M##+^cbdA4dCLPr0$oL~Mm8Bn#4$+9@L$(#*Pp%fW0&@t4F~+Q4$6OeIrG`|nG22@uVa-C zJ=H0n)NABBE9V2ZrDh$}Ob?>#U7^{{%b z^;_|*S@)*|RLscvyw85$_Y2}8p?L-UY)vO;|NFUQJ(sNEA?BESpVrme#d7mboB7l} z-Tl+e|M{(6F|!lpnSU$jtXi?CXvKcs<;$n_y<4FKOaZDTt`Q|Ei6yC4$wjF^iowXh z&`{UFLf61N#L&#jz{twj7|6CVFbMhoZ8M67-29Zxv`Q2WrdForKm^fXYnBlV)F276 tAviy+q&%@GmBBG3KPgqgGdD3kH7GSPrLyp3str&PgQu&X%Q~loCIB{EJ2wCT diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_clear_disabled.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_clear_disabled.png deleted file mode 100644 index d97c342d53690e6d286efbe5f37562747a49b96d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1774 zcmVU8P*7-ZbZ>KLZ*U+lnSp_Ufq@}0xwybFAi#%#fq@|}KQEO56)-X|e7nZL z$iTqBa9P*U#mSX{G{Bl%P*lRez;J+pfx##xwK$o9f#C}S14DXwNkIt%17i#W1A|CX zc0maP17iUL1A|C*NRTrF17iyV0~1e4YDEbH0|SF|enDkXW_m`6f}y3QrGjHhep0GJ zaAk2xYHqQDXI^rCQ9*uDVo7QW0|Nup4h9AW240u^5(W3f%sd4n162kpgNVo|1qcff zJ_s=cNG>fZg9jx8g8+j9g8_pBLjXe}Lp{R+hNBE`7{wV~7)u#fFy3PlV+vxLz;uCG zm^qSpA@ds+OO_6nTdaDlt*rOhEZL^9ePa)2-_4=K(Z%tFGm-NGmm}8}ZcXk5JW@PU zd4+f<@d@)yL(o<5icqT158+-B6_LH7;i6x}CW#w~Uy-Pgl#@Irl`kzV zeL|*8R$ca%T%Wv){2zs_iiJvgN^h0dsuZZ2sQy$tsNSU!s;Q*;LF<6_B%M@UD?LHI zSNcZ`78uqV#TeU~$eS{ozBIdFzSClfs*^S+dw;4dus<{M;#|MXC)T}S9v!D zcV!QCPhBq)ZyO(X-(bH4|NMaZz==UigLj2o41F2S6d@OB6%`R(5i>J(Puzn9wnW{e zu;hl6HK{k#IWjCVGqdJqU(99Cv(K+6*i`tgSi2;vbXD1#3jNBGs$DgVwO(~o>mN4i zHPtkqZIx>)Y(Ls5-Br|mx>vQYvH$Kwn@O`L|D75??eGkZnfg$5<;Xeg_o%+-I&+-3%01W^SH2RkDT>t<8AY({UO#lFTB>(_`g8%^e z{{R4h=>PzAFaQARU;qF*m;eA5Z<1fdMgRZyw(kRs!-6#o(LP%Wr3O<1=S3ZFo9z$bj(u70=3}tI#6DWj&F;Ob99q4>t z7t_JEGi|0s7bcyiT{LI@zd7fguOSTo_Tn%A3;+W_$om&@e+U59{C2xK>{t*000Isi zc-XLE_dt-QB?k*OY(G1$>uu7@#B2;ALf{;yd>Fer3 zxz>Q~gZLw#9*+Wwy1biLp*!&n>VXAqU0c|%HDJZ1jZ6!oDKES7+VWmrg9gjr1HUt9 z$&h=(yP22-u6mx^E9uZ+0pKCX;bJ-&1r%+uT+pDpXT$;nS`cq%Mnv${vs}4kKnFnO zP;ojL1*vOGZSwsAS`q0H5q$MLS1wr~GAT|cBOrBcX}?{*UqB~HsT)hjem%$S zQCYe=d4(eMUA?{!rJtE>6>2uC>s{nMUVQiovq!7(tSuZUVsBCpu612n+{HyeG&{C3 zg%Qx;Ym2+tg`4}D-D9)knmeH3*ac5hx88#8rcKL0fWiC005AajcYxmm08)I=nXx}} QjQ{`u07*qoM6N<$g6k0wDF6Tf diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_clear_normal.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_clear_normal.png deleted file mode 100644 index 33ad8d4b891b14d934e470b2222571ea859c77a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1945 zcmV;K2WI$*P)U8P*7-ZbZ>KLZ*U+lnSp_Ufq@}0xwybFAi#%#fq@|}KQEO56)-X|e7nZL z$iTqBa9P*U#mSX{G{Bl%P*lRez;J+pfx##xwK$o9f#C}S14DXwNkIt%17i#W1A|CX zc0maP17iUL1A|C*NRTrF17iyV0~1e4YDEbH0|SF|enDkXW_m`6f}y3QrGjHhep0GJ zaAk2xYHqQDXI^rCQ9*uDVo7QW0|Nup4h9AW240u^5(W3f%sd4n162kpgNVo|1qcff zJ_s=cNG>fZg9jx8g8+j9g8_pBLjXe}Lp{R+hNBE`7{wV~7)u#fFy3PlV+vxLz;uCG zm^qSpA@ds+OO_6nTdaDlt*rOhEZL^9ePa)2-_4=K(Z%tFGm-NGmm}8}ZcXk5JW@PU zd4+f<@d@)yL(o<5icqT158+-B6_LH7;i6x}CW#w~Uy-Pgl#@Irl`kzV zeL|*8R$ca%T%Wv){2zs_iiJvgN^h0dsuZZ2sQy$tsNSU!s;Q*;LF<6_B%M@UD?LHI zSNcZ`78uqV#TeU~$eS{ozBIdFzSClfs*^S+dw;4dus<{M;#|MXC)T}S9v!D zcV!QCPhBq)ZyO(X-(bH4|NMaZz==UigLj2o41F2S6d@OB6%`R(5i>J(Puzn9wnW{e zu;hl6HK{k#IWjCVGqdJqU(99Cv(K+6*i`tgSi2;vbXD1#3jNBGs$DgVwO(~o>mN4i zHPtkqZIx>)Y(Ls5-Br|mx>vQYvH$Kwn@O`L|D75??eGkZnfg$5<;Xeg_o%+-I&+-3%01W^SH2RkDT>t<8AY({UO#lFTB>(_`g8%^e z{{R4h=>PzAFaQARU;qF*m;eA5Z<1fdMgRZ<`$>NYxmjX{xd; z@m&{rFo*<6ia-&%?9S}Yj1NoMU6_?!qi=gB^D?>lzI)G{bI*)0`G1E*K~NAB1j^1w z0>tKJZeH2PwwY!w0t6BY3JN+p33SuQLYI(HkdcX#K*!j*7|BwgVB_Kabv%L#JBpC9 z;EQnJ<+1&B?8Szh`#X@?^XlV2b_Y-K5FTsACcc7-srF!J%cFRa5f;nX88so}^!n$z zoaNXjzHYk7GONT$qz7ti^`5C0{0Fct&sMz04AGszwAz7*v3&RHh^`S091pfpv3(b5 z_*4F8KwG3jHT04 zL)Y{;8%;+;M^cIuK77Jo4_dVE!}GH&5hG!l3Z``(DA*|D!7J6TwaW^Q$!{BPvBY1f zfE_QM@bQ{@gcj@j`1~x3tfQh^)q%AjL($PLWE_*Djkj1Kg2074d~6f{Nje^K7u;94 zsJv3$@rsafhDHP55kG-dHIPmFAA9=;s{MWcddV( zJFI2mtpvLr*Csj|Q8r$mAN(8x6+<_AKkZ*4LX3DO{@?b4Jsi2Lc%zUffeHejlb9+rq0PNT9OD z;u|vq-{=}^jSayj%5h_}ZkgGdzKgPOi{A&T+VkZWUN=qCxUcB??b4_oXFbpmY{r8l zAAy7`+*;!URqf8e1DIx-VoXo49%u+2!egDT);TPBON$juHQN2v;6f%oLvg2T=HjTH zV68;SR?~`g%UoVKaQk-bqv^ppmWX8HlM0b+kmj2@1ok$Lvua%nR#_xaD8_}Gdqhyt zw&OGA*(k-%DiJgiJLg#o1Tr!L6T|w0FfHFCBm_osWr=J^mg5%t6~${t-Jw00000NkvXXu0mjfxs7-r diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_clear_search_api_disabled_holo_light.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_clear_search_api_disabled_holo_light.png deleted file mode 100644 index 3edbd740858acce452a65675b594d87cd85c4cde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1504 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%xRe+5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8nflaTYtD^x(vzwcwbv89=@ zo12R>knQRQ)9aa6T#}fVoC>oy6KF3~uNhvwR?bDKi6!|(A^G_^uoMuGkzbNuoRMFk z;2dnK;G3A7nFr#7q6gwzm(-%nveXo}qWoM1aQIqfVzJ-F(A>z`+0Dqw5#euVHw$9} zR|{85phuLTdQ->=Gku_A^g)RODY3wWfGH5fgeQF<2cCIS^ME;~2$(fE*e!Y)7?=b+ zT^vIyZoLURops1T#P^YM)`G6?uC=+kf7_B4{*@J9^x)duU6<$Tu^imLQtVB+#DuWI zKp&sr#e2ikRF+h_7hGg6C3|* z?e*8ufgcND|MEKid{9C;-~RZ9Bc^sP~EP3ND_zG5Dxwk6j&$wE~4;Qc*`ssan{ zzn`9=dZ&RsirvSfCP;`whUHEmQ}f9$MSB`#rfaa*Eq?H{s4_-JY+eJUGP9%1oq zJCJw4f2WB2si`MZ$~H#$*nP`3S@opI(pSE?i0N0@>$2Vb7oL|#u)gB_!dQ1$La5q` zDeOVQ4#QJ|EiB?JGJhRxA5Ld^&RpYp@TAicHpRs4(vR3C88QC9{5(weR))#4lPN-s z1=7=NbKU$Nr0Hgbao(RTxaH2IZ#(aDrMoH3_0umA{h;I6BI6;^&o0#XM(`ImzsjuT zTnrQ3)U=jJbp=fS?83{ F1OTcH9Pt1E diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_clear_search_api_holo_light.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_clear_search_api_holo_light.png deleted file mode 100644 index 90db01b5bcf1246d6a94e83930cac63c93a6cf83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1540 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 diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png deleted file mode 100644 index 2abc45809c62513224e9d695542cb8dd8e8087b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezt=sPZ!6KjC*gdALL|E;9+*q=6m<7 zlueVX_4IZHnJ0qE#_rG0T(kiyWMEjjhCTn?qu5pu`=4q}27?c$C=-xvpo(CHaDZeV Zn6Yoz!5==w*?y}vd$@?2>|OKBsl;8 diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_light.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_light.png deleted file mode 100644 index bb6aef1d069a14a7fc1cea9780c919c61679e4fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpUtXipc%kc@k8uWjUIP~c#3xZ62X z=G4p^oaPsfxfS0Jish)R3f(&WG9yqa14Evg(y_dGGlfCy2iXqR3?>_SEs{VyhV?DH iJ0OaDc|iOR772{!kNsXaOPT8&i0|p@=d#Wzp$Py$I4IEo diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_menu_share_holo_dark.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_menu_share_holo_dark.png deleted file mode 100644 index 6f747c8f065940a8844587c682fb3c9443ad1ca2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 467 zcmV;^0WAKBP)SO)@i{}u0qYYqHziBfu2L*;{L?D;GxhmUqDjP ziMkTn=nm+BxmDP>FsP2fGnnz3AAnfGAiD%ptMDlguG*u-2|uL;kN%Xenfoz6Wm9neQuJ_f08buH`WL4SA>8mzG9{4uwy+$BT^9a|eO3@D0j4;gS>^u3i8D002ov JPDHLkV1mHE(I@}_ diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_menu_share_holo_light.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_menu_share_holo_light.png deleted file mode 100644 index 682b2fdec4cdcffe042a0eaba5574fcb553c6fab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 505 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 AsQ>@~ diff --git a/actionbarsherlock/res/drawable-hdpi/abs__ic_voice_search_api_holo_light.png b/actionbarsherlock/res/drawable-hdpi/abs__ic_voice_search_api_holo_light.png deleted file mode 100644 index 3481c982862cd524654e200187445a774446567f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1833 zcmbVNX;2eq7~YUb1P`!K89?kB6p2E1Hz5g$1PR%s1`Ngo6*2bY*3mT(eCwGjDt30z@ADk&)ul!ycbSpXq2nas~26ecnniH=emg*g*#j@Uj16nB_N zi=DC%Hqg(A)tr+Y(ebG%LzlQPJO*&###LsqLlu9w;l%7DLh{2@p8E^+tOq!T_lW zAkrjQDugA;2orvi3RR;rF{(mPu~6K{@h+@VEmI|-Ny!?GN`oM%Mu|v7GKol|K~;>b z*7RYuHV1{-On9GN3uBkTDuptM`n_1Wio`LBAhQXgsILR`g#<-73JE)?GKxVRX0q7) zdw+ReMT_F3WiD>kkc1U{nP0i(9rjT~DpaX7!gS@^xK)~D5v)#TJVPYB*I4ua$r;2r z1NocdKh4s2#B`uveAD{O=FRZnHfCZ-W;Dvr_J%MMH(iS=vz?dnp7r*Q|0OM8=!_4l zs;ZL3zhAiUWdL6Q-YyURf{oFuq)uPWZD82qEi67Cysi1BvmZvMgw)Irq>e&MQ~pM`Lu=nbBxwasjL&Tsbadl%z!58�PUR2s z;--Gn6L-Y44d%`7eX(hACTrQSaf!p)CX^44OWKiL4CvZ6umi8K5;zZ2#*ykw_khy5-2;-x4w&2R z09{9x#xx})BvjJ}TI2cLeM%Juon}o2C0ni%oPP$#W_j{v7Fn&)Y4-+12-XAz2ixMp zdk-dG3-j7Z^7|(bZX9v*jq7?`Wn~?YeZGM=J3B9(I(X1G#M{BXSmw#wPX}s^Mx$a& zd* zptYy_ughebWX6!_=*!|<*LPvVhwlqoZlfEYtjvv>6wjfX3p_g?JMFdJ!co__^o#We zw=b#O^i`T}%SWdnY zptrVi4hONM1>8N+Q_^*Hw7fWo0bv~uaDGTec^ju?7ft7iw};GWFmT;t zmqkFIFYh$^o^;LBh6ZkJNGZ)@ubCQlP9ArdMLX{p^!g2)d{G45wZD$82#Akx7wY?a zz21Agb)mdb(PM7iyy?!^d2(dCvbWL2&n$1d$2oqkM7b5PX3wkWY%R=ajlH#S8mQ3! ge6yDA3jkPwzzE(HQ|OAY)&8HCR-J`5r{^yG7imhbuK)l5 diff --git a/actionbarsherlock/res/drawable-hdpi/abs__list_activated_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__list_activated_holo.9.png deleted file mode 100644 index 4ea7afa00e2bfe057472ed5a196080fc80ad7383..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr2)kE{-7*QBRJJkl{&7FVVepxUS$Rt1LT2VAvn7lLLt0oo!v4%( tpjG6n=4tr&fORvYRP%q%M>EqU82;Q9of*be(FHVz!PC{xWt~$(699PnDoy|Z diff --git a/actionbarsherlock/res/drawable-hdpi/abs__list_divider_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__list_divider_holo_dark.9.png deleted file mode 100644 index 986ab0b9746301f2dd9401829da09e00995621b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~qMj~}Asp9}6B-)+^BAxRtXRm= az`@Yw&#rLZUbzUUfWgz%&t;ucLK6T(%Mo}0 diff --git a/actionbarsherlock/res/drawable-hdpi/abs__list_divider_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__list_divider_holo_light.9.png deleted file mode 100644 index 0279e17a123f8cbb3c7e3a9ce5c5af8e693b6977..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~!k#XUAsp9}6B-)+^LX%RmN2q0 Ycy4A9FVZ~13zTN?boFyt=akR{01+Y(GXMYp diff --git a/actionbarsherlock/res/drawable-hdpi/abs__list_focused_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__list_focused_holo.9.png deleted file mode 100644 index 516f5c7399c853d112a31d1e17c8c7f17180f9bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr5^nE{-7*QpO1)z4*}Q$iB}R!lH3 diff --git a/actionbarsherlock/res/drawable-hdpi/abs__list_longpressed_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__list_longpressed_holo.9.png deleted file mode 100644 index 4ea7afa00e2bfe057472ed5a196080fc80ad7383..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr2)kE{-7*QBRJJkl{&7FVVepxUS$Rt1LT2VAvn7lLLt0oo!v4%( tpjG6n=4tr&fORvYRP%q%M>EqU82;Q9of*be(FHVz!PC{xWt~$(699PnDoy|Z diff --git a/actionbarsherlock/res/drawable-hdpi/abs__list_pressed_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__list_pressed_holo_dark.9.png deleted file mode 100644 index 5654cd69429fd0a3502a05b5f827bffab89cc7e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr5^nE{-7*QD_LZ%D`aoRl?HIGCc%n7=x#)pUXO@geCyJM=ZAh diff --git a/actionbarsherlock/res/drawable-hdpi/abs__list_pressed_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__list_pressed_holo_light.9.png deleted file mode 100644 index 5654cd69429fd0a3502a05b5f827bffab89cc7e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEX7WqAsj$Z!;#Vf2?p zbb>IW`N`93fr5^nE{-7*QD_LZ%D`aoRl?HIGCc%n7=x#)pUXO@geCyJM=ZAh diff --git a/actionbarsherlock/res/drawable-hdpi/abs__list_selector_disabled_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__list_selector_disabled_holo_dark.9.png deleted file mode 100644 index f6fd30dcdc9c39c836e509486854f9da03486892..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^;y~=k!3HF){@Qy1DVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?cuyC{kcif|*A4j^95`Gq9-KV8B6o6ra`I!Z80pW;7d5zZGhRBg zm{FnhT6Xzih3ZMUGkfBc^kAT_eS7{3zPQ8d#DAm9s(?cuyC{kcif|*Eb3_81S$-+V)J@yPBVWyvqG&GeYz~KYxJdw0eeyIoHJnOEfn# R{sUUY;OXk;vd$@?2>|r{LWckV diff --git a/actionbarsherlock/res/drawable-hdpi/abs__menu_dropdown_panel_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__menu_dropdown_panel_holo_dark.9.png deleted file mode 100644 index 4d3d208578c61662986fdc16bd15c69759b48d6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 922 zcmV;L17-Y)P)!ytdud6iMT7O&4bD*mP3eKws)UN7D2k#e z%DbYt@4NEYnkjlINEK7=*RV3zwml#Px9r!q%}Y$QM*NqHEZ-wscn^ zf4p9=Kg#ZZAKY%YZvc!aCbL}F6eGxtBSzy=smEUmc6C{?q1YCQrid~5o$!73+BeU$Ee{DI^Yo4#-o87 zao*xiE9Z<+s}ttlWw19HGlEA1nW09+*~|#}a;CkeJh%bU1g9CP5h0^O2}4Hs%y=Lc z5q!OY8j*^uk~rBBK?ljmh#jL84Ev;rDo>_H#K|6e%Mo=CgLzw$rI$Y4Z-kUy6U47Z zMI2w^tmuV~pH%tJq!^(yWY-hbFl2;G2g)+VPqud2Sicc+jL>MvBTKK;HbN#jlrS<8 zl+;FqdPULzJ~Kh_!?j8>!xs^*nQAm$#290~ue;BBnY1w&wMw4#m(pwEDZd_oY1{Ux z>$>N)H(eWD*FCpw`-IsDKF28-6~1bz!JGs-W6Z&R1n>#KR{&q8us99Q}8ID#(NJr3oa@N-D4Rc$qhA--bT2} z_Wpf@Z`4749}#V+fwWJz^oyZKO1~J&exY-1*Kg?D$hu!fixvAiNfpmG;mo&f5BSEA wlE;@gYed_N;JFm#Y)Zw{1W}kQU9GkF3xsHEK4Myn7XSbN07*qoM6N<$g18=|djJ3c diff --git a/actionbarsherlock/res/drawable-hdpi/abs__menu_dropdown_panel_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__menu_dropdown_panel_holo_light.9.png deleted file mode 100644 index 924a99d173082ba58ca7527822359f228bb14dec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1061 zcmV+=1ls$FP)#d)-&;4-At916hopygyW1WQa|lkCWZ4-q&QLYwjy>%Jd>?UvK6*fy zdt!`Ep~K-gOUxeEG;B7TCA&L&Y`5FR`f3tF5S^VH!lJsKJqkfK0&PN7nPcRS?`4Ev z7V~vPKouy~L@5%v*=&-(hy0cgM*ETwjWz&8F3NVhH7#V4$3+kVgi2lPw-adOTXm|2 z;f`P0rx+seIw-H@dwPaOx@-q(hY$i2BS4u1XM~+%LI5%mN(D;0XOsl63U@~43e6EU z5mrW96C~;L2O}H%p$jmGc5)7LM&^oyAacV=14{s_wp`K^YIpyDFEM02mXk3OSEw-p zdORS~SGTvf|Cjl{`o#71_3u-2KzcK(ZU7La5JAil5&>9olp#5yVJhG_L?OnQ2x7(v zIfg2+Q2z$cZ7gkJK~)>%8)`3CJSNBlBGKwWz;6QnLDPCN+(q9 zAJ*09wM4d_hZLYxWa z2;mvCbu@F-B1H21)loz{?U-+?@nqk8kw`Vm31QkJFg_V%{OMfZr8mlq(-<|uJGVoHpVClAlh&-bsduQ(hI zi(GsU`1tt1hf_X{d`3<68b|S{tXYwd2YXzXl8Izg4y^21 zp<@H92ON{kB3P1HizBE$;EP~xzks74y{^`3Ur7(FmPO0@t2+WXW`VN|Gc9|AJ43ds z=_5ZJGT6$YN8bIa6HYZ^jFIn`&>W#9La9l$?6@3`ET&WsUkjFK0@?|yO)(6`*1l_s~_L1z$~& z@jZM)qqe)$B+Pe}79nG2sji9uR0#8Z){~%#a(p4yPG;@1CipK8G=YCTO^$u*mj`Me f=rGa5Ym5<}3Pv>t$oVA_00000NkvXXu0mjf+qu}} diff --git a/actionbarsherlock/res/drawable-hdpi/abs__progress_bg_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__progress_bg_holo_dark.9.png deleted file mode 100644 index 310c368e7a68479307866c479d1e4eefcf5db311..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^96&6^!3HF|1ZAax6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`h^LEVh{nXLlN`Ak3Qu?vqkba5WyT9CKZ;N%wBhP~?hKK2LK3q{Q@b8ror6q0>Kp=4vJYD@<);T3K0RYm>I5PkM diff --git a/actionbarsherlock/res/drawable-hdpi/abs__progress_bg_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__progress_bg_holo_light.9.png deleted file mode 100644 index 70cb7fc7e0bcfb850d4b365f1bccb5b743913e21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^96&6^!3HF|1ZAax6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`fTxRNh{nXLlN`Ak40u@7AASF0zb~yy)74d)-}Q|XM+&=H%L1l~ z70X`DZ5Q8J;=>T6aJiv_zhUdQx9rw$B!4Wi^!v;8!uD-LM?h!CZ3$B@rZO?tz^Iy& QK(iSCDOJO>Ym5d24oA2hD9A9kkZ#C-ocYxQulY$%dG^s1`jD zWrBMf{hI5z?Ps6d&cAMwxpu9tAQSLC;sV+l?CI!atlqGv_K~X}S&7D6#irA$G%zcr zGa^}SvXODrvrsWB#ZkB-c}-Y}>Q0!#L#9IQCX$ZI#7DnF9fJ8(R=8iR{NJvIR3GfdBS0fGXvSYugM@B@Fy~s_l`Jy)|ccqHxmVzApHz{x4N{y z#Xj0V$LH=@zsWY)$4Z)6--edG^VYGh&b$}$F3XeLt5=Uu0`p37@FaypB&t$KuAm9R zq*|yt7WOdr(m%g{dU1bs0-qy(nh~3JDc<<|K^(;cR4G!8UrKd|p;N zi5zZftW#Kk#vM}fdS+hLQ#;Dq?H?_`8P1nhqmR=j>Au${MMR)hh&5HCA z?cjx6pHV1ZFFx`ra1m|YMALE$u3RAxZp(6Eus@DJwzn!G7Cw2Mm%K&AN5Ia`DuuPd r`dvHM#yxB2nYDo;0!e2cs)*3P7gB8$K+RT%00000NkvXXu0mjfr&_ZI diff --git a/actionbarsherlock/res/drawable-hdpi/abs__progress_primary_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__progress_primary_holo_light.9.png deleted file mode 100644 index 1c269205e874bc6addc308efe5be4fb7c5da0edc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 917 zcmV;G18V$CDOJO>Ym5d24oA2hD9A9kkZ#C-ocYxQulY$%dG^s1`jD zWrBMf{hI5z?Ps6d&cAMwxpu9tAQSLC;sV+l?CI!atlqGv_K~X}S&7D6#irA$G%zcr zGa^}SvXODrvrsWB#ZkB-c}-Y}>Q0!#L#9IQCX$ZI#7DnF9fJ8(R=8iR{NJvIR3GfdBS0fGXvSYugM@B@Fy~s_l`Jy)|ccqHxmVzApHz{x4N{y z#Xj0V$LH=@zsWY)$4Z)6--edG^VYGh&b$}$F3XeLt5=Uu0`p37@FaypB&t$KuAm9R zq*|yt7WOdr(m%g{dU1bs0-qy(nh~3JDc<<|K^(;cR4G!8UrKd|p;N zi5zZftW#Kk#vM}fdS+hLQ#;Dq?H?_`8P1nhqmR=j>Au${MMR)hh&5HCA z?cjx6pHV1ZFFx`ra1m|YMALE$u3RAxZp(6Eus@DJwzn!G7Cw2Mm%K&AN5Ia`DuuPd r`dvHM#yxB2nYDo;0!e2cs)*3P7gB8$K+RT%00000NkvXXu0mjfr&_ZI diff --git a/actionbarsherlock/res/drawable-hdpi/abs__progress_secondary_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__progress_secondary_holo_dark.9.png deleted file mode 100644 index 40d0d1645cbf05e30bf092ace45403281da7f318..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^96&6^!3HF|1ZAax6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`oTrOph{nXLlMZq=7znVWA2oV&$ZSjW?F|h7ziq5jS#e}ezd(V) z{M(JTeF@SBrcbxn{QE=WZYK^04VRD=846z*9&b9ovtVvpnl(eT%D#{N!SzC3^S3#* f<|u1MCr7h0-;i__`(soEw28sf)z4*}Q$iB}%FaDT diff --git a/actionbarsherlock/res/drawable-hdpi/abs__progress_secondary_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__progress_secondary_holo_light.9.png deleted file mode 100644 index 40d0d1645cbf05e30bf092ace45403281da7f318..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^96&6^!3HF|1ZAax6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`oTrOph{nXLlMZq=7znVWA2oV&$ZSjW?F|h7ziq5jS#e}ezd(V) z{M(JTeF@SBrcbxn{QE=WZYK^04VRD=846z*9&b9ovtVvpnl(eT%D#{N!SzC3^S3#* f<|u1MCr7h0-;i__`(soEw28sf)z4*}Q$iB}%FaDT diff --git a/actionbarsherlock/res/drawable-hdpi/abs__spinner_48_inner_holo.png b/actionbarsherlock/res/drawable-hdpi/abs__spinner_48_inner_holo.png deleted file mode 100644 index c8358e9cefce502030416e05dc8faff139b886b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2081 zcmV++2;TRJP)YIdx5%v}IY-E={))x>B}kD^;1aO=v<01PBB|;(|LQ1lm?k zLWq;Nn-CY=ae0(~!^>I`t6s zs-B%JpquWw-vVT&b%#DKYKZiAR|9AYVtSC>+D1~E4^t2*_YE}4C7t2scS_b&i9ji7 zBYSvMwdlT0Go+O!I1;=rq$n|BisnJx=53v0;@hqm(7l)*=4rJMo!clNrP~Z@m{E-} z^JZ{ZNHx@{flX?mQSo``X|C|5u79fpM_&?X60Kt|A5rbxJ7+XZpRQ<_6xsZ!_#wo! zj#h1_U5!M-Io2>ob>UEYg+LRijsxnVI$Sub8=TigMynU~iXTIjns`*ZXjCM8l?je< z^3e1OfW}cB&*(9#LY#4(p+|S(CFYo)RH;RK=~N=zD5YZ@e|b@)#etF>)Z-yez@UzD zxn@bF&zGN~8oIPk4dfy-rEX5Ww8$EZ0F70%U;9F1W%-Z($&Ga-Maup1vncKQ7_DKl zn9!@7d$FjFqs1PKM)U|Dr6$Db)oTnV%fNxx{Okxr+DM%Qs^$R=K0p5VBBLXP|Go*uWAqrP!s#9EjG3Y5H)_%&0w$xIP8)2<gS?toB)4w_5VP~5v52jeNf?a@l%z&Ft# z7nB8|dUgD~fFBhAa+9}!Fnz66uJJUZMq$&Z-=x+YQJfJpw%hO;S zbE}u#&MHNeP>Upl#AP)>l0hdeKfNO4(#tQm-Akeu&02@RbFR7XY>6_k1%f(YAT(#fsAW zCKBlg4QBOIpq?mn>zJh1X=9x9hp4F}kQ(@481j?!sz3o)0BA?xOCB;{@vwLHR_qA* zZA`n>5_V~?==zrnj46C`9p$WNjB&zGc+-W7;QUT(*KSn_p>ds2!NyfVppL*7{NFHR zx3J%}=U0sLd(^D`)P?PxcXaJb1;-WXet3d^dmIcA@AOk%p(p(THF8j!=km|#V)bYd zpicX$PljfTc@O)})|@FD=Z~mC2i2imPj;N6y7k2(V~h2N*p=p#-z6}HxcB*hYkSJV z`IFSdb9yY-P}dA6b@>ZL?=z9&3we?^d^OD4aqs1Mx13&f#Qiy{cDn?wohTPSPjL-WpW1m}O&Ju5YPHyotYlm=9`GcY zrwYvY8;-f&ZSM33oCpsge2-Ip%afm3V!sl6q6gM{kN3J3%|Xrhwg)`uVUIiGY!FzE zIO3Qa-0aQX;)a}NjB&uQ|K;9KmvHqg(MeCoc*sw<&DEj$2|GyBp7MmJgBi=!jyvfZ z$6Ymtf^mwAKHp@Hd-~&L-Nsi~>l_hPjymE9wjDU*%(E+7 za!uA`P2O+vKSpg~;?JJlUH||9C3HntbYx+4WjbSWWnpw>05UK!F)c7SEiyAyF*Z6g zGdeOeEigAaFfi_TCsF_a03~!qSaf7zbY(hiZ)9m^c>ppnF)=MLI4v?WR53O>Gc!6e zGc7PTIxsMwC7)_* diff --git a/actionbarsherlock/res/drawable-hdpi/abs__spinner_48_outer_holo.png b/actionbarsherlock/res/drawable-hdpi/abs__spinner_48_outer_holo.png deleted file mode 100644 index f62f74bb38e8818fd970b7ec1f7862e543cc9d07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1811 zcmV+u2kiKXP)Q(x@RlU0R z*6*F+o^#JDHf2*b#j2Gf_PMBSbuGRn) zDJUkGcinCw!4`)d@_D~EMJnC5dvGXBz z^GjW6Gg4BPB{MBwxqQWN<0fP#?6J=Sj@WNJ!AH@8Kl`>9L$xnJF(@mqT0WPnt1qF1 z=Fx+;deGw@bGK5OQ+L*P{Upq+6DX1yGQbK>T~%EkI?XGa@}$o>ppa%>^8?Sie*2l7 zfHK3%D>%7|N++0Avr7*8vd@}G^Jo0fcfyUHfnsLZ&jU?a6Rn7I58e-AIzUHA66jy!AvGyBgcAIA_8&ya%2-o5w@+x^Frq z7x5uqjDu?ciVPZ-34&-=b^T>U$i3owu8N|PCmm@W9a)>Z@0e@OLVt>;Q1iTBsK`Y- zJ#Dm0pva)1q@Sv}wFUZZ<(6Yki*muoJ=kjDtmVDYq#tH=k$<|@5vTpkf+%-~CzQJb zDj5=FGBxvks&SW*YJTnCqA2*7ySf013>jGQpITpe;Jn|eigLRhZQhTXHIx~a$pm$C z{nZbIsz13R7nL1tHd-@KF*$Um(og?cC1;!x<)VYeI|B_UB@HdgHw5UWlj@?}cDp+O zMal|-j9w2i9i`?Cb8^v;J)JZZ3@FG_LfsGv{MVdZZorO4w{8Y134%<%0TH$=m)%OW z_@u(SziK>nET6ihG`KOcU?%zJh~m2+ycN)r5;qQq+h%%Xy;f)Ejn0a3UnsuS^+vZqWP#0th z#x}@k!|oI0qU+rNRV>J4GUFR$v|a9z%jMoM-5IE6CMAy{ll?bZ%p5f-7cDwzt|L%b z^86*Y-fp1pM3X+OAj(~JqWJ*PYCpbZCY5MgZSAj)V(>vz$zUg(ZywPKsOqx1Or~s4 ztCPVxWShrQgx&N<^IZW2u9-7hOofKj5BzxpoW= zdO}GqH|+&2+j}j6LUh@cv}2FCzaLvtWZ?^TwHb8;v&L-C`+P^-e$fT!yBz5Da{oL7hj@h;h3%R$P7X_J;dmT2? z8&V8*_<~22M7c%3b3D}BjlNwczv7fZds1ebGU8;svesTmESU0X4=BlHYF_eOt8iaY zL0I~yq8N;M$m4dU73%)xM=srNe&@#dxWo1;CZw8+{^f0pouFbc zV#*`lZz%0)HGlQf<_c&{Ktx7;z}?CzodgvZopY&OUp7)Q;eaFVO?})iuy4L9j zyLs2K^qSz1EvYP7>Ws{|~_-QddT;IiL%she&}m+lY?b~t3u zik_CPT+O0+6?K`iA!CLOr{nnY$OW(ay)*42s|TRe$lC9I+YPJ$b-IG8H~q!myML>= zroa>ruDyrb zV`&jHgSNQCgmI$=lu=hRYuXKOo3_xM&-4jsmA;l<3@^Ph&(-?zXM#=Hludb0$^QZH zs3&Vcm*{c;001R)MObuXVRU6WV{&C-bY%cCFflPLFgPtTGgL7)Ix{mmGBYhOH##sd z?sz9s0000bbVXQnWMOn=I&E)cX=Zr$HaasiIx;gYFgH3dFrOu# z?f?J)8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?002ovPDHLkV1l}_ BPJaLZ diff --git a/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_default_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_default_holo_dark.9.png deleted file mode 100644 index eb28ff9a5516c15667fa8fafbc22d608d1f77a06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?o1QL?ArY-_Z*Jr|WFXM+FkX}IYI~tj_}8!bFJ^a4j((ibs-&WN zGIsXEx)Wtn`lnsEAmpSFI79ccn9RKAsn<`<tk;t}o>yjV{qp%WbL{dki&M)*dw`x~@O1TaS?83{1OTcY Bcf0@q diff --git a/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_default_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_default_holo_light.9.png deleted file mode 100644 index d281adb553af892f758407b846bf31810b9d776b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 312 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?Tb?eCArY-_Z*Jr|WFXM+FkX}IYP%rckLbO*zpbz{y7bYSIrPClD)2Hc3qcaC*%7oYhKR%+5DyWbJ~oU4#{OKNlluqE0VJm zR?Ud&kaA;Q)O4{aB-unUR3g{I@EB82%f_aZWF5r`AFqi`v@HN~5*v&Qo>cRA$gv99 zHaapFv&*%1#4~?bwda`9)~}vNKHF@K`t|cGZ}Xb{RR4x!PC{xWt~$(69DLj BcXj{( diff --git a/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_disabled_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_disabled_holo_dark.9.png deleted file mode 100644 index b2985860907ac324b509b76731e8ef9e01bcef39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?E1oWnArY-_Z#r@{8;G<#%>2r*^uo7)-)HXL@_O1Ny%Iq#{YfeF z(mvLmIJH1t&`=}DOJmBWhqv04yB582t6X;JXNKdwfEg3JZl{PztUeIIdQ8h8YDr!LqoiBzejNy&kDcJs%rP689)vmGI{X_;^jtl6gm^<0^v)GdFRa+YOJx z7F>vKtz@b&Rr+MtRJ_Cdn)*bIu9V&{pI@`*?C`z(Yf|Vzp#K;=UHx3vIVCg!08ssU A5dZ)H diff --git a/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_disabled_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_disabled_holo_light.9.png deleted file mode 100644 index 4215396dd4e51fea9239323d313b72fde0ba86d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s(?E1oWnArY-_Z#r@{8;G<#%>2r*^ujlV;{V25Ur(E)S0c!zKPhEi z+Q+&RrxwTy8fpZ2X-wJl@K&30*P>T$mCG*u%y7IHFk@oZ?G!PI)dwP2k7*f%?N0KT z=P~Pe`QZt37-AUDv?qm~sFi(Y>bsQr3FCw4S+92))lbOG-Y30G>`_~0 diff --git a/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_focused_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_focused_holo_dark.9.png deleted file mode 100644 index a280eabf59b5eb69fa2a84280402b63d5e1bb8f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 524 zcmeAS@N?(olHy`uVBq!ia0vp^%0O(y!3HF+1t+BgDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9q_DjO#pI977^n-`=$MKI|ZI{A2#4tV=npb9cQAXy4X!_bwM}{Q4K( z1sl8bnxc=22fURRmTQmkS`l-5N%{4LzmAq3{WkJ?oSyR(lyW*m>cW(jDj1r7drC_% z+Ahf4U7%?EfVHA#U$%eE)HUhV{* zGqMRv58QeS1t+_UJh{!Nwtjop`q`x&KXzE!mvvsrOU)9V|3+xFYu0w7ttSN+pN66C zV4oMA@AG&3wK%+`$wcPZ<#Ux2T-c9-*heq_yZUm|{V%D1UlxhJm0zYfUETgVr;hpA zt-Fj|Jsx=O$lYh^6WL+vBibSA6WURD#!g`Ij9SHG25Jg!2FnzxlYN}N9h%V=a_mM! z$e|leQ;yweap>IrEpmd};fhV2Zrn5uN|m^)*v*dyQIi{G2ej@g`j zy#1roz10ezmNeBYwbLI^0W9{MT&2dcxOa)`zb@?O?Gu2 z*S413TzCHUdV}>`f)DaiKP_4HkL&Y-WAl>F%y}d1AGY65et#XKh5dqWo7Y|}14bu< Mr>mdKI;Vst0N8Ej(f|Me diff --git a/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_focused_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_focused_holo_light.9.png deleted file mode 100644 index f8d619b4d47ab5b104d6b1042c27fb16a3beca47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 523 zcmV+m0`&cfP)C3<00004b3#c}2nYxW zdK`GU$CA-E+tg1FUj3CV1Ez}l7r{NB_YWZ zgb+-Kh;2qAgunr)owSNT9jE|#(}iQ{0=K~F)j_f4%AIwfW*LI4SCjSena$3zhl@?`-N)f>fC&00iU>|7tSL}YGdG832Z z7Ry93w=$W@5~IozqskJa$`YfBUCf~8@-tLEe(Yg7ZJ&$d5^vAJVlkbz&)H#>=1rCU z=lI*@D9QucAy4<)W_$YF0~q6}sI5vC!>ie*fX@E1>5KTAKqegRE>ywO`Fw(I}^ N002ovPDHLkV1grX;W+>R diff --git a/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_pressed_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__spinner_ab_pressed_holo_dark.9.png deleted file mode 100644 index 955a2f34061ae8ac853050da355f89409fa0a784..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 464 zcmV;>0WbcEP)C3<00004b3#c}2nYxW zd0`Pl=$b2!s#>@tS z$Y#JV#)+K6SU+tW#+_RkXYzpRi_e9eTN!5>F{(z4su81V#Hi{OLkTB`etUYuM1<4( zFh4)_STHCiBAh-(+2ze7j|0M$*V@)G5^^0JhFHh^fzV_7Tf?-4Si|T*tYCB@#xY$W zMloF>#xN!zMlhxzoiQdMoiL^$+87%UEsQNlYm7|@05m?}iO1-}bYl(D3Ue3c7gw}A zD?zp;CtICi-;5NDtN#ybjCs$)&yQmArGt<$4!&l7(HXO5p7J23`oDJvMC3<00004b3#c}2nYxW zdPRE!~6H3V|7LaeL+kwzxO}{DvWjdA^uWhB*Ox4MVbeVt$Spwgkx< z!VkuXjKgSuY)h6Hw=%|LL;AyKLdLC(F?ASO9Y$7%k=0>jHH%rr7Kwb5&>UvDaCo}j z=j+357qeVAJX{{~a_138(!I8ROa__X7ee%7enXtUzOE0mAw(ah0z?m{B1Ao=21G5U zCPW=Z0YnW(5u`pwA*3EgF{C<11Ed;86J&FYMhHOp8-||_vny?o%`ne52fWVraQiWC zKdv-wupMF9(yd;3%<<_PN8|TOh%C!a80|#$F{54SO;q)d{~Z)(nS?QFWpYf|szS`q zFpt2hCCEz5&mZk`@i_(t4MLWruXxh=CcXUn1{k8P{&E{)e*gdg07*qoM6N<$f@(ay AcmMzZ diff --git a/actionbarsherlock/res/drawable-hdpi/abs__tab_selected_focused_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__tab_selected_focused_holo.9.png deleted file mode 100644 index 673e3bf10d60cc54b6dfef2fcda24575073adf61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1i!3HFsuehcLq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMgJWBc+iXw=G=Ra=)z4*}Q$iB}l;b6k diff --git a/actionbarsherlock/res/drawable-hdpi/abs__tab_selected_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__tab_selected_holo.9.png deleted file mode 100644 index d57df98b501944b4ba63623766c396b5bccc29ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1i!3HFsuehcLq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMg}h~fd(*my85}Sb4q9e0H>EG$N&HU diff --git a/actionbarsherlock/res/drawable-hdpi/abs__tab_unselected_pressed_holo.9.png b/actionbarsherlock/res/drawable-hdpi/abs__tab_unselected_pressed_holo.9.png deleted file mode 100644 index aadc6f87b21d7d5139f3bfe860f4c289f75d241f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!3HD^Kbl$tDVAa<&kznEsNqQI0P;BtJR*x3 z7`Qt@n9=;?>9s&XV^0^y5RRG22KRnVX>4qKXwM^^Uwi5RN2-aD!@msM(PItf+&Xuw+O+F;e0P1D%boFyt=akR{ E0I7Z;-v9sr diff --git a/actionbarsherlock/res/drawable-hdpi/abs__textfield_search_right_default_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__textfield_search_right_default_holo_dark.9.png deleted file mode 100644 index 4be4af5fab3a09cce65144c747f24c6ade600359..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmE`DPvC;#}JM4$v^)8w`Z37Am6po z+v)2g(?$k`c>N1yj{}(xupO|Bb9m#eWaid)`oBujjyMLj^RWk-B)8T8wKI6S`njxg HN@xNA1NtG- diff --git a/actionbarsherlock/res/drawable-hdpi/abs__textfield_search_right_default_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__textfield_search_right_default_holo_light.9.png deleted file mode 100644 index e72193f5921ec091dcbdb7a6da540c6ae62a0abf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmE`DLqdY#}JM4$v^)8w`Z37Am6po z+v)2g(?*5`F8a+MS1=|pKR7U*C#OeuU+2*R28QEj<(b@LKCA=kWbkzLb6Mw<&;$Tx C%ODE? diff --git a/actionbarsherlock/res/drawable-hdpi/abs__textfield_search_right_selected_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__textfield_search_right_selected_holo_dark.9.png deleted file mode 100644 index 8f20b9d2673d84e22fe4f92da5c6fba5524bd7c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmE`DN9cm#}JM4$v^)8w`Z37Am6po z+v)2g(?$k`;P+>Y&mX9;kTm#w#$Mr{KU16J0f(K87k2#dS899B%AjFfa`@;vsXm|~ N44$rjF6*2UngAGyC2#-$ diff --git a/actionbarsherlock/res/drawable-hdpi/abs__textfield_search_right_selected_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__textfield_search_right_selected_holo_light.9.png deleted file mode 100644 index 04f657e1db10e9694c00a2d0240c4dd96a062c37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmE`DKk$O#}JM4$q6$m+Zg$O@E^Uw z81lZJ?Gxk7s`Po4Y{w3tY?zt;Z*oT>n?b-q29KD3>Vk*AGBMnIke8aaIU*2f0)wZk KpUXO@geCxD+9O{8 diff --git a/actionbarsherlock/res/drawable-hdpi/abs__textfield_search_selected_holo_dark.9.png b/actionbarsherlock/res/drawable-hdpi/abs__textfield_search_selected_holo_dark.9.png deleted file mode 100644 index 99309ef6d3e32a2d3303400aa061e0508a70f758..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmE`DN9cm#}JM4$v^)8w`Z37Am6po z+v)2g(?*7dS92?$NlFNF3%qKd&uD!9kGjy}NRLj&jF%7WCrYdnXQ&Wp*=?oVF$ZV} NgQu&X%Q~loCII6IBdP!Z diff --git a/actionbarsherlock/res/drawable-hdpi/abs__textfield_search_selected_holo_light.9.png b/actionbarsherlock/res/drawable-hdpi/abs__textfield_search_selected_holo_light.9.png deleted file mode 100644 index 9bde7fbdce15a1c2873eb0779ffc0617fd9b15c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~k!3HF)wbmE`DRWO3#}JM4$q6$m+Zg$O@E^Uw z81lZJ?bE^f8J_14%!p_Ru>Zp|qw<;kM2WLbT|5rH?EgED6zpZtm|hnx*$^-bXas|& LtDnm{r-UW|n`=evwJLPDoBk{4*AEnmdKI;Vst0H2gA*Z=?k diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ab_bottom_solid_light_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__ab_bottom_solid_light_holo.9.png deleted file mode 100644 index 0706c8af658bde9602634950dfe3d5fa5886163f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%zMd|QAs)xyUfsxfz<`JK;_Z5A z-Y@ApO*&r-OgQM+#9X>wkYiu(tId138dhyGKCm}H$eLN@qysZ=3D*)nlM7YC@0xyy hn}nCMmBhQI$CPR`ipOiMnG7_T!PC{xWt~$(698&aE5rZ* diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ab_bottom_transparent_dark_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__ab_bottom_transparent_dark_holo.9.png deleted file mode 100644 index d814d02d31183b8f00f475a05c124004983d9eff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%PM$7~As)w*fBgS%&%9EC|%_%783w8jlt8^&t;ucLK6TeKPwmj diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ab_bottom_transparent_light_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__ab_bottom_transparent_light_holo.9.png deleted file mode 100644 index b139c8e49168e4404df0a46b30a4b30e90c1ccff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%PM$7~As)w*fBgS%&%9ECY>s_{MVWOZ(=mjBT1_sGr W&p6(H%v1uJ#^CAd=d#Wzp$P!PC@9VV diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ab_share_pack_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__ab_share_pack_holo_dark.9.png deleted file mode 100644 index 738cb38d072137cb68723c576a801e3f3471bd3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2849 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 diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ab_share_pack_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__ab_share_pack_holo_light.9.png deleted file mode 100644 index 2ed75a767a87ac573cb7306686035f2100459fb5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)n!3HFaZu8v$Qfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#4jVIz7XKNB(EC6kA5Ry@5Rc=@2?~6F)PwUxdYTwn zdMu8}YM6Xys1i$1bTr(^uv&TM3(=CrV!crU$Q6V-%Qg7n#gTe~DWM4fl0G)# diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ab_solid_dark_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__ab_solid_dark_holo.9.png deleted file mode 100644 index 743d00b6cd7e446c7badca9dd11d1579404569cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%KAtX)As)xyUQ!e~V8Fq8aW6aH z`M>?!MSK0VJ5DH+1)MRKpSquM-S5BdOIN+&sn~jE%jQNlsf-1UY_}X6mMgq#dKVMx ha^q%Y#@a>3az|3`-r6;1y%^A322WQ%mvv4FO#tkfF|q&v diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ab_solid_light_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__ab_solid_light_holo.9.png deleted file mode 100644 index 17c1fb921f9b7b46aaeefe7afb8302874fb0abd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%KAtX)As)xyURua|z<`JK;_Z5y z;?s*`91mY+Vs~LvSAIRQ|I~ek>wo_(4hk(}+Y^;`>!t%UugL`m=C=w5f(6PQ%h%~C hy?JA^CG4Uk|5eN5b2qlEYyz6g;OXk;vd$@?2>`YpFM0p~ diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ab_solid_shadow_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__ab_solid_shadow_holo.9.png deleted file mode 100644 index ddfc8e3d5c4131f2460254f183938477fc5a0679..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rhed`}n05R21qr&#kfCPg`@kT=WR_nY-)l@u)2m z9YjR(TNrC5J8zlf@MOx-MX#^q?zd~tP;1Ok`WbQLQ#YGy{=Yfu7pEGW;JmVaai5Cr S@!LSF89ZJ6T-G@yGywoUXh2*5 diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ab_stacked_solid_dark_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__ab_stacked_solid_dark_holo.9.png deleted file mode 100644 index 007a4b239244212339b817f8de9474a4dc34fde0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%zMd|QAs)xyURua|z<`JK;_L&H z*gyPBj&nSGnTg$nOT)YjBQU;+O3-o%)BNS9GKrK90(RDcPwA0 ir}XBH&6co>lKfV`a~Jh`>I4G~X7F_Nb6Mw<&;$VSc`p(G diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ab_stacked_solid_light_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__ab_stacked_solid_light_holo.9.png deleted file mode 100644 index ad6e1a4d9f3c81e20676f979a53cea2084ce903d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%KAtX)As)xyUQ!e~V8Fq8aqs`F z7bNtyi1zwxcbrft3piseKXpIjy5E1@m#%ulQ?d2Tmd%Z9QW*;x*={*DELV8f^e!gW h<;Km*jJ1o5{)rFFF7K diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ab_stacked_transparent_dark_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__ab_stacked_transparent_dark_holo.9.png deleted file mode 100644 index 0ad6c888b4c7e436e7d7c78432dbfdaecc95a7ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%Zk{fVAs)w*fBgS%&%9ECxB?U?=uVx Y$^4u51wHGE0Gi0)>FVdQ&MBb@0N@ZURR910 diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ab_stacked_transparent_light_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__ab_stacked_transparent_light_holo.9.png deleted file mode 100644 index 19b50abcb536602cf2cd36d5a19805464988bd20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%PM$7~As)w*fBgS%&%9ECmdKI;Vst03^XH%m4rY diff --git a/actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_default_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_default_holo_dark.9.png deleted file mode 100644 index 5461b9c00fd3fc513aa4465682e70e87cca36a6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQaYY4jv*T7lQS|h5*V8PD@dJb zGfWV2j%0YY@&Et-(u-Ft=sZxsVYp-gbGr;f^5z}?TUWk$0o2Ff>FVdQ&MBb@07WJt A3jhEB diff --git a/actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_default_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_default_holo_light.9.png deleted file mode 100644 index 5dc6f804aea8ca344275ac6eb497b6bfe0f117f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQd*uajv*T7lQS|h5*V8PD@dJb xGfWV2j%0Xds4&4P&{4SYp+J&{BRiiZ!)425)ejdW>;mdy@O1TaS?83{1ORBM8sz{0 diff --git a/actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_focused_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_focused_holo_dark.9.png deleted file mode 100644 index a70b53c59af769e3c98973ad9718670ce27259ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQYM}*jv*T7lYjjGZ_h07hy7xL zS%<;BUsuG{45zRSgeB^>bP0l+XkK D`1l&; diff --git a/actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_dark.9.png deleted file mode 100644 index 85d7aadd4dfb619883f68f1cc63e629698b5dab5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQbwLGjv*T7lQS|h5*V8PD@dJT z6Fe3@|6GeFPb#ATqtK84|Mweqan0i3X%}$jvMQLwz#trO`SaWQ^{znO44$rjF6*2U FngE5o9^U`} diff --git a/actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__btn_cab_done_pressed_holo_light.9.png deleted file mode 100644 index f7b01e012f895bfe2c4241e1d48771fc372b35cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^EI_Ql!3HEv&)kdyQU;zbjv*T7lQS|h5*V8PD@dJT z6Fe3@|6GeFPb#ATqY%TTAPubyB?B2J9?cgAJee4pt{u!zH{AaisF%Uh)z4*}Q$iB} D0X-aq diff --git a/actionbarsherlock/res/drawable-mdpi/abs__cab_background_bottom_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__cab_background_bottom_holo_dark.9.png deleted file mode 100644 index d8f1c8bd54f4f091e79389603095c99cf825cb6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%Zk{fVAs)w*Gcqy~4zxBtu(zuW zGMHg-@7EW5UBeRx4_{GYv)%pQnG{Mujhr&UNqv-pZ`Il{xB Xs2c0@Tz2whppguou6{1-oD!Md5lfPH{+~ zs&ZK!$GJ#`+OXn)bEl7O^s7vMLr%~_eO6@BP#xDsWzJIxbKZ~=QHwoEqiCN;6|k~9&?6VGu8wVeg}kjlqBUkXd|o%rApJ7Xx?SmelE6^*`N?mP%?P7H@yM z@176Te{31>^aeVqCP$2D`iM8b&G*loT1#z02OAN3)TGUD#xbYXQgqexFre>@9yw_< zoN>t9>xRrEIA?_IE1YrUo=P<2hNadJXB=4rbb%a&IXb5^sO2P4AoU2`8OJ_N3+RuU z?3bPMlGWJT{|mv5xDeck3qc!^Tkv+yM^@uWqQKxnw{tZ6G_7EN(=@mR#5tHjEptZL zT?o!N^e&F18P*7EfGlP>S;He0o_$19Sz!q7up>N&hdzT z+KgUQr1}UkLQL4KR;yolWSqh_YPX?lMz7!1&pz~~fd%z~_Z{#V_yT+aKE`}mgO%s( z*Zy2en({y`_&;C`{0061zkwyNiuqzpAev$qeWYoU3d{J#NzC8IACaX$H=;%xu?3!~ z#a`2j|4di>P9KpnLiZ0Fl^vDJdHW{hJgNDYHbk!VsHwq51hhtobGl;RmY>GHkg{)E zesWUhFRGl6)Eh$fMU__)%@X*lTj%8LuWk+fh;ux9b*`$4|A#h$uKO0E`Tzg`07*qo IM6N<$f=1Pyg8%>k diff --git a/actionbarsherlock/res/drawable-mdpi/abs__dialog_full_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__dialog_full_holo_light.9.png deleted file mode 100644 index f18050ea589eaa31233bc08e4f8a4e361747bc94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1003 zcmV%vbFc60S)hq5aquQtN zO>~Q-PMt}eDy?tfo9G5^U3x~HVu{=o-l^#5`3AXbFq#7CZ= zx~R)Z%-PngELWXE=jG+4wH{HY%RHtL$z+_dj#xsD@Y&isDVlJd1j7%A; z{S3ob2!NCVl}{yrl8B^V**9f-6IC==^T()w$-W%VAY54pg(^F>UjitZxrB-eCn8Lf zB*stQ-rl}17K`6RG#lbS(&{_eIc1V`#=6_}di{5~T>e4x!ZPZXM|a{QRmt`XV*pbC z)5T)(D?{j2cRHWXf1>hHw<=z1GC@s9Ro2lk0Wc$?r`}K3Qx5<^GzKt(+iwt@SwZ#Y z1K3Z>bSEt!roEr8rydA`NJoVD>nPSV+2(05UE>4T005_GAOuI89vS#iG4B18N9tN{ z^Z@tNBTj+gCOB47*w+ z+2Hb~>!f2H1$Hq!D=_Sb+i%D|qnZ-1^bbIwX<}v&QHjdz0&e>kOOQ$(hHgzP5DjJz z0f>y6M3En>w55Wi4nf3bKUf4p>o0~xvY>6}4YBjHqH^B)8ba{Lja`ks{5OurR;$m< ZjQ=n8%sUGgc=rGR002ovPDHLkV1nUn!$<%C diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ic_ab_back_holo_dark.png b/actionbarsherlock/res/drawable-mdpi/abs__ic_ab_back_holo_dark.png deleted file mode 100644 index df2d3d158e201f4b5bc8f478bfe194c819c762d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 466 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6n3BBRT^Rni_n+Ah2>S z4={E+nQaFWEGuwK2hw1@3^B*n9tLu5dAc};Xq+#-xYx_sQH13|{`71Pj-*6Uoi`#n zE(U8IKgsQz<^Rb4R70ym$22iPZttV^?_#_6n&0#=x|;ZH&dfx!jETDzs(0U>)g_uQmUhGGNWo+VotE}_5b3Zj`hnf_E}Q2 zkoV^c&!VIWreR+T-g@7!2<2C~cxLXYh02~hOPyXw&7V2OC7#SEE>Kd5q8W@Hc8e16}SQ(iDxmE@S#`ha8qiD#@ zPsvQH#I3=p$s!-9K@wy`aDG}zd16s2gJVj5QmTSyZen_BP-2>S z4={E+nQaFWEGuwK2hw1@3^B*n9tLvudAc};Xq?Zzc+iX4P{i%w`)y*!lC}nMxxP5m z`ipDd|3l#c1q-`17wzs7jap-@cWTC&8}(D4%&X3GaM#!SkY4?Tswdc+PM~^5?gXjDEJr|A(9^w&s1cyzt=Kg=58+)D;SHpB%sRSHFHUToUy>RV`*x3 zp=*`d7Z@F1xvAFw#q#fW_g_%cHx(CZDFFIJwZt`|BqgyV)hf9t6-Y4{85kPs8kp-E z7={=cTNxTy8JPmPRt5&f_Zu#wXvob^$xN%nt--0uA|I$h5@bVgep*R+Vo@rCV@iHf fs)A>3VtQ&&YGO)d;mK4RpdtoOS3j3^P6 diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ic_cab_done_holo_dark.png b/actionbarsherlock/res/drawable-mdpi/abs__ic_cab_done_holo_dark.png deleted file mode 100644 index a17b6a78920848c37a67246a76749b4cc1425a15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 566 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~Ijou`Xqh{y4_R~-EgIfxwlm><>K$vu5h!wc4! z9iP>XtrZVs65@3e-rKIN%Hh(x{ewWxt1j(s|L*kJ zSoUnickXv5=i7?TNH`^EJfpg4#&4;Y0qR0+drTg2JXGfUq3}Rr;{P9f_n*&gD7KkW z&D4IqLivGGRq&kmAH6(eA0`F~7S8rex88HAVS=03cY~80?cpzkFa4S5A6;t}xJ7Q# z9-saRVPfVT##U33AAO3A+Ypl|_94?@cK)tT4*8AF;-^j1iVm!a-M-<=iX&Itr@TnW zJpXO;4EOj9!Ar}#BHVL6_dHGGELXBQqN>Q8)gj~`k@s=>rw|ur?|x;upO5s^{asBY zKb@S=&SWDRsQzHyR;N3i0@8Cfnf~0l`P3PA4VeH(Ut{H!I{}l<<aB zB5gMTgH*M|HKHUXu_VC#5QQ<|d}62BjvZR2H60 RwE-$(@O1TaS?83{1OW6u*u?+< diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ic_cab_done_holo_light.png b/actionbarsherlock/res/drawable-mdpi/abs__ic_cab_done_holo_light.png deleted file mode 100644 index b28b3b54f4c81d482f797f31936cbd4013c093b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 552 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 diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ic_clear_normal.png b/actionbarsherlock/res/drawable-mdpi/abs__ic_clear_normal.png deleted file mode 100644 index 86944a879b986d941e6567d78fbac16c87ae9244..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1869 zcmbVNc~H}M6fTFTAW9JhxeNgj51OPWje@pKfI5QEBA|d$+W@sTscjVKdVuS?9w2h9 zu!^p(ipSu+I*za)qKMZh4tTpGiYF)@D~E`is<``y;~$%us6_Qf>3EP7d8-+ zSuC3rZA?5JA2A(OQ+kfdV#CSM8yGZ;HF-*gL8aCaG%$}y)sn&B%ahe0pw$F}ae@dq z!XP8kwBcqWp)^OvsLeXHSOZQ80VZdl41u1YRX~P*0ck=rg27L`C^NTgLm=?Ugw_Rv zpPh=2hyrAkkpKi7I8Y4>VL*s*5FTG75={iSFakp`7ecs!hzR9zQ5XikJRqZH)TE#a zEcA;OvkC^&Xxe~6PXctnG=pit3hET2u2VQ z9~N<8VGzQE&zE61CKg~a1QT!t{T$!IN?{zwL_!$n$z%wEg-T!nU&6;R9*)6ME??M> zm6Ik~MXHH@T`i;g87m0=E*6y;2^CElV<>7te+5LPQ8Z;rqYQvdDF7l=YAtD5TdwDG zv>0L3E+#agMoJHS$}g(@hCVJsqzKOFTO4KL4hj`=LnW957mEdaK`0OWg4O(=oI#8; zkfk{OQ!M>kOa)q|UrV1^d~F_rWID#kv<4`i7|nFtQaL7x$+*=PcRNxkacMnTzT(!p zfRg6DJ1Y_~Z$G;tw~$ix*L@nh0_gy+q{K6=O-)U1ZBL7fiw9T#wcP7iz?I7*wg8n!aY@L* z%F1466IZ9xDGw&8Ca%%8-9N%k=5}B-gNg) zDs^~|+ru7gAfdUoeO*+YE(gj=-VB=VaaeB5#xy?WU;B+3~rnji3!zw~u|NB5xDgMA*Ab}CoKR1b4{ zl>=_SIAEWB^HRqqsb8t5;#}&X_CmjxL@oZX6x`u-Nm{2|`y?pbN5T8(*$@T`ZH%+J z9q+wi#oajjm>l)vpmE_mr&lY%70+^a$7TKT;qFtqhuwA!$jh%>ho3F4%BgGKv%2K0 z$HF4;&SJ>7KIHm~u<^wO_8Z;3y_c~N@r~v)LwjwHt(kkY;`G=_K|x(kncTb+Ti2eM z7yH!X-5fzxm)r79(!ZaTJ+c?A_7b`^xjVa7S5;ayZg6q=sKBA)LhBfI?7p4HG-EdX zGM##G-t1BC0PE-nz1YH|+GW>beOJO<&x4C?Y3_ohAr4Hb&I{K{y07O> zYq)siMdY38b0^FH-T7Vnp?+Dwy~?6uy>H4FYTQ}9{^zjW>fFu1k;Wnu$QYKv+~3MD zkL9@kLKD%Thtmq5^yY3(U$KE}2<_4f7b{3i<6pkgb<{dv;FI&fmd#{QXNuR<0GE-t|?<-_xFWf6rQD zvp1?(m;K#mK7kAc23PhCb9_I|Uwpe=_~P7`{<9hKeqT15)CmrGep&{}lJt6uiX0l6LDtGM?vvS&HSN)*I> zeOGt*EnBDP@;N{6y`LG()$~n&=KfpyvX&R-FPte;1xy60C9V-ADTyViR>?)FK#IZ0 zz|c_Fz)aW3GQ`l_%D~9V#8}q=$S`=EA9fW*LvDUbW?Cg~4U>%CWdb!wf@}!RPb(=; nEJ|f?Ovz75Rq)JBOiv9;O-!jQJeg_(RK(!v>gTe~DWM4f-EB1! diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ic_clear_search_api_holo_light.png b/actionbarsherlock/res/drawable-mdpi/abs__ic_clear_search_api_holo_light.png deleted file mode 100644 index 15b86cbb21eb3bfb82d36aa9ce750906297a9225..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 743 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{0wkH`a%F)OQ-Tee`#-|*CiUbcIg;ND=p zYvDSd^|6iLOdqf$Xmz|*HxtvIt|l!1HU7>O^~bA&&;Fj*b;Hx}3d6&UEnVN=_&rrS zyUca-tl4jMo@$nFEpTFXzIjD+{<)ibKgss#-rp9f6_EGh??g@(2S&3=!i$ftp1=NR ze5Ls1tv8DvCnWJd(z*Zhh{1dQ0Dw1}N=Vgur< zo}V(7G@F#*B=UQaz!7tS(%x&E*VO)~n0V|`)7|K^f!Elpcvl1$gq+H{_D)QEMqY%8 z_vf1aTF*LU_FtRc+)-?b!3?Ao)T}9E5o1c=IR*74~B%^nkKn;>08-nxG qO3D+9QW+dm@{>{(JaZG%Q-e|yQz{EjrrH1%F?hQAxvXq8M>Z zk&z^%c%@bRQ#)+nOe){kHaX!!Ue%|-vcG@vo7s2MJqBDZfk5<_)|-ZFZPj9NlZ$EDG$w6h z^v#+%T(e!=j16si)bzU4HWV6_^stND&E;|5`nfYv$?gux?t!>a1t>hEvKg8)f3B--`qJ5Vc+(!(3AIVr zEf|cmkv%DM(IHdcJ}Sgr>#(5~Tn4TISAy%nrQvE?Laps69ZLLT!~WS0QV)l|q?Zr( z+%hOrq1e~am)EDre9b1+$FL^?hsoiT)~9EmS!B=eNVF1PP(kFFm`ljix)2F8;hG8d=#8;jP)h%8u`(ez=ZN9^bNjAY1@m$qMwqc*3 zT<9Z^7q-4S8p!6dM-010M=(>rk1eytHi>R-cR}tW4SUbF89%`nk>dMSnMgg-f@tvLl z8zJ1Aj<77hi)&@}=LO_3nTIUJfhLK?)MTgjijKG^e1tcvx@U?wd-4zBd{w~Rm8u&) z61IEoor<-v>QlY};sLy%=GMYsYZW#7TiibW&xJ?UJ`JsgWSk4`n=4tN;yWe=Mb9;n zrw!^kvCo<)%-&D;l)PgTvU~Z|j|VKn#)IlF_j=`rkH?YbC)&niUyM-$#5;BRtd~Vt zvDwmlW4up^P2AqKxmr=aNvNMq0%A$n_A&Ybf8s&n?eE2(zp1N=^sXKmlORRu-MwkG zqSrlb4;RY>`GT2~ewsriQ0>5-Cr@@n4LZ4_+db%Z)RR$pECx zV&kKm<~rTWsF|5CovUxbAuX%rMqUY#bK_3MXl`zRlnnCM)JOk#@Q|`yZle2b!xrs+ z?}@SMBoaxAn*F`n4c~I!tWN%NL;nce-(Ln9T2XV@wz0+fUe{x3EWBVphWolE&ZMpy zk=t+u)*ULX*vshr>?xS>+y1VFi$&0ZQQaET*YU40s&SgZh;!v@8ZAA*DJJ>D=a=0< zFKXQ=k&~NZZGoK2o`n~+R8w?*R>uuBc#s$EF{m0(={u8TU3kQEm9SfChYCn7J#=g4 z(PaFJU1FFZJS#?cN?VCdd62LmX1(Q&iCokv9@0&`0c7bz75vdTSAVg)Dte++U_U8a z)M|^@vmd{xiq;M1c-`XC1_k!;*hJ-2+0wh;$&M)lJC}axPr((&K~D-GVw^}ZK>;xo z8*&r{B7jDjnH@k`96(zW%`9zDXdCl`2T+hey^ru3{!bx1A}HkS<^L~SLob9t1%PwH KV``51)Bgpr>#?r@ diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ic_go_search_api_holo_light.png b/actionbarsherlock/res/drawable-mdpi/abs__ic_go_search_api_holo_light.png deleted file mode 100644 index 8518498eb6c93e3d4f9f5c806362bf3117b17852..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 570 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{0wkH`a%F)OQf4-y`wRCHWT>4=v6Z~W)^Ex~}&Cks#3Ph?YL zYs=^PA1JbT)~OR;KkxqfX5VYCuTH8yF+BVMK5jv$P8>M!p?~7X|K_(-ZNE?1#j0+Y zX}rfdsOO!o8=KoP`};Z1zsHB36rFKS#YJJm49Wj>o1-q)hN%bb=nB|jWMKUFU(#;% zzNwwTK`8{^tVraaWCe_M$vxef5w0QpFdP-veDuD zxhegZ|L;vckoBsbjg4*D|NoLZ`&-4e?`K!s|My<3S%8^2?NH;i6Q(?qt2KRNl&_PX0wV*1 z5qGtn%`^R9z@Swvag8WRNi0dVN-jzTQVd20hK9NZX1Yd}A%^Bw21ZsU#<~VThQZ_f zu&XEx;QVw%w1wevX{81fiqT9$oZHH(4a215zM2{s3I28IOo7eJ#J d>KPlRN5&o6d@ywr|9haR44$rjF6*2UngC}HDAND{ diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ic_menu_share_holo_dark.png b/actionbarsherlock/res/drawable-mdpi/abs__ic_menu_share_holo_dark.png deleted file mode 100644 index 6bf21e307ed392bf00fe80b162a6ce9115e62c84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 332 zcmV-S0ki&zP)h$s=>Sb2o({EW84x$2Sq@4Qvb1mj$j~;VIQBr2GX>%-APxay9!he7 z8W7h*gD?q**@0LXh%12j6cFzN;xHg)rA0Yl3bh0|IM)O5QD`2|BGz~0I$#-|1SL$5 zlJGbV2jtPKD8?58g7k0zp)`;V#9XwljI@z*K`Om-0V(CcdbDyt4~XM{*o)XuqGd@4 zDx{8=fp<=lEG6&%R0000-rS^s>8d@5ni2hppU0iV;YH8gwNa0%) z{Cz&}Jx|SbT`f+uL?986Pnf0|l@f5k0jz*^zeXXD13Pe$Xi*7R9^s5FmB7$P;6x!% z=kMH0V6IZ20v0@I38qpwTN6bU0_>(U;T<=GYX-1E8)QG}f-;!!681nE=wJ-aU=KPV z^-i_I3K%>@EawIsd5_!T)2R?x1}rE&N|%HcIQa;SqE5+gRv=Fy@M;YVKt`niqbhVk zpSlae%z=$G2Wp@TnqrmWnuKgf72^IDIDhdq{E7X5-;T%%62M`q*b}mOv3|8DyoG;R z;O#l^2#-VHDcnmy=|6xRPAT9SP9@+QP9YE&4z7Z?SGPkvc&h*a002ovPDHLkV1j;z BjTis` diff --git a/actionbarsherlock/res/drawable-mdpi/abs__ic_search.png b/actionbarsherlock/res/drawable-mdpi/abs__ic_search.png deleted file mode 100644 index 4be72f108ba1a4f36da5c3a59b1ed08ddcf7cb8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2280 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 diff --git a/actionbarsherlock/res/drawable-mdpi/abs__list_activated_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__list_activated_holo.9.png deleted file mode 100644 index 3bf8e03623c94b68d31963ffe7e59c72c3dcc059..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`86o-U3d5>t~CW>mH@a{g&g;s7!l1y4Byva-KaJLVIiI)OpBYodjS ofJx&-C1HsL_x|*Yp0_#7zz}{&aC*>dO_0?Lp00i_>zopr00f~Zw*UYD diff --git a/actionbarsherlock/res/drawable-mdpi/abs__list_divider_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__list_divider_holo_dark.9.png deleted file mode 100644 index 986ab0b9746301f2dd9401829da09e00995621b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~qMj~}Asp9}6B-)+^BAxRtXRm= az`@Yw&#rLZUbzUUfWgz%&t;ucLK6T(%Mo}0 diff --git a/actionbarsherlock/res/drawable-mdpi/abs__list_divider_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__list_divider_holo_light.9.png deleted file mode 100644 index 0279e17a123f8cbb3c7e3a9ce5c5af8e693b6977..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~!k#XUAsp9}6B-)+^LX%RmN2q0 Ycy4A9FVZ~13zTN?boFyt=akR{01+Y(GXMYp diff --git a/actionbarsherlock/res/drawable-mdpi/abs__list_focused_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__list_focused_holo.9.png deleted file mode 100644 index 7c0599e3a6fcce1d9b22e47bfdb63afb1d3d9c02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`6eo-U3d5>t~6?){p=$oZ!|i46oEul1LdSjZF4rt@IU_AhE`IYK8I wIB$ByaB<8!;4zVtCm{dd@wVRWcBu>u-xEd5&snyt0Gh?%>FVdQ&MBb@09FhvcK`qY diff --git a/actionbarsherlock/res/drawable-mdpi/abs__list_longpressed_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__list_longpressed_holo.9.png deleted file mode 100644 index 3bf8e03623c94b68d31963ffe7e59c72c3dcc059..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`86o-U3d5>t~CW>mH@a{g&g;s7!l1y4Byva-KaJLVIiI)OpBYodjS ofJx&-C1HsL_x|*Yp0_#7zz}{&aC*>dO_0?Lp00i_>zopr00f~Zw*UYD diff --git a/actionbarsherlock/res/drawable-mdpi/abs__list_pressed_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__list_pressed_holo_dark.9.png deleted file mode 100644 index 6e77525d2dbbc1673145d60d775602c85264330d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`6eo-U3d5>t~6?){p=$oZ!|i46oEul1LdSlBa@C*nY4{!0_J9HA2p woHspUxHx7V@R-QS6OjM!cw6swyHo~-e~lvMp^1B@1I=RaboFyt=akR{0Ay(_r~m)} diff --git a/actionbarsherlock/res/drawable-mdpi/abs__list_pressed_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__list_pressed_holo_light.9.png deleted file mode 100644 index 6e77525d2dbbc1673145d60d775602c85264330d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqEX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`6eo-U3d5>t~6?){p=$oZ!|i46oEul1LdSlBa@C*nY4{!0_J9HA2p woHspUxHx7V@R-QS6OjM!cw6swyHo~-e~lvMp^1B@1I=RaboFyt=akR{0Ay(_r~m)} diff --git a/actionbarsherlock/res/drawable-mdpi/abs__list_selector_disabled_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__list_selector_disabled_holo_dark.9.png deleted file mode 100644 index 92da2f0dd3711a2ceb843768cafd6b91a2807b43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^{6MVD!3HFkzrK_Oq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMg#;uvX%d>fBtxy+SfFGJhTv9Z9>9n%%Tr7{oI+Q@DMao9hQt@O?p#8;eZd15IY| MboFyt=akR{068-?^#A|> diff --git a/actionbarsherlock/res/drawable-mdpi/abs__list_selector_disabled_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__list_selector_disabled_holo_light.9.png deleted file mode 100644 index 42cb6463e4c28c6aeffa315c4fc869867dbb6b7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^{6MVD!3HFkzrK_Oq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMg@oJyIHz9Y|%SiynA|kd)58s-{92FmHki*;@KxND!%;H%=F4ZU(n;yg$GVRgBd(s L{an^LB{Ts54)-;@ diff --git a/actionbarsherlock/res/drawable-mdpi/abs__menu_dropdown_panel_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__menu_dropdown_panel_holo_dark.9.png deleted file mode 100644 index 460ec46eb0786706610e21ac9097de489cedfc33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 651 zcmV;60(AX}P)!1&^00004b3#c}2nYxW zdZ_-Wf*5)VugS&t+23J}V*z%DOHb#W|`Z#l>;cJ*L_P;jGoKD8nX4Z`xH*Q>s zTvTl`b;%gqS1znaOc|u@tz3t7=|UK<9Hr>BJ|D1%4AOYzE>c>YASL1(e+Y^`_iG?7 z1UL~EK(|`0e*W#*UXt~C{TfUweyI5sSBLVgO?u)p&e9+4(C=i^T1GuQJ|j^LdEE0 zfZFjzm@Nd117_`XxKDqSoJXh_wG-}tW_yHE!!B|TSvyio<6k9eTgoG9O0aTdZJ81x zmbul8Z%fpkT#Wc{ND1L@No&VX#iPVF7hx`c0JdkE;3e2%ZBQYi%Oe#dj=&z+_I>|? zOJi$dCv)FoZJG3n&>Qp|;vSo*JOkf=A5uR{`;uV-QwsX>Ho!a31HXV*se5TxFFA=4 zo=3!%#5;D2+DO|6R;c8b^-B2j{s4XhZw!t1m&l3O!HmBwHn=!)kb6yF?kI1MVX*Vu z<6hz)DH{^YBPWDzO$|0isCW3@P>L98oO;C$E5=4jGEPjLS?XZ=13IvJLaC?O;nLn? z=e?6_T^b`&$N3sK+o1N3^-DyB&=+_N>geY)_rHdJwBJ%s{^4(_WBZ5MLQM53U4RfX laXn(LVYMe-Njr@(d;;;gyUim^Wn%yU002ovPDHLkV1m`SB-{W1 diff --git a/actionbarsherlock/res/drawable-mdpi/abs__menu_dropdown_panel_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__menu_dropdown_panel_holo_light.9.png deleted file mode 100644 index e84adf2d41604323cdad8b15e7034b6137e02425..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 720 zcmV;>0x$iEP)!1&^00004b3#c}2nYxW zd09!jyup9SJyH%;E_KZI5Ed^B*iNJmRSj zBG=jNc2B+cMg+dzb=~X>SwfDye{PH^oqQ4$1^~*55|NVv2=ckIR8XoEqC|oOgc2g; zEPA&fNb-^8#Mr1#v(VQn5UdVR@QAWs>EP1 zTHM9Zaim5tPqqk+y4R~ii**RWgPIHWkr2Q-rv~$oD_;OFg!*vQOJ?oR%RhjSvm}}N zU}~@)A@q_TOphE%y@J$^Y;2GXG*T-_?U?-%UNYKi5n>WcgjmBq)+~pV5UB*Fc4!_E zr<_OV^tE=(@|l_%K9#lBPBbeU!!Q72CYl{ozqWE(s>}kg*Xy-fB`%jskbX;(+jyxw zA`k(lb8|^3?6_RfL_?Is~gyeh`O%xX?U(f4nJ zaCd?*qxs3xYk`99o-U3d5>wYsbmTgqz{8?`Dg4L(`abqnuZs;wTVv8ZBg|GX^f4xE z5ck=nld$UVv7H|oR+P30etdkz&;0SSW2^3}yn7y4rozh{Dy3k((DE(NNCr<=KbLh* G2~7afj5MhL diff --git a/actionbarsherlock/res/drawable-mdpi/abs__progress_bg_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__progress_bg_holo_light.9.png deleted file mode 100644 index 4bb22f0e10e621ef31f16100b3f682a09565c65d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159 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 RY6Dcn;OXk;vd$@?2>^cl_{IPL diff --git a/actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_default_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_default_holo_dark.9.png deleted file mode 100644 index 29aff4d43f71a025f464587ead52aff2ecae6a58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^59s(?1)eUBAs(G?r*GssWFX)$e`(35Y8e@;SI4XCdOETn3puLX+U@Np z`{}{9$F@!!Tb4}GnD8m&^|D{1rP|_tuSV&+Z=MCoD&l+{? zpGeMToA<;$LF?@fW~rUl3#RU765DB+Fm*PQ+)k?pQ&%&Ye!A+gR)$OeeXHaR#_cxq xcQACD7BHRDw&oXmu9s(?g`O^sAs(G?r*GssWFX)$e`(35d_EZ~i&w|H<&_`ZD(+MedV5zj zu-#_I+lqbxCf!wDY`(!qq|2YPZ`s2sD|KqW({JG~4*WL+Cpx;A`7$XPF&b}JE9dda zdDh0P2cC5-%kKDDBus2)4y)97FmX3?+)izQiL;plcWMSG#q&-%rTF<%+zn>y2h*Mj yizj?!^E*(P`ureMOz-ZiFXWg1cX%y7!FpSm=AYI1UI{?QGI+ZBxvX9s(?*`6+rAs(G?r#o^TG7xZ`zf?Wo$i4qI|8=SuS_>z)W_YPj?%Q>u zIp@ANM{x}Zqe@#*i-Jc_;!9;KcT)!P=e8Z65pgErb%iKSkCNb@A?yTt$n@r z2c`IHF%KKu<@hR|E_CSLV|hUMOZy3b87rAYm)KaVUb9s(?*`6+rAs(G?r#o^TG7xZ`zf?Wo$i2t+|9e$2v=&Zo&G1s6+_&pQ zbIyHljz-QjH&*S{-J;(gu&3N>@$LMyenNedpai4+B)&;SOq0|eu$bkReVyxuhm-Z9>GFCF_99MaBsxVXw=u8GrS3j3^P6KmrqN>Fc^oQq;b>Mt0(a$ z!tgX@A7RK4{kGy^A3#w21maN-UfpV|U0)B)Mu)Zk(%$xiP)OBD#retJ&sicWsshEL!WHUI0Z}S=i2Rqw=-{<_oUlU4$I1(Vt^KG}@Sd2k4!kUV zp9d;G14UN$xn@Z2Tv!X1WCiPlZi?T5Wo`s>dMMw4?2=HB&MqLoAdzh3Gg0e200000 LNkvXXu0mjf#CNP@ diff --git a/actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_focused_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_focused_holo_light.9.png deleted file mode 100644 index 6536ee63329bb47bec2bf2384aa494923cc2773a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 424 zcmV;Z0ayNsP)Km%mHHKmbPH_0G1~QE(|Z z3L*$mIy*=P@!u2&!BHHFf;fuc0uio1*2@YRBct9{0AyU2}iGVkcWw7UUPW(q{Hz&m;6;CQrhm;h30w)z2(`W_Vv zws(S3@Pah`KM=_o2%_3&n+}O86bq(Ag>`_N^4m7drC>+{^&N;72|01L0Qm!AONf3s S@;8qF0000Km%VDkFce0=d)+vOWKIG} zhpvGvb*AhYN}o4m@H1o!d4o*tRBGZMkUCTWmkL{wB~SUlAntIEgw4Gc(!&*+NcHqe zdbonr;tjwaz@#r!B?pk5-j_#K1)p#z)*b-3QShBfQxGf+4==MNa*z{HXhG0C1P_4~ zh;-k(7eP#tUz1`!Wij$Dh)MD;xve&Fv5GXEp_kweUysY@i1cm8S?~wm($ky-rf?^L z4cuB_3%3%uz>Nj2a3et6#z@uGqTe`wK1>2-pyo{<@B~f=x)vOqS_S8F z{BbGcPm`Srko*>0TM51dS0?bbgq{a9*ucpHu=A!M^DM~~^Y@aViMI>L4{MrZFUa%^ Q4*&oF07*qoM6N<$f+pdR_W%F@ diff --git a/actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_pressed_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__spinner_ab_pressed_holo_light.9.png deleted file mode 100644 index 6de0ba8841d25f20f12e14002ecc4c9ec6a7b2f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 370 zcmV-&0ge8NP)Kmp@CxKpa3{epU;uAYD{w zoy1-2XXsG+d5c4J(@pInLg`pK=_I6J(k2d`5V?BE{Yj@j2pl)OcgK;0qd#7akgCKEJ@PeExDlrpx^Tf8?8gJ#K-Da<_nm z+&*9_w+lGPs|OtA)dC)JfQDKAb-?t#>nbk~ygr<>n4NOeOiNA8R)UE3F)|0PZr-`P z{wS3Lh~%_Rw1t=h$DO2-+|>0Ilo0LghZEP}j*Edw;7F{TKbM3p1iOHI0}cLp61dt? QIsgCw07*qoM6N<$f;wQ9<^TWy diff --git a/actionbarsherlock/res/drawable-mdpi/abs__tab_selected_focused_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__tab_selected_focused_holo.9.png deleted file mode 100644 index c9972e74bb4fc7416960e238afd47b1ac363e316..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b~!3HEJ|NhSh5-4`^4B-HR8jh3>AfL0qBeIx* zfx8og8O=|gUJDd7^K@|x;h4Gh+(zC520Y9MizoD2>~^~(JZa^V pUoEkkaeSh9w)TUlKa6vZ+qJ0**((%Vy8umK@O1TaS?83{1OR&wE2RJc diff --git a/actionbarsherlock/res/drawable-mdpi/abs__tab_selected_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__tab_selected_holo.9.png deleted file mode 100644 index 587337caf74f9ba3d32ba1c7cc8fb8b0b5ba245b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b~!3HEJ|NhSh5-4`^4B-HR8jh3>AfL0qBeIx* zfx8og8O=|gUJDeo^mK6y;h4Gh+(zC53JlB#xw8$}k`45e4cLk;e3y7!_%!uv(Z^d6 t0#9x~Qa^f(Id{#0H&;LIP<)f9-+fKc+F|3Yl|VxnJYD@<);T3K0RZ_tFJ}M% diff --git a/actionbarsherlock/res/drawable-mdpi/abs__tab_selected_pressed_holo.9.png b/actionbarsherlock/res/drawable-mdpi/abs__tab_selected_pressed_holo.9.png deleted file mode 100644 index 155c4fc753ed43185b31df3bea2af1ea5b3e7482..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b~!3HEJ|NhSh5-4`^4B-HR8jh3>AfL0qBeIx* zfx8og8O=|gUJDeo@N{tu;h33haPQZY#>U2n_RP$O>mRT6my}r88lS< uMnfl1c4A|rBX^f%!~&s(1*$LFm>5oL2|PB@cz*+E5QC?ypUXO@geCw>u`ROz diff --git a/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_default_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_default_holo_dark.9.png deleted file mode 100644 index 081657ee7b828a74287d65d2f4644af9c7b55816..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQih%`jv*44lYjjGZ_jMS*7QH1 z$Cu9~IqOiSz?8?{Eo||(vKg$oJDqvb4v1Q5NJR27d@z6V;avVV1E6LGPgg&ebxsLQ E0ED?8Qvd(} diff --git a/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_default_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_default_holo_light.9.png deleted file mode 100644 index 3f312b465189caa47a7f8e4bc53c3222521e0bb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQrey_jv*44lYjjGZ_jMS*7QH1 y$CppZQKez^S5>Et`mrVp3OWu(*tYT>W@HfhtG!C@Uj!>q8-u5-pUXO@geCyVL>!s` diff --git a/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_right_default_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_right_default_holo_dark.9.png deleted file mode 100644 index b086fae8738227fc0b4f05171ded25ec1503e49d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQU;zbjv*44lYjjGZ_jMS*7QH1 z$Cu9~IqOiSz{ak|8`Hl@9XRLoNT6Brf-|eO+cr*y`8p4HWnZ4T3DnEr>FVdQ&MBb@ E0JhyB4*&oF diff --git a/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_right_default_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_right_default_holo_light.9.png deleted file mode 100644 index 73c336a77a9c908532b5b39098c22a878e0e87bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQktGFjv*44lYjjGZ_jMS*7QH1 w$CppZQANR3w^={dWI;j4L5+C_+aEG8Z2O~g(C$e@C{PoFr>mdKI;Vst0EP1$iU0rr diff --git a/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_right_selected_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_right_selected_holo_dark.9.png deleted file mode 100644 index 726e0ff427cd175c9c3607e25352bd696a3152c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQbwLGjv*44lYjjGZ_jMS*7QH1 z$CppT@G}o{phONwVb}j=LshAN!kv;Qt~79nzL7Xt$zT{YC1>l7eH(zf89ZJ6T-G@y GGywpjU?4sK diff --git a/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_right_selected_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_right_selected_holo_light.9.png deleted file mode 100644 index 726e0ff427cd175c9c3607e25352bd696a3152c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQbwLGjv*44lYjjGZ_jMS*7QH1 z$CppT@G}o{phONwVb}j=LshAN!kv;Qt~79nzL7Xt$zT{YC1>l7eH(zf89ZJ6T-G@y GGywpjU?4sK diff --git a/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_selected_holo_dark.9.png b/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_selected_holo_dark.9.png deleted file mode 100644 index 1767c169eef03f3370b0f8e40f531dd481a9b82d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQYM}*jv*44lYjjGZ_jMS*7QH1 z$CppT@G}o{phONw%V+tnLd~`l!OqNzXB@V%srV-z^vGhE?K{(iZ(fQrP(OpGtDnm{ Hr-UW|vZo$& diff --git a/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_selected_holo_light.9.png b/actionbarsherlock/res/drawable-mdpi/abs__textfield_search_selected_holo_light.9.png deleted file mode 100644 index 1767c169eef03f3370b0f8e40f531dd481a9b82d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQYM}*jv*44lYjjGZ_jMS*7QH1 z$CppT@G}o{phONw%V+tnLd~`l!OqNzXB@V%srV-z^vGhE?K{(iZ(fQrP(OpGtDnm{ Hr-UW|vZo$& diff --git a/actionbarsherlock/res/drawable-v11/abs__progress_medium_holo.xml b/actionbarsherlock/res/drawable-v11/abs__progress_medium_holo.xml deleted file mode 100644 index 6bcbdb83..00000000 --- a/actionbarsherlock/res/drawable-v11/abs__progress_medium_holo.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_bottom_solid_dark_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_bottom_solid_dark_holo.9.png deleted file mode 100644 index 575334699663b221b5a2b3251572a7c7a23ddb4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nET98VX=kc@k8Z|>$jV8FrZ@U7ta z-*T0WQ@><>I%v71J%hiqt0P@2{q!E)%~9Ermd_VC*s;IdoBnhS>rHk6>|lcSgpVF9 tjEp}SQ%vGx1w)$%c)I$ztaD0e0sua~Gttc^?peW`&R>iA3bc>G)78&qol`;+04`QPF8}}l diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_bottom_solid_light_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_bottom_solid_light_holo.9.png deleted file mode 100644 index 8155fe840532e1d0fc25450729892ea73c4e007a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETTu&Frkc@k8Z|>$jV8FrZ@J;?q zbcL8uwC8*^`8m#29p5Ib=%`p$wC&7oqt#odO)b{rdQv>$UUk^Hs0pFVdQ&MBb@0G6aYR{#J2 diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_bottom_transparent_light_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_bottom_transparent_light_holo.9.png deleted file mode 100644 index fa4d76af93de31de153c6a7d41c05496bb14d2c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETcuyC{kc@k8Z*AmdP~c#3C@cDZ z^MXtGfey<_%m2nWx~HUtq@RtOD!V+x#J|ag^QD{sZZM%<(R`m!o+Hzd-iC%RO>bP0l+XkKAqp+G diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_share_pack_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_share_pack_holo_dark.9.png deleted file mode 100644 index 9a70a5d1e3ad43f632287aff78d86289259099db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2878 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 Xx&sG-cNbs*00000NkvXXu0mjfHD**$ diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_solid_dark_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_solid_dark_holo.9.png deleted file mode 100644 index 6622cbad34409b2e09f69e305455482ee107baa6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETEKe85kc@k8FK-lVFc4sN{QB_B z&fog}EEk$2&*T)$|Ch61%h`96?xa8O-xitu^~t0=vn)PNZ(|U lO#br3!H&B!tiEU`L+e4N?emv^?*rP(;OXk;vd$@?2>`X4Gjad` diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_solid_light_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_solid_light_holo.9.png deleted file mode 100644 index c4272978338a232aa445ed5190abab61afcedb16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETEKe85kc@k8FK^^+Fc4rl_yt@$W?82D^ReIqPjo#d{bLmpkiN+x lnf&F6gB^EeSbfn>hW*nwPPt#_849$O!PC{xWt~$(697sdG9dr} diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_solid_shadow_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_solid_shadow_holo.9.png deleted file mode 100644 index d0df29d8b3fef9f71cda9b7a0975c68dcfb05685..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 290 zcmV+-0p0$IP)(^RAa&-b-qmfdL= zKY^DZ_=R_1v^+>Y{!mW=MF!v|2#Q>Q>z_&4i6T94j-Y4q`P>I~g?cE`S~^QhBCU5$ z-8a`dJ38hrt)qwm8XJx0+%VAuW=z7Jg@`1pBAUrf#Ef=wZl|UqH7RO)u1OwK(@xK~ zuV&5*5lN0GQV~igR!o15*n1TfDTP6ilQ72>QBJOyK^2jQYHlAzlrUMuFCtAA$s$=K oi)4{qME3aCu~lSF#Q4a(0o}otDK%H_Q2+n{07*qoM6N<$f*T@rc>n+a diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_stacked_solid_dark_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_stacked_solid_dark_holo.9.png deleted file mode 100644 index a0d9c1b957ea4a6ce62abd120668610d0cb2bd96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETEKe85kc@k8FK^^+Fc4rlxca~( z?t=fRa*SINS}wBuewp3mefy2x$=b4i8MC*B`RkorJG1!P69>HDUX#kpcm>9d6MZKb ky7}`x**qcrtNL{AY0h>p*ZiBQ0JN3C)78&qol`;+0O3wK)&Kwi diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_stacked_solid_light_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_stacked_solid_light_holo.9.png deleted file mode 100644 index d36f99fecf223779432fb843b823c04d739f05cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETEKe85kc@k8FK-lVFc4sN{Ca;{ zvU;8e%Y`P%GdTtG|K%*$a`xS%JL%8+w?$@ueKP6JEX#C%J{El7iLS?_f2=|R(l=Qo klfOK1u;Z=_t1sHgP`H~Vw5GX>6KE@gr>mdKI;Vst03NU~l>h($ diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_stacked_transparent_dark_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_stacked_transparent_dark_holo.9.png deleted file mode 100644 index 5ad475dc3f478734be31bc5763ff494e5f120914..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETR8JSjkc@k8Z!P3yFyvu&IDfHo z*MFzV3!h#&I<8{wJG6*7%`^0A*`zgvpO3}4Jy+2bzzZhGPxw0F1DlG16;n~mnRAu= eo1*Vq{$#i=98+;OAz%&ALIzJ)KbLh*2~7aXVK40f diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_stacked_transparent_light_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_stacked_transparent_light_holo.9.png deleted file mode 100644 index 6ade5eeb37d8388813cee512f8adaad0f6c15397..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETcuyC{kc@k8FE8XhU?9M9Fk3-& z>Hkf73eN%?4n{M7dy#!$d2ZSCCv)eTUt5@6!ODmi{A7$QW>Hb7V|gN6#Q)yLqkTHN Y-hRf#&+ODnfL1Yhy85}Sb4q9e0PNo==Kufz diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_transparent_dark_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_transparent_dark_holo.9.png deleted file mode 100644 index 719b9234df6fefc32c628a212141681df3414d85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETB2O2`kc@k8Z(Za)puoZEAojv! z?q20mzFS+?F-&~oGw)ovvN+_p>pJvXn6S<7W@Fox#)9&t;ucLK6T;ku_WZ diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ab_transparent_light_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__ab_transparent_light_holo.9.png deleted file mode 100644 index 6da264db26b5debc433e570e454f7ad596d3609c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETbWaz@kc@k8Z*Aml2;gwNxP9_w z>q*543$-17oYd6QwPclDxvFIP6Y06uZ3-`2R5T~}Ha6e^YubHkRDB$o9=Xj@xc>Lb i$;LIUf5PjFDj6>?G+3v-_OK(+N(N6?KbLh*2~7a3Fg*4E diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_default_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_default_holo_dark.9.png deleted file mode 100644 index 7ef2db75e273c3a4fa34a867d43714d47b67dfd9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#v+DHBf@#}JFt$r%|L2@FmD6{OlE zCs-P=E^ay;FECBu-~a#X*$!!Fy;QT1l2!H>nDyu1;UEQuS2t(=%(&d{0o2dn>FVdQ I&MBb@0Ph$gIRF3v diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_default_holo_light.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_default_holo_light.9.png deleted file mode 100644 index 2283b4c01f31c24c241101989a028a28e662ff2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#v+DPvC;#}JFt$r%|L2@FmD6{OlE zCs-P=E^ay;FECA@!GWvmzw+t@{SPuqdTbmsKKbP0l+XkKVJ9JJ diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_focused_holo_light.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_focused_holo_light.9.png deleted file mode 100644 index 3c909b51306d684dc9fc4deb674ab1e1feb7004e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#xSIG!$!Ar_~TGcqy~7@GboNVOeo z`FL&lz5>PtO@Rj=>T@VLG&w|ZbqQ*{RI`whRrVK{_2=K=E+vL!&S{*=@1z8QW-xfV L`njxgN@xNAaNr>U diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_dark.9.png deleted file mode 100644 index 131d1030c9d5b447ef62fc8e336d9d3950ff7519..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#v+DJxGG#}JFt$r%|L2@FmD6{Ok@ zwtT#{-1s4r1MA|Z!|?(x4J`lv|6k8`NJHzTnuV0CvcJHrKmQJQDKT8Re5&^Sxg#LM O7(8A5T-G@yGywoD=q9NE diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_light.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_light.9.png deleted file mode 100644 index 3e7dcdfdbaf66d51a90633e6f601bfe71b0c5069..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqR!3HEvyN#xSIG!$!Ar_~TGcqy~7@GboNVOeo z`FL%)@k1sD*2PVS;{{wASQ@v8h$x3#@+~m2a+{}M^7C)Is4GMKie-X3Pa7xz&0z3! L^>bP0l+XkKapWP} diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__cab_background_bottom_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__cab_background_bottom_holo_dark.9.png deleted file mode 100644 index 0bd09806f5c85ad3a33ec80c2a526e9dba34d1f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nETTu&Frkc@k8uN>rTFyLXm;P>R{ z?#-o|?nQl9Ua&YVWQl+9{Kh9CkJo#*NAA>4+xPwD`<&mEu1}vZI664|W68WNxRjX* q7uY2C$wZnF2qKv(-xu6mlE@I5@4DcHNa}B(#SEUVelF{r5}E+w(lnv~ diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__cab_background_bottom_holo_light.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__cab_background_bottom_holo_light.9.png deleted file mode 100644 index 43ed26d4784aa508b93551bdb0359b959bd2c91b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nET3{Mxwkc@k8uUzCjV8Fq8;LR1* z*j37dP53cYgnN@8iE~W|ez(m3TTj;06C0 vR9@;$usQD^o~Q2-Eg&#Ke!|DE+S9qyz8u@<_Da1C=l}*!S3j3^P6YLYC-!V(AVEFG+v!>way|q9)89ZJ6T-G@yGywpFG&bP? diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__dialog_full_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__dialog_full_holo_dark.9.png deleted file mode 100644 index f4970ad1c3278235157ac72f71fc98f159fdc439..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2159 zcmV-#2$1)QP)7pj*K04R=GS>IExgb+dqA%qY@2qDDdSi?}MdX75WMJ|ri_~yampZf~b zyDwJPzURp0aERFLx!K0Z6`{S(+b^7Rq0fZm(kDLm@P!|`&m~8kF)y`OQ+*6SLgj(n*c6WFZ`T<6tC6A%w8 z+L+Kg_>sWYRhaz=AtQLA^@LuUvKr4zS(=h&ATdHMd1uOv+V9M9YYe+zz%fKlM3B!~ zyq*EP{ZyC9dltDoQc<8ZrM^eE_Hte#g^dKR2>{;+o?xX#_XJ<6fcSW3 z(2+n3e1qrFpfvl1x~?#Fy4|E$M6lRgKuT?d8dD>b&VB465lv_ms575+OWy%#u@k+N zI%?Q+K~hGrT_7#|a=gF%@ZrOc@87@w`1bAFU(2$bW3Gd+|4`xmgT=9~$+>Rd`_AEe z?tAPdzh~^4zVA1WkB@)c-QE59<;$19v5OvFA}vv41E1cCHa5&@4N;9-`R?7jpWeKA z^Yg>QL%m+FvDt*4cRX_bt0?zBkB(K>DX%%#=N+5R(_-8y- zVb>j!?$Wbc5y%%}IfCs9*+@_USOKV3tJQDczI|KW-rgqvI6{s^UDwxjUH<~$ckEhw z$wzfwA%@V6dv=Zxn=8;sa(#b)ziOIh-@k{Dz1VCvD9chBW?(0HZ$3-*gQG?|lNRhy zsce!AuP~V46@dEg?(QVrAwo2L-=l3?V9=qSyONQk&Kv_~&Lf1nMm8E$0BV|mEX9~d zNP}Lf5}1xu21h4T$+9&-HQuut%PRmY8i6duXoOerBY}OxLGlJ5BU$zc%^yh8OvsW{ z7(^}+!OmYLNsSuWi7|-^5)oDyq5>gHA{u-eOKk`#f#=$OmM4_(@m{kC%_W5DAmmhR z=d>`52C;YCwuB;r{%j}Ebe_P7K+b^`h8A8*tydWpwYtuV2y(IKDEl%UBLZ0(i3V1m zfUn~Tp;05RlF3Ax+6Y;a8pF(Tjoo`iqE#Ca+!sAl5kbmO&cKL3&H*nkK%{gluy`-t zg(lV{G7z#PI)C*NX293=me{C~cPz9KvLxQ9W=NZ^Ugspsp|?>vp+=TQM}wGdXLXG{ zVi`Ci0$G}v=(F^hV}w+)Oe2t`iJ2g)`#yKX$5zN3ft&-L4rl3d-=WWF22RL{IarUJ z10V#?jlh->hk8-+(B={{f_KC0$_Y6UbF}H| z)iXk95=}<}9Szz&zBnPrq{TEU=*R&0y55rN8c7*TmhI~1gq#|$ON79_OO5CMyD7gV z9}@irgLxzpwBV#1S)NvH5*4HjnIZdKqfiE}-PZx=`o6zC@DCwmFGlT6G>P~~(uABG zK}Q3f7d(yIx@nqEUDtg*;O`-1HeJ_!ZJOp2fHih{)cJyq3PN^{5b9^?iHmLcxw*Od zt7)3gecv~S{b_{c(f57RG|lImo14Ed?FxBAs6Zqt*x!B;W5{pK*JF7#9(y&G-;L+K zAIl#wtZ4Xp+<&dElXaOZRbPeOuW5VVgIpFOP7$z(T3Yv~vHW)|AI5VJTZ64^6BEBSg#y zGM}I)%~}j17KiFDEnOcuUt#E@>0HCEcF3*~0j6Ce`xZm1O5Ih`IeuTN+ty1RWW4eh`~TOU@&BM)3MkQgMM@bdYm8B8c#1 z#@ViWE78D40!D<(#Tx`hXJ-KSDrqoae31hLi8 z$z>DjeP}^jBk1AK*j$2rhW(rzJ{2JYJMmiAitr^tE-^SXloO=ZTOgN*_a2ZHvyBd7 z1l@JghOv{s(P7lwc?A9CfSo}^z#H{B))n$biD&`>gkS9e;$0Z5~J8tXRDNuF002ovPDHLkV1mNB_TK;i diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__dialog_full_holo_light.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__dialog_full_holo_light.9.png deleted file mode 100644 index 172fc3b5e3caf3357e706be2a1f0d91f357c8e5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2302 zcmV2ok^m97efLZMJ76bgmHN3TVPgynL1iZF^o zv0AMLkI|bD5@Z+S7;_RWD$X2Q#-Gi>; z=tN2`078B~PH0>efZ`B@1i||(&~g>qMGRTwTrQXXbnj39hPAQB*)bIg_=HbA_WGzO zR;yL=j9HSDjSEl*;KYv!A@o|O_=;IUA}l9+ObGitX|Dzg#M7mV*iktr2nZlVbl%^^ zH53Ym36TIhGR!|u7{3PC~!L=Y2z z32ZT8B;zY)i(nCqF!62X25hwu6@!!-aVKznAwf{$S4ay%(<6lhDJ|l}=KVE%xD;tO zjxokGV%Vil6ww-?fi&aiwtz1TI;KLw!36;9iSC?$w}w5ZTIo^H5hBZ^Apum+pFjWp*|TRqUSD7TX^iIhX;RaeQQ zE(9uq^MWzvYwRam(2Co38gn;jAmP?U& z&MGvUhjxmcRMYbSg3kR zZt4g}LPgLEq&hYm(J$si0u;4;IwvxY6?fp6l#|X8fH;pmq-q5ISi1H|(Ge;Lg>w@fkyi)P5d7;2~0$MDQ@!DE$`cg61AQt41xJiqTo9Dlsio7bTA}sD9BZvH#!%wZ zmJ%ND@1^DnZ%X(Ld?$$A6k0J~NE59ixD&!XX{j@~=b>7mwKZvxCyp*B)cAo?C*Y0% z?1kZeY?X^e-9W)XxdpU^5OahW`IAUpYa}@W?W5#&t4q8l2swcYLBS!VH7P;dBP@_? zQAk2?GdMjs_n0oBI`TV#(4X2ifxe2hDg*@upKxQ&K(mtAk|`HJPz)_1HaAZ&&GHf7 zsz6IO?f{EsSe^=LZJ-DtRGZRNi3)(P24xANDG)6Gj(#dNGOP_9D0K*+?F8HR`Nj#&1(CYoj<+oYNw{1t4Y0L^ri-RBp`1VD6hPVuR0IkNiMUb`EeV02O|F6c zauGd$;Lv5&C{!~b&}Udb7lOKhLPE$D=wt2>b>Q`^nt&r(EH@_=La)06a5Fwnfw+Sp z&{C)%=8X_pC077s0o1}imRwSiS1dcYq8ac~BtElCsZ+`Ul=zAmLOFfPAwvBY@Kn$$ zk{zOiq+$R>LAX{rQ>;#)$VHAb@IJ99w*HlMq6mNtA~I*7`@~Y7+@e^8prDZQ`Pk}@ zSYXq1DD{)3Sw!SFBRAo~AvKngUU3Lg#cu0$<^+@bU0;P_H1st~XDv}F6a(QX9$Rbi YKbh+rFQXz7g8%>k07*qoM6N<$g2q=E^8f$< diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ic_ab_back_holo_dark.png b/actionbarsherlock/res/drawable-xhdpi/abs__ic_ab_back_holo_dark.png deleted file mode 100644 index 8ded62fb7b6a27a86f7b532c9a2b5a4ae999d34c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 741 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~JOTTd6q5Rc^#N8xy%NgI}`eR{7o3SVw~oLF?DlhO#(rS&-V`^Q!s%)gPgzJD$(6 zlPX(2b^RHIj&o60rR$>g!|G>TRxtl*e|^4a{T&6ax|r;1#_KA};b_owfAXfrk8RFR$o&QDy{Vn>#x#sulW#~7Jq)- z)TH!~FS$Xsf0AE4joN$h`JQ|K8Rwjx@86b-rgDVb@NxHUL6S>yvXNP=t#&QB{TPb^Ah ka7@WhN>%X8O-xS>N=;0uEIgTN160J|>FVdQ&MBb@0GkggF#rGn diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ic_ab_back_holo_light.png b/actionbarsherlock/res/drawable-xhdpi/abs__ic_ab_back_holo_light.png deleted file mode 100644 index 517e9f72d0c8d28a22360ad5d73476c25fd4db33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 661 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UOiAAEE)4(M`_JqL@;D1TB8!2v z2N=7Z%(epwmK8Xr18D^?ZvQoBE&~JOTu&Fr5Rcj%_$5Ae=jmr`i z3DvOQxBn=~BCIDR#iS^(^w0Zu6&JUPm!vIx7~`u}yzledo5s8M7#uS86ZssvI8sdD z&xg3?2M7HpA7}46mr}+fqP5gidGgVwQ1_}WN$aob&9(OVStj}6Xj_!ShugM~J~IZM zU$@KD($sJ1b4JGMs?Xp43SH*aH+p$-+40a@k*+<>G~DD-|-{tS&vG^x*%GGq=j0Y+3zJN#Vil?OA~@ zukBM`R53;FYi;h*X6Nv`Uq9z3iuI~5j`7&H`BAcUqjcZh^7x-d8^2$_pe40Fq;EPa z%hqE7x*0h;3a++#0KFc4?e_Zv*^k$mEo1DpzWsL9`(v*67M^+IpR-MVa>nHwC6*2c zw&pTkoOQ_aoMO7bofkh1@}JI}ZKA~9;BBq7`S!))DS4@K0yY}FSDK>kZ?)HK*JGG& z7n!~MQ}4z!!HZux9M^8s)pB{g?A$cwGrvCg`RlIwI(LVEXW4OK`|IMz?e(5Emfz@% z$^^!kYKdz^NlIc#s#S7PDv)9@GB7mMH89sTFbpv?wlXxZGBO2ntqcr|?>AgV(U6;; zl9^VCTZ2=RMLtl2B*=!~{Irtt#G+IN$CUh}R0Yr6#Prml)Wnp^!jq{sKt&9mu6{1- HoD!MOjfK$EgnR$;T z=N`Kp(hSrM@CU%evd=bf=-4w^bQmnuhmUH-jd<6WZ; zHl4_>Rk2U@t}L_t|AiwlQ891B3C|YS1B^O3M@oxo5*z)LB91b?+QOQX_r0yH)YX2= zvK_aW4}ZVF|MIp0)1X?{@CS{e_APBtKk;H~nV$PVB{N8HV+L1tOj6 z``KDz%d4l`HAyHPxAByb%b6xG^S8m<-YfXS7v>b+zlZNGcwheZcvv-P0dQ7=MviH9v^t)=yc559VF`j43j z_pMt2oAX|`goy_Fm~UMa9d%t_^^2qU)cXl;U0e%IRZSM> z>7Ksk_VioOmKv*1mN|c~ELg&~mMikt+LpAdYoES)QG3#uo404uV`0ytJ&!XS^rKz< zU6j9{ob*(;{k73gyQmwdmG2d+82l2_J(5-Z=Epp_^THpe+eb5HIvzUo?fW(va5{7P zd0GD0trC|9zjsRjleub%YeY#(Vo9o1a#1RfVlXl=G}JY)&^0g*F*LI>FtRc>2C}UT z3_|{Y+l-q7HAsSN2+mI{DNig)WpGT%PfAtr%uP&B Z4N6T+sVqF1Y6Dcn;OXk;vd$@?2>?&0tquSH diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ic_cab_done_holo_light.png b/actionbarsherlock/res/drawable-xhdpi/abs__ic_cab_done_holo_light.png deleted file mode 100644 index bb19810bc2062509e4e4968099a359ad73818728..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 915 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I0wfs{c7_5;rX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfwTh{zxw0jNgl<&3j(^ zeD(x}!be9sh1LD$__>xwFX-mty1-MRJ?GVgBPRYo&#phmts!D?ltV3&FI%+a$=z1Z zV;YHl1iMSDgJ+|>#46F---v^ z=n46F|IdfFb=)S0I4Coo@!g}n4Nex)S*)#RZPN@k9D49tzo1o|L;8h-cSg(aGrNAg7qQ^lmAJNnY2BwD zmg$yB$_Kc(9`bFT@$ln4rdg7D8~IZ-f3I60`0mq%qw5167@Xn!BqR{_Lfuy~aYE2x zQ4_Q6{SU<2c z;lT8&TH+c}l9E`GYL#4+3Zxi}3=9o*4J>pG%tH*#tPG5-jE#Y8D+7a&|KB#FXvob^ z$xN$6(O_z2Y7RsY4Yp<(!9Wd?ARB`7(@M${i&7aJQ}UBi6+Ckj(^G>|6H_V+Po~-c P6)||a`njxgN@xNAiwS~- diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ic_clear_disabled.png b/actionbarsherlock/res/drawable-xhdpi/abs__ic_clear_disabled.png deleted file mode 100644 index e35c5f05efdaecd358f87fbaae543f8e5d5d0331..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2531 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 WVgEmns=9(>1^{ytE8}V-6#hTCp0D=+ diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ic_clear_search_api_disabled_holo_light.png b/actionbarsherlock/res/drawable-xhdpi/abs__ic_clear_search_api_disabled_holo_light.png deleted file mode 100644 index 7fd7aeb2a63980f5c7459b96ae175b875f27add3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1315 zcmeAS@N?(olHy`uVBq!ia0vp^+91rq0wlddc6tLTrX+877l!}s{b%+Ad7K3vk;OpT z1B~5HX4`=T%L*LRfizez1K-K5QyCaov^`xMLp+YZo#ve{ohs5cKmXZmZ>G$w-JO@O z_$Dncy|l#DX=;KaYmSzf&V&g+I5)gx(wb5qs1h)7!mfsR25uDCBNMaEYi!b%Lx%#0Z>6%}_Ke;bM=$-hufo^&&725YD$vGBuUKV?<1 zW5r*8XXtLO5$#WZeo|;mb85TEyq_Keb3$U;>HYFK{YX}hy1N)ld|`iZ8c+f zaW}0jS<%V*aZgCBwd%4 z`mTTDHix9d^392b?Js?F`)aOklAwYhQ$?F@yb$ytH>J_Jb{Z~vrG;$w0s zy7gpFZTnjBVEMK z?u*UK{&)=cU7rs=ddas!yNA5%MN;fAeO3GpiZ3y(^OR`LtKE&RYG` z%T6M0Q((r64h>88-;=&fKXORn&)Y9<7j0ADM4op#Evb9DEVE3OxuAOMwTp8T79Bpj z^46Bw7ia(6t$e=h^6Gq+^)tU-Y>!_fu&_#YcJ0QCjvJ3m`|4emd(8LrvxuLIduy^w zKRn;Ob&-9_RrP6hYo5j|+EK9n+eN__H(s3nbj~C7+}RUuX{m{weGosZ*S#`Yezasg(E; z?-{fhY+_DS&eu;5`_fikR9#fupz-tEU2!F+6F=1F&8oh6DP7e>i}j<0lm5=$VtqvCS7PaJ&waLQ0xVeA<2r9FV_>h2sIGsVSbJsf1ID=TJ5=|I z&X8~@c`+{`NhyHi(Rj}}j=t-itc?USbMMp?m=EB?(?e-29Zxv`X9>CKeyCDB6UQN6rr@v)_sLiS3~Qp ztEzq2)O|!<>xiRNElR1gi&m6P`)xn$hne5Zy#N2rd-GvpEU{+CMPx+)0Kjn+5^l}o zg&!d#$jfNkdNdFGu4pqj;P63GZxgQ*_CY#Oc|`sUQ?}=CKZgE3#v~qpdI6&Bx^w_Q zunGk?wncWWW;l7-UI#@tQM0)~HL81;)HPu;pVQ0pgJQPrfpMpp=aU0}M<~a{2nw%n zU`-fLR8Od%K$J#9U{=UTI40i8@}fD@+Oa6N|E1RI6sbQ)pL!RfOePt0E*?-w>vc`F zFLoR~H8O{D0Fhbf&d=`-+1DWWi~EgA3{w%CBurf@x&z#)AS%CTjBJ;NXfEz(-q*!r&D zRZs9Vt%N#~h`fZ2dF&WAUxzdNEE zLcQ7z)<&U)d{TxG*7ZfZU%dui_e8AOG#Zu1*(e!@&OEmtgjVAmsh>Px!}hna+U*4u z-(P@*kBOd~_&ckM8!+$m47a*D-IZ(wJ}aDF{e;O>YW!u636JA2%GNI#9Kc(nk+Ttf zZ5oR_VO!WXDMZ#m`6;XjkCv`_D6eahzuUOoqFaafSiYTac<;TmC>LuaHD30rCoEXh zD5R1Oih#JsO2+Mq%9NFu7{5RCprvtcFS~~}?Jc*n#%9=R+B~=%4@*03!EPJP0MrnJ8N%7FfRW&1jKLlO`E6 z2Nzeo&ri0;XG#nsf-QzGDH@1K!SO+oQz;nwgfHIg%HhTbyKTOO$NB{~co(lFCB3>E zA&~-M`}RVuy48f;Y-C?8l|c;|{QHGA&~=s7pAt2h>u zaS=yuntEie>)yAC_-npL!3zTFzOgLKZ}$=3sW+~_Ul7!!J>-L1jXDCh?L;zNtpzrIp_ZRL}JEMXYA5@jiafE19#aIkmj zpOVnI=5TB*VZwzSHn(G2*x&nZOKW`I9?Av!cNOvbi#$Fwg7v#&)Ar=Xmc9st_ZL_3 z{@58B!k$KOp%D%6encJsnot-_4XUH2sc#F@HGpawXltoKc?EQiVmJC91DQf_cccHm zAysqDoo4|5*kD6(qXoG55dp>oiYrkGMRp+(t%)uKx-Xk($P)oj2rRtP1Q-4<4m6z) diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ic_go.png b/actionbarsherlock/res/drawable-xhdpi/abs__ic_go.png deleted file mode 100644 index 1e2dcfa02057f16f9f89e31fada93991c4eb9ab6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1983 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 diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png b/actionbarsherlock/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png deleted file mode 100644 index a92fb1d4af622cfad770d7c494121719a7896e61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=d7dtgAr-gYUQ-leFyLX@@b&p` z%gbN)&SLHDYV<0q^J4_6fq?|&@*V6j4#NRakTDF}Z~@#RP$drMna{J{ZM0wU(H|t@ M>FVdQ&MBb@0L8N*<^TWy diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_light.png b/actionbarsherlock/res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_light.png deleted file mode 100644 index 930ca8d95e8bee5a1240fba645d9dab919abd734..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=^`0({Ar-gYUf;;epuoZ6aJO@& z%&D0-IKvGL&8p&qV;O7KuliPO1yl(K>(rHwor_8Hg9|Y9Gj8!^hz0Vk4~QZ}ABcvv nF)(akj$uTI?LshtEWgbR4Rf6*RPme*0Ev6L`njxgN@xNAEX^ml diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ic_menu_share_holo_dark.png b/actionbarsherlock/res/drawable-xhdpi/abs__ic_menu_share_holo_dark.png deleted file mode 100644 index 45a0f1da0d01b7c0ba53830285c67d629bd0774a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 699 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEU~2MoaSW-r^>)^McjrWjeSoS8SCOEBs|%|?VJ7D=T9Yz_dLJ8 zJ9zK=&-=vhubx}{vF6<8-!m`2Et8%6G=f2_fi-~)r;kY>>MAgRkm@i7CT&PKJ^T(I*&Av>d6O5U0r~;hkX|;LrY6t%e!5sze0;lgN zzhmA1v9d1mdTWRDgJXqP4j5dhQr@DSSRpJN-*(9Bjp4$N@%tt%vt{r<#9TCmVT&q5 zPY_dpf5x8W&TrHi1EzgwuzL61gP~v}`*h7_ev9YX^%66WzmeOz)Rwd1sPzfWyZX+; ziqW^(w(Z~haJj|{8OsISSA~|G@%CQ8Y_d#7=yl$KAFm&t%#H|W$kcQ2;yBguIO76W zkG?He)AQ@KipLqRU6Nb%FPk$;xS@jW=|$x{C80dl?QT)`*~FQi^@N=fie6YGbN2D| z=`W4NG-chmgqp9bsxquQQuyVroI59@gwb7QnV5NMi~&p85J-Uv+l!N+#T%5W;<7yr4}f9Ow$JGA?da_{7}kE@t}@ET5LG{B2CIDTQC8`Twj U_qmZcFi|piy85}Sb4q9e0Mf@O?f?J) diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ic_menu_share_holo_light.png b/actionbarsherlock/res/drawable-xhdpi/abs__ic_menu_share_holo_light.png deleted file mode 100644 index 528e554abe239137182dd9069d1fa4ba02a109a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 935 zcmV;Y16cftP)=+L@6RIMT%_@p^A^X5UDRjLANf13Pq%);A`Pd+=!;23pXx; zAif`nPef)@LW&ftmV!!=U?`shr5Kn0)zPywg_Q~)Xf6@UsrA5Be7{a=6EByPs``206cpncnr4<@!q@mA~gUzaA3%HTX+%kDFHYT5Qf!vm`Me|1djAs_x*GR z&!z%kGhWI$<|3X<1;9qUl5@-=4yFR&S{y_@$C%@oE<1op+>aXzjC~!)$_ii$_F+%K z@y9V;#ya3q+!Mu4ce-D|$M^yJarJ;X=I|E&DieT9a7UE58@rw_;mfG%mg3n4+>X7G zDINV8W$>{wd4UPs8tHyn<_K%Vx4t-F{HB0#CbHyT8aIH=*w&T4zhI%?@Yvw4$UHw9 zfiH|AwZ;Wt3m(R<9MXfe~y?7+&yyx)=z7N}~%m5B!YmPaWaH#7@Q+5E; zIqP##(=Vn1;7AlEd2}e2K@tF-TcIq?su`V~Rw@AYX?JP!=ya5wR`qE`V>4fQR+^F$GWKC7sT4IxUFgD9>&BxJs0#D$E0dq8B&$(De03B_O{zBGgT!>|}k{a55 z!O~xj?u?9>EHL(EoJ!?lWDg$AX}pf&%~Sx?@v3~6qvvqAx*Saezy`dwo-+WR!8JMF zpTip|0k{c|kLwhu)oQ!f;y+34?@=W6(zkfKXdO_i)poDN4CtH&58$o=8{em4rdmY+ zbb?>20J>f0o#8w;#fEn(4AdV*y+C*HYaPJI-C#EObp@bT@IwJeLH&YX7XStYpFDt- zf=?R2Fu^AaVA$Z31du2AoO(cqH+@Lz(5e*i5O+3-*HCUO7(002ov JPDHLkV1h8vxv&5L diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ic_search.png b/actionbarsherlock/res/drawable-xhdpi/abs__ic_search.png deleted file mode 100644 index 998f91be9c4dff50a3ac354a3810a2afe39fe32b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3784 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 Z$DPpsU&xgE;c;3340Mc9_1aGO{{Rgi%2xmY diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__ic_search_api_holo_light.png b/actionbarsherlock/res/drawable-xhdpi/abs__ic_search_api_holo_light.png deleted file mode 100644 index a4cdf1c7927896d70e6b9f6af2eaa64b1bb41707..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3037 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 S!l#~*4goMWSah`&G3sAAl9aOm diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__list_activated_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__list_activated_holo.9.png deleted file mode 100644 index eda10e6123e1e1383c4617228ec0c96680d60dc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xamSQK*5Dp-y;YjHK@;M7UB8wRq zxI00Z(fs7;wLn1!PZ!4!jfu$#Gb-B{xqtMx1s*(O%+nLV7IxRdaaX6Iu&3070|zpW ye6d-ZyJWwc+pgOl@x443T>9p%`1p8cx&%YrImy|zOvgZGF?hQAxvX30u5yFboFyt=akR{ E00Z(eO#lD@ diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__list_longpressed_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__list_longpressed_holo.9.png deleted file mode 100644 index eda10e6123e1e1383c4617228ec0c96680d60dc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xamSQK*5Dp-y;YjHK@;M7UB8wRq zxI00Z(fs7;wLn1!PZ!4!jfu$#Gb-B{xqtMx1s*(O%+nLV7IxRdaaX6Iu&3070|zpW ye6d-ZyJWwc+pgOl@x443T>9p%`1p8cx&%YrImy|zOvgZGF?hQAxvX diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__list_pressed_holo_light.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__list_pressed_holo_light.9.png deleted file mode 100644 index e4b33935a3aa4f1af3fa9e9e199b5c47d43f4b74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xamSQK*5Dp-y;YjHK@;M7UB8wRq zxI00Z(fs7;wLn2vPZ!4!jfu$y_kK-b diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__list_selector_disabled_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__list_selector_disabled_holo_dark.9.png deleted file mode 100644 index 88726b69160589c8545759440e8d4e69dc984c67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^azGr$!3HF6SgS1tQk(@Ik;M!Q+?^oIXnykaTA*No zr;B4qM&sKXhJ1$tcw7#es=J@sd2yMiyW@jyg@u(=2qh%>1r1WJE1Ls*cJ{|veUO|(2?8OR-p?Vt(<)KXNk*dJ1<_`!jRpab6RMK;Rk47fDU#NEX#7yk4(~&Fr}L7DZp)K} zK)DDZgb+dqA%qY@2q7)3S*px^wsY!a9l?~jW2$HoDfOAoDc4?$q=mJH$Q@HesW|pH zEqI5t5pt#=^`ykNb$bDA+g_!6r>E#0Ebxb)V~E)@66{HSu%o+0#^7QK=<56_<*0g z4?VWXMFRkJB8s~XX6q}?LEeWW=Ef--P!X+fp` zQ#hbt=1@CWv@?Vrj0n$wG-wfB>s2&!$QdDJ0ulZgw-cuRiR{Y>^Hj3K6cvDZyr8vA z8lxp5*y$r9!v6G_XAF7`2PhmT)XW;J_(x39;8bKfgMu`e! zU+jWXwIOOF0-q>8C*JQsY~7_bBCuA z|Ap1-2&vJi9g(t&*dI@qVtrbEm_q)8uxlUymW^N&DQrSTF2REQdw9B(B*Fk-L?96w zfdFVX0=tCgq*<4>5rKwy4p!?>V+1b~mqyqhPm^M8N}pNlWK7Aa(;L|rtB1{dT%;u; z=)dm(?jeLfE6zhUB!2hW01y9MdY)1v=ujhBx3b+Xm&>Pd9KV)clx)K|j$bdA%O^}( zPFj=H`w_B~E-2}`eIdjBd_I2}hT(GvVW{|jkQIawhG7^!pU>wnc#H_%SRreOrJP6k z#f!~#`~_1^!^gPqw^)9R`+vop3DslHn(o!PiI0dTt@|45Za=)m1`%IwEW{fV$LVaF zE9RVsAMaWMjZlg;f(R_4iy{7r`=s=`3SdP<&^M)TPHqgUw5?z25;3$902*NlyMU*S zpa+j$RH$BIEX`7~H`b|A%pl=Pj|o!QHv-L&MvImjnCmfv9y@5Gq|A_|G$L4MNvqdg zg%(@J38}FG4N!(%uhEggMhM*%9HY#I^l zO-Wr$p$z~$ref=30GgqO)XJdORd}!BEq>NeB8p9{v^kJo2|NxCQwf^HCpGf6X;Wp4 zg!hgmb$FtdtQ>ASMriqL^@|$FBEhNWjw@zMktp~+Gzo9nO1w>OhBUKE#}ER(1L)vD UI+1b(O8@`>07*qoM6N<$f~tseq5uE@ diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__menu_dropdown_panel_holo_light.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__menu_dropdown_panel_holo_light.9.png deleted file mode 100644 index 93066c8403ddaac9b19571152ef499620bcc0e02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1551 zcmV+q2JrcbP)ZMyJc+a5x+ehm5NR9U3;9%`Hyz-(tJnPJWK72_ZxFO$7HJ!wl=MA(TM` z5z;&LLlB#EA&f^$3`&>pe6X)LdJ&`vfROKm-xd+jMbSqLMZ|438|}{L$EEgM9M^%w zHa{i`W4qmEM~t#0eOdu-0W1NOh@<%YUknyuBI#0I?3#!O*zRI&T@|+kOaOda%IhNv zM;99T5trXGZJ+ZJPec%b)$c$hhFbzf1btKUoQ@WxJHBtqt%Djjh@==IkkXLZmr_R= zETUs(|D2YHL30h7B}jQ1@s(0WN*y++$>%9Px0_7;Q^61da}ymGVa5oGC6I`(Se|An zXj@SBzbdSFK)Um(Fw#d8Mr2~>phE(63xW_TA*G~C`G7107k~`S4FDISDe;mJcscGO zI_^QW2+SjBmZ1U=9v>gytZ(L+77q^(-%!w_2qCD0PZix`L1IaO$h(b>d0@F@G3Eaa zi55W^GL}q#AgNiNjxa=>FZdR(r+ zxE>NCSff^sd0^fBMHn)m#E-cU=7+{dF-K!9f{S1|kOWYSoDj6e26s~&lfViRc^MJj z^>Y9iF9eSfmVwbcxJ7UPa3MH8F;)otZ%)TN7|p{_AvpQV#UO5SLMWM?>!O$+C0vaD z8(N!X1GsBg3ar^sKmkXku0dO*!9}nfXnYiL)Hg=pYKs73(^zvc9aG}t;{#B5>C;Y2 z2$?l`wfXukgc)%>9s%7AsDyH^rRNDOAHyeHMgYzG`@1jfJOi4h!RzZQK)65|cOA0& z28%R3H(uBEzOL&YU%_z=>~=fscDp^gsmfTk*1@j+TejVzGC zpG{n`bp4r^(iKT*Io^&x%OHc_WZd_EkhCG`k)*sFZ|A&V23>!#)HToxrIRJ-1q1Q~ z3qHxB_z~+bgihSWK3otqlC9O%9BoMC(eAot5j0oOB3|pwbjUE4*ONZd@_Kxq z*B8(0XhE_FfV`ZZwcn~gXn8&5;sQ&h03_lPHzc@QD2L`A0DB!p$qE$r97Hn6cmgfM z$;^GEI@&qEx+o;VEJ0ZAK#dKOL6F|xU|IwgE6|`&x_D{{k^myy5)6fQcS{yR>LIlD zb0eL(UISu`k;Dp-=L_3_9uII4xG36?ZZ5uUxd1Up2yq&z=dNHjN&oIh<{D_CLJUbUG4w?002ovPDHLkV1n`$ Bwt@fv diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__progress_bg_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__progress_bg_holo_dark.9.png deleted file mode 100644 index 345f5d3067c1b5a2b13f7234238468e8083e75e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr?*8<0#p>+uXou@pObhHwBu4M$1`kk47*5n0T@ zz}*SLjOHg#uLTMQc)B=-SoFS~;>gutz{8S$H2ll||1$b2>+ab^8r zChoU9-sVBr1cr+EHAcpdxgPN?*fw!WN@w!F_di=AUe22-xp-2_jNr43yl#?i1$i|o QK(iS+uXou@pObhHwBu4M$1`kk47*5n0T@ zz}*SLjOHg#uLTPFdAc};SoFS~;>gutz{8S$^!?BO&wHlFT~V_1=)TZ8!I{mdT_A)Z zztl5%UbEjFE&+!7%~#Kq{9)d)y{;#I@4EEH*bSem)2!T7Pp)1*OL*gdvC7^*b6)~Y OX7F_Nb6Mw<&;$Uil{z^9 diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__progress_primary_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__progress_primary_holo_dark.9.png deleted file mode 100644 index c6c3f1ec248835c16ee8a8f9d253769ea4196468..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1309 zcmV+&1>*XNP)>2T29Hys?P&Vm zZA9*OOSNlf`Pu!y*8AUEO|D+e=9Pi3BR)agfw#}SukU>S5_JQH{fFX7qt#y26-7>F z^lg#%AL~){ay($Vl%dNK|ns=8F95J5u4IuT)_iO}FO5AO!x2YA-ev{((MiCMb95Z27y1N{d~<$0ZOiAzT-4$^Y~d8=D&GctVLiOE-HZCX=>916 zaB}eD93BUF6!cN|FY@&i`W7!}IIL?H*U-;b(9ZeC>T4fo-D~%;%Al$SM;o1{CK^c@ zLsL?U%;F5uW`mKV6p@jG8Wm~81rvcAg~E0r38^#=q@={j6{7*N{-mRal zZyi757l1u@+(UUVUpKQfbx4*^AEZ`NBGTk&djR!;W=;+8vR!2ZvkZUiF_Uw;@^@UHY_tFNo|bZ|HqK}~Z_0kB z>1@!nFOf~^{KOi&lvG5Os4i`3m5LaZ>S{(}C2cS_3u25qx+GSC0x^F*mC<6C%zjX} z`(@Gi@=yT|C0D;bu>bAn+W30Hh5ZfH4VVpRc=$wP71`a_ciV~TTQkNXRQHQat7toU zZx*3Z?Q~QYQO|ZUR_Tl#qXtzIiPWWo(#}&aV(i6KuEST$lYVRUVscgaEz?@VCh+@z zYdAdahv=OS&fP(?9$16?`l0%F3gfnP`B71?hw4@2e4pjZouU=>X|R*`N-YD-DJj}uU$#5 zV>X}RzD~bXHhFf?KK=4JTCWrMiS*`U`G2n9l*Y@cp7B$uQwuKJNIF$*XNP)>2T29Hys?P&Vm zZA9*OOSNlf`Pu!y*8AUEO|D+e=9Pi3BR)agfw#}SukU>S5_JQH{fFX7qt#y26-7>F z^lg#%AL~){ay($Vl%dNK|ns=8F95J5u4IuT)_iO}FO5AO!x2YA-ev{((MiCMb95Z27y1N{d~<$0ZOiAzT-4$^Y~d8=D&GctVLiOE-HZCX=>916 zaB}eD93BUF6!cN|FY@&i`W7!}IIL?H*U-;b(9ZeC>T4fo-D~%;%Al$SM;o1{CK^c@ zLsL?U%;F5uW`mKV6p@jG8Wm~81rvcAg~E0r38^#=q@={j6{7*N{-mRal zZyi757l1u@+(UUVUpKQfbx4*^AEZ`NBGTk&djR!;W=;+8vR!2ZvkZUiF_Uw;@^@UHY_tFNo|bZ|HqK}~Z_0kB z>1@!nFOf~^{KOi&lvG5Os4i`3m5LaZ>S{(}C2cS_3u25qx+GSC0x^F*mC<6C%zjX} z`(@Gi@=yT|C0D;bu>bAn+W30Hh5ZfH4VVpRc=$wP71`a_ciV~TTQkNXRQHQat7toU zZx*3Z?Q~QYQO|ZUR_Tl#qXtzIiPWWo(#}&aV(i6KuEST$lYVRUVscgaEz?@VCh+@z zYdAdahv=OS&fP(?9$16?`l0%F3gfnP`B71?hw4@2e4pjZouU=>X|R*`N-YD-DJj}uU$#5 zV>X}RzD~bXHhFf?KK=4JTCWrMiS*`U`G2n9l*Y@cp7B$uQwuKJNIF$+uXou@pObhHwBu4M$1`kk47*5n0T@ zz}*SLjOHg#uLTN5dAc};So9|U`2XLYnVI=;y-5$#f-D2o4GsT&Tr`prfMCHsr=)`p zy9zZlQWAk&gL|Kjh|gcN+0MxMkn!S`=@A+#%ic(Om>d23|9^ht#EF9It^fc3f1ZP3 Y!dJ=4-o~HPfwnMsy85}Sb4q9e06h#o+yDRo diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__progress_secondary_holo_light.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__progress_secondary_holo_light.9.png deleted file mode 100644 index 205b66e2cdef686c5ed6369b14e64b38d0182984..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr?*8<0#p>+uXou@pObhHwBu4M$1`kk47*5n0T@ zz}*SLjOHg#uLTN5dAc};So9|U`2XLYnVI=;y-5$#f-D2o4GsT&Tr`prfMCHsr=)`p zy9zZlQWAk&gL|Kjh|gcN+0MxMkn!S`=@A+#%ic(Om>d23|9^ht#EF9It^fc3f1ZP3 Y!dJ=4-o~HPfwnMsy85}Sb4q9e06h#o+yDRo diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__spinner_48_inner_holo.png b/actionbarsherlock/res/drawable-xhdpi/abs__spinner_48_inner_holo.png deleted file mode 100644 index 19517c4b0aee1010c7041a76089fdfdbfa495e80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2769 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 diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_default_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_default_holo_dark.9.png deleted file mode 100644 index d8929fcd1864e92c78f24d34bb07ac0304bf5ebe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 395 zcmV;60d)R}P)%)khMb;v@5Yo)-?A$vWI3J{&4Tqm)VM&;#i3-!rXQ;}}A|kSK_xLoQ9!D=| zrQuRX_jo!D&!*woG(4MzXVdU(8lG)+!_Dl;%pOYTRyEwrUVwMtwRCnh!_9059DxJy zTsprAUsT~zdJlX8e>K+(FMd_}2<&RF8#?@^bn(8vHtbfpl-_eLJ!>=!D!!z&OE12( zv`a1CqqIva-mA1rDc-ZR3oqWgvUXO(tc zif5K~i;HKMc8iLSDD9eyk1Fk&iksP%L8V=5@ekmQ^NVfO%k2z5z^Qbob@&(X-FR)u p3HS~A?&0(Ut%!)oJooy?_kZokYAURbJh}h?002ovPDHLkV1n7-uz&yn diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_default_holo_light.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_default_holo_light.9.png deleted file mode 100644 index 9174c4e4bc984a89e1ed643bc66b1569466ef52b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 394 zcmV;50d@X~P)pS_@$ zhD#gW|+S$zvH?tjZ06u}I z+WCj@MGelS_rM46*K*DD;uob4z^?VWsl%^ISMTdf({7b>={={?i$=qw;%iE~^x|tv zyVT+%O1re;qe{D!;v-AD@ZzIOyU^khrCnI@sM0Q^cw}ieym)kJH?(+0X*aBRR%th+ zcxGw0x_EYJx2pJz(yqJstkSNlxS72&skG}Y{tg(Y7u%+n+Xa4rW9?Ay@Gs!I^V*st o@Ei2q)9D9V5fPDPZuO7v|4Ms3SH1lZVgLXD07*qoM6N<$f(F>P&Hw-a diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_dark.9.png deleted file mode 100644 index 3015d307088f12d52a9e99ff4575fd2153127e5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 381 zcmV-@0fPRCP)hG*08Y#N?T!?S64w!;lKvy+*1?>p3RGdlx#190x$dzj&7b^-9QUftoB@I?dG z(l;!l|3;oEFaA*ajtwD8hd-6>9*;+5M`bO2!%}+FXrQS0p3;u)|QJUO}XO$+G;+dssck%4fw5xbU zX__uxRhp)XSC*#P;_m>iSbo@k`^^CW{9xcU{p|2h0AG{O_A~&$L7!btFK9(XM7DX= bKfeD1Etg?&Fp}qT00000NkvXXu0mjfW#pxI diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_light.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_disabled_holo_light.9.png deleted file mode 100644 index 126637d1194f1d6609787774fb140818eaa4ba1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 381 zcmV-@0fPRCP)hG*08Y#N?T!?S64w!;lKvy+*1?>p3RGdlx#190x$dzj&7b^-9QUftoB@I?dG z(l;!l|3;oEFaA*ajtwD8hd-6>9*;+5M`bO2!%}+FXrQS0p3;u)|QJUO}XO$+G;+dssck%4fw5xbU zX__uxRhp)XSC*#P;_m>iSbo@k`^^CW{9xcU{p|2h0AG{O_A~&$L7!btFK9(XM7DX= bKfeD1iaRu(IeFS@00000NkvXXu0mjfR7Ip< diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_focused_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_focused_holo_dark.9.png deleted file mode 100644 index d45c7a864d9b36fc5d06ef7650bd22c228e3533e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 680 zcmV;Z0$2TsP)JMg@Fn128fNR{httc z2n-9ae~A~-WYQOAyjJ3`v+tFS>H?h>cjZI44!YCDJ4vU-UH-NFC!H?dNqTY9^x~%J z#ZA+To2C~xO)qX5=ft;__PrJUYC9#q>!rbyQFMFHPb=3hoe|&n)9~p|baWUbMthlMtLL6k^E5&wx9H zfkWKo4DxGy27JSv%4KLW#~I|sPnXY+fCHfNj(}ks%-+uyBgtHbMG(R)| O00009q_DOpcx|jv*P1Z)f>u3p>g<+)ulGcHZsoOUd0`v$ideb3Xs*rv6J! zg}R0?Ejbavstni13%M+(h~#=Y?=G{+sY|c-R?LyC;M~J_EGz53I-4BR z+cU4@A4T%4{LQ{7{nooe_R?;9Ufq56+wp;!Z_W|LdHU^V zuiix!E)rt*mg%eid+||lw)K3kxzR2XQeoHKTo0e>Tz_Z7KF;I+KDl^G6{a%9AKj}v z@Aq1v55LRoZXbD)<16^lF!*Li$^7}+)mu{zFEMCaSs}k;w&aatvA+!FKCV6>P_Fen z(L?roLe!sxPkWei7+T9&rtD<0W7^%ZdcE}hdZyQpKhHVIBAEwFVGN$GelF{r5}E)^ Cjyh@p diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_dark.9.png deleted file mode 100644 index 2cb34d7f60401a563454c03e266cc5181d9de996..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 609 zcmV-n0-pVeP)%5ec8;(Nh#y0Zthco9&fD+Scz(J_kqCSd>@N)Jrb#iJx@ z@geV)|0U|;Q8J4AW)%0$DDIn4+&81RZ$@$73{E^#CTa6Odr;zqGLyGk)zfLB)26Y5 z5#LU9dOW?JALQjc$4r{WH?GVFg))<)qMW_Ts@W~*Hgkd(m(u%LwVNxGwVfAK{BG$~ zHD4Zg33jP$CptYU%GrKa?RJ%hK*cvHEqE`!X=%Z0aT}!tZ^dnu7Q7Uk{&1!u)wl@^>7cUfAnUfgwQ!D?|Ir3GuneU%oh6!%$L*todw(!xf?LzEVJ7Y|ih z=v92GOd6`R(5v{nqI~u|T|T)5eQi`_Q>fI*QllCl)AthpQf>YCTIE0c%xyxW%x|6C zG>z*e{-?!>T@(EFL|;a6&!||%qb(l4cp2298zt1@mjOk(atXEgIq-{NzY%9xIi5qk vb6%{!-vcjz*7vDBaRYn@J|M2KzWDwRiVUw(_ikNA00000NkvXXu0mjfOP&sp diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_light.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__spinner_ab_pressed_holo_light.9.png deleted file mode 100644 index 82f752fdc28390f1dae188e66886f9fee783b4f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 602 zcmV-g0;TXoV&|>P?2N3a|H=XkIpb%g2C{mUcD8z%K5!WW71`A3B@}P?c zNzmeTUM-&`=;A@rh-=e`Ytx8p(}-)+h-=e`Yg0e*Nfwct-zMuNo?gfN+FNCOm6(Rs zNBrh8;rK_F^Mfu~8k>e2?@WdCI_7lHVR+IZj_>A~;=j0*zBpPVOJB@8&9C^w(v!^i zcs#`4qjGbZa60I4akN%e8hjOBptPW0e8JL!ZgC5x1-;^yN((y0EtVGC7q?tma9i9# zX~A7_N2LWf#T}Lw>=$=jTCiJOp|oJHxKe4sPI1N3!s5l1OACt?_fT4>Uffe@p<40r zRpP6(P_6jSy?2bx-x9}n#O>6o(Q^BiC^BxWR1^RB?JvEr|0>Nj5k)!eSD9&8HSzXK z2sbij-vth4?P;pL%~0mos(Tg<|DAn;kcS obzts&Y9%t@53qx{hWg?AJqc6disFjI`v3p{07*qoM6N<$f`4nJ zaCd?*qxs3xYk`8Mo-U3d5>t~6?){q5*x2~c-pCBZ5@_=ERFyG diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__tab_selected_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__tab_selected_holo.9.png deleted file mode 100644 index e4229f26b2771d884934b80d0056b8dd66d10edd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^Y(Ol;0U|59*B=E^EX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`8+o-U3d5>t~6?){q5*x2~c-l(n1@K5>ymj5$1a2Oc?!34d7Ck`Aq skg(^gW|wXH-lZoEvTk@AJm}J3sQWAGentL}KF}BjPgg&ebxsLQ0KFYBT>t<8 diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__tab_selected_pressed_holo.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__tab_selected_pressed_holo.9.png deleted file mode 100644 index e862cb12154541c150fb2d9bb98872bcff506317..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^Y(Ol;0U|59*B=E^EX7WqAsj$Z!;#Vf4nJ zaCd?*qxs3xYk`8Mo-U3d5>t~6?){q5*x2~c-pCBZ5m8aUV+M1MLNsm8aUV+8udAXlQhooEaFu)>JVsC;_i|1;&qn1z`CMwWxmD@8>XG@5j{z4 Z4Ch(42+t_Fa};PGgQu&X%Q~loCICWDCD8x? diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_right_default_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_right_default_holo_dark.9.png deleted file mode 100644 index 98f4871bb52aa7c60414b62dc102a63025d14b86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^qCm{e!3HEJoIX|yq+C2*978nDC;#~W-=0~Khvol7 z1H)I2CW)>m8aUVm(v1b%el;0fY!m7fYzsPhAkg_?o6!P}0Ord_0t$qVOiDg+P{Wat YL8LkPQkkjERiJqcp00i_>zopr0H|OnC;$Ke diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_right_default_holo_light.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_right_default_holo_light.9.png deleted file mode 100644 index 733373ed38d92906a3f639124b60d39cfe3ea469..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^qCm{e!3HEJoIX|yq})7R978nDC;#~W-=0~Khvol7 z1H)I2CW)>m8aUVm(v20J8xM$gbsA4Oq2MIp#mnr@>uNTIF}6W!#;>-fvxg@opE#)D b$jGop@Lc3+&hjll6B#^R{an^LB{Ts5lN~2O diff --git a/actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_right_selected_holo_dark.9.png b/actionbarsherlock/res/drawable-xhdpi/abs__textfield_search_right_selected_holo_dark.9.png deleted file mode 100644 index 0c6bb036dbff7c452df0032fac9daaaf3ed36cff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^qCm{e!3HEJoIX|yq})AS978nDC;#~W-=0~Khvol7 z1H)I2CW)>m8aUVm(v9t$CDZ2p!k(eA~|x?WSsfj bIFlKwHfSC=yJ^W9ppguou6{1-oD!Mm8aUVm(v9t$CDZ2p!k(eA~|x?WSsfj bIFlKwHfSC=yJ^W9ppguou6{1-oD!Mm8aUV)4xTaopEyItdE!^$Tn)$h3#7aBEDrH5l{lPKbU~WStl#0CqS)dY aj0`i|)DAxoJGT#LAcLo?pUXO@geCyp{V3}I diff --git a/actionbarsherlock/res/drawable/abs__activated_background_holo_dark.xml b/actionbarsherlock/res/drawable/abs__activated_background_holo_dark.xml deleted file mode 100644 index 85c2c021..00000000 --- a/actionbarsherlock/res/drawable/abs__activated_background_holo_dark.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__activated_background_holo_light.xml b/actionbarsherlock/res/drawable/abs__activated_background_holo_light.xml deleted file mode 100644 index 85c2c021..00000000 --- a/actionbarsherlock/res/drawable/abs__activated_background_holo_light.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__btn_cab_done_holo_dark.xml b/actionbarsherlock/res/drawable/abs__btn_cab_done_holo_dark.xml deleted file mode 100644 index cab89628..00000000 --- a/actionbarsherlock/res/drawable/abs__btn_cab_done_holo_dark.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__btn_cab_done_holo_light.xml b/actionbarsherlock/res/drawable/abs__btn_cab_done_holo_light.xml deleted file mode 100644 index 42ba8a0d..00000000 --- a/actionbarsherlock/res/drawable/abs__btn_cab_done_holo_light.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__ic_clear.xml b/actionbarsherlock/res/drawable/abs__ic_clear.xml deleted file mode 100644 index a16f4b22..00000000 --- a/actionbarsherlock/res/drawable/abs__ic_clear.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__ic_clear_holo_light.xml b/actionbarsherlock/res/drawable/abs__ic_clear_holo_light.xml deleted file mode 100644 index 256de80f..00000000 --- a/actionbarsherlock/res/drawable/abs__ic_clear_holo_light.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml b/actionbarsherlock/res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml deleted file mode 100644 index 2588a492..00000000 --- a/actionbarsherlock/res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - diff --git a/actionbarsherlock/res/drawable/abs__ic_menu_moreoverflow_holo_light.xml b/actionbarsherlock/res/drawable/abs__ic_menu_moreoverflow_holo_light.xml deleted file mode 100644 index e2078c96..00000000 --- a/actionbarsherlock/res/drawable/abs__ic_menu_moreoverflow_holo_light.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - diff --git a/actionbarsherlock/res/drawable/abs__item_background_holo_dark.xml b/actionbarsherlock/res/drawable/abs__item_background_holo_dark.xml deleted file mode 100644 index d99b7a42..00000000 --- a/actionbarsherlock/res/drawable/abs__item_background_holo_dark.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__item_background_holo_light.xml b/actionbarsherlock/res/drawable/abs__item_background_holo_light.xml deleted file mode 100644 index da5fb2e8..00000000 --- a/actionbarsherlock/res/drawable/abs__item_background_holo_light.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__list_selector_background_transition_holo_dark.xml b/actionbarsherlock/res/drawable/abs__list_selector_background_transition_holo_dark.xml deleted file mode 100644 index b2ce4f0f..00000000 --- a/actionbarsherlock/res/drawable/abs__list_selector_background_transition_holo_dark.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__list_selector_background_transition_holo_light.xml b/actionbarsherlock/res/drawable/abs__list_selector_background_transition_holo_light.xml deleted file mode 100644 index d7e31b1d..00000000 --- a/actionbarsherlock/res/drawable/abs__list_selector_background_transition_holo_light.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__list_selector_holo_dark.xml b/actionbarsherlock/res/drawable/abs__list_selector_holo_dark.xml deleted file mode 100644 index 08b8b12f..00000000 --- a/actionbarsherlock/res/drawable/abs__list_selector_holo_dark.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__list_selector_holo_light.xml b/actionbarsherlock/res/drawable/abs__list_selector_holo_light.xml deleted file mode 100644 index ada490bf..00000000 --- a/actionbarsherlock/res/drawable/abs__list_selector_holo_light.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__progress_horizontal_holo_dark.xml b/actionbarsherlock/res/drawable/abs__progress_horizontal_holo_dark.xml deleted file mode 100644 index bd19140a..00000000 --- a/actionbarsherlock/res/drawable/abs__progress_horizontal_holo_dark.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__progress_horizontal_holo_light.xml b/actionbarsherlock/res/drawable/abs__progress_horizontal_holo_light.xml deleted file mode 100644 index 321f07c8..00000000 --- a/actionbarsherlock/res/drawable/abs__progress_horizontal_holo_light.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__progress_medium_holo.xml b/actionbarsherlock/res/drawable/abs__progress_medium_holo.xml deleted file mode 100644 index 6d4814f8..00000000 --- a/actionbarsherlock/res/drawable/abs__progress_medium_holo.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__search_dropdown_dark.xml b/actionbarsherlock/res/drawable/abs__search_dropdown_dark.xml deleted file mode 100644 index 26284187..00000000 --- a/actionbarsherlock/res/drawable/abs__search_dropdown_dark.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__search_dropdown_light.xml b/actionbarsherlock/res/drawable/abs__search_dropdown_light.xml deleted file mode 100644 index 0d00c587..00000000 --- a/actionbarsherlock/res/drawable/abs__search_dropdown_light.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__spinner_ab_holo_dark.xml b/actionbarsherlock/res/drawable/abs__spinner_ab_holo_dark.xml deleted file mode 100644 index 4af5e22a..00000000 --- a/actionbarsherlock/res/drawable/abs__spinner_ab_holo_dark.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__spinner_ab_holo_light.xml b/actionbarsherlock/res/drawable/abs__spinner_ab_holo_light.xml deleted file mode 100644 index b7850847..00000000 --- a/actionbarsherlock/res/drawable/abs__spinner_ab_holo_light.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__tab_indicator_ab_holo.xml b/actionbarsherlock/res/drawable/abs__tab_indicator_ab_holo.xml deleted file mode 100644 index d34e2081..00000000 --- a/actionbarsherlock/res/drawable/abs__tab_indicator_ab_holo.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__textfield_searchview_holo_dark.xml b/actionbarsherlock/res/drawable/abs__textfield_searchview_holo_dark.xml deleted file mode 100644 index b6d58c04..00000000 --- a/actionbarsherlock/res/drawable/abs__textfield_searchview_holo_dark.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__textfield_searchview_holo_light.xml b/actionbarsherlock/res/drawable/abs__textfield_searchview_holo_light.xml deleted file mode 100644 index 3d6acf80..00000000 --- a/actionbarsherlock/res/drawable/abs__textfield_searchview_holo_light.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__textfield_searchview_right_holo_dark.xml b/actionbarsherlock/res/drawable/abs__textfield_searchview_right_holo_dark.xml deleted file mode 100644 index 05ff4eda..00000000 --- a/actionbarsherlock/res/drawable/abs__textfield_searchview_right_holo_dark.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - diff --git a/actionbarsherlock/res/drawable/abs__textfield_searchview_right_holo_light.xml b/actionbarsherlock/res/drawable/abs__textfield_searchview_right_holo_light.xml deleted file mode 100644 index f6d61e57..00000000 --- a/actionbarsherlock/res/drawable/abs__textfield_searchview_right_holo_light.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - diff --git a/actionbarsherlock/res/layout-large/abs__action_mode_close_item.xml b/actionbarsherlock/res/layout-large/abs__action_mode_close_item.xml deleted file mode 100644 index 8811dad8..00000000 --- a/actionbarsherlock/res/layout-large/abs__action_mode_close_item.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - diff --git a/actionbarsherlock/res/layout-v14/sherlock_spinner_dropdown_item.xml b/actionbarsherlock/res/layout-v14/sherlock_spinner_dropdown_item.xml deleted file mode 100644 index 6c183c05..00000000 --- a/actionbarsherlock/res/layout-v14/sherlock_spinner_dropdown_item.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/actionbarsherlock/res/layout-v14/sherlock_spinner_item.xml b/actionbarsherlock/res/layout-v14/sherlock_spinner_item.xml deleted file mode 100644 index 61dc0252..00000000 --- a/actionbarsherlock/res/layout-v14/sherlock_spinner_item.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/actionbarsherlock/res/layout-xlarge/abs__screen_action_bar.xml b/actionbarsherlock/res/layout-xlarge/abs__screen_action_bar.xml deleted file mode 100644 index 040df44a..00000000 --- a/actionbarsherlock/res/layout-xlarge/abs__screen_action_bar.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - diff --git a/actionbarsherlock/res/layout-xlarge/abs__screen_action_bar_overlay.xml b/actionbarsherlock/res/layout-xlarge/abs__screen_action_bar_overlay.xml deleted file mode 100644 index c64ef141..00000000 --- a/actionbarsherlock/res/layout-xlarge/abs__screen_action_bar_overlay.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__action_bar_home.xml b/actionbarsherlock/res/layout/abs__action_bar_home.xml deleted file mode 100644 index 5c1e9ec4..00000000 --- a/actionbarsherlock/res/layout/abs__action_bar_home.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__action_bar_tab.xml b/actionbarsherlock/res/layout/abs__action_bar_tab.xml deleted file mode 100644 index f46f7a04..00000000 --- a/actionbarsherlock/res/layout/abs__action_bar_tab.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - \ No newline at end of file diff --git a/actionbarsherlock/res/layout/abs__action_bar_tab_bar_view.xml b/actionbarsherlock/res/layout/abs__action_bar_tab_bar_view.xml deleted file mode 100644 index 0d51220c..00000000 --- a/actionbarsherlock/res/layout/abs__action_bar_tab_bar_view.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - \ No newline at end of file diff --git a/actionbarsherlock/res/layout/abs__action_bar_title_item.xml b/actionbarsherlock/res/layout/abs__action_bar_title_item.xml deleted file mode 100644 index dd69acad..00000000 --- a/actionbarsherlock/res/layout/abs__action_bar_title_item.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__action_menu_item_layout.xml b/actionbarsherlock/res/layout/abs__action_menu_item_layout.xml deleted file mode 100644 index 13149fd6..00000000 --- a/actionbarsherlock/res/layout/abs__action_menu_item_layout.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__action_menu_layout.xml b/actionbarsherlock/res/layout/abs__action_menu_layout.xml deleted file mode 100644 index a6f8e53f..00000000 --- a/actionbarsherlock/res/layout/abs__action_menu_layout.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - diff --git a/actionbarsherlock/res/layout/abs__action_mode_bar.xml b/actionbarsherlock/res/layout/abs__action_mode_bar.xml deleted file mode 100644 index 7168dc77..00000000 --- a/actionbarsherlock/res/layout/abs__action_mode_bar.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - diff --git a/actionbarsherlock/res/layout/abs__action_mode_close_item.xml b/actionbarsherlock/res/layout/abs__action_mode_close_item.xml deleted file mode 100644 index 875ec3e1..00000000 --- a/actionbarsherlock/res/layout/abs__action_mode_close_item.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - diff --git a/actionbarsherlock/res/layout/abs__activity_chooser_view.xml b/actionbarsherlock/res/layout/abs__activity_chooser_view.xml deleted file mode 100644 index 6a0ac9ec..00000000 --- a/actionbarsherlock/res/layout/abs__activity_chooser_view.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__activity_chooser_view_list_item.xml b/actionbarsherlock/res/layout/abs__activity_chooser_view_list_item.xml deleted file mode 100644 index b430032a..00000000 --- a/actionbarsherlock/res/layout/abs__activity_chooser_view_list_item.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__dialog_title_holo.xml b/actionbarsherlock/res/layout/abs__dialog_title_holo.xml deleted file mode 100644 index ab2b0ee6..00000000 --- a/actionbarsherlock/res/layout/abs__dialog_title_holo.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__list_menu_item_checkbox.xml b/actionbarsherlock/res/layout/abs__list_menu_item_checkbox.xml deleted file mode 100644 index 39aca3a8..00000000 --- a/actionbarsherlock/res/layout/abs__list_menu_item_checkbox.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - diff --git a/actionbarsherlock/res/layout/abs__list_menu_item_icon.xml b/actionbarsherlock/res/layout/abs__list_menu_item_icon.xml deleted file mode 100644 index 55ab28a2..00000000 --- a/actionbarsherlock/res/layout/abs__list_menu_item_icon.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - diff --git a/actionbarsherlock/res/layout/abs__list_menu_item_layout.xml b/actionbarsherlock/res/layout/abs__list_menu_item_layout.xml deleted file mode 100644 index 147f36fe..00000000 --- a/actionbarsherlock/res/layout/abs__list_menu_item_layout.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__list_menu_item_radio.xml b/actionbarsherlock/res/layout/abs__list_menu_item_radio.xml deleted file mode 100644 index ff54bbec..00000000 --- a/actionbarsherlock/res/layout/abs__list_menu_item_radio.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - diff --git a/actionbarsherlock/res/layout/abs__popup_menu_item_layout.xml b/actionbarsherlock/res/layout/abs__popup_menu_item_layout.xml deleted file mode 100644 index d42425ad..00000000 --- a/actionbarsherlock/res/layout/abs__popup_menu_item_layout.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__screen_action_bar.xml b/actionbarsherlock/res/layout/abs__screen_action_bar.xml deleted file mode 100644 index 1fb82fe9..00000000 --- a/actionbarsherlock/res/layout/abs__screen_action_bar.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__screen_action_bar_overlay.xml b/actionbarsherlock/res/layout/abs__screen_action_bar_overlay.xml deleted file mode 100644 index 0961ef56..00000000 --- a/actionbarsherlock/res/layout/abs__screen_action_bar_overlay.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__screen_simple.xml b/actionbarsherlock/res/layout/abs__screen_simple.xml deleted file mode 100644 index 33e2dea0..00000000 --- a/actionbarsherlock/res/layout/abs__screen_simple.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__screen_simple_overlay_action_mode.xml b/actionbarsherlock/res/layout/abs__screen_simple_overlay_action_mode.xml deleted file mode 100644 index f8b9fb18..00000000 --- a/actionbarsherlock/res/layout/abs__screen_simple_overlay_action_mode.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__search_dropdown_item_icons_2line.xml b/actionbarsherlock/res/layout/abs__search_dropdown_item_icons_2line.xml deleted file mode 100644 index e1d3dc49..00000000 --- a/actionbarsherlock/res/layout/abs__search_dropdown_item_icons_2line.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__search_view.xml b/actionbarsherlock/res/layout/abs__search_view.xml deleted file mode 100644 index 6ba31912..00000000 --- a/actionbarsherlock/res/layout/abs__search_view.xml +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/layout/abs__simple_dropdown_hint.xml b/actionbarsherlock/res/layout/abs__simple_dropdown_hint.xml deleted file mode 100644 index 8fc0eb12..00000000 --- a/actionbarsherlock/res/layout/abs__simple_dropdown_hint.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - diff --git a/actionbarsherlock/res/layout/sherlock_spinner_dropdown_item.xml b/actionbarsherlock/res/layout/sherlock_spinner_dropdown_item.xml deleted file mode 100644 index a6c6252d..00000000 --- a/actionbarsherlock/res/layout/sherlock_spinner_dropdown_item.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/actionbarsherlock/res/layout/sherlock_spinner_item.xml b/actionbarsherlock/res/layout/sherlock_spinner_item.xml deleted file mode 100644 index bea74017..00000000 --- a/actionbarsherlock/res/layout/sherlock_spinner_item.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/actionbarsherlock/res/values-land/abs__dimens.xml b/actionbarsherlock/res/values-land/abs__dimens.xml deleted file mode 100644 index 502cc16a..00000000 --- a/actionbarsherlock/res/values-land/abs__dimens.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - 40dip - - 4dip - - 16dp - - 12dp - - -2dp - - 4dip - diff --git a/actionbarsherlock/res/values-large-hdpi-1024x600/abs__dimens.xml b/actionbarsherlock/res/values-large-hdpi-1024x600/abs__dimens.xml deleted file mode 100644 index 3312cfa7..00000000 --- a/actionbarsherlock/res/values-large-hdpi-1024x600/abs__dimens.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - 48dip - - 8dip - - 18dp - - 14dp - - -3dp - - 5dip - diff --git a/actionbarsherlock/res/values-large-land-hdpi-1024x600/abs__dimens.xml b/actionbarsherlock/res/values-large-land-hdpi-1024x600/abs__dimens.xml deleted file mode 100644 index 502cc16a..00000000 --- a/actionbarsherlock/res/values-large-land-hdpi-1024x600/abs__dimens.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - 40dip - - 4dip - - 16dp - - 12dp - - -2dp - - 4dip - diff --git a/actionbarsherlock/res/values-large-land-mdpi-1024x600/abs__dimens.xml b/actionbarsherlock/res/values-large-land-mdpi-1024x600/abs__dimens.xml deleted file mode 100644 index 3312cfa7..00000000 --- a/actionbarsherlock/res/values-large-land-mdpi-1024x600/abs__dimens.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - 48dip - - 8dip - - 18dp - - 14dp - - -3dp - - 5dip - diff --git a/actionbarsherlock/res/values-large-mdpi-1024x600/abs__dimens.xml b/actionbarsherlock/res/values-large-mdpi-1024x600/abs__dimens.xml deleted file mode 100644 index 35910333..00000000 --- a/actionbarsherlock/res/values-large-mdpi-1024x600/abs__dimens.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - 56dip - - 4dip - - 18dp - - 14dp - - -3dp - - 9dip - - - 64dip - diff --git a/actionbarsherlock/res/values-large/abs__dimens.xml b/actionbarsherlock/res/values-large/abs__dimens.xml deleted file mode 100644 index 63b12f7f..00000000 --- a/actionbarsherlock/res/values-large/abs__dimens.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - 55% - - 80% - diff --git a/actionbarsherlock/res/values-sw600dp/abs__bools.xml b/actionbarsherlock/res/values-sw600dp/abs__bools.xml deleted file mode 100644 index 7a48e154..00000000 --- a/actionbarsherlock/res/values-sw600dp/abs__bools.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - false - diff --git a/actionbarsherlock/res/values-sw600dp/abs__dimens.xml b/actionbarsherlock/res/values-sw600dp/abs__dimens.xml deleted file mode 100644 index f6785381..00000000 --- a/actionbarsherlock/res/values-sw600dp/abs__dimens.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - 56dip - - 4dip - - 18dp - - 14dp - - -3dp - - 9dip - - 5 - - - 64dip - diff --git a/actionbarsherlock/res/values-v11/abs__themes.xml b/actionbarsherlock/res/values-v11/abs__themes.xml deleted file mode 100644 index 03473572..00000000 --- a/actionbarsherlock/res/values-v11/abs__themes.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - diff --git a/actionbarsherlock/res/values-v14/abs__styles.xml b/actionbarsherlock/res/values-v14/abs__styles.xml deleted file mode 100644 index 88a60dd9..00000000 --- a/actionbarsherlock/res/values-v14/abs__styles.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/values-v14/abs__themes.xml b/actionbarsherlock/res/values-v14/abs__themes.xml deleted file mode 100644 index 5fac1ab5..00000000 --- a/actionbarsherlock/res/values-v14/abs__themes.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/values-w360dp/abs__dimens.xml b/actionbarsherlock/res/values-w360dp/abs__dimens.xml deleted file mode 100644 index 6f49d7e4..00000000 --- a/actionbarsherlock/res/values-w360dp/abs__dimens.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - 3 - diff --git a/actionbarsherlock/res/values-w480dp/abs__bools.xml b/actionbarsherlock/res/values-w480dp/abs__bools.xml deleted file mode 100644 index 3eaf4aee..00000000 --- a/actionbarsherlock/res/values-w480dp/abs__bools.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - true - false - diff --git a/actionbarsherlock/res/values-w480dp/abs__config.xml b/actionbarsherlock/res/values-w480dp/abs__config.xml deleted file mode 100644 index 88357b0a..00000000 --- a/actionbarsherlock/res/values-w480dp/abs__config.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - true - - diff --git a/actionbarsherlock/res/values-w500dp/abs__dimens.xml b/actionbarsherlock/res/values-w500dp/abs__dimens.xml deleted file mode 100644 index 2fd4deea..00000000 --- a/actionbarsherlock/res/values-w500dp/abs__dimens.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - 4 - diff --git a/actionbarsherlock/res/values-w600dp/abs__dimens.xml b/actionbarsherlock/res/values-w600dp/abs__dimens.xml deleted file mode 100644 index b085952d..00000000 --- a/actionbarsherlock/res/values-w600dp/abs__dimens.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - 5 - diff --git a/actionbarsherlock/res/values-xlarge/abs__dimens.xml b/actionbarsherlock/res/values-xlarge/abs__dimens.xml deleted file mode 100644 index bfc535de..00000000 --- a/actionbarsherlock/res/values-xlarge/abs__dimens.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - 56dip - - 4dip - - 18dp - - 14dp - - -3dp - - 9dip - - - 64dip - - - 45% - - 72% - diff --git a/actionbarsherlock/res/values/abs__attrs.xml b/actionbarsherlock/res/values/abs__attrs.xml deleted file mode 100644 index 32631ca8..00000000 --- a/actionbarsherlock/res/values/abs__attrs.xml +++ /dev/null @@ -1,432 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/values/abs__bools.xml b/actionbarsherlock/res/values/abs__bools.xml deleted file mode 100644 index 0b432448..00000000 --- a/actionbarsherlock/res/values/abs__bools.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - false - true - true - - diff --git a/actionbarsherlock/res/values/abs__colors.xml b/actionbarsherlock/res/values/abs__colors.xml deleted file mode 100644 index 625c632f..00000000 --- a/actionbarsherlock/res/values/abs__colors.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - #ff000000 - #fff3f3f3 - @color/abs__background_holo_light - @color/abs__background_holo_dark - #ff4c4c4c - #ffb2b2b2 - @color/abs__bright_foreground_holo_light - @color/abs__bright_foreground_holo_dark - #ff33b5e5 - diff --git a/actionbarsherlock/res/values/abs__config.xml b/actionbarsherlock/res/values/abs__config.xml deleted file mode 100644 index 4c7b5d45..00000000 --- a/actionbarsherlock/res/values/abs__config.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - 320dp - - - false - - - true - - - false - - diff --git a/actionbarsherlock/res/values/abs__dimens.xml b/actionbarsherlock/res/values/abs__dimens.xml deleted file mode 100644 index 831289e0..00000000 --- a/actionbarsherlock/res/values/abs__dimens.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - 48dip - - 8dip - - 18dp - - 14dp - - -3dp - - 5dip - - 2 - - - 56dip - - - 64dip - - - 65% - - 95% - - - - 8dip - - - 8dip - - - 32dip - - - - 160dip - - - 320dip - diff --git a/actionbarsherlock/res/values/abs__ids.xml b/actionbarsherlock/res/values/abs__ids.xml deleted file mode 100644 index f9f56045..00000000 --- a/actionbarsherlock/res/values/abs__ids.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - diff --git a/actionbarsherlock/res/values/abs__strings.xml b/actionbarsherlock/res/values/abs__strings.xml deleted file mode 100644 index 06a2a2af..00000000 --- a/actionbarsherlock/res/values/abs__strings.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - Navigate home - - Navigate up - - More options - - - Done - - - See all... - - Select activity - - Share with... - - Choose an application - - Share with - - Share with %s - - - Search - - Search query - - Clear query - - Submit query - - Voice search - diff --git a/actionbarsherlock/res/values/abs__styles.xml b/actionbarsherlock/res/values/abs__styles.xml deleted file mode 100644 index 45a18c18..00000000 --- a/actionbarsherlock/res/values/abs__styles.xml +++ /dev/null @@ -1,412 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/res/values/abs__themes.xml b/actionbarsherlock/res/values/abs__themes.xml deleted file mode 100644 index 634fa798..00000000 --- a/actionbarsherlock/res/values/abs__themes.xml +++ /dev/null @@ -1,239 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/actionbarsherlock/src/android/support/v4/app/Watson.java b/actionbarsherlock/src/android/support/v4/app/Watson.java deleted file mode 100644 index d93de4c6..00000000 --- a/actionbarsherlock/src/android/support/v4/app/Watson.java +++ /dev/null @@ -1,144 +0,0 @@ -package android.support.v4.app; - -import android.util.Log; -import android.view.View; -import android.view.Window; -import com.actionbarsherlock.ActionBarSherlock.OnCreatePanelMenuListener; -import com.actionbarsherlock.ActionBarSherlock.OnMenuItemSelectedListener; -import com.actionbarsherlock.ActionBarSherlock.OnPreparePanelListener; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -import java.util.ArrayList; - -/** I'm in ur package. Stealing ur variables. */ -public abstract class Watson extends FragmentActivity implements OnCreatePanelMenuListener, OnPreparePanelListener, OnMenuItemSelectedListener { - private static final boolean DEBUG = false; - private static final String TAG = "Watson"; - - /** Fragment interface for menu creation callback. */ - public interface OnCreateOptionsMenuListener { - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater); - } - /** Fragment interface for menu preparation callback. */ - public interface OnPrepareOptionsMenuListener { - public void onPrepareOptionsMenu(Menu menu); - } - /** Fragment interface for menu item selection callback. */ - public interface OnOptionsItemSelectedListener { - public boolean onOptionsItemSelected(MenuItem item); - } - - private ArrayList mCreatedMenus; - - - /////////////////////////////////////////////////////////////////////////// - // Sherlock menu handling - /////////////////////////////////////////////////////////////////////////// - - @Override - public boolean onCreatePanelMenu(int featureId, Menu menu) { - if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] featureId: " + featureId + ", menu: " + menu); - - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - boolean result = onCreateOptionsMenu(menu); - if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] activity create result: " + result); - - MenuInflater inflater = getSupportMenuInflater(); - boolean show = false; - ArrayList newMenus = null; - if (mFragments.mAdded != null) { - for (int i = 0; i < mFragments.mAdded.size(); i++) { - Fragment f = mFragments.mAdded.get(i); - if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible && f instanceof OnCreateOptionsMenuListener) { - show = true; - ((OnCreateOptionsMenuListener)f).onCreateOptionsMenu(menu, inflater); - if (newMenus == null) { - newMenus = new ArrayList(); - } - newMenus.add(f); - } - } - } - - if (mCreatedMenus != null) { - for (int i = 0; i < mCreatedMenus.size(); i++) { - Fragment f = mCreatedMenus.get(i); - if (newMenus == null || !newMenus.contains(f)) { - f.onDestroyOptionsMenu(); - } - } - } - - mCreatedMenus = newMenus; - - if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] fragments create result: " + show); - result |= show; - - if (DEBUG) Log.d(TAG, "[onCreatePanelMenu] returning " + result); - return result; - } - return false; - } - - @Override - public boolean onPreparePanel(int featureId, View view, Menu menu) { - if (DEBUG) Log.d(TAG, "[onPreparePanel] featureId: " + featureId + ", view: " + view + " menu: " + menu); - - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - boolean result = onPrepareOptionsMenu(menu); - if (DEBUG) Log.d(TAG, "[onPreparePanel] activity prepare result: " + result); - - boolean show = false; - if (mFragments.mAdded != null) { - for (int i = 0; i < mFragments.mAdded.size(); i++) { - Fragment f = mFragments.mAdded.get(i); - if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible && f instanceof OnPrepareOptionsMenuListener) { - show = true; - ((OnPrepareOptionsMenuListener)f).onPrepareOptionsMenu(menu); - } - } - } - - if (DEBUG) Log.d(TAG, "[onPreparePanel] fragments prepare result: " + show); - result |= show; - - result &= menu.hasVisibleItems(); - if (DEBUG) Log.d(TAG, "[onPreparePanel] returning " + result); - return result; - } - return false; - } - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) { - if (DEBUG) Log.d(TAG, "[onMenuItemSelected] featureId: " + featureId + ", item: " + item); - - if (featureId == Window.FEATURE_OPTIONS_PANEL) { - if (onOptionsItemSelected(item)) { - return true; - } - - if (mFragments.mAdded != null) { - for (int i = 0; i < mFragments.mAdded.size(); i++) { - Fragment f = mFragments.mAdded.get(i); - if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible && f instanceof OnOptionsItemSelectedListener) { - if (((OnOptionsItemSelectedListener)f).onOptionsItemSelected(item)) { - return true; - } - } - } - } - } - return false; - } - - public abstract boolean onCreateOptionsMenu(Menu menu); - - public abstract boolean onPrepareOptionsMenu(Menu menu); - - public abstract boolean onOptionsItemSelected(MenuItem item); - - public abstract MenuInflater getSupportMenuInflater(); -} diff --git a/actionbarsherlock/src/com/actionbarsherlock/ActionBarSherlock.java b/actionbarsherlock/src/com/actionbarsherlock/ActionBarSherlock.java deleted file mode 100644 index ab160f83..00000000 --- a/actionbarsherlock/src/com/actionbarsherlock/ActionBarSherlock.java +++ /dev/null @@ -1,794 +0,0 @@ -package com.actionbarsherlock; - -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.Iterator; -import android.app.Activity; -import android.content.Context; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.KeyEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.internal.ActionBarSherlockCompat; -import com.actionbarsherlock.internal.ActionBarSherlockNative; -import com.actionbarsherlock.view.ActionMode; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -/** - *