├── .gitignore ├── .idea ├── compiler.xml ├── dictionaries │ └── sty.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── library-2.4.0.jar │ └── zxing-core-3.1.0.jar └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── animation.dex │ ├── data.mp3 │ └── libstyTool.so │ ├── java │ └── nico │ │ └── styTool │ │ └── plus │ │ ├── App.java │ │ ├── BinStr.java │ │ ├── BlurBitmapUtil.java │ │ ├── Bookmark.java │ │ ├── CardView.java │ │ ├── CardViewApi21.java │ │ ├── CardViewDelegate.java │ │ ├── CardViewEclairMr1.java │ │ ├── CardViewImpl.java │ │ ├── CardViewJellybeanMr1.java │ │ ├── Constant.java │ │ ├── DBSearchHelper.java │ │ ├── DarkFrameLayout.java │ │ ├── GankIoActivity.java │ │ ├── ListShower.java │ │ ├── MainActivity.java │ │ ├── MaterialDialog.java │ │ ├── Num.java │ │ ├── On.java │ │ ├── RoundRectDrawable.java │ │ ├── RoundRectDrawableWithShadow.java │ │ ├── SearchHistorysBean.java │ │ ├── SearchHistorysDao.java │ │ └── SlideBottomPanel.java │ └── res │ ├── anim │ ├── bga_sbl_activity_backward_enter.xml │ ├── bga_sbl_activity_backward_exit.xml │ ├── bga_sbl_activity_forward_enter.xml │ ├── bga_sbl_activity_forward_exit.xml │ ├── bga_sbl_activity_swipeback_enter.xml │ ├── bga_sbl_activity_swipeback_exit.xml │ ├── window_back.xml │ └── window_out.xml │ ├── drawable-hdpi │ ├── abc_btn_radio_to_on_mtrl_000.png │ ├── abc_btn_radio_to_on_mtrl_015.png │ ├── ic_adb_white_24dp.png │ ├── ic_add_alert_white_24dp.png │ ├── ic_arrow_back_white_24dp.png │ ├── ic_edit_white_24dp.png │ ├── ic_insert_emoticon_white_24dp.png │ ├── ic_launcher.png │ ├── ic_pause_white_24dp.png │ ├── ic_photo_white_24dp.png │ ├── ic_play_arrow_white_24dp.png │ ├── ic_send_white_24dp.png │ ├── ic_stop_white_24dp.png │ ├── image.png │ ├── notification.png │ ├── wifi_automatic.png │ └── wifi_file.png │ ├── drawable-mdpi │ ├── abc_btn_radio_to_on_mtrl_000.png │ ├── abc_btn_radio_to_on_mtrl_015.png │ ├── ic_adb_white_24dp.png │ ├── ic_add_alert_white_24dp.png │ ├── ic_arrow_back_white_24dp.png │ ├── ic_edit_white_24dp.png │ ├── ic_insert_emoticon_white_24dp.png │ ├── ic_launcher.png │ ├── ic_pause_white_24dp.png │ ├── ic_photo_white_24dp.png │ ├── ic_play_arrow_white_24dp.png │ ├── ic_send_white_24dp.png │ └── ic_stop_white_24dp.png │ ├── drawable-nodpi │ ├── emoji_0030.png │ ├── emoji_0031.png │ ├── emoji_0032.png │ ├── emoji_0033.png │ ├── emoji_0034.png │ ├── emoji_0035.png │ ├── emoji_0036.png │ ├── emoji_0037.png │ ├── emoji_0038.png │ ├── emoji_0039.png │ └── emoji_26a1.png │ ├── drawable-xhdpi │ ├── abc_btn_radio_to_on_mtrl_000.png │ ├── abc_btn_radio_to_on_mtrl_015.png │ ├── ic_adb_white_24dp.png │ ├── ic_add_alert_white_24dp.png │ ├── ic_arrow_back_white_24dp.png │ ├── ic_edit_white_24dp.png │ ├── ic_insert_emoticon_white_24dp.png │ ├── ic_launcher.png │ ├── ic_pause_white_24dp.png │ ├── ic_photo_white_24dp.png │ ├── ic_play_arrow_white_24dp.png │ ├── ic_send_white_24dp.png │ └── ic_stop_white_24dp.png │ ├── drawable-xxhdpi │ ├── abc_btn_radio_to_on_mtrl_000.png │ ├── abc_btn_radio_to_on_mtrl_015.png │ ├── abc_vei.png │ ├── box_notes.png │ ├── fals.png │ ├── ic_chevron_left_black_24dp.png │ ├── ic_chevron_right_black_24dp.png │ ├── ic_http_48px.png │ ├── ic_https_48px.png │ ├── ic_menu_black_24dp.png │ ├── ic_refresh_black_24dp.png │ ├── iml_s.png │ ├── ser.png │ └── sr.png │ ├── drawable-xxxhdpi │ ├── abc_btn_radio_to_on_mtrl_000.png │ ├── abc_btn_radio_to_on_mtrl_015.png │ ├── ic_adb_white_24dp.png │ ├── ic_add_alert_white_24dp.png │ ├── ic_arrow_back_white_24dp.png │ ├── ic_edit_white_24dp.png │ ├── ic_insert_emoticon_white_24dp.png │ ├── ic_pause_white_24dp.png │ ├── ic_photo_white_24dp.png │ ├── ic_play_arrow_white_24dp.png │ ├── ic_send_white_24dp.png │ └── ic_stop_white_24dp.png │ ├── drawable │ ├── bg_button_normal.xml │ ├── bg_button_pressed.xml │ ├── bga_sbl_shadow.9.png │ ├── button.xml │ ├── cs_b.xml │ ├── material_card.xml │ └── material_dialog_window.xml │ ├── layout │ ├── a_host.xml │ ├── history.xml │ ├── historylist.xml │ ├── item_search_history_word.xml │ ├── layout_material_dialog.xml │ ├── main.xml │ ├── th.xml │ ├── ut.xml │ └── window_popup.xml │ ├── menu │ └── headmenu.xml │ ├── values │ ├── attrs.xml │ ├── attrs_circle_progressbar.xml │ ├── bga_sbl_integers.xml │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ └── ganklo.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/dictionaries/sty.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Android > Lint > Correctness 39 | 40 | 41 | Android > Lint > Correctness > Messages 42 | 43 | 44 | Android > Lint > Performance 45 | 46 | 47 | Android > Lint > Usability > Icons 48 | 49 | 50 | Control flow issuesJava 51 | 52 | 53 | Java 54 | 55 | 56 | Probable bugsJava 57 | 58 | 59 | Threading issuesJava 60 | 61 | 62 | 63 | 64 | Android 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 92 | 93 | 94 | 95 | 96 | 97 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | QQ 2284467793 2 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.1" 6 | defaultConfig { 7 | applicationId "nico.styTool.plus" 8 | minSdkVersion 9 9 | targetSdkVersion 21 10 | versionCode 6 11 | versionName "6.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile 'com.android.support:design:23.0.0' 23 | compile 'com.android.support:appcompat-v7:23.0.0' 24 | compile fileTree(dir: 'libs', include: ['*.jar']) 25 | } 26 | 27 | -------------------------------------------------------------------------------- /app/libs/library-2.4.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/libs/library-2.4.0.jar -------------------------------------------------------------------------------- /app/libs/zxing-core-3.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/libs/zxing-core-3.1.0.jar -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/assets/animation.dex: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /app/src/main/assets/data.mp3: -------------------------------------------------------------------------------- 1 | ����#�-��t2%�7�}X> ���"��1Y�a�^X*��k06���h� -------------------------------------------------------------------------------- /app/src/main/assets/libstyTool.so: -------------------------------------------------------------------------------- 1 | ?elf -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/App.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | import android.app.*; 3 | import android.content.*; 4 | 5 | public class App extends Application 6 | { 7 | 8 | public static App a(Context r2_Context) 9 | { 10 | Context r0_Context = r2_Context.getApplicationContext(); 11 | if ((r0_Context instanceof App)) 12 | { 13 | return ((App) (r0_Context)); 14 | } 15 | else 16 | { 17 | throw new IllegalArgumentException("context must be from BrowserApp"); 18 | } 19 | }} 20 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/BinStr.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | public class BinStr 4 | { 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/BlurBitmapUtil.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | import android.graphics.*; 3 | import android.content.*; 4 | import android.renderscript.*; 5 | 6 | public class BlurBitmapUtil { 7 | //图片缩放比例 8 | private static final float BITMAP_SCALE = 0.4f; 9 | 10 | /** 11 | * 模糊图片的具体方法 12 | * 13 | * @param context 上下文对象 14 | * @param image 需要模糊的图片 15 | * @return 模糊处理后的图片 16 | */ 17 | public static Bitmap blurBitmap(Context context, Bitmap image,float blurRadius) { 18 | // 计算图片缩小后的长宽 19 | int width = Math.round(image.getWidth() * BITMAP_SCALE); 20 | int height = Math.round(image.getHeight() * BITMAP_SCALE); 21 | 22 | // 将缩小后的图片做为预渲染的图片 23 | Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false); 24 | // 创建一张渲染后的输出图片 25 | Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap); 26 | 27 | // 创建RenderScript内核对象 28 | RenderScript rs = RenderScript.create(context); 29 | // 创建一个模糊效果的RenderScript的工具对象 30 | ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); 31 | 32 | // 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间 33 | // 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去 34 | Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap); 35 | Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap); 36 | 37 | // 设置渲染的模糊程度, 25f是最大模糊度 38 | blurScript.setRadius(blurRadius); 39 | // 设置blurScript对象的输入内存 40 | blurScript.setInput(tmpIn); 41 | // 将输出数据保存到输出内存中 42 | blurScript.forEach(tmpOut); 43 | 44 | // 将数据填充到Allocation中 45 | tmpOut.copyTo(outputBitmap); 46 | 47 | return outputBitmap; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/Bookmark.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | 4 | import android.app.Activity; 5 | import android.database.Cursor; 6 | import android.database.SQLException; 7 | import android.database.sqlite.SQLiteDatabase; 8 | import android.database.sqlite.SQLiteException; 9 | 10 | import java.util.ArrayList; 11 | import java.util.HashMap; 12 | 13 | 14 | public class Bookmark 15 | { 16 | private final String DBNAME="MyBookmarkDB"; 17 | private final String TABLE_NAME="mybookmark"; 18 | 19 | private SQLiteDatabase m_db=null; 20 | private ArrayList> m_list=null; 21 | 22 | public void initDB(Activity activity) 23 | { 24 | this.openMyBookmark(activity); 25 | try 26 | { 27 | m_db.execSQL("CREATE TABLE mybookmark(Title TEXT,Url TEXT)"); 28 | } 29 | catch (SQLException e) 30 | { 31 | //Log.e("BOOKMARK", e.getMessage()); 32 | } 33 | this.closeMyBookmark(); 34 | 35 | m_list = new ArrayList>(); 36 | } 37 | 38 | public void insert(final String Title, final String Url) 39 | { 40 | String sql="INSERT INTO " + TABLE_NAME + " values (\"" + Title + "\",\"" + Url + "\")"; 41 | try 42 | { 43 | m_db.execSQL(sql); 44 | } 45 | catch (SQLException e) 46 | { 47 | //Log.e("BOOKMARK", e.getMessage()); 48 | } 49 | } 50 | 51 | public ArrayList> getList() 52 | { 53 | m_list.clear(); 54 | Cursor cur = m_db.rawQuery("select * from " + TABLE_NAME, null); 55 | if (cur != null) 56 | { 57 | if (cur.moveToFirst()) 58 | { 59 | do 60 | { 61 | HashMap map=new HashMap(); 62 | map.put("Title", cur.getString(0)); 63 | map.put("Url", cur.getString(1)); 64 | m_list.add(map); 65 | 66 | }while(cur.moveToNext()); 67 | } 68 | } 69 | return m_list; 70 | } 71 | 72 | public void openMyBookmark(Activity activity) 73 | { 74 | try 75 | { 76 | m_db = activity.openOrCreateDatabase(DBNAME, 0, null); 77 | } 78 | catch (SQLiteException e) 79 | { 80 | m_db = null; 81 | } 82 | } 83 | 84 | public void closeMyBookmark() 85 | { 86 | m_db.close(); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/CardView.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Rect; 6 | import android.os.Build; 7 | import android.util.AttributeSet; 8 | import android.widget.FrameLayout; 9 | 10 | /** 11 | * A FrameLayout with a rounded corner background and shadow. 12 | *

13 | * CardView uses elevation property on L for shadows and falls back to a custom shadow 14 | * implementation on older platforms. 15 | *

