Add back DSLV / ActionListViewSettings
Contains updates by Griffin Millender <griffinn.millender@gmail.com> and the SlimROMs team AICPfy: - make it play better with themes - bring it to Oreo - Update SettingsActivity to forward extras from PreferenceScreen to the new fragment (allows using DSLV from xml) Change-Id: I7514cdfa3603ed6e24deeb251875a716a52a02b1
This commit is contained in:
11
res/drawable/dslv_ic_grabber.xml
Normal file
11
res/drawable/dslv_ic_grabber.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="36dp"
|
||||||
|
android:height="36dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="?android:attr/textColorSecondary"
|
||||||
|
android:pathData="M20 9H4v2h16V9zM4 15h16v-2H4v2z" />
|
||||||
|
</vector>
|
||||||
13
res/drawable/ic_menu_add.xml
Normal file
13
res/drawable/ic_menu_add.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="?android:attr/textColorPrimary"
|
||||||
|
android:pathData="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
|
||||||
|
<path
|
||||||
|
android:pathData="M0 0h24v24H0z" />
|
||||||
|
</vector>
|
||||||
68
res/layout/dslv_action_list_view_item.xml
Normal file
68
res/layout/dslv_action_list_view_item.xml
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2014 Slimroms
|
||||||
|
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
|
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||||
|
android:paddingTop="8dip"
|
||||||
|
android:paddingBottom="8dip" >
|
||||||
|
<ImageView
|
||||||
|
android:id="@id/drag_handle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/dslv_ic_grabber"
|
||||||
|
android:layout_marginEnd="8dip"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
android:contentDescription="@null" />
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="fill_horizontal|center_vertical"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingRight="5dp">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/click_action_description"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="fill_horizontal"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:textAlignment="viewStart" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/longpress_action_description"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="fill_horizontal"
|
||||||
|
android:layout_marginTop="2dip"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:textAlignment="viewStart" />
|
||||||
|
</LinearLayout>
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="36dip"
|
||||||
|
android:layout_height="36dip"
|
||||||
|
android:layout_marginEnd="8dip"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
android:contentDescription="@null" />
|
||||||
|
</GridLayout>
|
||||||
67
res/layout/dslv_action_list_view_main.xml
Normal file
67
res/layout/dslv_action_list_view_main.xml
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2014 Slimroms
|
||||||
|
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/fragment_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" >
|
||||||
|
</LinearLayout>
|
||||||
|
<View
|
||||||
|
android:id="@+id/divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:background="?android:attr/listDivider"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/disable_message"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dip"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:text="@string/shortcut_action_disable_message"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:visibility="gone" />
|
||||||
|
<com.blissroms.blissify.preferences.dslv.DragSortListView
|
||||||
|
android:id="@android:id/list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingTop="0dp"
|
||||||
|
android:paddingBottom="0dp"
|
||||||
|
android:paddingLeft="0dp"
|
||||||
|
android:layout_margin="0dp"
|
||||||
|
android:dividerHeight="1dp"
|
||||||
|
settings:dragEnabled="true"
|
||||||
|
settings:collapsedHeight="2dp"
|
||||||
|
settings:dragScrollStart="0.33"
|
||||||
|
settings:maxDragScrollSpeed="0.5"
|
||||||
|
settings:floatAlpha="0.6"
|
||||||
|
settings:slideShuffleSpeed="0.3"
|
||||||
|
settings:trackDragSort="false"
|
||||||
|
settings:useDefaultController="true"
|
||||||
|
settings:dragHandleId="@id/drag_handle"
|
||||||
|
settings:sortEnabled="true"
|
||||||
|
settings:removeEnabled="true"
|
||||||
|
settings:dragStartMode="onMove"
|
||||||
|
settings:removeMode="flingRemove"
|
||||||
|
settings:floatBackgroundColor="?android:attr/colorBackgroundFloating" />
|
||||||
|
</LinearLayout>
|
||||||
40
res/values-vi/dslv_strings.xml
Normal file
40
res/values-vi/dslv_strings.xml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- Slim lockscreen shortcuts -->
|
||||||
|
<string name="shortcut_action_none">Không</string>
|
||||||
|
<string name="shortcut_action_longpress">Nhấn giữ:</string>
|
||||||
|
<string name="shortcut_action_select_action_longpress">Chọn một hành động khi chạm giữ:</string>
|
||||||
|
<string name="shortcut_action_select_action">Chọn hành động:</string>
|
||||||
|
<string name="shortcut_action_select_action_newaction">Chọn hành động mới:</string>
|
||||||
|
<string name="shortcut_action_reset">Thiết lập lại</string>
|
||||||
|
<string name="shortcut_action_add">Thêm</string>
|
||||||
|
<string name="shortcut_action_max">Đã đạt tới kích thước tối đa mục</string>
|
||||||
|
<string name="shortcut_action_warning">Khuyến cáo</string>
|
||||||
|
<string name="shortcut_action_warning_message">Không thể xóa mục sau cùng</string>
|
||||||
|
<string name="shortcut_action_disable_message">Đã tắt\nThêm một mục để kích hoạt tính năng này</string>
|
||||||
|
<string name="shortcut_image_not_valid">Các ứng dụng đã chọn không trả về một biểu tượng hợp lệ hoặc không hỗ trợ hình ảnh cắt xén. Hãy sử dụng một ứng dụng.</string>
|
||||||
|
<string name="shortcut_duplicate_entry">Các hành động đã chọn không thể được thêm vào hai lần</string>
|
||||||
|
<string name="shortcut_action_help_shortcut">phím tắt</string>
|
||||||
|
<string name="shortcut_action_help_button">phím</string>
|
||||||
|
<string name="shortcut_action_help_app">ứng dụng</string>
|
||||||
|
<string name="shortcut_action_help_icon">, trong khi lựa chọn biểu tượng sẽ hiện tùy chọn</string>
|
||||||
|
<string name="shortcut_action_help_main">Để thêm một %1$s, hãy chọn biểu tượng Thêm. Một khi một %1$s được thêm, chọn hàng sẽ thay đổi đối tượng%2$s\n\nĐể gỡ bỏ một %1$s, vuốt theo chiều ngang sang trái hoặc phảii. Để gọi lại một %1$s trong danh sách bằng cách kéo theo chiều dọc neo bên trái.\n\nĐể xóa hoặc thiết lập lại về mặc định, chọn biểu tượng Thiết lập lại.</string>
|
||||||
|
<string name="shortcut_action_help_delete_last_entry">Loại bỏ mọi %1$s trong danh sách sẽ tắt tính năng hoàn toàn.</string>
|
||||||
|
<string name="shortcut_action_help_pie_second_layer_delete_last_entry">Loại bỏ mọi %1$s trong danh sách sẽ tắt tính năng hoàn toàn.</string>
|
||||||
|
<string name="shortcuts_applications">Ứng dụng</string>
|
||||||
|
<string name="shortcuts_select_custom_app_title">Chọn ứng dụng tùy chỉnh</string>
|
||||||
|
<string name="shortcuts_icon_picker_type">Chọn loại biểu tượng:</string>
|
||||||
|
<string name="shortcuts_icon_default">Mặc định</string>
|
||||||
|
<string name="shortcuts_icon_custom">Bộ sưu tập</string>
|
||||||
|
<string name="reset_message">Đặt lại tất cả các mục về mặc định?</string>
|
||||||
|
<string name="help">Trợ giúp</string>
|
||||||
|
<string name="shortcut_action_app">Tuỳ chỉnh ứng dụng</string>
|
||||||
|
<string name="shortcut_action_home">Trang chủ</string>
|
||||||
|
<string name="shortcut_action_back">Quay lại</string>
|
||||||
|
<string name="shortcut_action_menu">Menu</string>
|
||||||
|
<string name="shortcut_action_ime">Mở trình chuyển đổi bàn phím</string>
|
||||||
|
<string name="shortcut_action_power_menu">Trình đơn nguồn</string>
|
||||||
|
<string name="shortcut_action_recent">Gần đây</string>
|
||||||
|
<string name="shortcut_action_power">Tắt màn hình</string>
|
||||||
|
<string name="shortcut_action_search">Tìm kiếm trong ứng dụng</string>
|
||||||
|
</resources>
|
||||||
152
res/values/dslv_arrays.xml
Normal file
152
res/values/dslv_arrays.xml
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Icon type for DSLV. -->
|
||||||
|
<string-array name="icon_types">
|
||||||
|
<item>@string/shortcuts_icon_default</item>
|
||||||
|
<!--
|
||||||
|
<item>@string/shortcuts_icon_presets</item>
|
||||||
|
-->
|
||||||
|
<item>@string/shortcuts_icon_custom</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="shortcut_icon_picker_labels">
|
||||||
|
<!--
|
||||||
|
<item>@string/shortcuts_icon_picker_alarm</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_andy</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_battery</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_browser</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_calendar</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_camera</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_cloud</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_contact</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_directdial</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_directmessage</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_drive</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_dropbox</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_email</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_email2</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_evernote</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_facebook</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_favorite</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_file_browser</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_file_browser2</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_fitness</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_gallery</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_gears</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_google_small</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_gplus</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_gtalk</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_help</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_joystick</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_key</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_laptop</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_luggage</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_maps</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_market</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_movie</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_music</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_nav</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_notes</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_package</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_phone</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_pinterest</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_play</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_pocket</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_quicksettings</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_rss</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_sdcard</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_search</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_sms</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_tasks</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_terminal</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_transit</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_tv</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_twitter</item>
|
||||||
|
<item>@string/shortcuts_icon_picker_unlock</item>
|
||||||
|
-->
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="shortcut_icon_picker_icons" translatable="false">
|
||||||
|
<!--
|
||||||
|
<item>@*android:drawable/ic_shortcut_alarm</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_andy</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_battery</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_browser</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_calendar</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_camera</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_cloud</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_contact</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_directdial</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_directmessage</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_drive</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_dropbox</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_email</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_email2</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_evernote</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_facebook</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_favorite</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_file_browser</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_file_browser2</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_fitness</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_gallery</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_gear</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_google_small</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_gplus</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_gtalk</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_help</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_joystick</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_key</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_laptop</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_luggage</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_maps</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_market</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_movie</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_music</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_nav</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_notes</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_package</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_phone</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_pinterest</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_play</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_pocket</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_quicksettings</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_rss</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_sdcard</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_search</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_sms</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_tasks</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_terminal</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_transit</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_tv</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_twitter</item>
|
||||||
|
<item>@*android:drawable/ic_shortcut_unlock</item>
|
||||||
|
-->
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="shortcut_action_entries">
|
||||||
|
<item>@string/shortcut_action_back</item>-
|
||||||
|
<item>@string/shortcut_action_app</item>-
|
||||||
|
<item>@string/shortcut_action_home</item>-
|
||||||
|
<item>@string/shortcut_action_menu</item>
|
||||||
|
<item>@string/shortcut_action_ime</item>
|
||||||
|
<item>@string/shortcut_action_power_menu</item>
|
||||||
|
<item>@string/shortcut_action_recent</item>
|
||||||
|
<item>@string/shortcut_action_power</item>
|
||||||
|
<item>@string/shortcut_action_search</item>
|
||||||
|
<item>@string/shortcut_action_none</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="shortcut_action_values" translatable="false">
|
||||||
|
<item>**back**</item>
|
||||||
|
<item>**app**</item>
|
||||||
|
<item>**home**</item>
|
||||||
|
<item>**menu_big**</item>
|
||||||
|
<item>**ime**</item>
|
||||||
|
<item>**power_menu**</item>
|
||||||
|
<item>**recents**</item>
|
||||||
|
<item>**power**</item>
|
||||||
|
<item>**search**</item>
|
||||||
|
<item>**null**</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
</resources>
|
||||||
32
res/values/dslv_attrs.xml
Normal file
32
res/values/dslv_attrs.xml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- For DSLV -->
|
||||||
|
<declare-styleable name="DragSortListView">
|
||||||
|
<attr name="collapsedHeight" format="dimension" />
|
||||||
|
<attr name="dragScrollStart" format="float" />
|
||||||
|
<attr name="maxDragScrollSpeed" format="float" />
|
||||||
|
<attr name="floatBackgroundColor" format="color" />
|
||||||
|
<attr name="removeMode">
|
||||||
|
<enum name="clickRemove" value="0" />
|
||||||
|
<enum name="flingRemove" value="1" />
|
||||||
|
</attr>
|
||||||
|
<attr name="trackDragSort" format="boolean"/>
|
||||||
|
<attr name="floatAlpha" format="float"/>
|
||||||
|
<attr name="slideShuffleSpeed" format="float"/>
|
||||||
|
<attr name="removeAnimationDuration" format="integer"/>
|
||||||
|
<attr name="dropAnimationDuration" format="integer"/>
|
||||||
|
<attr name="dragEnabled" format="boolean" />
|
||||||
|
<attr name="sortEnabled" format="boolean" />
|
||||||
|
<attr name="removeEnabled" format="boolean" />
|
||||||
|
<attr name="dragStartMode">
|
||||||
|
<enum name="onDown" value="0" />
|
||||||
|
<enum name="onMove" value="1" />
|
||||||
|
<enum name="onLongPress" value="2"/>
|
||||||
|
</attr>
|
||||||
|
<attr name="dragHandleId" format="integer" />
|
||||||
|
<attr name="flingHandleId" format="integer" />
|
||||||
|
<attr name="clickRemoveId" format="integer" />
|
||||||
|
<attr name="useDefaultController" format="boolean" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
</resources>
|
||||||
21
res/values/dslv_ids.xml
Normal file
21
res/values/dslv_ids.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
**
|
||||||
|
** Copyright 2014, 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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
<resources>
|
||||||
|
<item type="id" name="drag_handle" />
|
||||||
|
</resources>
|
||||||
42
res/values/dslv_strings.xml
Normal file
42
res/values/dslv_strings.xml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Slim lockscreen shortcuts -->
|
||||||
|
<string name="shortcut_action_none">None</string>
|
||||||
|
<string name="shortcut_action_longpress">Longpress:</string>
|
||||||
|
<string name="shortcut_action_select_action_longpress">Choose longpress action:</string>
|
||||||
|
<string name="shortcut_action_select_action">Choose action:</string>
|
||||||
|
<string name="shortcut_action_select_action_newaction">Choose new action:</string>
|
||||||
|
<string name="shortcut_action_reset">Reset</string>
|
||||||
|
<string name="shortcut_action_add">Add</string>
|
||||||
|
<string name="shortcut_action_max">Maximum entries size has been reached</string>
|
||||||
|
<string name="shortcut_action_warning">Warning</string>
|
||||||
|
<string name="shortcut_action_warning_message">It is not possible to delete last entry</string>
|
||||||
|
<string name="shortcut_action_disable_message">Disabled\nAdd an entry to enable this feature</string>
|
||||||
|
<string name="shortcut_image_not_valid">The chosen app did not return a valid icon or does not support image cropping. Use another app.</string>
|
||||||
|
<string name="shortcut_duplicate_entry">The chosen action cannot be added twice</string>
|
||||||
|
<string name="shortcut_action_help_shortcut">shortcut</string>
|
||||||
|
<string name="shortcut_action_help_button">button</string>
|
||||||
|
<string name="shortcut_action_help_app">app</string>
|
||||||
|
<string name="shortcut_action_help_icon">, while selecting the icon will bring up customization options</string>
|
||||||
|
<string name="shortcut_action_help_main">To add a %1$s, select the Add icon. Once a %1$s is added, selecting the row will change the target%2$s\n\nTo remove a %1$s, swipe the row horizontally left or right. Re-order a %1$s in the list by vertically dragging the anchor on the left.\n\nTo clear or reset to defaults, select the Reset icon.</string>
|
||||||
|
<string name="shortcut_action_help_delete_last_entry">Removing every %1$s in the list will disable the feature entirely.</string>
|
||||||
|
<string name="shortcut_action_help_pie_second_layer_delete_last_entry">Removing every %1$s in the list will disable the second pie layer entirely.</string>
|
||||||
|
<string name="shortcuts_applications">Applications</string>
|
||||||
|
<string name="shortcuts_select_custom_app_title">Select custom application</string>
|
||||||
|
<string name="shortcuts_icon_picker_type">Select icon type:</string>
|
||||||
|
<string name="shortcuts_icon_default">Default</string>
|
||||||
|
<string name="shortcuts_icon_custom">Gallery</string>
|
||||||
|
<string name="reset_message">Reset all entries to default?</string>
|
||||||
|
<string name="help">Help</string>
|
||||||
|
<string name="shortcut_action_app">Custom app</string>
|
||||||
|
<string name="shortcut_action_home">Home</string>
|
||||||
|
<string name="shortcut_action_back">Back</string>
|
||||||
|
<string name="shortcut_action_menu">Menu</string>
|
||||||
|
<string name="shortcut_action_ime">Open IME Switcher</string>
|
||||||
|
<string name="shortcut_action_power_menu">Power menu</string>
|
||||||
|
<string name="shortcut_action_recent">Recents</string>
|
||||||
|
<string name="shortcut_action_power">Screen Off</string>
|
||||||
|
<string name="shortcut_action_search">Search in app</string>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 SlimRoms 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.cherish.settings.preferences;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.Intent.ShortcutIconResource;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
|
||||||
|
import com.android.internal.util.slim.AppHelper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class SlimShortcutPickerHelper {
|
||||||
|
|
||||||
|
public static final int REQUEST_PICK_SHORTCUT = 100;
|
||||||
|
public static final int REQUEST_PICK_APPLICATION = 101;
|
||||||
|
public static final int REQUEST_CREATE_SHORTCUT = 102;
|
||||||
|
|
||||||
|
private Activity mParent;
|
||||||
|
private OnPickListener mListener;
|
||||||
|
private PackageManager mPackageManager;
|
||||||
|
private int lastFragmentId;
|
||||||
|
|
||||||
|
public interface OnPickListener {
|
||||||
|
void shortcutPicked(String uri, String friendlyName, Bitmap bmp, boolean isApplication);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlimShortcutPickerHelper(Activity parent, OnPickListener listener) {
|
||||||
|
mParent = parent;
|
||||||
|
mPackageManager = mParent.getPackageManager();
|
||||||
|
mListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
|
switch (requestCode) {
|
||||||
|
case REQUEST_PICK_APPLICATION:
|
||||||
|
completeSetCustomApp(data);
|
||||||
|
break;
|
||||||
|
case REQUEST_CREATE_SHORTCUT:
|
||||||
|
completeSetCustomShortcut(data);
|
||||||
|
break;
|
||||||
|
case REQUEST_PICK_SHORTCUT:
|
||||||
|
processShortcut(data, REQUEST_PICK_APPLICATION, REQUEST_CREATE_SHORTCUT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pickShortcut(int fragmentId) {
|
||||||
|
pickShortcut(fragmentId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pickShortcut(int fragmentId, boolean fullAppsOnly) {
|
||||||
|
lastFragmentId = fragmentId;
|
||||||
|
|
||||||
|
if (fullAppsOnly) {
|
||||||
|
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||||
|
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||||
|
|
||||||
|
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
|
||||||
|
pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
|
||||||
|
startFragmentOrActivity(pickIntent, REQUEST_PICK_APPLICATION);
|
||||||
|
} else {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
|
||||||
|
ArrayList<String> shortcutNames = new ArrayList<String>();
|
||||||
|
shortcutNames.add(mParent.getString(R.string.shortcuts_applications));
|
||||||
|
bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames);
|
||||||
|
|
||||||
|
ArrayList<ShortcutIconResource> shortcutIcons = new ArrayList<ShortcutIconResource>();
|
||||||
|
shortcutIcons.add(ShortcutIconResource.fromContext(mParent,
|
||||||
|
android.R.drawable.sym_def_app_icon));
|
||||||
|
bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons);
|
||||||
|
|
||||||
|
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
|
||||||
|
pickIntent.putExtra(Intent.EXTRA_INTENT, new Intent(Intent.ACTION_CREATE_SHORTCUT));
|
||||||
|
pickIntent.putExtra(Intent.EXTRA_TITLE, mParent.getText(
|
||||||
|
R.string.shortcuts_select_custom_app_title));
|
||||||
|
pickIntent.putExtras(bundle);
|
||||||
|
startFragmentOrActivity(pickIntent, REQUEST_PICK_SHORTCUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startFragmentOrActivity(Intent pickIntent, int requestCode) {
|
||||||
|
if (lastFragmentId == 0) {
|
||||||
|
mParent.startActivityForResult(pickIntent, requestCode);
|
||||||
|
} else {
|
||||||
|
Fragment cFrag = mParent.getFragmentManager().findFragmentById(lastFragmentId);
|
||||||
|
if (cFrag != null) {
|
||||||
|
mParent.startActivityFromFragment(cFrag, pickIntent, requestCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processShortcut(Intent intent,
|
||||||
|
int requestCodeApplication, int requestCodeShortcut) {
|
||||||
|
// Handle case where user selected "Applications"
|
||||||
|
String applicationName = mParent.getResources().getString(R.string.shortcuts_applications);
|
||||||
|
String shortcutName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
|
||||||
|
|
||||||
|
if (applicationName != null && applicationName.equals(shortcutName)) {
|
||||||
|
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||||
|
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||||
|
|
||||||
|
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
|
||||||
|
pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
|
||||||
|
startFragmentOrActivity(pickIntent, requestCodeApplication);
|
||||||
|
} else {
|
||||||
|
startFragmentOrActivity(intent, requestCodeShortcut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void completeSetCustomApp(Intent data) {
|
||||||
|
mListener.shortcutPicked(data.toUri(0),
|
||||||
|
AppHelper.getFriendlyActivityName(mParent, mPackageManager, data, false), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void completeSetCustomShortcut(Intent data) {
|
||||||
|
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
|
||||||
|
/* preserve shortcut name, we want to restore it later */
|
||||||
|
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, data.getStringExtra(
|
||||||
|
Intent.EXTRA_SHORTCUT_NAME));
|
||||||
|
String appUri = intent.toUri(0);
|
||||||
|
appUri = appUri.replaceAll("com.android.contacts.action.QUICK_CONTACT",
|
||||||
|
"android.intent.action.VIEW");
|
||||||
|
|
||||||
|
// Check if icon is present
|
||||||
|
Bitmap bmp = null;
|
||||||
|
Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
|
||||||
|
if (extra != null && extra instanceof Bitmap) {
|
||||||
|
bmp = (Bitmap) extra;
|
||||||
|
}
|
||||||
|
// No icon till now check if icon resource is present
|
||||||
|
if (bmp == null) {
|
||||||
|
extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
|
||||||
|
if (extra != null && extra instanceof Intent.ShortcutIconResource) {
|
||||||
|
try {
|
||||||
|
Intent.ShortcutIconResource iconResource = (ShortcutIconResource) extra;
|
||||||
|
Resources resources =
|
||||||
|
mPackageManager.getResourcesForApplication(iconResource.packageName);
|
||||||
|
final int id = resources.getIdentifier(iconResource.resourceName, null, null);
|
||||||
|
bmp = BitmapFactory.decodeResource(resources, id);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mListener.shortcutPicked(appUri,
|
||||||
|
AppHelper.getFriendlyShortcutName(mParent, mPackageManager, intent), bmp, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,983 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Slimroms
|
||||||
|
* Copyright (C) 2015-2017 Android Ice Cold 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.cherish.settings.preferences.dslv;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.DialogFragment;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.app.FragmentManager;
|
||||||
|
import android.app.ListFragment;
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.provider.MediaStore;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.AdapterView.OnItemClickListener;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.android.internal.util.slim.ActionConfig;
|
||||||
|
import com.android.internal.util.slim.ActionConstants;
|
||||||
|
import com.android.internal.util.slim.ActionHelper;
|
||||||
|
import com.android.internal.util.slim.ImageHelper;
|
||||||
|
import com.android.internal.util.slim.DeviceUtils;
|
||||||
|
import com.android.internal.util.slim.DeviceUtils.FilteredDeviceFeaturesArray;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.cherish.settings.preferences.SlimShortcutPickerHelper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class ActionListViewSettings extends ListFragment implements
|
||||||
|
SlimShortcutPickerHelper.OnPickListener {
|
||||||
|
|
||||||
|
private static final int DLG_SHOW_ACTION_DIALOG = 0;
|
||||||
|
private static final int DLG_SHOW_ICON_PICKER = 1;
|
||||||
|
private static final int DLG_DELETION_NOT_ALLOWED = 2;
|
||||||
|
private static final int DLG_SHOW_HELP_SCREEN = 3;
|
||||||
|
private static final int DLG_RESET_TO_DEFAULT = 4;
|
||||||
|
|
||||||
|
private static final int MENU_HELP = Menu.FIRST;
|
||||||
|
private static final int MENU_ADD = MENU_HELP + 1;
|
||||||
|
private static final int MENU_RESET = MENU_ADD + 1;
|
||||||
|
|
||||||
|
private static final int NAV_BAR = 0;
|
||||||
|
private static final int PIE = 1;
|
||||||
|
private static final int PIE_SECOND = 2;
|
||||||
|
private static final int NAV_RING = 3;
|
||||||
|
private static final int LOCKSCREEN_SHORTCUT = 4;
|
||||||
|
private static final int POWER_MENU_SHORTCUT = 5;
|
||||||
|
private static final int SHAKE_EVENTS_DISABLED = 6;
|
||||||
|
private static final int RECENT_APP_SIDEBAR = 7;
|
||||||
|
|
||||||
|
private static final int DEFAULT_MAX_ACTION_NUMBER = 5;
|
||||||
|
|
||||||
|
public static final int REQUEST_PICK_CUSTOM_ICON = 1000;
|
||||||
|
|
||||||
|
private int mActionMode;
|
||||||
|
private int mMaxAllowedActions;
|
||||||
|
private boolean mUseAppPickerOnly;
|
||||||
|
private boolean mUseFullAppsOnly;
|
||||||
|
private boolean mDisableLongpress;
|
||||||
|
private boolean mDisableIconPicker;
|
||||||
|
private boolean mDisableDeleteLastEntry;
|
||||||
|
|
||||||
|
private TextView mDisableMessage;
|
||||||
|
|
||||||
|
private ActionConfigsAdapter mActionConfigsAdapter;
|
||||||
|
|
||||||
|
private ArrayList<ActionConfig> mActionConfigs;
|
||||||
|
private ActionConfig mActionConfig;
|
||||||
|
|
||||||
|
private boolean mAdditionalFragmentAttached;
|
||||||
|
private String mAdditionalFragment;
|
||||||
|
private View mDivider;
|
||||||
|
|
||||||
|
private int mPendingIndex = -1;
|
||||||
|
private boolean mPendingLongpress;
|
||||||
|
private boolean mPendingNewAction;
|
||||||
|
|
||||||
|
private String[] mActionDialogValues;
|
||||||
|
private String[] mActionDialogEntries;
|
||||||
|
private String mActionValuesKey;
|
||||||
|
private String mActionEntriesKey;
|
||||||
|
|
||||||
|
private Activity mActivity;
|
||||||
|
private SlimShortcutPickerHelper mPicker;
|
||||||
|
|
||||||
|
private File mImageTmp;
|
||||||
|
|
||||||
|
private DragSortListView.DropListener onDrop =
|
||||||
|
new DragSortListView.DropListener() {
|
||||||
|
@Override
|
||||||
|
public void drop(int from, int to) {
|
||||||
|
ActionConfig item = mActionConfigsAdapter.getItem(from);
|
||||||
|
|
||||||
|
mActionConfigsAdapter.remove(item);
|
||||||
|
mActionConfigsAdapter.insert(item, to);
|
||||||
|
|
||||||
|
setConfig(mActionConfigs, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private DragSortListView.RemoveListener onRemove =
|
||||||
|
new DragSortListView.RemoveListener() {
|
||||||
|
@Override
|
||||||
|
public void remove(int which) {
|
||||||
|
ActionConfig item = mActionConfigsAdapter.getItem(which);
|
||||||
|
mActionConfigsAdapter.remove(item);
|
||||||
|
if (mDisableDeleteLastEntry && mActionConfigs.size() == 0) {
|
||||||
|
mActionConfigsAdapter.add(item);
|
||||||
|
showDialogInner(DLG_DELETION_NOT_ALLOWED, 0, false, false);
|
||||||
|
} else {
|
||||||
|
deleteIconFileIfPresent(item, true);
|
||||||
|
setConfig(mActionConfigs, false);
|
||||||
|
if (mActionConfigs.size() == 0) {
|
||||||
|
showDisableMessage(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
|
||||||
|
return inflater.inflate(R.layout.dslv_action_list_view_main, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Activity activity) {
|
||||||
|
super.onAttach(activity);
|
||||||
|
mActivity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
Resources res = getResources();
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
// Tell Lint these arrays are used
|
||||||
|
int unused = R.array.shortcut_action_values;
|
||||||
|
unused = R.array.shortcut_action_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
mActionMode = getArguments().getInt("actionMode", NAV_BAR);
|
||||||
|
mMaxAllowedActions = getArguments().getInt("maxAllowedActions", DEFAULT_MAX_ACTION_NUMBER);
|
||||||
|
mAdditionalFragment = getArguments().getString("fragment", null);
|
||||||
|
mActionValuesKey = getArguments().getString("actionValues", "shortcut_action_values");
|
||||||
|
mActionEntriesKey = getArguments().getString("actionEntries", "shortcut_action_entries");
|
||||||
|
mDisableLongpress = getArguments().getBoolean("disableLongpress", false);
|
||||||
|
mUseAppPickerOnly = getArguments().getBoolean("useAppPickerOnly", false);
|
||||||
|
mUseFullAppsOnly = getArguments().getBoolean("useOnlyFullAppPicker", false);
|
||||||
|
mDisableIconPicker = getArguments().getBoolean("disableIconPicker", false);
|
||||||
|
mDisableDeleteLastEntry = getArguments().getBoolean("disableDeleteLastEntry", false);
|
||||||
|
|
||||||
|
mDisableMessage = (TextView) view.findViewById(R.id.disable_message);
|
||||||
|
|
||||||
|
FilteredDeviceFeaturesArray finalActionDialogArray = new FilteredDeviceFeaturesArray();
|
||||||
|
finalActionDialogArray = DeviceUtils.filterUnsupportedDeviceFeatures(mActivity,
|
||||||
|
res.getStringArray(res.getIdentifier(
|
||||||
|
mActionValuesKey, "array", "com.android.settings")),
|
||||||
|
res.getStringArray(res.getIdentifier(
|
||||||
|
mActionEntriesKey, "array", "com.android.settings")));
|
||||||
|
mActionDialogValues = finalActionDialogArray.values;
|
||||||
|
mActionDialogEntries = finalActionDialogArray.entries;
|
||||||
|
|
||||||
|
mPicker = new SlimShortcutPickerHelper(mActivity, this);
|
||||||
|
|
||||||
|
mImageTmp = new File(mActivity.getCacheDir()
|
||||||
|
+ File.separator + "shortcut.tmp");
|
||||||
|
|
||||||
|
DragSortListView listView = (DragSortListView) getListView();
|
||||||
|
|
||||||
|
listView.setDropListener(onDrop);
|
||||||
|
listView.setRemoveListener(onRemove);
|
||||||
|
|
||||||
|
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
|
||||||
|
long arg3) {
|
||||||
|
if (mUseFullAppsOnly) {
|
||||||
|
if (mPicker != null) {
|
||||||
|
mPendingIndex = arg2;
|
||||||
|
mPendingLongpress = false;
|
||||||
|
mPendingNewAction = false;
|
||||||
|
mPicker.pickShortcut(getId(), true);
|
||||||
|
}
|
||||||
|
} else if (!mUseAppPickerOnly) {
|
||||||
|
showDialogInner(DLG_SHOW_ACTION_DIALOG, arg2, false, false);
|
||||||
|
} else {
|
||||||
|
if (mPicker != null) {
|
||||||
|
mPendingIndex = arg2;
|
||||||
|
mPendingLongpress = false;
|
||||||
|
mPendingNewAction = false;
|
||||||
|
mPicker.pickShortcut(getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!mDisableLongpress) {
|
||||||
|
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
|
||||||
|
long arg3) {
|
||||||
|
if (mUseFullAppsOnly) {
|
||||||
|
if (mPicker != null) {
|
||||||
|
mPendingIndex = arg2;
|
||||||
|
mPendingLongpress = true;
|
||||||
|
mPendingNewAction = false;
|
||||||
|
mPicker.pickShortcut(getId(), true);
|
||||||
|
}
|
||||||
|
} else if (!mUseAppPickerOnly) {
|
||||||
|
showDialogInner(DLG_SHOW_ACTION_DIALOG, arg2, true, false);
|
||||||
|
} else {
|
||||||
|
if (mPicker != null) {
|
||||||
|
mPendingIndex = arg2;
|
||||||
|
mPendingLongpress = true;
|
||||||
|
mPendingNewAction = false;
|
||||||
|
mPicker.pickShortcut(getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
mActionConfigs = getConfig();
|
||||||
|
|
||||||
|
if (mActionConfigs != null) {
|
||||||
|
mActionConfigsAdapter = new ActionConfigsAdapter(mActivity, mActionConfigs);
|
||||||
|
setListAdapter(mActionConfigsAdapter);
|
||||||
|
showDisableMessage(mActionConfigs.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
mDivider = (View) view.findViewById(R.id.divider);
|
||||||
|
loadAdditionalFragment();
|
||||||
|
|
||||||
|
// get shared preference
|
||||||
|
SharedPreferences preferences =
|
||||||
|
mActivity.getSharedPreferences("dslv_settings", Activity.MODE_PRIVATE);
|
||||||
|
if (!preferences.getBoolean("first_help_shown_mode_" + mActionMode, false)) {
|
||||||
|
preferences.edit()
|
||||||
|
.putBoolean("first_help_shown_mode_" + mActionMode, true).commit();
|
||||||
|
showDialogInner(DLG_SHOW_HELP_SCREEN, 0, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
setHasOptionsMenu(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
if (mAdditionalFragmentAttached) {
|
||||||
|
FragmentManager fragmentManager = getFragmentManager();
|
||||||
|
Fragment fragment = fragmentManager.findFragmentById(R.id.fragment_container);
|
||||||
|
if (fragment != null && !fragmentManager.isDestroyed()) {
|
||||||
|
fragmentManager.beginTransaction().remove(fragment).commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadAdditionalFragment() {
|
||||||
|
if (mAdditionalFragment != null && !mAdditionalFragment.isEmpty()) {
|
||||||
|
try {
|
||||||
|
Class<?> classAdditionalFragment = Class.forName(mAdditionalFragment);
|
||||||
|
Fragment fragment = (Fragment) classAdditionalFragment.newInstance();
|
||||||
|
getFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.fragment_container, fragment).commit();
|
||||||
|
if (mDivider != null) {
|
||||||
|
mDivider.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
mAdditionalFragmentAttached = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
mAdditionalFragmentAttached = false;
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shortcutPicked(String action,
|
||||||
|
String description, Bitmap bmp, boolean isApplication) {
|
||||||
|
if (mPendingIndex == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bmp != null && !mPendingLongpress) {
|
||||||
|
// Icon is present, save it for future use and add the file path to the action.
|
||||||
|
String fileName = mActivity.getFilesDir()
|
||||||
|
+ File.separator + "shortcut_" + System.currentTimeMillis() + ".png";
|
||||||
|
try {
|
||||||
|
FileOutputStream out = new FileOutputStream(fileName);
|
||||||
|
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||||
|
out.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
action = action + "?hasExtraIcon=" + fileName;
|
||||||
|
File image = new File(fileName);
|
||||||
|
image.setReadable(true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mPendingNewAction) {
|
||||||
|
addNewAction(action, description);
|
||||||
|
} else {
|
||||||
|
updateAction(action, description, null, mPendingIndex, mPendingLongpress);
|
||||||
|
}
|
||||||
|
mPendingLongpress = false;
|
||||||
|
mPendingNewAction = false;
|
||||||
|
mPendingIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
|
if (requestCode == SlimShortcutPickerHelper.REQUEST_PICK_SHORTCUT
|
||||||
|
|| requestCode == SlimShortcutPickerHelper.REQUEST_PICK_APPLICATION
|
||||||
|
|| requestCode == SlimShortcutPickerHelper.REQUEST_CREATE_SHORTCUT) {
|
||||||
|
mPicker.onActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
|
} else if (requestCode == REQUEST_PICK_CUSTOM_ICON && mPendingIndex != -1) {
|
||||||
|
if (mImageTmp.length() == 0 || !mImageTmp.exists()) {
|
||||||
|
mPendingIndex = -1;
|
||||||
|
Toast.makeText(mActivity,
|
||||||
|
getResources().getString(R.string.shortcut_image_not_valid),
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
File image = new File(mActivity.getFilesDir() + File.separator
|
||||||
|
+ "shortcut_" + System.currentTimeMillis() + ".png");
|
||||||
|
String path = image.getAbsolutePath();
|
||||||
|
mImageTmp.renameTo(image);
|
||||||
|
image.setReadable(true, false);
|
||||||
|
updateAction(null, null, path, mPendingIndex, false);
|
||||||
|
mPendingIndex = -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mImageTmp.exists()) {
|
||||||
|
mImageTmp.delete();
|
||||||
|
}
|
||||||
|
mPendingLongpress = false;
|
||||||
|
mPendingNewAction = false;
|
||||||
|
mPendingIndex = -1;
|
||||||
|
}
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAction(String action, String description, String icon,
|
||||||
|
int which, boolean longpress) {
|
||||||
|
|
||||||
|
if (!longpress && checkForDuplicateMainNavActions(action)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionConfig actionConfig = mActionConfigsAdapter.getItem(which);
|
||||||
|
mActionConfigsAdapter.remove(actionConfig);
|
||||||
|
|
||||||
|
if (!longpress) {
|
||||||
|
deleteIconFileIfPresent(actionConfig, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (icon != null) {
|
||||||
|
actionConfig.setIcon(icon);
|
||||||
|
} else {
|
||||||
|
if (longpress) {
|
||||||
|
actionConfig.setLongpressAction(action);
|
||||||
|
actionConfig.setLongpressActionDescription(description);
|
||||||
|
} else {
|
||||||
|
deleteIconFileIfPresent(actionConfig, true);
|
||||||
|
actionConfig.setClickAction(action);
|
||||||
|
actionConfig.setClickActionDescription(description);
|
||||||
|
actionConfig.setIcon(ActionConstants.ICON_EMPTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mActionConfigsAdapter.insert(actionConfig, which);
|
||||||
|
showDisableMessage(false);
|
||||||
|
setConfig(mActionConfigs, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkForDuplicateMainNavActions(String action) {
|
||||||
|
ActionConfig actionConfig;
|
||||||
|
for (int i = 0; i < mActionConfigs.size(); i++) {
|
||||||
|
actionConfig = mActionConfigsAdapter.getItem(i);
|
||||||
|
if (actionConfig.getClickAction().equals(action)) {
|
||||||
|
Toast.makeText(mActivity,
|
||||||
|
getResources().getString(R.string.shortcut_duplicate_entry),
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteIconFileIfPresent(ActionConfig action, boolean deleteShortCutIcon) {
|
||||||
|
File oldImage = new File(action.getIcon());
|
||||||
|
if (oldImage.exists()) {
|
||||||
|
oldImage.delete();
|
||||||
|
}
|
||||||
|
oldImage = new File(action.getClickAction().replaceAll(".*?hasExtraIcon=", ""));
|
||||||
|
if (oldImage.exists() && deleteShortCutIcon) {
|
||||||
|
oldImage.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDisableMessage(boolean show) {
|
||||||
|
if (mDisableMessage == null || mDisableDeleteLastEntry) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (show) {
|
||||||
|
mDisableMessage.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
mDisableMessage.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case MENU_ADD:
|
||||||
|
if (mActionConfigs.size() == mMaxAllowedActions) {
|
||||||
|
Toast.makeText(mActivity,
|
||||||
|
getResources().getString(R.string.shortcut_action_max),
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (mUseFullAppsOnly) {
|
||||||
|
if (mPicker != null) {
|
||||||
|
mPendingIndex = 0;
|
||||||
|
mPendingLongpress = false;
|
||||||
|
mPendingNewAction = true;
|
||||||
|
mPicker.pickShortcut(getId(), true);
|
||||||
|
}
|
||||||
|
} else if (!mUseAppPickerOnly) {
|
||||||
|
showDialogInner(DLG_SHOW_ACTION_DIALOG, 0, false, true);
|
||||||
|
} else {
|
||||||
|
if (mPicker != null) {
|
||||||
|
mPendingIndex = 0;
|
||||||
|
mPendingLongpress = false;
|
||||||
|
mPendingNewAction = true;
|
||||||
|
mPicker.pickShortcut(getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MENU_RESET:
|
||||||
|
showDialogInner(DLG_RESET_TO_DEFAULT, 0, false, true);
|
||||||
|
break;
|
||||||
|
case MENU_HELP:
|
||||||
|
showDialogInner(DLG_SHOW_HELP_SCREEN, 0, false, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
|
menu.add(0, MENU_HELP, 0, R.string.help)
|
||||||
|
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||||
|
menu.add(0, MENU_RESET, 0, R.string.shortcut_action_reset)
|
||||||
|
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||||
|
menu.add(0, MENU_ADD, 0, R.string.shortcut_action_add)
|
||||||
|
.setIcon(R.drawable.ic_menu_add)
|
||||||
|
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addNewAction(String action, String description) {
|
||||||
|
if (checkForDuplicateMainNavActions(action)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ActionConfig actionConfig = new ActionConfig(
|
||||||
|
action, description,
|
||||||
|
ActionConstants.ACTION_NULL, getResources().getString(R.string.shortcut_action_none),
|
||||||
|
ActionConstants.ICON_EMPTY);
|
||||||
|
|
||||||
|
mActionConfigsAdapter.add(actionConfig);
|
||||||
|
showDisableMessage(false);
|
||||||
|
setConfig(mActionConfigs, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<ActionConfig> getConfig() {
|
||||||
|
switch (mActionMode) {
|
||||||
|
/* Disabled for now till all features are back. Enable it step per step!!!!!!
|
||||||
|
case LOCKSCREEN_SHORTCUT:
|
||||||
|
return ActionHelper.getLockscreenShortcutConfig(mActivity);
|
||||||
|
case NAV_BAR:
|
||||||
|
return ActionHelper.getNavBarConfigWithDescription(
|
||||||
|
mActivity, mActionValuesKey, mActionEntriesKey);
|
||||||
|
case NAV_RING:
|
||||||
|
return ActionHelper.getNavRingConfigWithDescription(
|
||||||
|
mActivity, mActionValuesKey, mActionEntriesKey);
|
||||||
|
case PIE:
|
||||||
|
return ActionHelper.getPieConfigWithDescription(
|
||||||
|
mActivity, mActionValuesKey, mActionEntriesKey);
|
||||||
|
case PIE_SECOND:
|
||||||
|
return ActionHelper.getPieSecondLayerConfigWithDescription(
|
||||||
|
mActivity, mActionValuesKey, mActionEntriesKey);
|
||||||
|
case POWER_MENU_SHORTCUT:
|
||||||
|
return PolicyHelper.getPowerMenuConfigWithDescription(
|
||||||
|
mActivity, mActionValuesKey, mActionEntriesKey);
|
||||||
|
case SHAKE_EVENTS_DISABLED:
|
||||||
|
return ActionHelper.getDisabledShakeApps(mActivity);
|
||||||
|
*/
|
||||||
|
case RECENT_APP_SIDEBAR:
|
||||||
|
return ActionHelper.getRecentAppSidebarConfigWithDescription(
|
||||||
|
mActivity, mActionValuesKey, mActionEntriesKey);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setConfig(ArrayList<ActionConfig> actionConfigs, boolean reset) {
|
||||||
|
switch (mActionMode) {
|
||||||
|
/* Disabled for now till all features are back. Enable it step per step!!!!!!
|
||||||
|
case LOCKSCREEN_SHORTCUT:
|
||||||
|
ActionHelper.setLockscreenShortcutConfig(mActivity, actionConfigs, reset);
|
||||||
|
break;
|
||||||
|
case NAV_BAR:
|
||||||
|
ActionHelper.setNavBarConfig(mActivity, actionConfigs, reset);
|
||||||
|
break;
|
||||||
|
case NAV_RING:
|
||||||
|
ActionHelper.setNavRingConfig(mActivity, actionConfigs, reset);
|
||||||
|
break;
|
||||||
|
case PIE:
|
||||||
|
ActionHelper.setPieConfig(mActivity, actionConfigs, reset);
|
||||||
|
break;
|
||||||
|
case PIE_SECOND:
|
||||||
|
ActionHelper.setPieSecondLayerConfig(mActivity, actionConfigs, reset);
|
||||||
|
break;
|
||||||
|
case POWER_MENU_SHORTCUT:
|
||||||
|
PolicyHelper.setPowerMenuConfig(mActivity, actionConfigs, reset);
|
||||||
|
break;
|
||||||
|
case SHAKE_EVENTS_DISABLED:
|
||||||
|
ActionHelper.setDisabledShakeApps(mActivity, actionConfigs, reset);
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
case RECENT_APP_SIDEBAR:
|
||||||
|
ActionHelper.setRecentAppSidebarConfig(mActivity, actionConfigs, reset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ViewHolder {
|
||||||
|
public TextView longpressActionDescriptionView;
|
||||||
|
public ImageView iconView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ActionConfigsAdapter extends ArrayAdapter<ActionConfig> {
|
||||||
|
|
||||||
|
private int mIconColor;
|
||||||
|
|
||||||
|
public ActionConfigsAdapter(Context context, List<ActionConfig> clickActionDescriptions) {
|
||||||
|
super(context, R.layout.dslv_action_list_view_item,
|
||||||
|
R.id.click_action_description, clickActionDescriptions);
|
||||||
|
|
||||||
|
// Themed resources
|
||||||
|
int[] attrs = new int[] {
|
||||||
|
android.R.attr.textColorPrimary,
|
||||||
|
};
|
||||||
|
TypedArray ta = context.getTheme().obtainStyledAttributes(attrs);
|
||||||
|
mIconColor = ta.getColor(0, 0xff808080);
|
||||||
|
ta.recycle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||||
|
View v = super.getView(position, convertView, parent);
|
||||||
|
|
||||||
|
if (v != convertView && v != null) {
|
||||||
|
ViewHolder holder = new ViewHolder();
|
||||||
|
|
||||||
|
TextView longpressActionDecription =
|
||||||
|
(TextView) v.findViewById(R.id.longpress_action_description);
|
||||||
|
ImageView icon = (ImageView) v.findViewById(R.id.icon);
|
||||||
|
|
||||||
|
if (mDisableLongpress) {
|
||||||
|
longpressActionDecription.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
holder.longpressActionDescriptionView = longpressActionDecription;
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.iconView = icon;
|
||||||
|
|
||||||
|
v.setTag(holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewHolder holder = (ViewHolder) v.getTag();
|
||||||
|
|
||||||
|
if (!mDisableLongpress) {
|
||||||
|
holder.longpressActionDescriptionView.setText(
|
||||||
|
getResources().getString(R.string.shortcut_action_longpress)
|
||||||
|
+ " " + getItem(position).getLongpressActionDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
Drawable d = null;
|
||||||
|
String iconUri = getItem(position).getIcon();
|
||||||
|
if (mActionMode == POWER_MENU_SHORTCUT) {
|
||||||
|
/* Disabled for now till slims power menu is back!!!!!!!!!!!!!!
|
||||||
|
d = ImageHelper.resize(
|
||||||
|
mActivity, PolicyHelper.getPowerMenuIconImage(mActivity,
|
||||||
|
getItem(position).getClickAction(),
|
||||||
|
iconUri, false), 36); */
|
||||||
|
} else {
|
||||||
|
d = ImageHelper.resize(
|
||||||
|
mActivity, ActionHelper.getActionIconImage(mActivity,
|
||||||
|
getItem(position).getClickAction(),
|
||||||
|
iconUri), 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iconUri != null && iconUri.startsWith(ActionConstants.SYSTEM_ICON_IDENTIFIER)) {
|
||||||
|
d.setTint(mIconColor);
|
||||||
|
}
|
||||||
|
holder.iconView.setImageDrawable(d);
|
||||||
|
|
||||||
|
if (!mDisableIconPicker && holder.iconView.getDrawable() != null) {
|
||||||
|
holder.iconView.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
mPendingIndex = position;
|
||||||
|
showDialogInner(DLG_SHOW_ICON_PICKER, 0, false, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDialogInner(int id, int which, boolean longpress, boolean newAction) {
|
||||||
|
DialogFragment newFragment =
|
||||||
|
MyAlertDialogFragment.newInstance(id, which, longpress, newAction);
|
||||||
|
newFragment.setTargetFragment(this, 0);
|
||||||
|
newFragment.show(getFragmentManager(), "dialog " + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MyAlertDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
|
private int mIconColor;
|
||||||
|
|
||||||
|
public static MyAlertDialogFragment newInstance(int id,
|
||||||
|
int which, boolean longpress, boolean newAction) {
|
||||||
|
MyAlertDialogFragment frag = new MyAlertDialogFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putInt("id", id);
|
||||||
|
args.putInt("which", which);
|
||||||
|
args.putBoolean("longpress", longpress);
|
||||||
|
args.putBoolean("newAction", newAction);
|
||||||
|
frag.setArguments(args);
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionListViewSettings getOwner() {
|
||||||
|
return (ActionListViewSettings) getTargetFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
int id = getArguments().getInt("id");
|
||||||
|
final int which = getArguments().getInt("which");
|
||||||
|
final boolean longpress = getArguments().getBoolean("longpress");
|
||||||
|
final boolean newAction = getArguments().getBoolean("newAction");
|
||||||
|
switch (id) {
|
||||||
|
case DLG_RESET_TO_DEFAULT:
|
||||||
|
return new AlertDialog.Builder(getActivity())
|
||||||
|
.setTitle(R.string.shortcut_action_reset)
|
||||||
|
.setMessage(R.string.reset_message)
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.setPositiveButton(R.string.ok,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
// first delete custom icons in case they exist
|
||||||
|
ArrayList<ActionConfig> actionConfigs = getOwner().getConfig();
|
||||||
|
for (int i = 0; i < actionConfigs.size(); i++) {
|
||||||
|
getOwner().deleteIconFileIfPresent(actionConfigs.get(i), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset provider values and action adapter to default
|
||||||
|
getOwner().setConfig(null, true);
|
||||||
|
getOwner().mActionConfigsAdapter.clear();
|
||||||
|
|
||||||
|
// Add the new default objects fetched from @getConfig()
|
||||||
|
actionConfigs = getOwner().getConfig();
|
||||||
|
final int newConfigsSize = actionConfigs.size();
|
||||||
|
for (int i = 0; i < newConfigsSize; i++) {
|
||||||
|
getOwner().mActionConfigsAdapter.add(actionConfigs.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// dirty helper if actionConfigs list has no entries
|
||||||
|
// to proper update the content. .notifyDatSetChanged()
|
||||||
|
// does not work in this case.
|
||||||
|
if (newConfigsSize == 0) {
|
||||||
|
ActionConfig emptyAction =
|
||||||
|
new ActionConfig(null, null, null, null, null);
|
||||||
|
getOwner().mActionConfigsAdapter.add(emptyAction);
|
||||||
|
getOwner().mActionConfigsAdapter.remove(emptyAction);
|
||||||
|
}
|
||||||
|
getOwner().showDisableMessage(newConfigsSize == 0);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
case DLG_SHOW_HELP_SCREEN:
|
||||||
|
Resources res = getResources();
|
||||||
|
String finalHelpMessage;
|
||||||
|
String actionMode;
|
||||||
|
String icon = "";
|
||||||
|
switch (getOwner().mActionMode) {
|
||||||
|
case LOCKSCREEN_SHORTCUT:
|
||||||
|
case POWER_MENU_SHORTCUT:
|
||||||
|
actionMode = res.getString(R.string.shortcut_action_help_shortcut);
|
||||||
|
break;
|
||||||
|
case SHAKE_EVENTS_DISABLED:
|
||||||
|
actionMode = res.getString(R.string.shortcut_action_help_app);
|
||||||
|
break;
|
||||||
|
case NAV_BAR:
|
||||||
|
case NAV_RING:
|
||||||
|
case PIE:
|
||||||
|
case PIE_SECOND:
|
||||||
|
case RECENT_APP_SIDEBAR:
|
||||||
|
default:
|
||||||
|
actionMode = res.getString(R.string.shortcut_action_help_button);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!getOwner().mDisableIconPicker) {
|
||||||
|
icon = res.getString(R.string.shortcut_action_help_icon);
|
||||||
|
}
|
||||||
|
finalHelpMessage = res.getString(
|
||||||
|
R.string.shortcut_action_help_main, actionMode, icon);
|
||||||
|
if (!getOwner().mDisableDeleteLastEntry) {
|
||||||
|
finalHelpMessage += " " + res.getString(
|
||||||
|
getOwner().mActionMode == PIE_SECOND
|
||||||
|
? R.string.shortcut_action_help_pie_second_layer_delete_last_entry
|
||||||
|
: R.string.shortcut_action_help_delete_last_entry, actionMode);
|
||||||
|
}
|
||||||
|
return new AlertDialog.Builder(getActivity())
|
||||||
|
.setTitle(R.string.help)
|
||||||
|
.setMessage(finalHelpMessage)
|
||||||
|
.setNegativeButton(R.string.ok,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
case DLG_DELETION_NOT_ALLOWED:
|
||||||
|
return new AlertDialog.Builder(getActivity())
|
||||||
|
.setTitle(R.string.shortcut_action_warning)
|
||||||
|
.setMessage(R.string.shortcut_action_warning_message)
|
||||||
|
.setNegativeButton(R.string.ok,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
case DLG_SHOW_ACTION_DIALOG:
|
||||||
|
int title;
|
||||||
|
if (longpress) {
|
||||||
|
title = R.string.shortcut_action_select_action_longpress;
|
||||||
|
} else if (newAction) {
|
||||||
|
title = R.string.shortcut_action_select_action_newaction;
|
||||||
|
} else {
|
||||||
|
title = R.string.shortcut_action_select_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for normal press action we filter out null value
|
||||||
|
// due it does not make sense to set a null action
|
||||||
|
// on normal press action
|
||||||
|
String[] values = null;
|
||||||
|
String[] entries = null;
|
||||||
|
if (!longpress) {
|
||||||
|
List<String> finalEntriesList = new ArrayList<String>();
|
||||||
|
List<String> finalValuesList = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (int i = 0; i < getOwner().mActionDialogValues.length; i++) {
|
||||||
|
if (!getOwner().mActionDialogValues[i]
|
||||||
|
.equals(ActionConstants.ACTION_NULL)) {
|
||||||
|
finalEntriesList.add(getOwner().mActionDialogEntries[i]);
|
||||||
|
finalValuesList.add(getOwner().mActionDialogValues[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entries = finalEntriesList.toArray(new String[finalEntriesList.size()]);
|
||||||
|
values = finalValuesList.toArray(new String[finalValuesList.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String[] finalDialogValues =
|
||||||
|
longpress ? getOwner().mActionDialogValues : values;
|
||||||
|
final String[] finalDialogEntries =
|
||||||
|
longpress ? getOwner().mActionDialogEntries : entries;
|
||||||
|
|
||||||
|
return new AlertDialog.Builder(getActivity())
|
||||||
|
.setTitle(title)
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.setItems(finalDialogEntries,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int item) {
|
||||||
|
if (finalDialogValues[item].equals(ActionConstants.ACTION_APP)) {
|
||||||
|
if (getOwner().mPicker != null) {
|
||||||
|
getOwner().mPendingIndex = which;
|
||||||
|
getOwner().mPendingLongpress = longpress;
|
||||||
|
getOwner().mPendingNewAction = newAction;
|
||||||
|
getOwner().mPicker.pickShortcut(getOwner().getId());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (newAction) {
|
||||||
|
getOwner().addNewAction(finalDialogValues[item],
|
||||||
|
finalDialogEntries[item]);
|
||||||
|
} else {
|
||||||
|
getOwner().updateAction(finalDialogValues[item],
|
||||||
|
finalDialogEntries[item],
|
||||||
|
null, which, longpress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
case DLG_SHOW_ICON_PICKER:
|
||||||
|
return new AlertDialog.Builder(getActivity())
|
||||||
|
.setTitle(R.string.shortcuts_icon_picker_type)
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.setItems(R.array.icon_types,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
switch(which) {
|
||||||
|
case 0: // Default
|
||||||
|
getOwner().updateAction(null, null,
|
||||||
|
ActionConstants.ICON_EMPTY,
|
||||||
|
getOwner().mPendingIndex, false);
|
||||||
|
getOwner().mPendingIndex = -1;
|
||||||
|
break;
|
||||||
|
case 1: // System defaults
|
||||||
|
/*
|
||||||
|
ListView list = new ListView(getActivity());
|
||||||
|
list.setAdapter(new IconAdapter(mIconColor));
|
||||||
|
final Dialog holoDialog = new Dialog(getActivity());
|
||||||
|
holoDialog.setTitle(
|
||||||
|
R.string.shortcuts_icon_picker_choose_icon_title);
|
||||||
|
holoDialog.setContentView(list);
|
||||||
|
list.setOnItemClickListener(new OnItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> parent, View view,
|
||||||
|
int position, long id) {
|
||||||
|
IconAdapter adapter = (IconAdapter) parent.getAdapter();
|
||||||
|
getOwner().updateAction(null, null,
|
||||||
|
adapter.getItemReference(position),
|
||||||
|
getOwner().mPendingIndex, false);
|
||||||
|
getOwner().mPendingIndex = -1;
|
||||||
|
holoDialog.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
holoDialog.show();
|
||||||
|
break;
|
||||||
|
case 2: // Custom user icon
|
||||||
|
*/
|
||||||
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
|
||||||
|
intent.setType("image/*");
|
||||||
|
intent.putExtra("crop", "true");
|
||||||
|
intent.putExtra("scale", true);
|
||||||
|
intent.putExtra("outputFormat",
|
||||||
|
Bitmap.CompressFormat.PNG.toString());
|
||||||
|
intent.putExtra("aspectX", 100);
|
||||||
|
intent.putExtra("aspectY", 100);
|
||||||
|
intent.putExtra("outputX", 100);
|
||||||
|
intent.putExtra("outputY", 100);
|
||||||
|
try {
|
||||||
|
getOwner().mImageTmp.createNewFile();
|
||||||
|
getOwner().mImageTmp.setWritable(true, false);
|
||||||
|
intent.putExtra(MediaStore.EXTRA_OUTPUT,
|
||||||
|
Uri.fromFile(getOwner().mImageTmp));
|
||||||
|
intent.putExtra("return-data", false);
|
||||||
|
getOwner().startActivityForResult(
|
||||||
|
intent, REQUEST_PICK_CUSTOM_ICON);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("unknown id " + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IconAdapter extends BaseAdapter {
|
||||||
|
|
||||||
|
TypedArray icons;
|
||||||
|
String[] labels;
|
||||||
|
int color;
|
||||||
|
|
||||||
|
public IconAdapter(int iconColor) {
|
||||||
|
labels = getResources().getStringArray(R.array.shortcut_icon_picker_labels);
|
||||||
|
icons = getResources().obtainTypedArray(R.array.shortcut_icon_picker_icons);
|
||||||
|
color = iconColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getItem(int position) {
|
||||||
|
return icons.getDrawable(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return labels.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getItemReference(int position) {
|
||||||
|
String name = icons.getString(position);
|
||||||
|
int separatorIndex = name.lastIndexOf(File.separator);
|
||||||
|
int periodIndex = name.lastIndexOf('.');
|
||||||
|
return ActionConstants.SYSTEM_ICON_IDENTIFIER
|
||||||
|
+ name.substring(separatorIndex + 1, periodIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
View iView = convertView;
|
||||||
|
if (convertView == null) {
|
||||||
|
iView = View.inflate(getActivity(), android.R.layout.simple_list_item_1, null);
|
||||||
|
}
|
||||||
|
TextView tt = (TextView) iView.findViewById(android.R.id.text1);
|
||||||
|
tt.setText(labels[position]);
|
||||||
|
Drawable ic = ((Drawable) getItem(position)).mutate();
|
||||||
|
ic.setTint(color);
|
||||||
|
tt.setCompoundDrawablePadding(15);
|
||||||
|
tt.setCompoundDrawablesWithIntrinsicBounds(ic, null, null, null);
|
||||||
|
return iView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,488 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 Carl Bauer
|
||||||
|
* Copyright (C) 2014 SlimRoms 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.cherish.settings.preferences.dslv;
|
||||||
|
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.view.GestureDetector;
|
||||||
|
import android.view.HapticFeedbackConstants;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewConfiguration;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that starts and stops item drags on a {@link DragSortListView}
|
||||||
|
* based on touch gestures. This class also inherits from
|
||||||
|
* {@link SimpleFloatViewManager}, which provides basic float View
|
||||||
|
* creation.
|
||||||
|
*
|
||||||
|
* An instance of this class is meant to be passed to the methods
|
||||||
|
* {@link DragSortListView#setTouchListener()} and
|
||||||
|
* {@link DragSortListView#setFloatViewManager()} of your
|
||||||
|
* {@link DragSortListView} instance.
|
||||||
|
*/
|
||||||
|
public class DragSortController extends SimpleFloatViewManager
|
||||||
|
implements View.OnTouchListener, GestureDetector.OnGestureListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drag init mode enum.
|
||||||
|
*/
|
||||||
|
public static final int ON_DOWN = 0;
|
||||||
|
public static final int ON_DRAG = 1;
|
||||||
|
public static final int ON_LONG_PRESS = 2;
|
||||||
|
|
||||||
|
private int mDragInitMode = ON_DOWN;
|
||||||
|
|
||||||
|
private boolean mSortEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove mode enum.
|
||||||
|
*/
|
||||||
|
public static final int CLICK_REMOVE = 0;
|
||||||
|
public static final int FLING_REMOVE = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current remove mode.
|
||||||
|
*/
|
||||||
|
private int mRemoveMode;
|
||||||
|
|
||||||
|
private boolean mRemoveEnabled = false;
|
||||||
|
private boolean mIsRemoving = false;
|
||||||
|
|
||||||
|
private GestureDetector mDetector;
|
||||||
|
|
||||||
|
private GestureDetector mFlingRemoveDetector;
|
||||||
|
|
||||||
|
private int mTouchSlop;
|
||||||
|
|
||||||
|
public static final int MISS = -1;
|
||||||
|
|
||||||
|
private int mHitPos = MISS;
|
||||||
|
private int mFlingHitPos = MISS;
|
||||||
|
|
||||||
|
private int mClickRemoveHitPos = MISS;
|
||||||
|
|
||||||
|
private int[] mTempLoc = new int[2];
|
||||||
|
|
||||||
|
private int mItemX;
|
||||||
|
private int mItemY;
|
||||||
|
|
||||||
|
private int mCurrX;
|
||||||
|
private int mCurrY;
|
||||||
|
|
||||||
|
private boolean mDragging = false;
|
||||||
|
|
||||||
|
private float mFlingSpeed = 500f;
|
||||||
|
|
||||||
|
private int mDragHandleId;
|
||||||
|
|
||||||
|
private int mClickRemoveId;
|
||||||
|
|
||||||
|
private int mFlingHandleId;
|
||||||
|
private boolean mCanDrag;
|
||||||
|
|
||||||
|
private DragSortListView mDslv;
|
||||||
|
private int mPositionX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link #DragSortController(DragSortListView, int)} with a
|
||||||
|
* 0 drag handle id, FLING_RIGHT_REMOVE remove mode,
|
||||||
|
* and ON_DOWN drag init. By default, sorting is enabled, and
|
||||||
|
* removal is disabled.
|
||||||
|
*
|
||||||
|
* @param dslv The DSLV instance
|
||||||
|
*/
|
||||||
|
public DragSortController(DragSortListView dslv) {
|
||||||
|
this(dslv, 0, ON_DOWN, FLING_REMOVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DragSortController(DragSortListView dslv,
|
||||||
|
int dragHandleId, int dragInitMode, int removeMode) {
|
||||||
|
this(dslv, dragHandleId, dragInitMode, removeMode, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DragSortController(DragSortListView dslv, int dragHandleId,
|
||||||
|
int dragInitMode, int removeMode, int clickRemoveId) {
|
||||||
|
this(dslv, dragHandleId, dragInitMode, removeMode, clickRemoveId, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, sorting is enabled, and removal is disabled.
|
||||||
|
*
|
||||||
|
* @param dslv The DSLV instance
|
||||||
|
* @param dragHandleId The resource id of the View that represents
|
||||||
|
* the drag handle in a list item.
|
||||||
|
*/
|
||||||
|
public DragSortController(DragSortListView dslv, int dragHandleId, int dragInitMode,
|
||||||
|
int removeMode, int clickRemoveId, int flingHandleId) {
|
||||||
|
super(dslv);
|
||||||
|
mDslv = dslv;
|
||||||
|
mDetector = new GestureDetector(dslv.getContext(), this);
|
||||||
|
mFlingRemoveDetector = new GestureDetector(dslv.getContext(), mFlingRemoveListener);
|
||||||
|
mFlingRemoveDetector.setIsLongpressEnabled(false);
|
||||||
|
mTouchSlop = ViewConfiguration.get(dslv.getContext()).getScaledTouchSlop();
|
||||||
|
mDragHandleId = dragHandleId;
|
||||||
|
mClickRemoveId = clickRemoveId;
|
||||||
|
mFlingHandleId = flingHandleId;
|
||||||
|
setRemoveMode(removeMode);
|
||||||
|
setDragInitMode(dragInitMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getDragInitMode() {
|
||||||
|
return mDragInitMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set how a drag is initiated. Needs to be one of
|
||||||
|
* {@link ON_DOWN}, {@link ON_DRAG}, or {@link ON_LONG_PRESS}.
|
||||||
|
*
|
||||||
|
* @param mode The drag init mode.
|
||||||
|
*/
|
||||||
|
public void setDragInitMode(int mode) {
|
||||||
|
mDragInitMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/Disable list item sorting. Disabling is useful if only item
|
||||||
|
* removal is desired. Prevents drags in the vertical direction.
|
||||||
|
*
|
||||||
|
* @param enabled Set <code>true</code> to enable list
|
||||||
|
* item sorting.
|
||||||
|
*/
|
||||||
|
public void setSortEnabled(boolean enabled) {
|
||||||
|
mSortEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSortEnabled() {
|
||||||
|
return mSortEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One of {@link CLICK_REMOVE}, {@link FLING_RIGHT_REMOVE},
|
||||||
|
* {@link FLING_LEFT_REMOVE},
|
||||||
|
* {@link SLIDE_RIGHT_REMOVE}, or {@link SLIDE_LEFT_REMOVE}.
|
||||||
|
*/
|
||||||
|
public void setRemoveMode(int mode) {
|
||||||
|
mRemoveMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRemoveMode() {
|
||||||
|
return mRemoveMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/Disable item removal without affecting remove mode.
|
||||||
|
*/
|
||||||
|
public void setRemoveEnabled(boolean enabled) {
|
||||||
|
mRemoveEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRemoveEnabled() {
|
||||||
|
return mRemoveEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the resource id for the View that represents the drag
|
||||||
|
* handle in a list item.
|
||||||
|
*
|
||||||
|
* @param id An android resource id.
|
||||||
|
*/
|
||||||
|
public void setDragHandleId(int id) {
|
||||||
|
mDragHandleId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the resource id for the View that represents the fling
|
||||||
|
* handle in a list item.
|
||||||
|
*
|
||||||
|
* @param id An android resource id.
|
||||||
|
*/
|
||||||
|
public void setFlingHandleId(int id) {
|
||||||
|
mFlingHandleId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the resource id for the View that represents click
|
||||||
|
* removal button.
|
||||||
|
*
|
||||||
|
* @param id An android resource id.
|
||||||
|
*/
|
||||||
|
public void setClickRemoveId(int id) {
|
||||||
|
mClickRemoveId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets flags to restrict certain motions of the floating View
|
||||||
|
* based on DragSortController settings (such as remove mode).
|
||||||
|
* Starts the drag on the DragSortListView.
|
||||||
|
*
|
||||||
|
* @param position The list item position (includes headers).
|
||||||
|
* @param deltaX Touch x-coord minus left edge of floating View.
|
||||||
|
* @param deltaY Touch y-coord minus top edge of floating View.
|
||||||
|
*
|
||||||
|
* @return True if drag started, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean startDrag(int position, int deltaX, int deltaY) {
|
||||||
|
|
||||||
|
int dragFlags = 0;
|
||||||
|
if (mSortEnabled && !mIsRemoving) {
|
||||||
|
dragFlags |= DragSortListView.DRAG_POS_Y | DragSortListView.DRAG_NEG_Y;
|
||||||
|
}
|
||||||
|
if (mRemoveEnabled && mIsRemoving) {
|
||||||
|
dragFlags |= DragSortListView.DRAG_POS_X;
|
||||||
|
dragFlags |= DragSortListView.DRAG_NEG_X;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDragging = mDslv.startDrag(position - mDslv.getHeaderViewsCount(), dragFlags, deltaX,
|
||||||
|
deltaY);
|
||||||
|
return mDragging;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent ev) {
|
||||||
|
if (!mDslv.isDragEnabled() || mDslv.listViewIntercepted()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDetector.onTouchEvent(ev);
|
||||||
|
if (mRemoveEnabled && mDragging && mRemoveMode == FLING_REMOVE) {
|
||||||
|
mFlingRemoveDetector.onTouchEvent(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
int action = ev.getAction() & MotionEvent.ACTION_MASK;
|
||||||
|
switch (action) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
mCurrX = (int) ev.getX();
|
||||||
|
mCurrY = (int) ev.getY();
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
if (mRemoveEnabled && mIsRemoving) {
|
||||||
|
int x = mPositionX >= 0 ? mPositionX : -mPositionX;
|
||||||
|
int removePoint = mDslv.getWidth() / 2;
|
||||||
|
if (x > removePoint) {
|
||||||
|
mDslv.stopDragWithVelocity(true, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
mIsRemoving = false;
|
||||||
|
mDragging = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides to provide fading when slide removal is enabled.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onDragFloatView(View floatView, Point position, Point touch) {
|
||||||
|
|
||||||
|
if (mRemoveEnabled && mIsRemoving) {
|
||||||
|
mPositionX = position.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the position to start dragging based on the ACTION_DOWN
|
||||||
|
* MotionEvent. This function simply calls
|
||||||
|
* {@link #dragHandleHitPosition(MotionEvent)}. Override
|
||||||
|
* to change drag handle behavior;
|
||||||
|
* this function is called internally when an ACTION_DOWN
|
||||||
|
* event is detected.
|
||||||
|
*
|
||||||
|
* @param ev The ACTION_DOWN MotionEvent.
|
||||||
|
*
|
||||||
|
* @return The list position to drag if a drag-init gesture is
|
||||||
|
* detected; MISS if unsuccessful.
|
||||||
|
*/
|
||||||
|
public int startDragPosition(MotionEvent ev) {
|
||||||
|
return dragHandleHitPosition(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int startFlingPosition(MotionEvent ev) {
|
||||||
|
return mRemoveMode == FLING_REMOVE ? flingHandleHitPosition(ev) : MISS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for the touch of an item's drag handle (specified by
|
||||||
|
* {@link #setDragHandleId(int)}), and returns that item's position
|
||||||
|
* if a drag handle touch was detected.
|
||||||
|
*
|
||||||
|
* @param ev The ACTION_DOWN MotionEvent.
|
||||||
|
|
||||||
|
* @return The list position of the item whose drag handle was
|
||||||
|
* touched; MISS if unsuccessful.
|
||||||
|
*/
|
||||||
|
public int dragHandleHitPosition(MotionEvent ev) {
|
||||||
|
return viewIdHitPosition(ev, mDragHandleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int flingHandleHitPosition(MotionEvent ev) {
|
||||||
|
return viewIdHitPosition(ev, mFlingHandleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int viewIdHitPosition(MotionEvent ev, int id) {
|
||||||
|
final int x = (int) ev.getX();
|
||||||
|
final int y = (int) ev.getY();
|
||||||
|
|
||||||
|
int touchPos = mDslv.pointToPosition(x, y); // includes headers/footers
|
||||||
|
|
||||||
|
final int numHeaders = mDslv.getHeaderViewsCount();
|
||||||
|
final int numFooters = mDslv.getFooterViewsCount();
|
||||||
|
final int count = mDslv.getCount();
|
||||||
|
|
||||||
|
// Log.d("mobeta", "touch down on position " + itemnum);
|
||||||
|
// We're only interested if the touch was on an
|
||||||
|
// item that's not a header or footer.
|
||||||
|
if (touchPos != AdapterView.INVALID_POSITION && touchPos >= numHeaders
|
||||||
|
&& touchPos < (count - numFooters)) {
|
||||||
|
final View item = mDslv.getChildAt(touchPos - mDslv.getFirstVisiblePosition());
|
||||||
|
final int rawX = (int) ev.getRawX();
|
||||||
|
final int rawY = (int) ev.getRawY();
|
||||||
|
|
||||||
|
View dragBox = id == 0 ? item : (View) item.findViewById(id);
|
||||||
|
if (dragBox != null) {
|
||||||
|
dragBox.getLocationOnScreen(mTempLoc);
|
||||||
|
|
||||||
|
if (rawX > mTempLoc[0] && rawY > mTempLoc[1] &&
|
||||||
|
rawX < mTempLoc[0] + dragBox.getWidth() &&
|
||||||
|
rawY < mTempLoc[1] + dragBox.getHeight()) {
|
||||||
|
|
||||||
|
mItemX = item.getLeft();
|
||||||
|
mItemY = item.getTop();
|
||||||
|
|
||||||
|
return touchPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return MISS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onDown(MotionEvent ev) {
|
||||||
|
if (mRemoveEnabled && mRemoveMode == CLICK_REMOVE) {
|
||||||
|
mClickRemoveHitPos = viewIdHitPosition(ev, mClickRemoveId);
|
||||||
|
}
|
||||||
|
|
||||||
|
mHitPos = startDragPosition(ev);
|
||||||
|
if (mHitPos != MISS && mDragInitMode == ON_DOWN) {
|
||||||
|
startDrag(mHitPos, (int) ev.getX() - mItemX, (int) ev.getY() - mItemY);
|
||||||
|
}
|
||||||
|
|
||||||
|
mIsRemoving = false;
|
||||||
|
mCanDrag = true;
|
||||||
|
mPositionX = 0;
|
||||||
|
mFlingHitPos = startFlingPosition(ev);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||||
|
|
||||||
|
final int x1 = (int) e1.getX();
|
||||||
|
final int y1 = (int) e1.getY();
|
||||||
|
final int x2 = (int) e2.getX();
|
||||||
|
final int y2 = (int) e2.getY();
|
||||||
|
final int deltaX = x2 - mItemX;
|
||||||
|
final int deltaY = y2 - mItemY;
|
||||||
|
|
||||||
|
if (mCanDrag && !mDragging && (mHitPos != MISS || mFlingHitPos != MISS)) {
|
||||||
|
if (mHitPos != MISS) {
|
||||||
|
if (mDragInitMode == ON_DRAG && Math.abs(y2 - y1) > mTouchSlop && mSortEnabled) {
|
||||||
|
startDrag(mHitPos, deltaX, deltaY);
|
||||||
|
} else if (mDragInitMode != ON_DOWN
|
||||||
|
&& Math.abs(x2 - x1) > mTouchSlop && mRemoveEnabled) {
|
||||||
|
mIsRemoving = true;
|
||||||
|
startDrag(mFlingHitPos, deltaX, deltaY);
|
||||||
|
}
|
||||||
|
} else if (mFlingHitPos != MISS) {
|
||||||
|
if (Math.abs(x2 - x1) > mTouchSlop && mRemoveEnabled) {
|
||||||
|
mIsRemoving = true;
|
||||||
|
startDrag(mFlingHitPos, deltaX, deltaY);
|
||||||
|
} else if (Math.abs(y2 - y1) > mTouchSlop) {
|
||||||
|
mCanDrag = false; // if started to scroll the list then
|
||||||
|
// don't allow sorting nor fling-removing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// return whatever
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLongPress(MotionEvent e) {
|
||||||
|
// Log.d("mobeta", "lift listener long pressed");
|
||||||
|
if (mHitPos != MISS && mDragInitMode == ON_LONG_PRESS) {
|
||||||
|
mDslv.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||||
|
startDrag(mHitPos, mCurrX - mItemX, mCurrY - mItemY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// complete the OnGestureListener interface
|
||||||
|
@Override
|
||||||
|
public final boolean onFling(MotionEvent e1,
|
||||||
|
MotionEvent e2, float velocityX, float velocityY) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// complete the OnGestureListener interface
|
||||||
|
@Override
|
||||||
|
public boolean onSingleTapUp(MotionEvent ev) {
|
||||||
|
if (mRemoveEnabled && mRemoveMode == CLICK_REMOVE) {
|
||||||
|
if (mClickRemoveHitPos != MISS) {
|
||||||
|
mDslv.removeItem(mClickRemoveHitPos - mDslv.getHeaderViewsCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// complete the OnGestureListener interface
|
||||||
|
@Override
|
||||||
|
public void onShowPress(MotionEvent ev) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
private GestureDetector.OnGestureListener mFlingRemoveListener =
|
||||||
|
new GestureDetector.SimpleOnGestureListener() {
|
||||||
|
@Override
|
||||||
|
public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
|
||||||
|
float velocityY) {
|
||||||
|
// Log.d("mobeta", "on fling remove called");
|
||||||
|
if (mRemoveEnabled && mIsRemoving) {
|
||||||
|
int w = mDslv.getWidth();
|
||||||
|
int minPos = w / 5;
|
||||||
|
if (velocityX > mFlingSpeed) {
|
||||||
|
if (mPositionX > -minPos) {
|
||||||
|
mDslv.stopDragWithVelocity(true, velocityX);
|
||||||
|
}
|
||||||
|
} else if (velocityX < -mFlingSpeed) {
|
||||||
|
if (mPositionX < minPos) {
|
||||||
|
mDslv.stopDragWithVelocity(true, velocityX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mIsRemoving = false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
118
src/com/cherish/settings/preferences/dslv/DragSortItemView.java
Normal file
118
src/com/cherish/settings/preferences/dslv/DragSortItemView.java
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 Carl Bauer
|
||||||
|
* Copyright (C) 2014 SlimRoms 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.cherish.settings.preferences.dslv;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.MeasureSpec;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AbsListView;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lightweight ViewGroup that wraps list items obtained from user's
|
||||||
|
* ListAdapter. ItemView expects a single child that has a definite
|
||||||
|
* height (i.e. the child's layout height is not MATCH_PARENT).
|
||||||
|
* The width of
|
||||||
|
* ItemView will always match the width of its child (that is,
|
||||||
|
* the width MeasureSpec given to ItemView is passed directly
|
||||||
|
* to the child, and the ItemView measured width is set to the
|
||||||
|
* child's measured width). The height of ItemView can be anything;
|
||||||
|
* the
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* The purpose of this class is to optimize slide
|
||||||
|
* shuffle animations.
|
||||||
|
*/
|
||||||
|
public class DragSortItemView extends ViewGroup {
|
||||||
|
|
||||||
|
private int mGravity = Gravity.TOP;
|
||||||
|
|
||||||
|
public DragSortItemView(Context context) {
|
||||||
|
super(context);
|
||||||
|
|
||||||
|
// always init with standard ListView layout params
|
||||||
|
setLayoutParams(new AbsListView.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.FILL_PARENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
|
//setClipChildren(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGravity(int gravity) {
|
||||||
|
mGravity = gravity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGravity() {
|
||||||
|
return mGravity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||||
|
final View child = getChildAt(0);
|
||||||
|
|
||||||
|
if (child == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mGravity == Gravity.TOP) {
|
||||||
|
child.layout(0, 0, getMeasuredWidth(), child.getMeasuredHeight());
|
||||||
|
} else {
|
||||||
|
child.layout(0, getMeasuredHeight() - child.getMeasuredHeight(),
|
||||||
|
getMeasuredWidth(), getMeasuredHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
|
||||||
|
int height = MeasureSpec.getSize(heightMeasureSpec);
|
||||||
|
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||||
|
|
||||||
|
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||||
|
|
||||||
|
final View child = getChildAt(0);
|
||||||
|
if (child == null) {
|
||||||
|
setMeasuredDimension(0, width);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child.isLayoutRequested()) {
|
||||||
|
// Always let child be as tall as it wants.
|
||||||
|
measureChild(child, widthMeasureSpec,
|
||||||
|
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (heightMode == MeasureSpec.UNSPECIFIED) {
|
||||||
|
ViewGroup.LayoutParams lp = getLayoutParams();
|
||||||
|
|
||||||
|
if (lp.height > 0) {
|
||||||
|
height = lp.height;
|
||||||
|
} else {
|
||||||
|
height = child.getMeasuredHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setMeasuredDimension(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
3067
src/com/cherish/settings/preferences/dslv/DragSortListView.java
Normal file
3067
src/com/cherish/settings/preferences/dslv/DragSortListView.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 Carl Bauer
|
||||||
|
* Copyright (C) 2014 SlimRoms 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.cherish.settings.preferences.dslv;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple implementation of the FloatViewManager class. Uses list
|
||||||
|
* items as they appear in the ListView to create the floating View.
|
||||||
|
*/
|
||||||
|
public class SimpleFloatViewManager implements DragSortListView.FloatViewManager {
|
||||||
|
|
||||||
|
private Bitmap mFloatBitmap;
|
||||||
|
|
||||||
|
private ImageView mImageView;
|
||||||
|
|
||||||
|
private int mFloatBGColor = Color.BLACK;
|
||||||
|
|
||||||
|
private ListView mListView;
|
||||||
|
|
||||||
|
public SimpleFloatViewManager(ListView lv) {
|
||||||
|
mListView = lv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackgroundColor(int color) {
|
||||||
|
mFloatBGColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This simple implementation creates a Bitmap copy of the
|
||||||
|
* list item currently shown at ListView <code>position</code>.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public View onCreateFloatView(int position) {
|
||||||
|
// Guaranteed that this will not be null? I think so. Nope, got
|
||||||
|
// a NullPointerException once...
|
||||||
|
View v = mListView.getChildAt(
|
||||||
|
position + mListView.getHeaderViewsCount() - mListView.getFirstVisiblePosition());
|
||||||
|
|
||||||
|
if (v == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.setPressed(false);
|
||||||
|
|
||||||
|
// Create a copy of the drawing cache so that it does not get
|
||||||
|
// recycled by the framework when the list tries to clean up memory
|
||||||
|
//v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
|
||||||
|
v.setDrawingCacheEnabled(true);
|
||||||
|
mFloatBitmap = Bitmap.createBitmap(v.getDrawingCache());
|
||||||
|
v.setDrawingCacheEnabled(false);
|
||||||
|
|
||||||
|
if (mImageView == null) {
|
||||||
|
mImageView = new ImageView(mListView.getContext());
|
||||||
|
}
|
||||||
|
mImageView.setBackgroundColor(mFloatBGColor);
|
||||||
|
mImageView.setPadding(0, 0, 0, 0);
|
||||||
|
mImageView.setImageBitmap(mFloatBitmap);
|
||||||
|
mImageView.setLayoutParams(new ViewGroup.LayoutParams(v.getWidth(), v.getHeight()));
|
||||||
|
|
||||||
|
return mImageView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This does nothing
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onDragFloatView(View floatView, Point position, Point touch) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the Bitmap from the ImageView created in
|
||||||
|
* onCreateFloatView() and tells the system to recycle it.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onDestroyFloatView(View floatView) {
|
||||||
|
((ImageView) floatView).setImageDrawable(null);
|
||||||
|
|
||||||
|
mFloatBitmap.recycle();
|
||||||
|
mFloatBitmap = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user