16 | * Due to expensive nature of rounded corner clipping, on platforms before L, CardView does not 17 | * clip its children that intersect with rounded corners. Instead, it adds padding to avoid such 18 | * intersection (See {@link #setPreventCornerOverlap(boolean)} to change this behavior). 19 | *

20 | * Before L, CardView adds padding to its content and draws shadows to that area. This padding 21 | * amount is equal to maxCardElevation + (1 - cos45) * cornerRadius on the sides and 22 | * maxCardElevation * 1.5 + (1 - cos45) * cornerRadius on top and bottom. 23 | *

24 | * Since padding is used to offset content for shadows, you cannot set padding on CardView. 25 | * Instead, 26 | * you can use content padding attributes in XML or {@link #setContentPadding(int, int, int, int)} 27 | * in code to set the padding between the edges of the Card and children of CardView. 28 | *

29 | * Note that, if you specify exact dimensions for the CardView, because of the shadows, its content 30 | * area will be different between platforms before L and after L. By using api version specific 31 | * resource values, you can avoid these changes. Alternatively, If you want CardView to add inner 32 | * padding on platforms L and after as well, you can set {@link #setUseCompatPadding(boolean)} to 33 | * true. 34 | *

35 | * To change CardView's elevation in a backward compatible way, use 36 | * {@link #setCardElevation(float)}. CardView will use elevation API on L and before L, it will 37 | * change the shadow size. To avoid moving the View while shadow size is changing, shadow size is 38 | * clamped by {@link #getMaxCardElevation()}. If you want to change elevation dynamically, you 39 | * should call {@link #setMaxCardElevation(float)} when CardView is initialized. 40 | * 41 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardBackgroundColor 42 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardCornerRadius 43 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardElevation 44 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardMaxElevation 45 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardUseCompatPadding 46 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardPreventCornerOverlap 47 | * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPadding 48 | * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingLeft 49 | * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingTop 50 | * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingRight 51 | * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingBottom 52 | */ 53 | public class CardView extends FrameLayout implements CardViewDelegate { 54 | 55 | private static final CardViewImpl IMPL; 56 | 57 | static { 58 | if (Build.VERSION.SDK_INT >= 21) { 59 | IMPL = new CardViewApi21(); 60 | } else if (Build.VERSION.SDK_INT >= 17) { 61 | IMPL = new CardViewJellybeanMr1(); 62 | } else { 63 | IMPL = new CardViewEclairMr1(); 64 | } 65 | IMPL.initStatic(); 66 | } 67 | 68 | private boolean mCompatPadding; 69 | 70 | private boolean mPreventCornerOverlap; 71 | 72 | private final Rect mContentPadding = new Rect(); 73 | 74 | private final Rect mShadowBounds = new Rect(); 75 | 76 | 77 | public CardView(Context context) { 78 | super(context); 79 | initialize(context, null, 0); 80 | } 81 | 82 | public CardView(Context context, AttributeSet attrs) { 83 | super(context, attrs); 84 | initialize(context, attrs, 0); 85 | } 86 | 87 | public CardView(Context context, AttributeSet attrs, int defStyleAttr) { 88 | super(context, attrs, defStyleAttr); 89 | initialize(context, attrs, defStyleAttr); 90 | } 91 | 92 | @Override 93 | public void setPadding(int left, int top, int right, int bottom) { 94 | // NO OP 95 | } 96 | 97 | public void setPaddingRelative(int start, int top, int end, int bottom) { 98 | // NO OP 99 | } 100 | 101 | /** 102 | * Returns whether CardView will add inner padding on platforms L and after. 103 | * 104 | * @return True CardView adds inner padding on platforms L and after to have same dimensions 105 | * with platforms before L. 106 | */ 107 | @Override 108 | public boolean getUseCompatPadding() { 109 | return mCompatPadding; 110 | } 111 | 112 | /** 113 | * CardView adds additional padding to draw shadows on platforms before L. 114 | *

115 | * This may cause Cards to have different sizes between L and before L. If you need to align 116 | * CardView with other Views, you may need api version specific dimension resources to account 117 | * for the changes. 118 | * As an alternative, you can set this flag to true and CardView will add the same 119 | * padding values on platforms L and after. 120 | *

121 | * Since setting this flag to true adds unnecessary gaps in the UI, default value is 122 | * false. 123 | * 124 | * @param useCompatPadding True if CardView should add padding for the shadows on platforms L 125 | * and above. 126 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardUseCompatPadding 127 | */ 128 | public void setUseCompatPadding(boolean useCompatPadding) { 129 | if (mCompatPadding == useCompatPadding) { 130 | return; 131 | } 132 | mCompatPadding = useCompatPadding; 133 | IMPL.onCompatPaddingChanged(this); 134 | } 135 | 136 | /** 137 | * Sets the padding between the Card's edges and the children of CardView. 138 | *

139 | * Depending on platform version or {@link #getUseCompatPadding()} settings, CardView may 140 | * update these values before calling {@link android.view.View#setPadding(int, int, int, int)}. 141 | * 142 | * @param left The left padding in pixels 143 | * @param top The top padding in pixels 144 | * @param right The right padding in pixels 145 | * @param bottom The bottom padding in pixels 146 | * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPadding 147 | * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingLeft 148 | * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingTop 149 | * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingRight 150 | * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingBottom 151 | */ 152 | public void setContentPadding(int left, int top, int right, int bottom) { 153 | mContentPadding.set(left, top, right, bottom); 154 | IMPL.updatePadding(this); 155 | } 156 | 157 | @Override 158 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 159 | if (IMPL instanceof CardViewApi21 == false) { 160 | final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 161 | switch (widthMode) { 162 | case MeasureSpec.EXACTLY: 163 | case MeasureSpec.AT_MOST: 164 | final int minWidth = (int) Math.ceil(IMPL.getMinWidth(this)); 165 | widthMeasureSpec = MeasureSpec.makeMeasureSpec(Math.max(minWidth, 166 | MeasureSpec.getSize(widthMeasureSpec)), widthMode); 167 | break; 168 | } 169 | 170 | final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 171 | switch (heightMode) { 172 | case MeasureSpec.EXACTLY: 173 | case MeasureSpec.AT_MOST: 174 | final int minHeight = (int) Math.ceil(IMPL.getMinHeight(this)); 175 | heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.max(minHeight, 176 | MeasureSpec.getSize(heightMeasureSpec)), heightMode); 177 | break; 178 | } 179 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 180 | } else { 181 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 182 | } 183 | } 184 | 185 | private void initialize(Context context, AttributeSet attrs, int defStyleAttr) { 186 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CardView, defStyleAttr, 187 | R.style.CardView_Light); 188 | int backgroundColor = a.getColor(R.styleable.CardView_cardBackgroundColor, 0); 189 | float radius = a.getDimension(R.styleable.CardView_cardCornerRadius, 0); 190 | float elevation = a.getDimension(R.styleable.CardView_cardElevation, 0); 191 | float maxElevation = a.getDimension(R.styleable.CardView_cardMaxElevation, 0); 192 | mCompatPadding = a.getBoolean(R.styleable.CardView_cardUseCompatPadding, false); 193 | mPreventCornerOverlap = a.getBoolean(R.styleable.CardView_cardPreventCornerOverlap, true); 194 | int defaultPadding = a.getDimensionPixelSize(R.styleable.CardView_contentPadding, 0); 195 | mContentPadding.left = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingLeft, 196 | defaultPadding); 197 | mContentPadding.top = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingTop, 198 | defaultPadding); 199 | mContentPadding.right = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingRight, 200 | defaultPadding); 201 | mContentPadding.bottom = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingBottom, 202 | defaultPadding); 203 | if (elevation > maxElevation) { 204 | maxElevation = elevation; 205 | } 206 | a.recycle(); 207 | IMPL.initialize(this, context, backgroundColor, radius, elevation, maxElevation); 208 | } 209 | 210 | /** 211 | * Updates the background color of the CardView 212 | * 213 | * @param color The new color to set for the card background 214 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardBackgroundColor 215 | */ 216 | public void setCardBackgroundColor(int color) { 217 | IMPL.setBackgroundColor(this, color); 218 | } 219 | 220 | /** 221 | * Returns the inner padding after the Card's left edge 222 | * 223 | * @return the inner padding after the Card's left edge 224 | */ 225 | public int getContentPaddingLeft() { 226 | return mContentPadding.left; 227 | } 228 | 229 | /** 230 | * Returns the inner padding before the Card's right edge 231 | * 232 | * @return the inner padding before the Card's right edge 233 | */ 234 | public int getContentPaddingRight() { 235 | return mContentPadding.right; 236 | } 237 | 238 | /** 239 | * Returns the inner padding after the Card's top edge 240 | * 241 | * @return the inner padding after the Card's top edge 242 | */ 243 | public int getContentPaddingTop() { 244 | return mContentPadding.top; 245 | } 246 | 247 | /** 248 | * Returns the inner padding before the Card's bottom edge 249 | * 250 | * @return the inner padding before the Card's bottom edge 251 | */ 252 | public int getContentPaddingBottom() { 253 | return mContentPadding.bottom; 254 | } 255 | 256 | /** 257 | * Updates the corner radius of the CardView. 258 | * 259 | * @param radius The radius in pixels of the corners of the rectangle shape 260 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardCornerRadius 261 | * @see #setRadius(float) 262 | */ 263 | public void setRadius(float radius) { 264 | IMPL.setRadius(this, radius); 265 | } 266 | 267 | /** 268 | * Returns the corner radius of the CardView. 269 | * 270 | * @return Corner radius of the CardView 271 | * @see #getRadius() 272 | */ 273 | public float getRadius() { 274 | return IMPL.getRadius(this); 275 | } 276 | 277 | /** 278 | * Internal method used by CardView implementations to update the padding. 279 | * 280 | * @hide 281 | */ 282 | @Override 283 | public void setShadowPadding(int left, int top, int right, int bottom) { 284 | mShadowBounds.set(left, top, right, bottom); 285 | super.setPadding(left + mContentPadding.left, top + mContentPadding.top, 286 | right + mContentPadding.right, bottom + mContentPadding.bottom); 287 | } 288 | 289 | /** 290 | * Updates the backward compatible elevation of the CardView. 291 | * 292 | * @param radius The backward compatible elevation in pixels. 293 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardElevation 294 | * @see #getCardElevation() 295 | * @see #setMaxCardElevation(float) 296 | */ 297 | public void setCardElevation(float radius) { 298 | IMPL.setElevation(this, radius); 299 | } 300 | 301 | /** 302 | * Returns the backward compatible elevation of the CardView. 303 | * 304 | * @return Elevation of the CardView 305 | * @see #setCardElevation(float) 306 | * @see #getMaxCardElevation() 307 | */ 308 | public float getCardElevation() { 309 | return IMPL.getElevation(this); 310 | } 311 | 312 | /** 313 | * Updates the backward compatible elevation of the CardView. 314 | *

315 | * Calling this method has no effect if device OS version is L or newer and 316 | * {@link #getUseCompatPadding()} is false. 317 | * 318 | * @param radius The backward compatible elevation in pixels. 319 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardElevation 320 | * @see #setCardElevation(float) 321 | * @see #getMaxCardElevation() 322 | */ 323 | public void setMaxCardElevation(float radius) { 324 | IMPL.setMaxElevation(this, radius); 325 | } 326 | 327 | /** 328 | * Returns the backward compatible elevation of the CardView. 329 | * 330 | * @return Elevation of the CardView 331 | * @see #setMaxCardElevation(float) 332 | * @see #getCardElevation() 333 | */ 334 | public float getMaxCardElevation() { 335 | return IMPL.getMaxElevation(this); 336 | } 337 | 338 | /** 339 | * Returns whether CardView should add extra padding to content to avoid overlaps with rounded 340 | * corners on API versions 20 and below. 341 | * 342 | * @return True if CardView prevents overlaps with rounded corners on platforms before L. 343 | * Default value is true. 344 | */ 345 | @Override 346 | public boolean getPreventCornerOverlap() { 347 | return mPreventCornerOverlap; 348 | } 349 | 350 | /** 351 | * On API 20 and before, CardView does not clip the bounds of the Card for the rounded corners. 352 | * Instead, it adds padding to content so that it won't overlap with the rounded corners. 353 | * You can disable this behavior by setting this field to false. 354 | *

355 | * Setting this value on API 21 and above does not have any effect unless you have enabled 356 | * compatibility padding. 357 | * 358 | * @param preventCornerOverlap Whether CardView should add extra padding to content to avoid 359 | * overlaps with the CardView corners. 360 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardPreventCornerOverlap 361 | * @see #setUseCompatPadding(boolean) 362 | */ 363 | public void setPreventCornerOverlap(boolean preventCornerOverlap) { 364 | if (preventCornerOverlap == mPreventCornerOverlap) { 365 | return; 366 | } 367 | mPreventCornerOverlap = preventCornerOverlap; 368 | IMPL.onPreventCornerOverlapChanged(this); 369 | } 370 | } 371 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/CardViewApi21.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | 4 | import android.content.Context; 5 | import android.view.View; 6 | 7 | class CardViewApi21 implements CardViewImpl { 8 | 9 | @Override 10 | public void initialize(CardViewDelegate cardView, Context context, int backgroundColor, 11 | float radius, float elevation, float maxElevation) { 12 | final RoundRectDrawable backgroundDrawable = new RoundRectDrawable(backgroundColor, radius); 13 | cardView.setBackgroundDrawable(backgroundDrawable); 14 | View view = (View) cardView; 15 | view.setClipToOutline(true); 16 | view.setElevation(elevation); 17 | setMaxElevation(cardView, maxElevation); 18 | } 19 | 20 | @Override 21 | public void setRadius(CardViewDelegate cardView, float radius) { 22 | ((RoundRectDrawable) (cardView.getBackground())).setRadius(radius); 23 | } 24 | 25 | @Override 26 | public void initStatic() { 27 | } 28 | 29 | @Override 30 | public void setMaxElevation(CardViewDelegate cardView, float maxElevation) { 31 | ((RoundRectDrawable) (cardView.getBackground())).setPadding(maxElevation, 32 | cardView.getUseCompatPadding(), cardView.getPreventCornerOverlap()); 33 | updatePadding(cardView); 34 | } 35 | 36 | @Override 37 | public float getMaxElevation(CardViewDelegate cardView) { 38 | return ((RoundRectDrawable) (cardView.getBackground())).getPadding(); 39 | } 40 | 41 | @Override 42 | public float getMinWidth(CardViewDelegate cardView) { 43 | return getRadius(cardView) * 2; 44 | } 45 | 46 | @Override 47 | public float getMinHeight(CardViewDelegate cardView) { 48 | return getRadius(cardView) * 2; 49 | } 50 | 51 | @Override 52 | public float getRadius(CardViewDelegate cardView) { 53 | return ((RoundRectDrawable) (cardView.getBackground())).getRadius(); 54 | } 55 | 56 | @Override 57 | public void setElevation(CardViewDelegate cardView, float elevation) { 58 | ((View) cardView).setElevation(elevation); 59 | } 60 | 61 | @Override 62 | public float getElevation(CardViewDelegate cardView) { 63 | return ((View) cardView).getElevation(); 64 | } 65 | 66 | @Override 67 | public void updatePadding(CardViewDelegate cardView) { 68 | if (!cardView.getUseCompatPadding()) { 69 | cardView.setShadowPadding(0, 0, 0, 0); 70 | return; 71 | } 72 | float elevation = getMaxElevation(cardView); 73 | final float radius = getRadius(cardView); 74 | int hPadding = (int) Math.ceil(RoundRectDrawableWithShadow 75 | .calculateHorizontalPadding(elevation, radius, cardView.getPreventCornerOverlap())); 76 | int vPadding = (int) Math.ceil(RoundRectDrawableWithShadow 77 | .calculateVerticalPadding(elevation, radius, cardView.getPreventCornerOverlap())); 78 | cardView.setShadowPadding(hPadding, vPadding, hPadding, vPadding); 79 | } 80 | 81 | @Override 82 | public void onCompatPaddingChanged(CardViewDelegate cardView) { 83 | setMaxElevation(cardView, getMaxElevation(cardView)); 84 | } 85 | 86 | @Override 87 | public void onPreventCornerOverlapChanged(CardViewDelegate cardView) { 88 | setMaxElevation(cardView, getMaxElevation(cardView)); 89 | } 90 | 91 | @Override 92 | public void setBackgroundColor(CardViewDelegate cardView, int color) { 93 | ((RoundRectDrawable) (cardView.getBackground())).setColor(color); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/CardViewDelegate.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | import android.graphics.Rect; 4 | import android.graphics.drawable.Drawable; 5 | 6 | /** 7 | * Interface provided by CardView to implementations. 8 | *

9 | * Necessary to resolve circular dependency between base CardView and platform implementations. 10 | */ 11 | interface CardViewDelegate { 12 | void setBackgroundDrawable(Drawable paramDrawable); 13 | Drawable getBackground(); 14 | boolean getUseCompatPadding(); 15 | boolean getPreventCornerOverlap(); 16 | float getRadius(); 17 | void setShadowPadding(int left, int top, int right, int bottom); 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/CardViewEclairMr1.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.graphics.Rect; 7 | import android.graphics.RectF; 8 | import android.view.View; 9 | 10 | class CardViewEclairMr1 implements CardViewImpl { 11 | 12 | final RectF sCornerRect = new RectF(); 13 | 14 | @Override 15 | public void initStatic() { 16 | // Draws a round rect using 7 draw operations. This is faster than using 17 | // canvas.drawRoundRect before JBMR1 because API 11-16 used alpha mask textures to draw 18 | // shapes. 19 | RoundRectDrawableWithShadow.sRoundRectHelper 20 | = new RoundRectDrawableWithShadow.RoundRectHelper() { 21 | @Override 22 | public void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius, 23 | Paint paint) { 24 | final float twoRadius = cornerRadius * 2; 25 | final float innerWidth = bounds.width() - twoRadius - 1; 26 | final float innerHeight = bounds.height() - twoRadius - 1; 27 | // increment it to account for half pixels. 28 | if (cornerRadius >= 1f) { 29 | cornerRadius += .5f; 30 | sCornerRect.set(-cornerRadius, -cornerRadius, cornerRadius, cornerRadius); 31 | int saved = canvas.save(); 32 | canvas.translate(bounds.left + cornerRadius, bounds.top + cornerRadius); 33 | canvas.drawArc(sCornerRect, 180, 90, true, paint); 34 | canvas.translate(innerWidth, 0); 35 | canvas.rotate(90); 36 | canvas.drawArc(sCornerRect, 180, 90, true, paint); 37 | canvas.translate(innerHeight, 0); 38 | canvas.rotate(90); 39 | canvas.drawArc(sCornerRect, 180, 90, true, paint); 40 | canvas.translate(innerWidth, 0); 41 | canvas.rotate(90); 42 | canvas.drawArc(sCornerRect, 180, 90, true, paint); 43 | canvas.restoreToCount(saved); 44 | //draw top and bottom pieces 45 | canvas.drawRect(bounds.left + cornerRadius - 1f, bounds.top, 46 | bounds.right - cornerRadius + 1f, bounds.top + cornerRadius, 47 | paint); 48 | canvas.drawRect(bounds.left + cornerRadius - 1f, 49 | bounds.bottom - cornerRadius + 1f, bounds.right - cornerRadius + 1f, 50 | bounds.bottom, paint); 51 | } 52 | //// center 53 | canvas.drawRect(bounds.left, bounds.top + Math.max(0, cornerRadius - 1f), 54 | bounds.right, bounds.bottom - cornerRadius + 1f, paint); 55 | } 56 | }; 57 | } 58 | 59 | @Override 60 | public void initialize(CardViewDelegate cardView, Context context, int backgroundColor, 61 | float radius, float elevation, float maxElevation) { 62 | RoundRectDrawableWithShadow background = createBackground(context, backgroundColor, radius, 63 | elevation, maxElevation); 64 | background.setAddPaddingForCorners(cardView.getPreventCornerOverlap()); 65 | cardView.setBackgroundDrawable(background); 66 | updatePadding(cardView); 67 | } 68 | 69 | RoundRectDrawableWithShadow createBackground(Context context, int backgroundColor, 70 | float radius, float elevation, float maxElevation) { 71 | return new RoundRectDrawableWithShadow(context.getResources(), backgroundColor, radius, 72 | elevation, maxElevation); 73 | } 74 | 75 | @Override 76 | public void updatePadding(CardViewDelegate cardView) { 77 | Rect shadowPadding = new Rect(); 78 | getShadowBackground(cardView).getMaxShadowAndCornerPadding(shadowPadding); 79 | ((View) cardView).setMinimumHeight((int) Math.ceil(getMinHeight(cardView))); 80 | ((View) cardView).setMinimumWidth((int) Math.ceil(getMinWidth(cardView))); 81 | cardView.setShadowPadding(shadowPadding.left, shadowPadding.top, 82 | shadowPadding.right, shadowPadding.bottom); 83 | } 84 | 85 | @Override 86 | public void onCompatPaddingChanged(CardViewDelegate cardView) { 87 | // NO OP 88 | } 89 | 90 | @Override 91 | public void onPreventCornerOverlapChanged(CardViewDelegate cardView) { 92 | getShadowBackground(cardView).setAddPaddingForCorners(cardView.getPreventCornerOverlap()); 93 | updatePadding(cardView); 94 | } 95 | 96 | @Override 97 | public void setBackgroundColor(CardViewDelegate cardView, int color) { 98 | getShadowBackground(cardView).setColor(color); 99 | } 100 | 101 | @Override 102 | public void setRadius(CardViewDelegate cardView, float radius) { 103 | getShadowBackground(cardView).setCornerRadius(radius); 104 | updatePadding(cardView); 105 | } 106 | 107 | @Override 108 | public float getRadius(CardViewDelegate cardView) { 109 | return getShadowBackground(cardView).getCornerRadius(); 110 | } 111 | 112 | @Override 113 | public void setElevation(CardViewDelegate cardView, float elevation) { 114 | getShadowBackground(cardView).setShadowSize(elevation); 115 | } 116 | 117 | @Override 118 | public float getElevation(CardViewDelegate cardView) { 119 | return getShadowBackground(cardView).getShadowSize(); 120 | } 121 | 122 | @Override 123 | public void setMaxElevation(CardViewDelegate cardView, float maxElevation) { 124 | getShadowBackground(cardView).setMaxShadowSize(maxElevation); 125 | updatePadding(cardView); 126 | } 127 | 128 | @Override 129 | public float getMaxElevation(CardViewDelegate cardView) { 130 | return getShadowBackground(cardView).getMaxShadowSize(); 131 | } 132 | 133 | @Override 134 | public float getMinWidth(CardViewDelegate cardView) { 135 | return getShadowBackground(cardView).getMinWidth(); 136 | } 137 | 138 | @Override 139 | public float getMinHeight(CardViewDelegate cardView) { 140 | return getShadowBackground(cardView).getMinHeight(); 141 | } 142 | 143 | private RoundRectDrawableWithShadow getShadowBackground(CardViewDelegate cardView) { 144 | return ((RoundRectDrawableWithShadow) cardView.getBackground()); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/CardViewImpl.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | 4 | import android.content.Context; 5 | /** 6 | * Interface for platform specific CardView implementations. 7 | */ 8 | interface CardViewImpl { 9 | void initialize(CardViewDelegate cardView, Context context, int backgroundColor, float radius, 10 | float elevation, float maxElevation); 11 | 12 | void setRadius(CardViewDelegate cardView, float radius); 13 | 14 | float getRadius(CardViewDelegate cardView); 15 | 16 | void setElevation(CardViewDelegate cardView, float elevation); 17 | 18 | float getElevation(CardViewDelegate cardView); 19 | 20 | void initStatic(); 21 | 22 | void setMaxElevation(CardViewDelegate cardView, float maxElevation); 23 | 24 | float getMaxElevation(CardViewDelegate cardView); 25 | 26 | float getMinWidth(CardViewDelegate cardView); 27 | 28 | float getMinHeight(CardViewDelegate cardView); 29 | 30 | void updatePadding(CardViewDelegate cardView); 31 | 32 | void onCompatPaddingChanged(CardViewDelegate cardView); 33 | 34 | void onPreventCornerOverlapChanged(CardViewDelegate cardView); 35 | 36 | void setBackgroundColor(CardViewDelegate cardView, int color); 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/CardViewJellybeanMr1.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.graphics.RectF; 7 | 8 | class CardViewJellybeanMr1 extends CardViewEclairMr1 { 9 | 10 | @Override 11 | public void initStatic() { 12 | RoundRectDrawableWithShadow.sRoundRectHelper 13 | = new RoundRectDrawableWithShadow.RoundRectHelper() { 14 | @Override 15 | public void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius, 16 | Paint paint) { 17 | canvas.drawRoundRect(bounds, cornerRadius, cornerRadius, paint); 18 | } 19 | }; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/Constant.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | /** 4 | * Created by luxin on 15-12-18. 5 | * http://luxin.gitcafe.io 6 | */ 7 | public interface Constant 8 | { 9 | public final static int NUMBER_PAGER = 20; 10 | 11 | public final static String a_mi = "2017.02.22“9.0”更新日志"; 12 | public final static String a_miui = "-新功能 视频转换则为MP3\n-新功能 运程管理\n-新功能 视频MD5修改(老司机)\n-新功能 系统sm信息伪装\n-新功能 修复使用xposeo微信闪退\n-新组件 对于全部兼容界面沉浸处理\n-全新界面(主页,萝莉)\n-尝试兼容到高系统\n-修复 主页闪退"; 13 | public final static String a_ios = "2017.01.04[8.6]更新日志\n-新功能 查看Ta动态\n-新功能 动态执行shll\n-新功能 萝莉,ADM视频下载\n-新功能 微信自动招呼|自动加人\n-新功能 蓝色文字代码\n-修复 消息通知系统\n-修复 部分功能无反应\n-新功能 萝莉下载增加多类型\n2016.12.26[8.?]更新日志\n-新组件 特效文字生成(横线)\n-新功能 xposed轰炸机\n-新功能 QQ空间抢红包\n-新功能 应用管理器\n-修复 xposed抢红包|QQ\n-新功能 查看Ta资料"; 14 | 15 | public final static String httpw = "datas"; 16 | public final static String bin_styTool = "富强 民主 文明 和谐 自由 平等 公正 法制 爱国 敬业 诚信 友善"; 17 | public final static String httpkdex = "http://music.daigua.red/index.php?hm="; 18 | public final static String httpkres = "http://la.vvoso.com/?qq="; 19 | public final static String iddex = "http://tool.vvoso.com/tool/qiuqiu/?host=tool.vvoso.com&url="; 20 | 21 | public final static String idres = "&s=3"; 22 | public final static String idvip = "http://hongzj.win/?hone="; 23 | public final static String kii_KEY = "http://styTool.top/?hone="; 24 | public final static String id = "name"; 25 | public final static String idKEY = "http://QQ.nico.com/subview/30877/8100505.htm?fr=aladdin&ref=wise&ssid=0&from=2001a&uid=0&pu=usm@4,sz@1320_1003,ta@iphone_2_4.4_1_10.9&bd_page_type=1&baiduid=391D799A8649F695FDA6E64F3EFBDEE1&tj="; 26 | public final static String io = "123456789@:'+-,.?!:/@...;'~()<>#$%^_+-={}|qwertyuioplmknjbhvgcfxazs"; 27 | public final static String QQ = "2284467793"; 28 | public final static String android = "test"; 29 | public final static String USERIMG = "http://file.bmob.cn/"; 30 | public final static String ACTION_REGISTER_SUCCESS_FINISH="register.success.finish"; 31 | public final static String TULING_KEY="9a9e143ec4444a02d5c17892d6b4cdbf"; 32 | public final static String TULING_KKEY="styTool.nico.QQ.www.wap.blog.bbs.MT2.0.com.cn.net.orghttp://ftp://@126.com@163.com@sina.com@sina.cn@hotmail.com@live.cn@gmail.com@qq.com@sohu.com"; 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/DBSearchHelper.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteOpenHelper; 6 | 7 | public class DBSearchHelper extends SQLiteOpenHelper { 8 | 9 | private static final String DATABASE_NAME = "searchhistory.db"; 10 | private static final int DATABASE_VERSION = 1; 11 | 12 | public DBSearchHelper(Context context) { 13 | super(context, DATABASE_NAME, null, DATABASE_VERSION); 14 | } 15 | 16 | @Override 17 | public void onCreate(SQLiteDatabase db) { 18 | 19 | db.execSQL("CREATE TABLE IF NOT EXISTS t_historywords" + 20 | "(_id INTEGER PRIMARY KEY AUTOINCREMENT, historyword VARCHAR, updatetime LONG)"); 21 | 22 | } 23 | 24 | @Override 25 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 26 | 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/DarkFrameLayout.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.Paint; 7 | import android.util.AttributeSet; 8 | import android.view.MotionEvent; 9 | import android.widget.FrameLayout; 10 | 11 | /** 12 | * Created by NeXT on 15/8/3. 13 | */ 14 | public class DarkFrameLayout extends FrameLayout { 15 | 16 | public static final int MAX_ALPHA = 0X0f; 17 | 18 | private int alpha = 0x00; 19 | private Paint mFadePaint; 20 | 21 | private SlideBottomPanel slideBottomPanel; 22 | 23 | public DarkFrameLayout(Context context) { 24 | this(context, null); 25 | } 26 | 27 | public DarkFrameLayout(Context context, AttributeSet attrs) { 28 | this(context, attrs, 0); 29 | } 30 | 31 | public DarkFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { 32 | super(context, attrs, defStyleAttr); 33 | mFadePaint = new Paint(); 34 | } 35 | 36 | @Override 37 | protected void dispatchDraw(Canvas canvas) { 38 | super.dispatchDraw(canvas); 39 | drawFade(canvas); 40 | } 41 | 42 | private void drawFade(Canvas canvas) { 43 | mFadePaint.setColor(Color.argb(alpha, 0, 0, 0)); 44 | canvas.drawRect(0, 0, getMeasuredWidth(), getHeight(), mFadePaint); 45 | } 46 | 47 | public void fade(boolean fade) { 48 | alpha = fade ? 0x0f : 0x00; 49 | invalidate(); 50 | } 51 | 52 | public void fade(int alpha) { 53 | this.alpha = alpha; 54 | invalidate(); 55 | } 56 | 57 | @Override 58 | public boolean onInterceptTouchEvent(MotionEvent ev) { 59 | return slideBottomPanel.isPanelShowing(); 60 | } 61 | 62 | public int getCurrentAlpha() { 63 | return alpha; 64 | } 65 | 66 | public void setSlideBottomPanel(SlideBottomPanel slideBottomPanel) { 67 | this.slideBottomPanel = slideBottomPanel; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/GankIoActivity.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | import android.content.ClipboardManager; 4 | import android.content.Context; 5 | import android.content.DialogInterface; 6 | import android.content.Intent; 7 | import android.content.SharedPreferences; 8 | import android.os.Bundle; 9 | import android.preference.Preference; 10 | import android.preference.Preference.OnPreferenceClickListener; 11 | import android.preference.PreferenceActivity; 12 | import android.preference.PreferenceScreen; 13 | import android.widget.Toast; 14 | import android.app.*; 15 | import android.widget.*; 16 | import android.widget.CompoundButton.*; 17 | import android.view.*; 18 | import android.text.*; 19 | 20 | public class GankIoActivity extends Activity 21 | { 22 | public String getSharePreing(Context context, String field) 23 | { 24 | SharedPreferences sp = context.getSharedPreferences("nico.styTool", Context.MODE_PRIVATE); 25 | String value = sp.getString(field, ""); 26 | return value; 27 | } 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) 30 | { 31 | super.onCreate(savedInstanceState); 32 | setContentView(R.layout.th); 33 | 34 | }} 35 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/ListShower.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.content.res.Configuration; 6 | import android.os.Bundle; 7 | import android.view.View; 8 | import android.widget.AdapterView; 9 | import android.widget.AdapterView.OnItemClickListener; 10 | import android.widget.ListView; 11 | import android.widget.SimpleAdapter; 12 | 13 | import java.util.ArrayList; 14 | import java.util.HashMap; 15 | 16 | public class ListShower extends Activity 17 | { 18 | 19 | private final String LIST="List"; 20 | private final int RESULT_OK=1; 21 | private final String RUL="Url"; 22 | 23 | private ListView m_listview; 24 | private ArrayList> m_list=null; 25 | @SuppressWarnings("unchecked") 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) 28 | { 29 | // TODO Auto-generated method stub 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.history); 32 | 33 | m_listview = (ListView)findViewById(R.id.historyList); 34 | m_list = (ArrayList>)getIntent().getSerializableExtra(LIST); 35 | 36 | SimpleAdapter adapter=new SimpleAdapter(this, m_list, R.layout.historylist, new String[]{"Title","Url"}, new int[]{R.id.Title,R.id.Url}); 37 | 38 | m_listview.setAdapter(adapter); 39 | 40 | m_listview.setOnItemClickListener(new OnItemClickListener() 41 | { 42 | public void onItemClick(AdapterView parent, View view, int position, long id) 43 | { 44 | Intent intent=new Intent(); 45 | intent.putExtra("adm","bilibili"); 46 | setResult(MainActivity.RESULT_CODE, intent); 47 | finish(); 48 | 49 | } 50 | 51 | }); 52 | 53 | } 54 | 55 | @Override 56 | public void onConfigurationChanged(Configuration newConfig) 57 | { 58 | super.onConfigurationChanged(newConfig); 59 | if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) 60 | { 61 | // land do nothing is ok 62 | } 63 | else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) 64 | { 65 | // port do nothing is ok 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/MaterialDialog.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.Context; 5 | import android.content.DialogInterface; 6 | import android.graphics.Color; 7 | import android.graphics.drawable.ColorDrawable; 8 | import android.graphics.drawable.Drawable; 9 | import android.os.Build; 10 | import android.view.Gravity; 11 | import android.view.LayoutInflater; 12 | import android.view.View; 13 | import android.view.ViewGroup; 14 | import android.view.Window; 15 | import android.view.WindowManager; 16 | import android.view.inputmethod.InputMethodManager; 17 | import android.widget.AutoCompleteTextView; 18 | import android.widget.Button; 19 | import android.widget.EditText; 20 | import android.widget.LinearLayout; 21 | import android.widget.ListAdapter; 22 | import android.widget.ListView; 23 | import android.widget.TextView; 24 | 25 | /** 26 | * Created by drakeet on 9/28/14. 27 | */ 28 | public class MaterialDialog 29 | { 30 | 31 | private final static int BUTTON_BOTTOM = 9; 32 | private final static int BUTTON_TOP = 9; 33 | 34 | private boolean mCancel; 35 | private Context mContext; 36 | private AlertDialog mAlertDialog; 37 | private MaterialDialog.Builder mBuilder; 38 | private View mView; 39 | private int mTitleResId; 40 | private CharSequence mTitle; 41 | private int mMessageResId; 42 | private CharSequence mMessage; 43 | private Button mPositiveButton; 44 | private LinearLayout.LayoutParams mLayoutParams; 45 | private Button mNegativeButton; 46 | private boolean mHasShow = false; 47 | private int mBackgroundResId = -1; 48 | private Drawable mBackgroundDrawable; 49 | private View mMessageContentView; 50 | private int mMessageContentViewResId; 51 | private DialogInterface.OnDismissListener mOnDismissListener; 52 | private int pId = -1, nId = -1; 53 | private String pText, nText; 54 | View.OnClickListener pListener, nListener; 55 | 56 | 57 | public MaterialDialog(Context context) 58 | { 59 | this.mContext = context; 60 | } 61 | 62 | 63 | public void show() 64 | { 65 | if (!mHasShow) 66 | { 67 | mBuilder = new Builder(); 68 | } 69 | else 70 | { 71 | mAlertDialog.show(); 72 | } 73 | mHasShow = true; 74 | } 75 | 76 | 77 | public MaterialDialog setView(View view) 78 | { 79 | mView = view; 80 | if (mBuilder != null) 81 | { 82 | mBuilder.setView(view); 83 | } 84 | return this; 85 | } 86 | 87 | 88 | public MaterialDialog setContentView(View view) 89 | { 90 | mMessageContentView = view; 91 | mMessageContentViewResId = 0; 92 | if (mBuilder != null) 93 | { 94 | mBuilder.setContentView(mMessageContentView); 95 | } 96 | return this; 97 | } 98 | 99 | 100 | /** 101 | * Set a custom view resource to be the contents of the dialog. 102 | * 103 | * @param layoutResId resource ID to be inflated 104 | */ 105 | public MaterialDialog setContentView(int layoutResId) 106 | { 107 | mMessageContentViewResId = layoutResId; 108 | mMessageContentView = null; 109 | if (mBuilder != null) 110 | { 111 | mBuilder.setContentView(layoutResId); 112 | } 113 | return this; 114 | } 115 | 116 | 117 | public MaterialDialog setBackground(Drawable drawable) 118 | { 119 | mBackgroundDrawable = drawable; 120 | if (mBuilder != null) 121 | { 122 | mBuilder.setBackground(mBackgroundDrawable); 123 | } 124 | return this; 125 | } 126 | 127 | 128 | public MaterialDialog setBackgroundResource(int resId) 129 | { 130 | mBackgroundResId = resId; 131 | if (mBuilder != null) 132 | { 133 | mBuilder.setBackgroundResource(mBackgroundResId); 134 | } 135 | return this; 136 | } 137 | 138 | 139 | public void dismiss() 140 | { 141 | mAlertDialog.dismiss(); 142 | } 143 | 144 | 145 | private int dip2px(float dpValue) 146 | { 147 | final float scale = mContext.getResources().getDisplayMetrics().density; 148 | return (int) (dpValue * scale + 0.5f); 149 | } 150 | 151 | 152 | private static boolean isLollipop() 153 | { 154 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; 155 | } 156 | 157 | 158 | public MaterialDialog setTitle(int resId) 159 | { 160 | mTitleResId = resId; 161 | if (mBuilder != null) 162 | { 163 | mBuilder.setTitle(resId); 164 | } 165 | return this; 166 | } 167 | 168 | 169 | public MaterialDialog setTitle(CharSequence title) 170 | { 171 | mTitle = title; 172 | if (mBuilder != null) 173 | { 174 | mBuilder.setTitle(title); 175 | } 176 | return this; 177 | } 178 | 179 | 180 | public MaterialDialog setMessage(int resId) 181 | { 182 | mMessageResId = resId; 183 | if (mBuilder != null) 184 | { 185 | mBuilder.setMessage(resId); 186 | } 187 | return this; 188 | } 189 | 190 | 191 | public MaterialDialog setMessage(CharSequence message) 192 | { 193 | mMessage = message; 194 | if (mBuilder != null) 195 | { 196 | mBuilder.setMessage(message); 197 | } 198 | return this; 199 | } 200 | 201 | 202 | public MaterialDialog setPositiveButton(int resId, final View.OnClickListener listener) 203 | { 204 | this.pId = resId; 205 | this.pListener = listener; 206 | return this; 207 | } 208 | 209 | 210 | public Button getPositiveButton() 211 | { 212 | return mPositiveButton; 213 | } 214 | 215 | 216 | public Button getNegativeButton() 217 | { 218 | return mNegativeButton; 219 | } 220 | 221 | 222 | public MaterialDialog setPositiveButton(String text, final View.OnClickListener listener) 223 | { 224 | this.pText = text; 225 | this.pListener = listener; 226 | return this; 227 | } 228 | 229 | 230 | public MaterialDialog setNegativeButton(int resId, final View.OnClickListener listener) 231 | { 232 | this.nId = resId; 233 | this.nListener = listener; 234 | return this; 235 | } 236 | 237 | 238 | public MaterialDialog setNegativeButton(String text, final View.OnClickListener listener) 239 | { 240 | this.nText = text; 241 | this.nListener = listener; 242 | return this; 243 | } 244 | 245 | 246 | /** 247 | * Sets whether this dialog is canceled when touched outside the window's 248 | * bounds OR pressed the back key. If setting to true, the dialog is 249 | * set to be cancelable if not 250 | * already set. 251 | * 252 | * @param cancel Whether the dialog should be canceled when touched outside 253 | * the window OR pressed the back key. 254 | */ 255 | public MaterialDialog setCanceledOnTouchOutside(boolean cancel) 256 | { 257 | this.mCancel = cancel; 258 | if (mBuilder != null) 259 | { 260 | mBuilder.setCanceledOnTouchOutside(mCancel); 261 | } 262 | return this; 263 | } 264 | 265 | 266 | public MaterialDialog setOnDismissListener(DialogInterface.OnDismissListener onDismissListener) 267 | { 268 | this.mOnDismissListener = onDismissListener; 269 | return this; 270 | } 271 | 272 | 273 | private class Builder 274 | { 275 | 276 | private TextView mTitleView; 277 | private ViewGroup mMessageContentRoot; 278 | private TextView mMessageView; 279 | private Window mAlertDialogWindow; 280 | private LinearLayout mButtonLayout; 281 | 282 | 283 | private Builder() 284 | { 285 | mAlertDialog = new AlertDialog.Builder(mContext).create(); 286 | mAlertDialog.show(); 287 | 288 | mAlertDialog.getWindow() 289 | .clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 290 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 291 | mAlertDialog.getWindow() 292 | .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE); 293 | 294 | mAlertDialogWindow = mAlertDialog.getWindow(); 295 | mAlertDialogWindow.setBackgroundDrawable( 296 | new ColorDrawable(android.graphics.Color.TRANSPARENT)); 297 | 298 | View contentView = LayoutInflater.from(mContext) 299 | .inflate(R.layout.layout_material_dialog, null); 300 | contentView.setFocusable(true); 301 | contentView.setFocusableInTouchMode(true); 302 | 303 | mAlertDialogWindow.setBackgroundDrawableResource(R.drawable.material_dialog_window); 304 | 305 | mAlertDialogWindow.setContentView(contentView); 306 | 307 | mTitleView = (TextView) mAlertDialogWindow.findViewById(R.id.title); 308 | mMessageView = (TextView) mAlertDialogWindow.findViewById(R.id.message); 309 | mButtonLayout = (LinearLayout) mAlertDialogWindow.findViewById(R.id.buttonLayout); 310 | mPositiveButton = (Button) mButtonLayout.findViewById(R.id.btn_p); 311 | mNegativeButton = (Button) mButtonLayout.findViewById(R.id.btn_n); 312 | mMessageContentRoot = (ViewGroup) mAlertDialogWindow.findViewById( 313 | R.id.message_content_root); 314 | if (mView != null) 315 | { 316 | LinearLayout linearLayout = (LinearLayout) mAlertDialogWindow.findViewById( 317 | R.id.contentView); 318 | linearLayout.removeAllViews(); 319 | linearLayout.addView(mView); 320 | } 321 | if (mTitleResId != 0) 322 | { 323 | setTitle(mTitleResId); 324 | } 325 | if (mTitle != null) 326 | { 327 | setTitle(mTitle); 328 | } 329 | if (mTitle == null && mTitleResId == 0) 330 | { 331 | mTitleView.setVisibility(View.GONE); 332 | } 333 | if (mMessageResId != 0) 334 | { 335 | setMessage(mMessageResId); 336 | } 337 | if (mMessage != null) 338 | { 339 | setMessage(mMessage); 340 | } 341 | if (pId != -1) 342 | { 343 | mPositiveButton.setVisibility(View.VISIBLE); 344 | mPositiveButton.setText(pId); 345 | mPositiveButton.setOnClickListener(pListener); 346 | if (isLollipop()) 347 | { 348 | mPositiveButton.setElevation(0); 349 | } 350 | } 351 | if (nId != -1) 352 | { 353 | mNegativeButton.setVisibility(View.VISIBLE); 354 | mNegativeButton.setText(nId); 355 | mNegativeButton.setOnClickListener(nListener); 356 | if (isLollipop()) 357 | { 358 | mNegativeButton.setElevation(0); 359 | } 360 | } 361 | if (!isNullOrEmpty(pText)) 362 | { 363 | mPositiveButton.setVisibility(View.VISIBLE); 364 | mPositiveButton.setText(pText); 365 | mPositiveButton.setOnClickListener(pListener); 366 | if (isLollipop()) 367 | { 368 | mPositiveButton.setElevation(0); 369 | } 370 | } 371 | 372 | if (!isNullOrEmpty(nText)) 373 | { 374 | mNegativeButton.setVisibility(View.VISIBLE); 375 | mNegativeButton.setText(nText); 376 | mNegativeButton.setOnClickListener(nListener); 377 | if (isLollipop()) 378 | { 379 | mNegativeButton.setElevation(0); 380 | } 381 | } 382 | if (isNullOrEmpty(pText) && pId == -1) 383 | { 384 | mPositiveButton.setVisibility(View.GONE); 385 | } 386 | if (isNullOrEmpty(nText) && nId == -1) 387 | { 388 | mNegativeButton.setVisibility(View.GONE); 389 | } 390 | if (mBackgroundResId != -1) 391 | { 392 | LinearLayout linearLayout = (LinearLayout) mAlertDialogWindow.findViewById( 393 | R.id.material_background); 394 | linearLayout.setBackgroundResource(mBackgroundResId); 395 | } 396 | if (mBackgroundDrawable != null) 397 | { 398 | LinearLayout linearLayout = (LinearLayout) mAlertDialogWindow.findViewById( 399 | R.id.material_background); 400 | linearLayout.setBackground(mBackgroundDrawable); 401 | } 402 | 403 | if (mMessageContentView != null) 404 | { 405 | this.setContentView(mMessageContentView); 406 | } 407 | else if (mMessageContentViewResId != 0) 408 | { 409 | this.setContentView(mMessageContentViewResId); 410 | } 411 | mAlertDialog.setCanceledOnTouchOutside(mCancel); 412 | mAlertDialog.setCancelable(mCancel); 413 | if (mOnDismissListener != null) 414 | { 415 | mAlertDialog.setOnDismissListener(mOnDismissListener); 416 | } 417 | } 418 | 419 | 420 | public void setTitle(int resId) 421 | { 422 | mTitleView.setText(resId); 423 | } 424 | 425 | 426 | public void setTitle(CharSequence title) 427 | { 428 | mTitleView.setText(title); 429 | } 430 | 431 | 432 | public void setMessage(int resId) 433 | { 434 | if (mMessageView != null) 435 | { 436 | mMessageView.setText(resId); 437 | } 438 | } 439 | 440 | 441 | public void setMessage(CharSequence message) 442 | { 443 | if (mMessageView != null) 444 | { 445 | mMessageView.setText(message); 446 | } 447 | } 448 | 449 | 450 | /** 451 | * set positive button 452 | * 453 | * @param text the name of button 454 | */ 455 | public void setPositiveButton(String text, final View.OnClickListener listener) 456 | { 457 | Button button = new Button(mContext); 458 | LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( 459 | LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); 460 | button.setLayoutParams(params); 461 | button.setBackgroundResource(R.drawable.material_card); 462 | button.setTextColor(Color.argb(255, 35, 159, 242)); 463 | button.setText(text); 464 | button.setGravity(Gravity.CENTER); 465 | button.setTextSize(14); 466 | button.setPadding(dip2px(12), 0, dip2px(32), dip2px(BUTTON_BOTTOM)); 467 | button.setOnClickListener(listener); 468 | mButtonLayout.addView(button); 469 | } 470 | 471 | 472 | /** 473 | * set negative button 474 | * 475 | * @param text the name of button 476 | */ 477 | public void setNegativeButton(String text, final View.OnClickListener listener) 478 | { 479 | Button button = new Button(mContext); 480 | LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( 481 | LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); 482 | button.setLayoutParams(params); 483 | button.setBackgroundResource(R.drawable.material_card); 484 | button.setText(text); 485 | button.setTextColor(Color.argb(222, 0, 0, 0)); 486 | button.setTextSize(14); 487 | button.setGravity(Gravity.CENTER); 488 | button.setPadding(0, 0, 0, dip2px(8)); 489 | button.setOnClickListener(listener); 490 | if (mButtonLayout.getChildCount() > 0) 491 | { 492 | params.setMargins(20, 0, 10, dip2px(BUTTON_BOTTOM)); 493 | button.setLayoutParams(params); 494 | mButtonLayout.addView(button, 1); 495 | } 496 | else 497 | { 498 | button.setLayoutParams(params); 499 | mButtonLayout.addView(button); 500 | } 501 | } 502 | 503 | 504 | public void setView(View view) 505 | { 506 | LinearLayout l = (LinearLayout) mAlertDialogWindow.findViewById(R.id.contentView); 507 | l.removeAllViews(); 508 | ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams( 509 | ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 510 | view.setLayoutParams(layoutParams); 511 | 512 | view.setOnFocusChangeListener(new View.OnFocusChangeListener() { 513 | @Override public void onFocusChange(View v, boolean hasFocus) 514 | { 515 | mAlertDialogWindow.setSoftInputMode( 516 | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); 517 | // show imm 518 | InputMethodManager imm = (InputMethodManager) mContext.getSystemService( 519 | Context.INPUT_METHOD_SERVICE); 520 | imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 521 | InputMethodManager.HIDE_IMPLICIT_ONLY); 522 | } 523 | }); 524 | 525 | l.addView(view); 526 | 527 | if (view instanceof ViewGroup) 528 | { 529 | 530 | ViewGroup viewGroup = (ViewGroup) view; 531 | 532 | for (int i = 0; i < viewGroup.getChildCount(); i++) 533 | { 534 | if (viewGroup.getChildAt(i) instanceof EditText) 535 | { 536 | EditText editText = (EditText) viewGroup.getChildAt(i); 537 | editText.setFocusable(true); 538 | editText.requestFocus(); 539 | editText.setFocusableInTouchMode(true); 540 | } 541 | } 542 | for (int i = 0; i < viewGroup.getChildCount(); i++) 543 | { 544 | if (viewGroup.getChildAt(i) instanceof AutoCompleteTextView) 545 | { 546 | AutoCompleteTextView autoCompleteTextView = (AutoCompleteTextView) viewGroup 547 | .getChildAt(i); 548 | autoCompleteTextView.setFocusable(true); 549 | autoCompleteTextView.requestFocus(); 550 | autoCompleteTextView.setFocusableInTouchMode(true); 551 | } 552 | } 553 | } 554 | } 555 | 556 | 557 | public void setContentView(View contentView) 558 | { 559 | ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams( 560 | ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 561 | contentView.setLayoutParams(layoutParams); 562 | if (contentView instanceof ListView) 563 | { 564 | setListViewHeightBasedOnChildren((ListView) contentView); 565 | } 566 | LinearLayout linearLayout = (LinearLayout) mAlertDialogWindow.findViewById( 567 | R.id.message_content_view); 568 | if (linearLayout != null) 569 | { 570 | linearLayout.removeAllViews(); 571 | linearLayout.addView(contentView); 572 | } 573 | for (int i = 0; i < (linearLayout != null ? linearLayout.getChildCount() : 0); i++) 574 | { 575 | if (linearLayout.getChildAt(i) instanceof AutoCompleteTextView) 576 | { 577 | AutoCompleteTextView autoCompleteTextView 578 | = (AutoCompleteTextView) linearLayout.getChildAt(i); 579 | autoCompleteTextView.setFocusable(true); 580 | autoCompleteTextView.requestFocus(); 581 | autoCompleteTextView.setFocusableInTouchMode(true); 582 | } 583 | } 584 | } 585 | 586 | 587 | /** 588 | * Set a custom view resource to be the contents of the dialog. The 589 | * resource will be inflated into a ScrollView. 590 | * 591 | * @param layoutResId resource ID to be inflated 592 | */ 593 | public void setContentView(int layoutResId) 594 | { 595 | mMessageContentRoot.removeAllViews(); 596 | // Not setting this to the other content view because user has defined their own 597 | // layout params, and we don't want to overwrite those. 598 | LayoutInflater.from(mMessageContentRoot.getContext()) 599 | .inflate(layoutResId, mMessageContentRoot); 600 | } 601 | 602 | 603 | public void setBackground(Drawable drawable) 604 | { 605 | LinearLayout linearLayout = (LinearLayout) mAlertDialogWindow.findViewById( 606 | R.id.material_background); 607 | linearLayout.setBackground(drawable); 608 | } 609 | 610 | 611 | public void setBackgroundResource(int resId) 612 | { 613 | LinearLayout linearLayout = (LinearLayout) mAlertDialogWindow.findViewById( 614 | R.id.material_background); 615 | linearLayout.setBackgroundResource(resId); 616 | } 617 | 618 | 619 | public void setCanceledOnTouchOutside(boolean canceledOnTouchOutside) 620 | { 621 | mAlertDialog.setCanceledOnTouchOutside(canceledOnTouchOutside); 622 | mAlertDialog.setCancelable(canceledOnTouchOutside); 623 | } 624 | } 625 | 626 | 627 | private boolean isNullOrEmpty(String nText) 628 | { 629 | return nText == null || nText.isEmpty(); 630 | } 631 | 632 | 633 | private void setListViewHeightBasedOnChildren(ListView listView) 634 | { 635 | ListAdapter listAdapter = listView.getAdapter(); 636 | if (listAdapter == null) 637 | { 638 | // pre-condition 639 | return; 640 | } 641 | 642 | int totalHeight = 0; 643 | for (int i = 0; i < listAdapter.getCount(); i++) 644 | { 645 | View listItem = listAdapter.getView(i, null, listView); 646 | listItem.measure(0, 0); 647 | totalHeight += listItem.getMeasuredHeight(); 648 | } 649 | 650 | ViewGroup.LayoutParams params = listView.getLayoutParams(); 651 | params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); 652 | listView.setLayoutParams(params); 653 | } 654 | } 655 | 656 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/Num.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Canvas; 6 | import android.graphics.Color; 7 | import android.graphics.Paint; 8 | import android.graphics.RectF; 9 | import android.os.Bundle; 10 | import android.os.Parcelable; 11 | import android.util.AttributeSet; 12 | import android.view.View; 13 | 14 | import static nico.styTool.plus.Num.ProgressTextVisibility.Invisible; 15 | import static nico.styTool.plus.Num.ProgressTextVisibility.Visible; 16 | 17 | /** 18 | * Created by daimajia on 14-4-30. 19 | */ 20 | public class Num extends View { 21 | private int mMaxProgress = 100; 22 | 23 | /** 24 | * Current progress, can not exceed the max progress. 25 | */ 26 | private int mCurrentProgress = 0; 27 | 28 | /** 29 | * The progress area bar color. 30 | */ 31 | private int mReachedBarColor; 32 | 33 | /** 34 | * The bar unreached area color. 35 | */ 36 | private int mUnreachedBarColor; 37 | 38 | /** 39 | * The progress text color. 40 | */ 41 | private int mTextColor; 42 | 43 | /** 44 | * The progress text size. 45 | */ 46 | private float mTextSize; 47 | 48 | /** 49 | * The height of the reached area. 50 | */ 51 | private float mReachedBarHeight; 52 | 53 | /** 54 | * The height of the unreached area. 55 | */ 56 | private float mUnreachedBarHeight; 57 | 58 | /** 59 | * The suffix of the number. 60 | */ 61 | private String mSuffix = "%"; 62 | 63 | /** 64 | * The prefix. 65 | */ 66 | private String mPrefix = ""; 67 | 68 | 69 | private final int default_text_color = Color.rgb(66, 145, 241); 70 | private final int default_reached_color = Color.rgb(66, 145, 241); 71 | private final int default_unreached_color = Color.rgb(204, 204, 204); 72 | private final float default_progress_text_offset; 73 | private final float default_text_size; 74 | private final float default_reached_bar_height; 75 | private final float default_unreached_bar_height; 76 | 77 | /** 78 | * For save and restore instance of progressbar. 79 | */ 80 | private static final String INSTANCE_STATE = "saved_instance"; 81 | private static final String INSTANCE_TEXT_COLOR = "text_color"; 82 | private static final String INSTANCE_TEXT_SIZE = "text_size"; 83 | private static final String INSTANCE_REACHED_BAR_HEIGHT = "reached_bar_height"; 84 | private static final String INSTANCE_REACHED_BAR_COLOR = "reached_bar_color"; 85 | private static final String INSTANCE_UNREACHED_BAR_HEIGHT = "unreached_bar_height"; 86 | private static final String INSTANCE_UNREACHED_BAR_COLOR = "unreached_bar_color"; 87 | private static final String INSTANCE_MAX = "max"; 88 | private static final String INSTANCE_PROGRESS = "progress"; 89 | private static final String INSTANCE_SUFFIX = "suffix"; 90 | private static final String INSTANCE_PREFIX = "prefix"; 91 | private static final String INSTANCE_TEXT_VISIBILITY = "text_visibility"; 92 | 93 | private static final int PROGRESS_TEXT_VISIBLE = 0; 94 | 95 | 96 | /** 97 | * The width of the text that to be drawn. 98 | */ 99 | private float mDrawTextWidth; 100 | 101 | /** 102 | * The drawn text start. 103 | */ 104 | private float mDrawTextStart; 105 | 106 | /** 107 | * The drawn text end. 108 | */ 109 | private float mDrawTextEnd; 110 | 111 | /** 112 | * The text that to be drawn in onDraw(). 113 | */ 114 | private String mCurrentDrawText; 115 | 116 | /** 117 | * The Paint of the reached area. 118 | */ 119 | private Paint mReachedBarPaint; 120 | /** 121 | * The Paint of the unreached area. 122 | */ 123 | private Paint mUnreachedBarPaint; 124 | /** 125 | * The Paint of the progress text. 126 | */ 127 | private Paint mTextPaint; 128 | 129 | /** 130 | * Unreached bar area to draw rect. 131 | */ 132 | private RectF mUnreachedRectF = new RectF(0, 0, 0, 0); 133 | /** 134 | * Reached bar area rect. 135 | */ 136 | private RectF mReachedRectF = new RectF(0, 0, 0, 0); 137 | 138 | /** 139 | * The progress text offset. 140 | */ 141 | private float mOffset; 142 | 143 | /** 144 | * Determine if need to draw unreached area. 145 | */ 146 | private boolean mDrawUnreachedBar = true; 147 | 148 | private boolean mDrawReachedBar = true; 149 | 150 | private boolean mIfDrawText = true; 151 | 152 | /** 153 | * Listener 154 | */ 155 | private On mListener; 156 | 157 | public enum ProgressTextVisibility { 158 | Visible, Invisible 159 | } 160 | 161 | public Num(Context context) { 162 | this(context, null); 163 | } 164 | 165 | public Num(Context context, AttributeSet attrs) { 166 | this(context, attrs, R.attr.numberProgressBarStyle); 167 | } 168 | 169 | public Num(Context context, AttributeSet attrs, int defStyleAttr) { 170 | super(context, attrs, defStyleAttr); 171 | 172 | default_reached_bar_height = dp2px(1.5f); 173 | default_unreached_bar_height = dp2px(1.0f); 174 | default_text_size = sp2px(10); 175 | default_progress_text_offset = dp2px(3.0f); 176 | 177 | //load styled attributes. 178 | final TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MaterialRefreshLayout, 179 | defStyleAttr, 0); 180 | 181 | mReachedBarColor = attributes.getColor(R.styleable.MaterialRefreshLayout_progress_reached_color, default_reached_color); 182 | mUnreachedBarColor = attributes.getColor(R.styleable.MaterialRefreshLayout_progress_unreached_color, default_unreached_color); 183 | mTextColor = attributes.getColor(R.styleable.MaterialRefreshLayout_progress_text_color, default_text_color); 184 | mTextSize = attributes.getDimension(R.styleable.MaterialRefreshLayout_progress_text_size, default_text_size); 185 | 186 | mReachedBarHeight = attributes.getDimension(R.styleable.MaterialRefreshLayout_progress_reached_bar_height, default_reached_bar_height); 187 | mUnreachedBarHeight = attributes.getDimension(R.styleable.MaterialRefreshLayout_progress_unreached_bar_height, default_unreached_bar_height); 188 | mOffset = attributes.getDimension(R.styleable.MaterialRefreshLayout_progress_text_offset, default_progress_text_offset); 189 | 190 | int textVisible = attributes.getInt(R.styleable.MaterialRefreshLayout_progress_text_visibility, PROGRESS_TEXT_VISIBLE); 191 | if (textVisible != PROGRESS_TEXT_VISIBLE) { 192 | mIfDrawText = false; 193 | } 194 | 195 | setProgress(attributes.getInt(R.styleable.MaterialRefreshLayout_progress_current, 0)); 196 | setMax(attributes.getInt(R.styleable.MaterialRefreshLayout_progress_max, 100)); 197 | 198 | attributes.recycle(); 199 | initializePainters(); 200 | } 201 | 202 | @Override 203 | protected int getSuggestedMinimumWidth() { 204 | return (int) mTextSize; 205 | } 206 | 207 | @Override 208 | protected int getSuggestedMinimumHeight() { 209 | return Math.max((int) mTextSize, Math.max((int) mReachedBarHeight, (int) mUnreachedBarHeight)); 210 | } 211 | 212 | @Override 213 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 214 | setMeasuredDimension(measure(widthMeasureSpec, true), measure(heightMeasureSpec, false)); 215 | } 216 | 217 | private int measure(int measureSpec, boolean isWidth) { 218 | int result; 219 | int mode = MeasureSpec.getMode(measureSpec); 220 | int size = MeasureSpec.getSize(measureSpec); 221 | int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom(); 222 | if (mode == MeasureSpec.EXACTLY) { 223 | result = size; 224 | } else { 225 | result = isWidth ? getSuggestedMinimumWidth() : getSuggestedMinimumHeight(); 226 | result += padding; 227 | if (mode == MeasureSpec.AT_MOST) { 228 | if (isWidth) { 229 | result = Math.max(result, size); 230 | } else { 231 | result = Math.min(result, size); 232 | } 233 | } 234 | } 235 | return result; 236 | } 237 | 238 | @Override 239 | protected void onDraw(Canvas canvas) { 240 | if (mIfDrawText) { 241 | calculateDrawRectF(); 242 | } else { 243 | calculateDrawRectFWithoutProgressText(); 244 | } 245 | 246 | if (mDrawReachedBar) { 247 | canvas.drawRect(mReachedRectF, mReachedBarPaint); 248 | } 249 | 250 | if (mDrawUnreachedBar) { 251 | canvas.drawRect(mUnreachedRectF, mUnreachedBarPaint); 252 | } 253 | 254 | if (mIfDrawText) 255 | canvas.drawText(mCurrentDrawText, mDrawTextStart, mDrawTextEnd, mTextPaint); 256 | } 257 | 258 | private void initializePainters() { 259 | mReachedBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 260 | mReachedBarPaint.setColor(mReachedBarColor); 261 | 262 | mUnreachedBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 263 | mUnreachedBarPaint.setColor(mUnreachedBarColor); 264 | 265 | mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 266 | mTextPaint.setColor(mTextColor); 267 | mTextPaint.setTextSize(mTextSize); 268 | } 269 | 270 | 271 | private void calculateDrawRectFWithoutProgressText() { 272 | mReachedRectF.left = getPaddingLeft(); 273 | mReachedRectF.top = getHeight() / 2.0f - mReachedBarHeight / 2.0f; 274 | mReachedRectF.right = (getWidth() - getPaddingLeft() - getPaddingRight()) / (getMax() * 1.0f) * getProgress() + getPaddingLeft(); 275 | mReachedRectF.bottom = getHeight() / 2.0f + mReachedBarHeight / 2.0f; 276 | 277 | mUnreachedRectF.left = mReachedRectF.right; 278 | mUnreachedRectF.right = getWidth() - getPaddingRight(); 279 | mUnreachedRectF.top = getHeight() / 2.0f + -mUnreachedBarHeight / 2.0f; 280 | mUnreachedRectF.bottom = getHeight() / 2.0f + mUnreachedBarHeight / 2.0f; 281 | } 282 | 283 | private void calculateDrawRectF() { 284 | 285 | mCurrentDrawText = String.format("%d", getProgress() * 100 / getMax()); 286 | mCurrentDrawText = mPrefix + mCurrentDrawText + mSuffix; 287 | mDrawTextWidth = mTextPaint.measureText(mCurrentDrawText); 288 | 289 | if (getProgress() == 0) { 290 | mDrawReachedBar = false; 291 | mDrawTextStart = getPaddingLeft(); 292 | } else { 293 | mDrawReachedBar = true; 294 | mReachedRectF.left = getPaddingLeft(); 295 | mReachedRectF.top = getHeight() / 2.0f - mReachedBarHeight / 2.0f; 296 | mReachedRectF.right = (getWidth() - getPaddingLeft() - getPaddingRight()) / (getMax() * 1.0f) * getProgress() - mOffset + getPaddingLeft(); 297 | mReachedRectF.bottom = getHeight() / 2.0f + mReachedBarHeight / 2.0f; 298 | mDrawTextStart = (mReachedRectF.right + mOffset); 299 | } 300 | 301 | mDrawTextEnd = (int) ((getHeight() / 2.0f) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2.0f)); 302 | 303 | if ((mDrawTextStart + mDrawTextWidth) >= getWidth() - getPaddingRight()) { 304 | mDrawTextStart = getWidth() - getPaddingRight() - mDrawTextWidth; 305 | mReachedRectF.right = mDrawTextStart - mOffset; 306 | } 307 | 308 | float unreachedBarStart = mDrawTextStart + mDrawTextWidth + mOffset; 309 | if (unreachedBarStart >= getWidth() - getPaddingRight()) { 310 | mDrawUnreachedBar = false; 311 | } else { 312 | mDrawUnreachedBar = true; 313 | mUnreachedRectF.left = unreachedBarStart; 314 | mUnreachedRectF.right = getWidth() - getPaddingRight(); 315 | mUnreachedRectF.top = getHeight() / 2.0f + -mUnreachedBarHeight / 2.0f; 316 | mUnreachedRectF.bottom = getHeight() / 2.0f + mUnreachedBarHeight / 2.0f; 317 | } 318 | } 319 | 320 | /** 321 | * Get progress text color. 322 | * 323 | * @return progress text color. 324 | */ 325 | public int getTextColor() { 326 | return mTextColor; 327 | } 328 | 329 | /** 330 | * Get progress text size. 331 | * 332 | * @return progress text size. 333 | */ 334 | public float getProgressTextSize() { 335 | return mTextSize; 336 | } 337 | 338 | public int getUnreachedBarColor() { 339 | return mUnreachedBarColor; 340 | } 341 | 342 | public int getReachedBarColor() { 343 | return mReachedBarColor; 344 | } 345 | 346 | public int getProgress() { 347 | return mCurrentProgress; 348 | } 349 | 350 | public int getMax() { 351 | return mMaxProgress; 352 | } 353 | 354 | public float getReachedBarHeight() { 355 | return mReachedBarHeight; 356 | } 357 | 358 | public float getUnreachedBarHeight() { 359 | return mUnreachedBarHeight; 360 | } 361 | 362 | public void setProgressTextSize(float textSize) { 363 | this.mTextSize = textSize; 364 | mTextPaint.setTextSize(mTextSize); 365 | invalidate(); 366 | } 367 | 368 | public void setProgressTextColor(int textColor) { 369 | this.mTextColor = textColor; 370 | mTextPaint.setColor(mTextColor); 371 | invalidate(); 372 | } 373 | 374 | public void setUnreachedBarColor(int barColor) { 375 | this.mUnreachedBarColor = barColor; 376 | mUnreachedBarPaint.setColor(mUnreachedBarColor); 377 | invalidate(); 378 | } 379 | 380 | public void setReachedBarColor(int progressColor) { 381 | this.mReachedBarColor = progressColor; 382 | mReachedBarPaint.setColor(mReachedBarColor); 383 | invalidate(); 384 | } 385 | 386 | public void setReachedBarHeight(float height) { 387 | mReachedBarHeight = height; 388 | } 389 | 390 | public void setUnreachedBarHeight(float height) { 391 | mUnreachedBarHeight = height; 392 | } 393 | 394 | public void setMax(int maxProgress) { 395 | if (maxProgress > 0) { 396 | this.mMaxProgress = maxProgress; 397 | invalidate(); 398 | } 399 | } 400 | 401 | public void setSuffix(String suffix) { 402 | if (suffix == null) { 403 | mSuffix = ""; 404 | } else { 405 | mSuffix = suffix; 406 | } 407 | } 408 | 409 | public String getSuffix() { 410 | return mSuffix; 411 | } 412 | 413 | public void setPrefix(String prefix) { 414 | if (prefix == null) 415 | mPrefix = ""; 416 | else { 417 | mPrefix = prefix; 418 | } 419 | } 420 | 421 | public String getPrefix() { 422 | return mPrefix; 423 | } 424 | 425 | public void incrementProgressBy(int by) { 426 | if (by > 0) { 427 | setProgress(getProgress() + by); 428 | } 429 | 430 | if(mListener != null){ 431 | mListener.onProgressChange(getProgress(), getMax()); 432 | } 433 | } 434 | 435 | public void setProgress(int progress) { 436 | if (progress <= getMax() && progress >= 0) { 437 | this.mCurrentProgress = progress; 438 | invalidate(); 439 | } 440 | } 441 | 442 | @Override 443 | protected Parcelable onSaveInstanceState() { 444 | final Bundle bundle = new Bundle(); 445 | bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState()); 446 | bundle.putInt(INSTANCE_TEXT_COLOR, getTextColor()); 447 | bundle.putFloat(INSTANCE_TEXT_SIZE, getProgressTextSize()); 448 | bundle.putFloat(INSTANCE_REACHED_BAR_HEIGHT, getReachedBarHeight()); 449 | bundle.putFloat(INSTANCE_UNREACHED_BAR_HEIGHT, getUnreachedBarHeight()); 450 | bundle.putInt(INSTANCE_REACHED_BAR_COLOR, getReachedBarColor()); 451 | bundle.putInt(INSTANCE_UNREACHED_BAR_COLOR, getUnreachedBarColor()); 452 | bundle.putInt(INSTANCE_MAX, getMax()); 453 | bundle.putInt(INSTANCE_PROGRESS, getProgress()); 454 | bundle.putString(INSTANCE_SUFFIX, getSuffix()); 455 | bundle.putString(INSTANCE_PREFIX, getPrefix()); 456 | bundle.putBoolean(INSTANCE_TEXT_VISIBILITY, getProgressTextVisibility()); 457 | return bundle; 458 | } 459 | 460 | @Override 461 | protected void onRestoreInstanceState(Parcelable state) { 462 | if (state instanceof Bundle) { 463 | final Bundle bundle = (Bundle) state; 464 | mTextColor = bundle.getInt(INSTANCE_TEXT_COLOR); 465 | mTextSize = bundle.getFloat(INSTANCE_TEXT_SIZE); 466 | mReachedBarHeight = bundle.getFloat(INSTANCE_REACHED_BAR_HEIGHT); 467 | mUnreachedBarHeight = bundle.getFloat(INSTANCE_UNREACHED_BAR_HEIGHT); 468 | mReachedBarColor = bundle.getInt(INSTANCE_REACHED_BAR_COLOR); 469 | mUnreachedBarColor = bundle.getInt(INSTANCE_UNREACHED_BAR_COLOR); 470 | initializePainters(); 471 | setMax(bundle.getInt(INSTANCE_MAX)); 472 | setProgress(bundle.getInt(INSTANCE_PROGRESS)); 473 | setPrefix(bundle.getString(INSTANCE_PREFIX)); 474 | setSuffix(bundle.getString(INSTANCE_SUFFIX)); 475 | setProgressTextVisibility(bundle.getBoolean(INSTANCE_TEXT_VISIBILITY) ? Visible : Invisible); 476 | super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE)); 477 | return; 478 | } 479 | super.onRestoreInstanceState(state); 480 | } 481 | 482 | public float dp2px(float dp) { 483 | final float scale = getResources().getDisplayMetrics().density; 484 | return dp * scale + 0.5f; 485 | } 486 | 487 | public float sp2px(float sp) { 488 | final float scale = getResources().getDisplayMetrics().scaledDensity; 489 | return sp * scale; 490 | } 491 | 492 | public void setProgressTextVisibility(ProgressTextVisibility visibility) { 493 | mIfDrawText = visibility == Visible; 494 | invalidate(); 495 | } 496 | 497 | public boolean getProgressTextVisibility() { 498 | return mIfDrawText; 499 | } 500 | 501 | public void setOnProgressBarListener(On listener){ 502 | mListener = listener; 503 | } 504 | } 505 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/On.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | /** 4 | * Created by lelexxx on 15-4-23. 5 | */ 6 | public interface On { 7 | 8 | void onProgressChange(int current, int max); 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/RoundRectDrawable.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | 4 | import android.graphics.Canvas; 5 | import android.graphics.ColorFilter; 6 | import android.graphics.Outline; 7 | import android.graphics.Paint; 8 | import android.graphics.PixelFormat; 9 | import android.graphics.Rect; 10 | import android.graphics.RectF; 11 | import android.graphics.drawable.Drawable; 12 | 13 | import static nico.styTool.plus.RoundRectDrawableWithShadow.calculateVerticalPadding; 14 | import static nico.styTool.plus.RoundRectDrawableWithShadow.calculateHorizontalPadding; 15 | 16 | /** 17 | * Very simple drawable that draws a rounded rectangle background with arbitrary corners and also 18 | * reports proper outline for L. 19 | *

20 | * Simpler and uses less resources compared to GradientDrawable or ShapeDrawable. 21 | */ 22 | class RoundRectDrawable extends Drawable { 23 | private float mRadius; 24 | private final Paint mPaint; 25 | private final RectF mBoundsF; 26 | private final Rect mBoundsI; 27 | private float mPadding; 28 | private boolean mInsetForPadding = false; 29 | private boolean mInsetForRadius = true; 30 | 31 | public RoundRectDrawable(int backgroundColor, float radius) { 32 | mRadius = radius; 33 | mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); 34 | mPaint.setColor(backgroundColor); 35 | mBoundsF = new RectF(); 36 | mBoundsI = new Rect(); 37 | } 38 | 39 | void setPadding(float padding, boolean insetForPadding, boolean insetForRadius) { 40 | if (padding == mPadding && mInsetForPadding == insetForPadding && 41 | mInsetForRadius == insetForRadius) { 42 | return; 43 | } 44 | mPadding = padding; 45 | mInsetForPadding = insetForPadding; 46 | mInsetForRadius = insetForRadius; 47 | updateBounds(null); 48 | invalidateSelf(); 49 | } 50 | 51 | float getPadding() { 52 | return mPadding; 53 | } 54 | 55 | @Override 56 | public void draw(Canvas canvas) { 57 | canvas.drawRoundRect(mBoundsF, mRadius, mRadius, mPaint); 58 | } 59 | 60 | private void updateBounds(Rect bounds) { 61 | if (bounds == null) { 62 | bounds = getBounds(); 63 | } 64 | mBoundsF.set(bounds.left, bounds.top, bounds.right, bounds.bottom); 65 | mBoundsI.set(bounds); 66 | if (mInsetForPadding) { 67 | float vInset = calculateVerticalPadding(mPadding, mRadius, mInsetForRadius); 68 | float hInset = calculateHorizontalPadding(mPadding, mRadius, mInsetForRadius); 69 | mBoundsI.inset((int) Math.ceil(hInset), (int) Math.ceil(vInset)); 70 | // to make sure they have same bounds. 71 | mBoundsF.set(mBoundsI); 72 | } 73 | } 74 | 75 | @Override 76 | protected void onBoundsChange(Rect bounds) { 77 | super.onBoundsChange(bounds); 78 | updateBounds(bounds); 79 | } 80 | 81 | @Override 82 | public void getOutline(Outline outline) { 83 | outline.setRoundRect(mBoundsI, mRadius); 84 | } 85 | 86 | void setRadius(float radius) { 87 | if (radius == mRadius) { 88 | return; 89 | } 90 | mRadius = radius; 91 | updateBounds(null); 92 | invalidateSelf(); 93 | } 94 | 95 | @Override 96 | public void setAlpha(int alpha) { 97 | // not supported because older versions do not support 98 | } 99 | 100 | @Override 101 | public void setColorFilter(ColorFilter cf) { 102 | // not supported because older versions do not support 103 | } 104 | 105 | @Override 106 | public int getOpacity() { 107 | return PixelFormat.TRANSLUCENT; 108 | } 109 | 110 | public float getRadius() { 111 | return mRadius; 112 | } 113 | 114 | public void setColor(int color) { 115 | mPaint.setColor(color); 116 | invalidateSelf(); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/RoundRectDrawableWithShadow.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | 4 | import android.content.res.Resources; 5 | import android.graphics.Canvas; 6 | import android.graphics.ColorFilter; 7 | import android.graphics.LinearGradient; 8 | import android.graphics.Paint; 9 | import android.graphics.Path; 10 | import android.graphics.PixelFormat; 11 | import android.graphics.RadialGradient; 12 | import android.graphics.Rect; 13 | import android.graphics.RectF; 14 | import android.graphics.Shader; 15 | import android.graphics.drawable.Drawable; 16 | 17 | /** 18 | * A rounded rectangle drawable which also includes a shadow around. 19 | */ 20 | class RoundRectDrawableWithShadow extends Drawable { 21 | // used to calculate content padding 22 | final static double COS_45 = Math.cos(Math.toRadians(45)); 23 | 24 | final static float SHADOW_MULTIPLIER = 1.5f; 25 | 26 | final int mInsetShadow; // extra shadow to avoid gaps between card and shadow 27 | 28 | /* 29 | * This helper is set by CardView implementations. 30 | *

31 | * Prior to API 17, canvas.drawRoundRect is expensive; which is why we need this interface 32 | * to draw efficient rounded rectangles before 17. 33 | * */ 34 | static RoundRectHelper sRoundRectHelper; 35 | 36 | Paint mPaint; 37 | 38 | Paint mCornerShadowPaint; 39 | 40 | Paint mEdgeShadowPaint; 41 | 42 | final RectF mCardBounds; 43 | 44 | float mCornerRadius; 45 | 46 | Path mCornerShadowPath; 47 | 48 | // updated value with inset 49 | float mMaxShadowSize; 50 | 51 | // actual value set by developer 52 | float mRawMaxShadowSize; 53 | 54 | // multiplied value to account for shadow offset 55 | float mShadowSize; 56 | 57 | // actual value set by developer 58 | float mRawShadowSize; 59 | 60 | private boolean mDirty = true; 61 | 62 | private final int mShadowStartColor; 63 | 64 | private final int mShadowEndColor; 65 | 66 | private boolean mAddPaddingForCorners = true; 67 | 68 | /** 69 | * If shadow size is set to a value above max shadow, we print a warning 70 | */ 71 | private boolean mPrintedShadowClipWarning = false; 72 | 73 | RoundRectDrawableWithShadow(Resources resources, int backgroundColor, float radius, 74 | float shadowSize, float maxShadowSize) { 75 | mShadowStartColor = resources.getColor(R.color.cardview_shadow_start_color); 76 | mShadowEndColor = resources.getColor(R.color.cardview_shadow_end_color); 77 | mInsetShadow = resources.getDimensionPixelSize(R.dimen.cardview_compat_inset_shadow); 78 | mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); 79 | mPaint.setColor(backgroundColor); 80 | mCornerShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); 81 | mCornerShadowPaint.setStyle(Paint.Style.FILL); 82 | mCornerRadius = (int) (radius + .5f); 83 | mCardBounds = new RectF(); 84 | mEdgeShadowPaint = new Paint(mCornerShadowPaint); 85 | mEdgeShadowPaint.setAntiAlias(false); 86 | setShadowSize(shadowSize, maxShadowSize); 87 | } 88 | 89 | /** 90 | * Casts the value to an even integer. 91 | */ 92 | private int toEven(float value) { 93 | int i = (int) (value + .5f); 94 | if (i % 2 == 1) { 95 | return i - 1; 96 | } 97 | return i; 98 | } 99 | 100 | public void setAddPaddingForCorners(boolean addPaddingForCorners) { 101 | mAddPaddingForCorners = addPaddingForCorners; 102 | invalidateSelf(); 103 | } 104 | 105 | @Override 106 | public void setAlpha(int alpha) { 107 | mPaint.setAlpha(alpha); 108 | mCornerShadowPaint.setAlpha(alpha); 109 | mEdgeShadowPaint.setAlpha(alpha); 110 | } 111 | 112 | @Override 113 | protected void onBoundsChange(Rect bounds) { 114 | super.onBoundsChange(bounds); 115 | mDirty = true; 116 | } 117 | 118 | void setShadowSize(float shadowSize, float maxShadowSize) { 119 | if (shadowSize < 0 || maxShadowSize < 0) { 120 | throw new IllegalArgumentException("invalid shadow size"); 121 | } 122 | shadowSize = toEven(shadowSize); 123 | maxShadowSize = toEven(maxShadowSize); 124 | if (shadowSize > maxShadowSize) { 125 | shadowSize = maxShadowSize; 126 | if (!mPrintedShadowClipWarning) { 127 | mPrintedShadowClipWarning = true; 128 | } 129 | } 130 | if (mRawShadowSize == shadowSize && mRawMaxShadowSize == maxShadowSize) { 131 | return; 132 | } 133 | mRawShadowSize = shadowSize; 134 | mRawMaxShadowSize = maxShadowSize; 135 | mShadowSize = (int)(shadowSize * SHADOW_MULTIPLIER + mInsetShadow + .5f); 136 | mMaxShadowSize = maxShadowSize + mInsetShadow; 137 | mDirty = true; 138 | invalidateSelf(); 139 | } 140 | 141 | @Override 142 | public boolean getPadding(Rect padding) { 143 | int vOffset = (int) Math.ceil(calculateVerticalPadding(mRawMaxShadowSize, mCornerRadius, 144 | mAddPaddingForCorners)); 145 | int hOffset = (int) Math.ceil(calculateHorizontalPadding(mRawMaxShadowSize, mCornerRadius, 146 | mAddPaddingForCorners)); 147 | padding.set(hOffset, vOffset, hOffset, vOffset); 148 | return true; 149 | } 150 | 151 | static float calculateVerticalPadding(float maxShadowSize, float cornerRadius, 152 | boolean addPaddingForCorners) { 153 | if (addPaddingForCorners) { 154 | return (float) (maxShadowSize * SHADOW_MULTIPLIER + (1 - COS_45) * cornerRadius); 155 | } else { 156 | return maxShadowSize * SHADOW_MULTIPLIER; 157 | } 158 | } 159 | 160 | static float calculateHorizontalPadding(float maxShadowSize, float cornerRadius, 161 | boolean addPaddingForCorners) { 162 | if (addPaddingForCorners) { 163 | return (float) (maxShadowSize + (1 - COS_45) * cornerRadius); 164 | } else { 165 | return maxShadowSize; 166 | } 167 | } 168 | 169 | @Override 170 | public void setColorFilter(ColorFilter cf) { 171 | mPaint.setColorFilter(cf); 172 | mCornerShadowPaint.setColorFilter(cf); 173 | mEdgeShadowPaint.setColorFilter(cf); 174 | } 175 | 176 | @Override 177 | public int getOpacity() { 178 | return PixelFormat.TRANSLUCENT; 179 | } 180 | 181 | void setCornerRadius(float radius) { 182 | radius = (int) (radius + .5f); 183 | if (mCornerRadius == radius) { 184 | return; 185 | } 186 | mCornerRadius = radius; 187 | mDirty = true; 188 | invalidateSelf(); 189 | } 190 | 191 | @Override 192 | public void draw(Canvas canvas) { 193 | if (mDirty) { 194 | buildComponents(getBounds()); 195 | mDirty = false; 196 | } 197 | canvas.translate(0, mRawShadowSize / 2); 198 | drawShadow(canvas); 199 | canvas.translate(0, -mRawShadowSize / 2); 200 | sRoundRectHelper.drawRoundRect(canvas, mCardBounds, mCornerRadius, mPaint); 201 | } 202 | 203 | private void drawShadow(Canvas canvas) { 204 | final float edgeShadowTop = -mCornerRadius - mShadowSize; 205 | final float inset = mCornerRadius + mInsetShadow + mRawShadowSize / 2; 206 | final boolean drawHorizontalEdges = mCardBounds.width() - 2 * inset > 0; 207 | final boolean drawVerticalEdges = mCardBounds.height() - 2 * inset > 0; 208 | // LT 209 | int saved = canvas.save(); 210 | canvas.translate(mCardBounds.left + inset, mCardBounds.top + inset); 211 | canvas.drawPath(mCornerShadowPath, mCornerShadowPaint); 212 | if (drawHorizontalEdges) { 213 | canvas.drawRect(0, edgeShadowTop, 214 | mCardBounds.width() - 2 * inset, -mCornerRadius, 215 | mEdgeShadowPaint); 216 | } 217 | canvas.restoreToCount(saved); 218 | // RB 219 | saved = canvas.save(); 220 | canvas.translate(mCardBounds.right - inset, mCardBounds.bottom - inset); 221 | canvas.rotate(180f); 222 | canvas.drawPath(mCornerShadowPath, mCornerShadowPaint); 223 | if (drawHorizontalEdges) { 224 | canvas.drawRect(0, edgeShadowTop, 225 | mCardBounds.width() - 2 * inset, -mCornerRadius + mShadowSize, 226 | mEdgeShadowPaint); 227 | } 228 | canvas.restoreToCount(saved); 229 | // LB 230 | saved = canvas.save(); 231 | canvas.translate(mCardBounds.left + inset, mCardBounds.bottom - inset); 232 | canvas.rotate(270f); 233 | canvas.drawPath(mCornerShadowPath, mCornerShadowPaint); 234 | if (drawVerticalEdges) { 235 | canvas.drawRect(0, edgeShadowTop, 236 | mCardBounds.height() - 2 * inset, -mCornerRadius, mEdgeShadowPaint); 237 | } 238 | canvas.restoreToCount(saved); 239 | // RT 240 | saved = canvas.save(); 241 | canvas.translate(mCardBounds.right - inset, mCardBounds.top + inset); 242 | canvas.rotate(90f); 243 | canvas.drawPath(mCornerShadowPath, mCornerShadowPaint); 244 | if (drawVerticalEdges) { 245 | canvas.drawRect(0, edgeShadowTop, 246 | mCardBounds.height() - 2 * inset, -mCornerRadius, mEdgeShadowPaint); 247 | } 248 | canvas.restoreToCount(saved); 249 | } 250 | 251 | private void buildShadowCorners() { 252 | RectF innerBounds = new RectF(-mCornerRadius, -mCornerRadius, mCornerRadius, mCornerRadius); 253 | RectF outerBounds = new RectF(innerBounds); 254 | outerBounds.inset(-mShadowSize, -mShadowSize); 255 | 256 | if (mCornerShadowPath == null) { 257 | mCornerShadowPath = new Path(); 258 | } else { 259 | mCornerShadowPath.reset(); 260 | } 261 | mCornerShadowPath.setFillType(Path.FillType.EVEN_ODD); 262 | mCornerShadowPath.moveTo(-mCornerRadius, 0); 263 | mCornerShadowPath.rLineTo(-mShadowSize, 0); 264 | // outer arc 265 | mCornerShadowPath.arcTo(outerBounds, 180f, 90f, false); 266 | // inner arc 267 | mCornerShadowPath.arcTo(innerBounds, 270f, -90f, false); 268 | mCornerShadowPath.close(); 269 | float startRatio = mCornerRadius / (mCornerRadius + mShadowSize); 270 | mCornerShadowPaint.setShader(new RadialGradient(0, 0, mCornerRadius + mShadowSize, 271 | new int[]{mShadowStartColor, mShadowStartColor, mShadowEndColor}, 272 | new float[]{0f, startRatio, 1f} 273 | , Shader.TileMode.CLAMP)); 274 | 275 | // we offset the content shadowSize/2 pixels up to make it more realistic. 276 | // this is why edge shadow shader has some extra space 277 | // When drawing bottom edge shadow, we use that extra space. 278 | mEdgeShadowPaint.setShader(new LinearGradient(0, -mCornerRadius + mShadowSize, 0, 279 | -mCornerRadius - mShadowSize, 280 | new int[]{mShadowStartColor, mShadowStartColor, mShadowEndColor}, 281 | new float[]{0f, .5f, 1f}, Shader.TileMode.CLAMP)); 282 | mEdgeShadowPaint.setAntiAlias(false); 283 | } 284 | 285 | private void buildComponents(Rect bounds) { 286 | // Card is offset SHADOW_MULTIPLIER * maxShadowSize to account for the shadow shift. 287 | // We could have different top-bottom offsets to avoid extra gap above but in that case 288 | // center aligning Views inside the CardView would be problematic. 289 | final float verticalOffset = mRawMaxShadowSize * SHADOW_MULTIPLIER; 290 | mCardBounds.set(bounds.left + mRawMaxShadowSize, bounds.top + verticalOffset, 291 | bounds.right - mRawMaxShadowSize, bounds.bottom - verticalOffset); 292 | buildShadowCorners(); 293 | } 294 | 295 | float getCornerRadius() { 296 | return mCornerRadius; 297 | } 298 | 299 | void getMaxShadowAndCornerPadding(Rect into) { 300 | getPadding(into); 301 | } 302 | 303 | void setShadowSize(float size) { 304 | setShadowSize(size, mRawMaxShadowSize); 305 | } 306 | 307 | void setMaxShadowSize(float size) { 308 | setShadowSize(mRawShadowSize, size); 309 | } 310 | 311 | float getShadowSize() { 312 | return mRawShadowSize; 313 | } 314 | 315 | float getMaxShadowSize() { 316 | return mRawMaxShadowSize; 317 | } 318 | 319 | float getMinWidth() { 320 | final float content = 2 * 321 | Math.max(mRawMaxShadowSize, mCornerRadius + mInsetShadow + mRawMaxShadowSize / 2); 322 | return content + (mRawMaxShadowSize + mInsetShadow) * 2; 323 | } 324 | 325 | float getMinHeight() { 326 | final float content = 2 * Math.max(mRawMaxShadowSize, mCornerRadius + mInsetShadow 327 | + mRawMaxShadowSize * SHADOW_MULTIPLIER / 2); 328 | return content + (mRawMaxShadowSize * SHADOW_MULTIPLIER + mInsetShadow) * 2; 329 | } 330 | 331 | public void setColor(int color) { 332 | mPaint.setColor(color); 333 | invalidateSelf(); 334 | } 335 | 336 | static interface RoundRectHelper { 337 | void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius, Paint paint); 338 | } 339 | } 340 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/SearchHistorysBean.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | public class SearchHistorysBean { 4 | public int _id; 5 | public String historyword; 6 | public long updatetime; 7 | 8 | public SearchHistorysBean(){ 9 | 10 | } 11 | 12 | public SearchHistorysBean(String historyword, long updatetime) { 13 | this.historyword = historyword; 14 | this.updatetime = updatetime; 15 | } 16 | 17 | public SearchHistorysBean(int _id) { 18 | this._id = _id; 19 | } 20 | 21 | 22 | public SearchHistorysBean(String historyword) { 23 | this.historyword = historyword; 24 | } 25 | 26 | 27 | public SearchHistorysBean(long updatetime) { 28 | this.updatetime = updatetime; 29 | } 30 | 31 | public SearchHistorysBean(int _id, String historyword, long updatetime) { 32 | this._id = _id; 33 | this.historyword = historyword; 34 | this.updatetime = updatetime; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | 40 | return historyword; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/SearchHistorysDao.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | import android.content.Context; 4 | import android.database.Cursor; 5 | import android.database.sqlite.SQLiteDatabase; 6 | 7 | import java.util.ArrayList; 8 | 9 | public class SearchHistorysDao { 10 | 11 | private DBSearchHelper helper; 12 | 13 | private SQLiteDatabase db; 14 | 15 | public SearchHistorysDao(Context context) { 16 | helper = new DBSearchHelper(context); 17 | } 18 | 19 | 20 | /** 21 | * 对数据库进行增加或是update的操作 22 | * 23 | */ 24 | 25 | public void addOrUpdate(String word){ 26 | SQLiteDatabase db = helper.getWritableDatabase(); 27 | String sql = "select _id from t_historywords where historyword = ? "; 28 | Cursor cursor = db.rawQuery(sql, new String[]{word}); 29 | if(cursor.getCount()>0){ 30 | //说明数据库中已经有数据:更新数据库的时间: 31 | String sql_update = "update t_historywords set updatetime = ? where historyword = ? "; 32 | db.execSQL(sql_update, new String[]{System.currentTimeMillis()+"",word}); 33 | }else{ 34 | //直接插入一条记录: 35 | String sql_add = "insert into t_historywords(historyword,updatetime) values (?,?);"; 36 | db.execSQL(sql_add, new String[]{word,System.currentTimeMillis()+""}); 37 | } 38 | 39 | cursor.close(); 40 | db.close(); 41 | } 42 | 43 | /** 44 | * 查询数据库中所有的数据 45 | * 46 | */ 47 | 48 | public ArrayList findAll(){ 49 | ArrayList data = new ArrayList();; 50 | SQLiteDatabase db = helper.getReadableDatabase(); 51 | Cursor cursor = db.query("t_historywords", null, null, null, null, null, "updatetime desc"); 52 | //遍历游标,将数据存储在 53 | while(cursor.moveToNext()){ 54 | SearchHistorysBean searchDBData = new SearchHistorysBean(); 55 | searchDBData._id =cursor.getInt(cursor.getColumnIndex("_id")); 56 | searchDBData.historyword = cursor.getString(cursor.getColumnIndex("historyword")); 57 | searchDBData.updatetime = cursor.getLong(cursor.getColumnIndex("updatetime")); 58 | data.add(searchDBData); 59 | } 60 | cursor.close(); 61 | db.close(); 62 | return data; 63 | } 64 | 65 | 66 | /** 67 | * 68 | * 删除数据库中的所有数据 69 | */ 70 | 71 | public void deleteAll(){ 72 | SQLiteDatabase db = helper.getReadableDatabase(); 73 | db.execSQL("delete from t_historywords"); 74 | db.close(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/nico/styTool/plus/SlideBottomPanel.java: -------------------------------------------------------------------------------- 1 | package nico.styTool.plus; 2 | 3 | import android.animation.Animator; 4 | import android.animation.ValueAnimator; 5 | import android.app.Application; 6 | import android.content.Context; 7 | import android.content.res.TypedArray; 8 | import android.os.Build; 9 | import android.util.AttributeSet; 10 | import android.view.LayoutInflater; 11 | import android.view.MotionEvent; 12 | import android.view.VelocityTracker; 13 | import android.view.View; 14 | import android.view.ViewConfiguration; 15 | import android.view.ViewGroup; 16 | import android.view.animation.AccelerateInterpolator; 17 | import android.view.animation.Interpolator; 18 | import android.widget.AbsListView; 19 | import android.widget.FrameLayout; 20 | import android.widget.ScrollView; 21 | 22 | import com.nineoldandroids.animation.ObjectAnimator; 23 | import com.nineoldandroids.view.ViewHelper; 24 | 25 | /** 26 | * Created by NeXT on 15/8/3. 27 | */ 28 | public class SlideBottomPanel extends FrameLayout { 29 | 30 | private static final int TAG_BACKGROUND = 1; 31 | private static final int TAG_PANEL = 2; 32 | 33 | private static final int DEFAULT_BACKGROUND_ID = -1; 34 | private static final int DEFAULT_TITLE_HEIGHT_NO_DISPLAY = 60; 35 | private static final int DEFAULT_PANEL_HEIGHT = 380; 36 | private static final int DEFAULT_MOVE_DISTANCE_TO_TRIGGER = 30; 37 | private static final int DEFAULT_ANIMATION_DURATION = 250; 38 | private static final int MAX_CLICK_TIME = 300; 39 | private static final boolean DEFAULT_FADE = true; 40 | private static final boolean DEFAULT_BOUNDARY = true; 41 | private static final boolean DEFAULT_HIDE_PANEL_TITLE = false; 42 | 43 | private static float MAX_CLICK_DISTANCE = 5; 44 | 45 | private int mChildCount; 46 | private float mDensity; 47 | private boolean isAnimating = false; 48 | private boolean isPanelShowing = false; 49 | 50 | private float xVelocity; 51 | private float yVelocity; 52 | private float mTouchSlop; 53 | private int mMaxVelocity; 54 | private int mMinVelocity; 55 | private VelocityTracker mVelocityTracker; 56 | 57 | private int mMeasureHeight; 58 | private float firstDownX; 59 | private float firstDownY; 60 | private float downY; 61 | private float deltaY; 62 | private long mPressStartTime; 63 | private boolean isDragging = false; 64 | 65 | private int mBackgroundId; 66 | private float mPanelHeight; 67 | private float mTitleHeightNoDisplay; 68 | private float mMoveDistanceToTrigger; 69 | private int mAnimationDuration; 70 | private boolean mIsFade = true; 71 | private boolean mBoundary = true; 72 | private boolean mHidePanelTitle = false; 73 | private boolean isPanelOnTouch = false; 74 | 75 | private Interpolator mOpenAnimationInterpolator = new AccelerateInterpolator(); 76 | private Interpolator mCloseAnimationInterpolator = new AccelerateInterpolator(); 77 | 78 | private Context mContext; 79 | private DarkFrameLayout mDarkFrameLayout; 80 | 81 | public SlideBottomPanel(Context context) { 82 | this(context, null); 83 | } 84 | 85 | public SlideBottomPanel(Context context, AttributeSet attrs) { 86 | this(context, attrs, 0); 87 | } 88 | 89 | public SlideBottomPanel(Context context, AttributeSet attrs, int defStyleAttr) { 90 | super(context, attrs, defStyleAttr); 91 | 92 | mContext = context; 93 | mDensity = getResources().getDisplayMetrics().density; 94 | 95 | ViewConfiguration vc = ViewConfiguration.get(mContext); 96 | mMaxVelocity = vc.getScaledMaximumFlingVelocity(); 97 | mMinVelocity = vc.getScaledMinimumFlingVelocity(); 98 | mTouchSlop = vc.getScaledTouchSlop(); 99 | 100 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideBottomPanel, defStyleAttr, 0); 101 | 102 | mBackgroundId = a.getResourceId(R.styleable.SlideBottomPanel_sbp_background_layout, DEFAULT_BACKGROUND_ID); 103 | mPanelHeight = a.getDimension(R.styleable.SlideBottomPanel_sbp_panel_height, dp2px(DEFAULT_PANEL_HEIGHT)); 104 | mBoundary = a.getBoolean(R.styleable.SlideBottomPanel_sbp_boundary, DEFAULT_BOUNDARY); 105 | MAX_CLICK_DISTANCE = mTitleHeightNoDisplay = a.getDimension(R.styleable.SlideBottomPanel_sbp_title_height_no_display,dp2px(DEFAULT_TITLE_HEIGHT_NO_DISPLAY)); 106 | mMoveDistanceToTrigger = a.getDimension(R.styleable.SlideBottomPanel_sbp_move_distance_trigger, dp2px(DEFAULT_MOVE_DISTANCE_TO_TRIGGER)); 107 | mAnimationDuration = a.getInt(R.styleable.SlideBottomPanel_sbp_animation_duration, DEFAULT_ANIMATION_DURATION); 108 | mHidePanelTitle = a.getBoolean(R.styleable.SlideBottomPanel_sbp_hide_panel_title, DEFAULT_HIDE_PANEL_TITLE); 109 | mIsFade = a.getBoolean(R.styleable.SlideBottomPanel_sbp_fade, DEFAULT_FADE); 110 | 111 | a.recycle(); 112 | 113 | initBackgroundView(); 114 | } 115 | 116 | @Override 117 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 118 | super.onLayout(changed, left, top, right, bottom); 119 | mChildCount = getChildCount(); 120 | int t = (int) (mMeasureHeight - mTitleHeightNoDisplay); 121 | for (int i = 0; i < mChildCount; i++) { 122 | View childView = getChildAt(i); 123 | if (childView.getTag() == null || (int) childView.getTag() != TAG_BACKGROUND) { 124 | childView.layout(0, t, childView.getMeasuredWidth(), childView.getMeasuredHeight() + t); 125 | childView.setTag(TAG_PANEL); 126 | // if (childView instanceof ViewGroup) { 127 | // ((ViewGroup)childView).setClipChildren(false); 128 | // } 129 | } else if (childView.getTag() == null){//空指计 130 | childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight()); 131 | childView.setPadding(0, 0, 0, (int)mTitleHeightNoDisplay); 132 | } 133 | } 134 | } 135 | 136 | @Override 137 | public boolean onInterceptTouchEvent(MotionEvent ev) { 138 | return isDragging; 139 | } 140 | 141 | @Override 142 | public boolean onTouchEvent(MotionEvent event) { 143 | return true; 144 | } 145 | 146 | @Override 147 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 148 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 149 | mMeasureHeight = getMeasuredHeight(); 150 | } 151 | 152 | @Override 153 | public boolean dispatchTouchEvent(MotionEvent ev) { 154 | initVelocityTracker(ev); 155 | boolean isConsume = false; 156 | switch (ev.getAction()) { 157 | case MotionEvent.ACTION_DOWN: 158 | isConsume = handleActionDown(ev); 159 | break; 160 | case MotionEvent.ACTION_MOVE: 161 | handleActionMove(ev); 162 | break; 163 | case MotionEvent.ACTION_UP: 164 | handleActionUp(ev); 165 | releaseVelocityTracker(); 166 | break; 167 | } 168 | return isConsume || super.dispatchTouchEvent(ev); 169 | } 170 | 171 | private void initBackgroundView() { 172 | if (mBackgroundId != -1) { 173 | mDarkFrameLayout = new DarkFrameLayout(mContext); 174 | mDarkFrameLayout.addView(LayoutInflater.from(mContext).inflate(mBackgroundId, null)); 175 | mDarkFrameLayout.setTag(TAG_BACKGROUND); 176 | mDarkFrameLayout.setSlideBottomPanel(this); 177 | addView(mDarkFrameLayout); 178 | } 179 | } 180 | 181 | private void handleActionUp(MotionEvent event) { 182 | if (!isPanelOnTouch) { 183 | return; 184 | } 185 | long pressDuration = System.currentTimeMillis() - mPressStartTime; 186 | computeVelocity(); 187 | if (!isPanelShowing && ((event.getY() - firstDownY) < 0 && (Math.abs(event.getY() - firstDownY) > mMoveDistanceToTrigger)) 188 | || (yVelocity < 0 && Math.abs(yVelocity) > Math.abs(xVelocity) && Math.abs(yVelocity) > mMinVelocity)) { 189 | displayPanel(); 190 | } else if (!isPanelShowing && pressDuration < MAX_CLICK_TIME && 191 | distance(firstDownX, firstDownY, event.getX(), event.getY()) < MAX_CLICK_DISTANCE) { 192 | displayPanel(); 193 | } else if (!isPanelShowing && isDragging && ((event.getY() - firstDownY > 0) || 194 | Math.abs(event.getY() - firstDownY) < mMoveDistanceToTrigger)){ 195 | hidePanel(); 196 | } 197 | 198 | if (isPanelShowing) { 199 | View mPanel = findViewWithTag(TAG_PANEL); 200 | float currentY = ViewHelper.getY(mPanel); 201 | if (currentY < (mMeasureHeight - mPanelHeight) || 202 | currentY < (mMeasureHeight - mPanelHeight + mMoveDistanceToTrigger)) { 203 | ObjectAnimator.ofFloat(mPanel, "y", currentY, mMeasureHeight - mPanelHeight) 204 | .setDuration(mAnimationDuration).start(); 205 | } else if (currentY > mMeasureHeight - mPanelHeight + mMoveDistanceToTrigger){ 206 | hidePanel(); 207 | } 208 | } 209 | 210 | isPanelOnTouch = false; 211 | isDragging = false; 212 | deltaY = 0; 213 | } 214 | 215 | private void handleActionMove(MotionEvent event) { 216 | if (!isPanelOnTouch) { 217 | return; 218 | } 219 | if (isPanelShowing && supportScrollInView((int) (firstDownY - event.getY()))) { 220 | return; 221 | } 222 | computeVelocity(); 223 | if (Math.abs(xVelocity) > Math.abs(yVelocity)) { 224 | return; 225 | } 226 | if (!isDragging && Math.abs(event.getY() - firstDownY) > mTouchSlop 227 | && Math.abs(event.getX() - firstDownX) < mTouchSlop) { 228 | isDragging = true; 229 | downY = event.getY(); 230 | } 231 | if (isDragging) { 232 | deltaY = event.getY() - downY; 233 | downY = event.getY(); 234 | 235 | View touchingView = findViewWithTag(TAG_PANEL); 236 | 237 | if (mHidePanelTitle && isPanelShowing) { 238 | hidePanelTitle(touchingView); 239 | } 240 | 241 | if (mDarkFrameLayout != null && mIsFade) { 242 | float currentY = ViewHelper.getY(touchingView); 243 | if (currentY > mMeasureHeight - mPanelHeight && 244 | currentY < mMeasureHeight - mTitleHeightNoDisplay) { 245 | mDarkFrameLayout.fade( 246 | (int) ((1 - currentY / (mMeasureHeight - mTitleHeightNoDisplay)) * DarkFrameLayout.MAX_ALPHA)); 247 | } 248 | } 249 | if (!mBoundary) { 250 | touchingView.offsetTopAndBottom((int) deltaY); 251 | } else { 252 | float touchingViewY = ViewHelper.getY(touchingView); 253 | if (touchingViewY + deltaY <= mMeasureHeight - mPanelHeight) { 254 | touchingView.offsetTopAndBottom((int) (mMeasureHeight - mPanelHeight - touchingViewY)); 255 | } else if (touchingViewY + deltaY >= mMeasureHeight - mTitleHeightNoDisplay) { 256 | touchingView.offsetTopAndBottom((int) (mMeasureHeight - mTitleHeightNoDisplay - touchingViewY)); 257 | } else { 258 | touchingView.offsetTopAndBottom((int) deltaY); 259 | } 260 | } 261 | } 262 | } 263 | 264 | private boolean handleActionDown(MotionEvent event) { 265 | boolean isConsume = false; 266 | mPressStartTime = System.currentTimeMillis(); 267 | firstDownX = event.getX(); 268 | firstDownY = downY = event.getY(); 269 | if (!isPanelShowing && downY > mMeasureHeight - mTitleHeightNoDisplay) { 270 | isPanelOnTouch = true; 271 | isConsume = true; 272 | } else if (!isPanelShowing && downY <= mMeasureHeight - mTitleHeightNoDisplay) { 273 | isPanelOnTouch = false; 274 | } else if (isPanelShowing && downY > mMeasureHeight - mPanelHeight) { 275 | isPanelOnTouch = true; 276 | } else if (isPanelShowing && downY < mMeasureHeight - mPanelHeight) { 277 | hidePanel(); 278 | isPanelOnTouch = false; 279 | } 280 | return isConsume; 281 | } 282 | 283 | private void hidePanel() { 284 | if (isAnimating) { 285 | return; 286 | } 287 | final View mPanel = findViewWithTag(TAG_PANEL); 288 | final int t = (int)(mMeasureHeight - mTitleHeightNoDisplay); 289 | ValueAnimator animator = ValueAnimator.ofFloat( 290 | ViewHelper.getY(mPanel), mMeasureHeight - mTitleHeightNoDisplay); 291 | animator.setInterpolator(mCloseAnimationInterpolator); 292 | animator.setTarget(mPanel); 293 | animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 294 | @Override 295 | public void onAnimationUpdate(ValueAnimator animation) { 296 | float value = (float) animation.getAnimatedValue(); 297 | ViewHelper.setY(mPanel, value); 298 | if (mDarkFrameLayout != null && mIsFade && value < t) { 299 | mDarkFrameLayout.fade((int) ((1 - value / t) * DarkFrameLayout.MAX_ALPHA)); 300 | } 301 | } 302 | }); 303 | animator.addListener(new Animator.AnimatorListener() { 304 | @Override 305 | public void onAnimationStart(Animator animation) { 306 | isAnimating = true; 307 | } 308 | 309 | @Override 310 | public void onAnimationEnd(Animator animation) { 311 | isAnimating = false; 312 | isPanelShowing = false; 313 | showPanelTitle(mPanel); 314 | } 315 | 316 | @Override 317 | public void onAnimationCancel(Animator animation) { 318 | isAnimating = false; 319 | isPanelShowing = false; 320 | showPanelTitle(mPanel); 321 | } 322 | 323 | @Override 324 | public void onAnimationRepeat(Animator animation) { 325 | } 326 | }); 327 | animator.start(); 328 | } 329 | 330 | public void displayPanel() { 331 | if (isPanelShowing || isAnimating) { 332 | return; 333 | } 334 | if (mIsFade || mDarkFrameLayout != null) { 335 | mDarkFrameLayout.fade(true); 336 | } 337 | final View mPanel = findViewWithTag(TAG_PANEL); 338 | ValueAnimator animator = ValueAnimator.ofFloat(ViewHelper.getY(mPanel), mMeasureHeight - mPanelHeight) 339 | .setDuration(mAnimationDuration); 340 | animator.setTarget(mPanel); 341 | animator.setInterpolator(mOpenAnimationInterpolator); 342 | animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 343 | @Override 344 | public void onAnimationUpdate(ValueAnimator animation) { 345 | float value = (float) animation.getAnimatedValue(); 346 | ViewHelper.setY(mPanel, value); 347 | if (mDarkFrameLayout != null && mIsFade 348 | && mDarkFrameLayout.getCurrentAlpha() != DarkFrameLayout.MAX_ALPHA) { 349 | mDarkFrameLayout.fade( 350 | (int) ((1 - value / (mMeasureHeight - mTitleHeightNoDisplay)) * DarkFrameLayout.MAX_ALPHA)); 351 | } 352 | } 353 | }); 354 | animator.addListener(new Animator.AnimatorListener() { 355 | @Override 356 | public void onAnimationStart(Animator animation) { 357 | isAnimating = true; 358 | } 359 | 360 | @Override 361 | public void onAnimationEnd(Animator animation) { 362 | isAnimating = false; 363 | } 364 | 365 | @Override 366 | public void onAnimationCancel(Animator animation) { 367 | isAnimating = false; 368 | } 369 | 370 | @Override 371 | public void onAnimationRepeat(Animator animation) { 372 | } 373 | }); 374 | animator.start(); 375 | isPanelShowing = true; 376 | hidePanelTitle(mPanel); 377 | } 378 | 379 | private void showPanelTitle(View panel) { 380 | if (panel instanceof ViewGroup && mHidePanelTitle) { 381 | try { 382 | View childView = ((ViewGroup) panel).getChildAt(1); 383 | if (childView.getVisibility() != View.VISIBLE) { 384 | childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight()); 385 | childView.setVisibility(View.VISIBLE); 386 | } 387 | } catch (NullPointerException e) { 388 | e.printStackTrace(); 389 | } 390 | } 391 | } 392 | 393 | private void hidePanelTitle(View panel) { 394 | if (panel instanceof ViewGroup && mHidePanelTitle) { 395 | try { 396 | ((ViewGroup) panel).getChildAt(1).setVisibility(View.INVISIBLE); 397 | } catch (NullPointerException e) { 398 | e.printStackTrace(); 399 | } 400 | } 401 | } 402 | 403 | public void hide() { 404 | if(!isPanelShowing) return; 405 | hidePanel(); 406 | } 407 | 408 | private void computeVelocity() { 409 | //units是单位表示, 1代表px/毫秒, 1000代表px/秒 410 | mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity); 411 | xVelocity = mVelocityTracker.getXVelocity(); 412 | yVelocity = mVelocityTracker.getYVelocity(); 413 | } 414 | 415 | private boolean supportScrollInView(int direction) { 416 | 417 | View view = findViewWithTag(TAG_PANEL); 418 | if (view instanceof ViewGroup) { 419 | View childView = findTopChildUnder((ViewGroup) view, firstDownX, firstDownY); 420 | if (childView == null) { 421 | return false; 422 | } 423 | if (childView instanceof AbsListView) { 424 | AbsListView absListView = (AbsListView) childView; 425 | if (Build.VERSION.SDK_INT >= 19) { 426 | return absListView.canScrollList(direction); 427 | } else { 428 | return absListViewCanScrollList(absListView,direction); 429 | } 430 | } else if (childView instanceof ScrollView) { 431 | ScrollView scrollView = (ScrollView) childView; 432 | if (Build.VERSION.SDK_INT >= 14) { 433 | return scrollView.canScrollVertically(direction); 434 | } else { 435 | return scrollViewCanScrollVertically(scrollView, direction); 436 | } 437 | 438 | } else if (childView instanceof ViewGroup){ 439 | View grandchildView = findTopChildUnder((ViewGroup) childView, firstDownX, firstDownY); 440 | if (grandchildView == null) { 441 | return false; 442 | } 443 | if (grandchildView instanceof ViewGroup) { 444 | if (grandchildView instanceof AbsListView) { 445 | AbsListView absListView = (AbsListView) grandchildView; 446 | if (Build.VERSION.SDK_INT >= 19) { 447 | return absListView.canScrollList(direction); 448 | } else { 449 | return absListViewCanScrollList(absListView,direction); 450 | } 451 | } else if (grandchildView instanceof ScrollView) { 452 | ScrollView scrollView = (ScrollView) grandchildView; 453 | if (Build.VERSION.SDK_INT >= 14) { 454 | return scrollView.canScrollVertically(direction); 455 | } else { 456 | return scrollViewCanScrollVertically(scrollView, direction); 457 | } 458 | } 459 | } 460 | } 461 | 462 | 463 | } 464 | return false; 465 | } 466 | 467 | private View findTopChildUnder(ViewGroup parentView, float x, float y) { 468 | int childCount = parentView.getChildCount(); 469 | for (int i = childCount - 1; i >= 0; i--) { 470 | final View child = parentView.getChildAt(i); 471 | if (x >= child.getLeft() && x < child.getRight() && 472 | y >= child.getTop() + mMeasureHeight - mPanelHeight && 473 | y < child.getBottom() + mMeasureHeight - mPanelHeight) { 474 | return child; 475 | } 476 | } 477 | return null; 478 | } 479 | 480 | /** 481 | * Copy From ScrollView (API Level >= 14) 482 | * @param direction Negative to check scrolling up, positive to check 483 | * scrolling down. 484 | * @return true if the scrollView can be scrolled in the specified direction, 485 | * false otherwise 486 | */ 487 | private boolean scrollViewCanScrollVertically(ScrollView scrollView,int direction) { 488 | final int offset = Math.max(0, scrollView.getScrollY()); 489 | final int range = computeVerticalScrollRange(scrollView) - scrollView.getHeight(); 490 | if (range == 0) return false; 491 | if (direction < 0) { //scroll up 492 | return offset > 0; 493 | } else {//scroll down 494 | return offset < range - 1; 495 | } 496 | } 497 | 498 | /** 499 | * Copy From ScrollView (API Level >= 14) 500 | *

The scroll range of a scroll view is the overall height of all of its 501 | * children.

502 | */ 503 | private int computeVerticalScrollRange(ScrollView scrollView) { 504 | final int count = scrollView.getChildCount(); 505 | final int contentHeight = scrollView.getHeight() - scrollView.getPaddingBottom() - scrollView.getPaddingTop(); 506 | if (count == 0) { 507 | return contentHeight; 508 | } 509 | 510 | int scrollRange = scrollView.getChildAt(0).getBottom(); 511 | final int scrollY = scrollView.getScrollY(); 512 | final int overScrollBottom = Math.max(0, scrollRange - contentHeight); 513 | if (scrollY < 0) { 514 | scrollRange -= scrollY; 515 | } else if (scrollY > overScrollBottom) { 516 | scrollRange += scrollY - overScrollBottom; 517 | } 518 | 519 | return scrollRange; 520 | } 521 | 522 | /** 523 | * Copy From AbsListView (API Level >= 19) 524 | * @param absListView AbsListView 525 | * @param direction Negative to check scrolling up, positive to check 526 | * scrolling down. 527 | * @return true if the list can be scrolled in the specified direction, 528 | * false otherwise 529 | */ 530 | private boolean absListViewCanScrollList(AbsListView absListView,int direction) { 531 | final int childCount = absListView.getChildCount(); 532 | if (childCount == 0) { 533 | return false; 534 | } 535 | final int firstPosition = absListView.getFirstVisiblePosition(); 536 | if (direction > 0) {//can scroll down 537 | final int lastBottom = absListView.getChildAt(childCount - 1).getBottom(); 538 | final int lastPosition = firstPosition + childCount; 539 | return lastPosition < absListView.getCount() || lastBottom > absListView.getHeight() - absListView.getPaddingTop(); 540 | } else {//can scroll up 541 | final int firstTop = absListView.getChildAt(0).getTop(); 542 | return firstPosition > 0 || firstTop < absListView.getPaddingTop(); 543 | } 544 | } 545 | 546 | private void initVelocityTracker(MotionEvent event) { 547 | if (mVelocityTracker == null) { 548 | mVelocityTracker = VelocityTracker.obtain(); 549 | } 550 | mVelocityTracker.addMovement(event); 551 | } 552 | 553 | private void releaseVelocityTracker() { 554 | if (mVelocityTracker != null) { 555 | mVelocityTracker.clear(); 556 | mVelocityTracker.recycle(); 557 | mVelocityTracker = null; 558 | } 559 | } 560 | 561 | private double distance(float x1, float y1, float x2, float y2) { 562 | float deltaX = x1 - x2; 563 | float deltaY = y1 - y2; 564 | return Math.sqrt(deltaX * deltaX + deltaY * deltaY); 565 | } 566 | 567 | private int px2dp(int pxValue) { 568 | return (int) (pxValue / mDensity + 0.5f); 569 | } 570 | 571 | private int dp2px(int dpValue) { 572 | return (int) (dpValue * mDensity + 0.5f); 573 | } 574 | 575 | public boolean isPanelShowing() { 576 | return isPanelShowing; 577 | } 578 | } 579 | -------------------------------------------------------------------------------- /app/src/main/res/anim/bga_sbl_activity_backward_enter.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/bga_sbl_activity_backward_exit.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/bga_sbl_activity_forward_enter.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/bga_sbl_activity_forward_exit.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/bga_sbl_activity_swipeback_enter.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/bga_sbl_activity_swipeback_exit.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/window_back.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/anim/window_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/abc_btn_radio_to_on_mtrl_000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/abc_btn_radio_to_on_mtrl_000.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/abc_btn_radio_to_on_mtrl_015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/abc_btn_radio_to_on_mtrl_015.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_adb_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/ic_adb_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_add_alert_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/ic_add_alert_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_edit_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/ic_edit_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_insert_emoticon_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/ic_insert_emoticon_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_pause_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/ic_pause_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_photo_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/ic_photo_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/ic_play_arrow_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_send_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/ic_send_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_stop_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/ic_stop_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/image.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/notification.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/wifi_automatic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/wifi_automatic.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/wifi_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-hdpi/wifi_file.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/abc_btn_radio_to_on_mtrl_000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/abc_btn_radio_to_on_mtrl_000.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/abc_btn_radio_to_on_mtrl_015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/abc_btn_radio_to_on_mtrl_015.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_adb_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/ic_adb_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_add_alert_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/ic_add_alert_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_arrow_back_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/ic_arrow_back_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_edit_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/ic_edit_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_insert_emoticon_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/ic_insert_emoticon_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_pause_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/ic_pause_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_photo_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/ic_photo_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_play_arrow_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/ic_play_arrow_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_send_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/ic_send_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_stop_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-mdpi/ic_stop_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/emoji_0030.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-nodpi/emoji_0030.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/emoji_0031.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-nodpi/emoji_0031.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/emoji_0032.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-nodpi/emoji_0032.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/emoji_0033.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-nodpi/emoji_0033.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/emoji_0034.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-nodpi/emoji_0034.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/emoji_0035.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-nodpi/emoji_0035.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/emoji_0036.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-nodpi/emoji_0036.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/emoji_0037.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-nodpi/emoji_0037.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/emoji_0038.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-nodpi/emoji_0038.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/emoji_0039.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-nodpi/emoji_0039.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/emoji_26a1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-nodpi/emoji_26a1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/abc_btn_radio_to_on_mtrl_000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/abc_btn_radio_to_on_mtrl_000.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/abc_btn_radio_to_on_mtrl_015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/abc_btn_radio_to_on_mtrl_015.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_adb_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/ic_adb_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_add_alert_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/ic_add_alert_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_arrow_back_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/ic_arrow_back_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_edit_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/ic_edit_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_insert_emoticon_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/ic_insert_emoticon_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_pause_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/ic_pause_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_photo_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/ic_photo_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/ic_play_arrow_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_send_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/ic_send_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_stop_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xhdpi/ic_stop_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/abc_btn_radio_to_on_mtrl_000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/abc_btn_radio_to_on_mtrl_000.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/abc_btn_radio_to_on_mtrl_015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/abc_btn_radio_to_on_mtrl_015.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/abc_vei.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/abc_vei.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/box_notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/box_notes.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/fals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/fals.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_chevron_left_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/ic_chevron_left_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_chevron_right_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/ic_chevron_right_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_http_48px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/ic_http_48px.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_https_48px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/ic_https_48px.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_menu_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/ic_menu_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_refresh_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/ic_refresh_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/iml_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/iml_s.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/ser.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/sr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxhdpi/sr.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/abc_btn_radio_to_on_mtrl_000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxxhdpi/abc_btn_radio_to_on_mtrl_000.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/abc_btn_radio_to_on_mtrl_015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxxhdpi/abc_btn_radio_to_on_mtrl_015.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_adb_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxxhdpi/ic_adb_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_add_alert_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxxhdpi/ic_add_alert_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_arrow_back_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxxhdpi/ic_arrow_back_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_edit_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxxhdpi/ic_edit_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_insert_emoticon_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxxhdpi/ic_insert_emoticon_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_pause_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxxhdpi/ic_pause_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_photo_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxxhdpi/ic_photo_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_send_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxxhdpi/ic_send_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_stop_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable-xxxhdpi/ic_stop_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button_pressed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bga_sbl_shadow.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stytooldex/pius1/8b02bc3e9be0ea46535be03c91fc1168adc610d5/app/src/main/res/drawable/bga_sbl_shadow.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/cs_b.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/material_card.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/material_dialog_window.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/a_host.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 | 22 | 23 | 27 | 28 | 32 | 33 | 38 | 39 | 47 | 48 | 56 | 57 | 65 | 66 | 74 | 75 | 83 | 84 | 92 | 93 | 101 | 102 | 110 | 111 | 112 | 113 | 114 | 115 | 123 | 124 | 134 | 135 | 136 | 137 | 141 | 142 | 148 | 149 | 155 | 156 | 157 | 158 | 159 | 160 | 166 | 167 | 177 | 178 | 179 | 180 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | -------------------------------------------------------------------------------- /app/src/main/res/layout/history.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/historylist.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 18 | 19 | 25 | 26 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_search_history_word.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 19 | 20 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_material_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 17 | 18 | 24 | 25 | 35 | 36 | 43 | 44 | 50 | 51 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 76 | 77 |