├── .gitignore ├── README.md ├── build.gradle ├── gradle.properties ├── library ├── .gitignore ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── fonts │ │ ├── opensans_bold.ttf │ │ ├── opensans_extrabold.ttf │ │ ├── opensans_extralight.ttf │ │ ├── opensans_light.ttf │ │ ├── opensans_regular.ttf │ │ ├── roboto_bold.ttf │ │ ├── roboto_extrabold.ttf │ │ ├── roboto_extralight.ttf │ │ ├── roboto_light.ttf │ │ └── roboto_regular.ttf │ ├── java │ └── com │ │ └── cengalabs │ │ └── flatui │ │ ├── Attributes.java │ │ ├── FlatUI.java │ │ ├── TouchEffectAnimator.java │ │ └── views │ │ ├── FlatAutoCompleteTextView.java │ │ ├── FlatButton.java │ │ ├── FlatCheckBox.java │ │ ├── FlatEditText.java │ │ ├── FlatRadioButton.java │ │ ├── FlatSeekBar.java │ │ ├── FlatTextView.java │ │ └── FlatToggleButton.java │ └── res │ └── values │ ├── attrs.xml │ ├── colors.xml │ └── strings.xml ├── maven_push.gradle ├── sample-images ├── flat_ui_theme_sand.png ├── showcase.png └── themes.png ├── sample ├── .gitignore ├── build.gradle ├── proguard-rules.txt └── src │ └── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ └── com │ │ └── cengalabs │ │ └── flatui │ │ └── sample │ │ ├── MainActivity.java │ │ └── RippleLinearLayout.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── layout │ ├── activity_main.xml │ ├── simple_flat_list_item.xml │ └── spinner_button.xml │ ├── menu │ └── main.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | #Android generated 2 | bin 3 | gen 4 | gen* 5 | 6 | #Eclipse 7 | .project 8 | .classpath 9 | .settings 10 | 11 | #IntelliJ IDEA 12 | .idea 13 | *.iml 14 | *.ipr 15 | *.iws 16 | out 17 | 18 | #Maven 19 | target 20 | release.properties 21 | pom.xml.* 22 | 23 | #Ant 24 | build.xml 25 | local.properties 26 | proguard.cfg 27 | 28 | #Gradle 29 | .gradle 30 | build 31 | gradlew 32 | gradle 33 | 34 | #OSX 35 | .DS_Store 36 | 37 | #Personal Files 38 | signin.properties 39 | *.keystore -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Android FlatUI 2 | =================== 3 | 4 | FlatUI is a library that lets you use native android widgets with a better and customized look. 5 | 6 | You can define the widgets in XML or create on run time in JAVA. Even though the widgets are customized, you can create your styles with attributes. 7 | 8 | There are many predefined themes inside this library but you can also use your own colors easily. 9 | 10 | !!! There may be some unexpected results with different screen resolutions and different Android versions. If you have some problems or solutions to those problems please let me know. 11 | 12 | 13 | Features included 14 | ----------------- 15 | * Creating widgets inside XML. 16 | * Creating widgets inside JAVA. 17 | * Using existing and custom themes. 18 | * Using existing and custom fonts. 19 | * Changing theme and attributes at runtime. 20 | * Changing ActionBar theme. 21 | 22 | Latest Changes 23 | ----------------- 24 | * Add ease and ripple effects to buttons : 3.0.0 25 | * Fix issue #30 - Merge pull requests #34 (@sherwinrobles), #32 (@aliok), #28 (@weiwelcome0) :2.2.0 26 | * Fix issue #22 - NPE-while-creating-views-dynamically :2.1.1 27 | * Fix issue #14, 15, 19, 26 - Attribute name clash (contribution from @aimanbaharum) :2.1.0 28 | * Fix issue #17 - FlatButton padding applied (solution from @jstefanowski) :2.0.4 29 | * Fix issue #18 - Consecutive activity opening (pull request from @michalbrz) :2.0.3 30 | 31 | Widgets 32 | ----------- 33 | ![Themes][1] 34 | 35 | Themes 36 | ----------- 37 | ![Themes][2] 38 | 39 | 40 | Including into your project 41 | ------------------------- 42 | 43 | Add the following dependency to your `build.gradle`. 44 | 45 | dependencies { 46 | compile 'com.github.eluleci:flatui:3.0.0' 47 | } 48 | 49 | 50 | 51 | ## Main Java functions 52 | 53 | ```java 54 | 55 | // Converts the default values (radius, size, border) to dp to be compatible with different 56 | // screen sizes. If you skip this there may be problem with different screen densities 57 | FlatUI.initDefaultValues(this); 58 | 59 | // Setting default theme to avoid to add the attribute "theme" to XML 60 | // and to be able to change the whole theme at once 61 | FlatUI.setDefaultTheme(FlatUI.DEEP); 62 | FlatUI.setDefaultTheme(R.array.my_custom_theme); // for using custom theme as default 63 | 64 | // Getting action bar drawable and setting it. 65 | // Sometimes weird problems may occur while changing action bar drawable at runtime. 66 | // You can try to set title of the action bar to invalidate it after setting background. 67 | getActionBar().setBackgroundDrawable(FlatUI.getActionBarDrawable(FlatUI.DEEP, false)); 68 | getSupportActionBar().setBackgroundDrawable(FlatUI.getActionBarDrawable(FlatUI.DEEP, false)); 69 | 70 | ``` 71 | 72 | ## Using custom colors 73 | 74 | You can use your own colors in two ways. 75 | 76 | 1 - Creating color array in xml and referencing it. 77 | 78 | ```xml 79 | 80 | 81 | #ad843d 82 | #d4a14a 83 | #fbbf58 84 | #fae8c8 85 | 86 | 87 | @color/custom_theme_darker 88 | @color/custom_theme_dark 89 | @color/custom_theme_primary 90 | @color/custom_theme_light 91 | 92 | 93 | 94 | 97 | 98 | ``` 99 | 100 | 2 - Creating color array in java and setting it 101 | 102 | ```java 103 | 104 | int[] myColors = {Color.RED, Color.BLUE, Color.GREEN, Color.BLACK}; 105 | 106 | ((FlatSeekBar) findViewById(R.id.seekbar)).getAttributes().setColors(myColors); 107 | 108 | ``` 109 | 110 | ## Using custom fonts 111 | 112 | Roboto and Open Sans are already included to the library but you can use any font with Android FlatUI. 113 | Place your font file in assets/fonts/ folder of your project and use fontFamily and fontWeight attributes to your view. 114 | Your font file's name should be formatted like 'fontname_fontweight.ttf'. 115 | It is important to name the font file in correct way otherwise the font cannot be created. 116 | If your font file is .otf you can use the 'fontExtension' attribute for it. 117 | 118 | ```xml 119 | 120 | 121 | 122 | 127 | 128 | ``` 129 | 130 | ## Attribute list 131 | 132 | These are only common attributes for most of the views. You can see the full list of available attributes in [attrs.xml][3] 133 | 134 | - fl_theme : theme of the element (reference: @array/themeName) 135 | 136 | - fl_textAppearance : text color on the element. dark or light colors of the theme.(none, dark, light) 137 | - fl_fontFamily : name of the font family (string) 138 | - fl_fontWeight : font weight of the text (string) (extralight, light, regular, bold, extrabold) 139 | - fl_fontExtension : extension of the font. use if not ttf (string) 140 | 141 | - fl_borderWidth : border width of the element. (dimension) 142 | - fl_cornerRadius : corner radius of the element. (dimension) 143 | - fl_size : size of the element. (dimension) 144 | 145 | ## Samples 146 | 147 | Only showing specific attributes for views. 148 | 149 | ```xml 150 | 151 | 152 | xmlns:flatui="http://schemas.android.com/apk/res-auto" 153 | 154 | 155 | 165 | 166 | 167 | 168 | 173 | 174 | 175 | 176 | 179 | 180 | 181 | 182 | 183 | 186 | 187 | 188 | 189 | 193 | 194 | 195 | 196 | 199 | 200 | 201 | 202 | 205 | 206 | 207 | 208 | 209 | 212 | 213 | 214 | ``` 215 | 216 | License 217 | -------- 218 | 219 | Copyright 2014 CengaLabs. 220 | 221 | Licensed under the Apache License, Version 2.0 (the "License"); 222 | you may not use this file except in compliance with the License. 223 | You may obtain a copy of the License at 224 | 225 | http://www.apache.org/licenses/LICENSE-2.0 226 | 227 | Unless required by applicable law or agreed to in writing, software 228 | distributed under the License is distributed on an "AS IS" BASIS, 229 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 230 | See the License for the specific language governing permissions and 231 | limitations under the License. 232 | 233 | 234 | [1]: https://raw.github.com/eluleci/FlatUI/master/sample-images/showcase.png 235 | [2]: https://raw.github.com/eluleci/FlatUI/master/sample-images/themes.png 236 | [3]: https://github.com/eluleci/FlatUI/blob/master/library/src/main/res/values/attrs.xml -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | mavenCentral() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:0.12.+' 9 | } 10 | } 11 | 12 | def isReleaseBuild() { 13 | return version.contains("SNAPSHOT") == false 14 | } 15 | 16 | allprojects { 17 | version = VERSION_NAME 18 | group = GROUP 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | } 24 | 25 | apply plugin: 'android-reporting' -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | VERSION_NAME=3.0.0 2 | VERSION_CODE=12 3 | GROUP=com.github.eluleci 4 | 5 | POM_DESCRIPTION=FlatUI widgets for Android 6 | POM_URL=https://github.com/eluleci/FlatUI 7 | POM_SCM_URL=https://github.com/eluleci/FlatUI 8 | POM_SCM_CONNECTION=scm:git@github.com:eluleci/FlatUI.git 9 | POM_SCM_DEV_CONNECTION=scm:git@github.com:eluleci/FlatUI.git 10 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 11 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 12 | POM_LICENCE_DIST=repo 13 | POM_DEVELOPER_ID=eluleci 14 | POM_DEVELOPER_NAME=Emrullah Luleci 15 | 16 | ANDROID_BUILD_TARGET_SDK_VERSION=19 17 | ANDROID_BUILD_TOOLS_VERSION=19.1.0 18 | ANDROID_BUILD_SDK_VERSION=19 -------------------------------------------------------------------------------- /library/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'android-library' 2 | 3 | android { 4 | compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION) 5 | buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION 6 | 7 | defaultConfig { 8 | minSdkVersion 8 9 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION) 10 | } 11 | 12 | sourceSets { 13 | main { 14 | manifest.srcFile 'src/main/AndroidManifest.xml' 15 | java.srcDirs = ['src/main/java'] 16 | res.srcDirs = ['src/main/res'] 17 | } 18 | } 19 | 20 | resourcePrefix 'fl_' 21 | } 22 | 23 | dependencies { 24 | } 25 | 26 | apply from: '../maven_push.gradle' -------------------------------------------------------------------------------- /library/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=FlatUI Kit 2 | POM_ARTIFACT_ID=flatui 3 | POM_PACKAGING=aar -------------------------------------------------------------------------------- /library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /library/src/main/assets/fonts/opensans_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/library/src/main/assets/fonts/opensans_bold.ttf -------------------------------------------------------------------------------- /library/src/main/assets/fonts/opensans_extrabold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/library/src/main/assets/fonts/opensans_extrabold.ttf -------------------------------------------------------------------------------- /library/src/main/assets/fonts/opensans_extralight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/library/src/main/assets/fonts/opensans_extralight.ttf -------------------------------------------------------------------------------- /library/src/main/assets/fonts/opensans_light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/library/src/main/assets/fonts/opensans_light.ttf -------------------------------------------------------------------------------- /library/src/main/assets/fonts/opensans_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/library/src/main/assets/fonts/opensans_regular.ttf -------------------------------------------------------------------------------- /library/src/main/assets/fonts/roboto_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/library/src/main/assets/fonts/roboto_bold.ttf -------------------------------------------------------------------------------- /library/src/main/assets/fonts/roboto_extrabold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/library/src/main/assets/fonts/roboto_extrabold.ttf -------------------------------------------------------------------------------- /library/src/main/assets/fonts/roboto_extralight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/library/src/main/assets/fonts/roboto_extralight.ttf -------------------------------------------------------------------------------- /library/src/main/assets/fonts/roboto_light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/library/src/main/assets/fonts/roboto_light.ttf -------------------------------------------------------------------------------- /library/src/main/assets/fonts/roboto_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/library/src/main/assets/fonts/roboto_regular.ttf -------------------------------------------------------------------------------- /library/src/main/java/com/cengalabs/flatui/Attributes.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui; 2 | 3 | import android.content.res.Resources; 4 | import android.graphics.Color; 5 | 6 | /** 7 | * This class holds the values of the common attributes. 8 | */ 9 | public class Attributes { 10 | 11 | public static int INVALID = -1; 12 | 13 | public static int DEFAULT_THEME = R.array.blood; 14 | public static final int DEFAULT_TOUCH_EFFECT = 0; 15 | public static final int EASE_TOUCH_EFFECT = 1; 16 | public static final int RIPPLE_TOUCH_EFFECT = 2; 17 | 18 | public static final String DEFAULT_FONT_FAMILY = "roboto"; 19 | public static final String DEFAULT_FONT_WEIGHT = "light"; 20 | public static final String DEFAULT_FONT_EXTENSION = "ttf"; 21 | public static final int DEFAULT_TEXT_APPEARANCE = 0; 22 | 23 | public static int DEFAULT_RADIUS_DP = 4; 24 | public static int DEFAULT_BORDER_WIDTH_DP = 2; 25 | public static int DEFAULT_SIZE_DP = 10; 26 | 27 | public static int DEFAULT_RADIUS_PX = 8; 28 | public static int DEFAULT_BORDER_WIDTH_PX = 4; 29 | public static int DEFAULT_SIZE_PX = 20; 30 | 31 | /** 32 | * Color related fields 33 | */ 34 | private int[] colors; 35 | private int theme = -1; 36 | private int touchEffect = DEFAULT_TOUCH_EFFECT; 37 | 38 | /** 39 | * Font related fields 40 | */ 41 | private String fontFamily = DEFAULT_FONT_FAMILY; 42 | private String fontWeight = DEFAULT_FONT_WEIGHT; 43 | private String fontExtension = DEFAULT_FONT_EXTENSION; 44 | private int textAppearance = DEFAULT_TEXT_APPEARANCE; 45 | 46 | /** 47 | * Size related fields 48 | */ 49 | private int radius = DEFAULT_RADIUS_PX; 50 | private int size = DEFAULT_SIZE_PX; 51 | private int borderWidth = DEFAULT_BORDER_WIDTH_PX; 52 | 53 | /** 54 | * Attribute change listener. Used to redraw the view when attributes are changed. 55 | */ 56 | private AttributeChangeListener attributeChangeListener; 57 | 58 | public Attributes(AttributeChangeListener attributeChangeListener, Resources resources) { 59 | this.attributeChangeListener = attributeChangeListener; 60 | setThemeSilent(DEFAULT_THEME, resources); 61 | } 62 | 63 | public int getTheme() { 64 | return theme; 65 | } 66 | 67 | public void setTheme(int theme, Resources resources) { 68 | setThemeSilent(theme, resources); 69 | attributeChangeListener.onThemeChange(); 70 | } 71 | 72 | public void setThemeSilent(int theme, Resources resources) { 73 | try { 74 | this.theme = theme; 75 | colors = resources.getIntArray(theme); 76 | } catch (Resources.NotFoundException e) { 77 | 78 | // setting theme blood if exception occurs (especially used for preview rendering by IDE) 79 | colors = new int[]{Color.parseColor("#732219"), Color.parseColor("#a63124"), 80 | Color.parseColor("#d94130"), Color.parseColor("#f2b6ae")}; 81 | } 82 | } 83 | 84 | public void setColors(int[] colors) { 85 | this.colors = colors; 86 | attributeChangeListener.onThemeChange(); 87 | } 88 | 89 | public int getColor(int colorPos) { 90 | return colors[colorPos]; 91 | } 92 | 93 | public String getFontFamily() { 94 | return fontFamily; 95 | } 96 | 97 | public void setFontFamily(String fontFamily) { 98 | if (fontFamily != null && !fontFamily.equals("") && !fontFamily.equals("null")) 99 | this.fontFamily = fontFamily; 100 | } 101 | 102 | public String getFontWeight() { 103 | return fontWeight; 104 | } 105 | 106 | public void setFontWeight(String fontWeight) { 107 | if (fontWeight != null && !fontWeight.equals("") && !fontWeight.equals("null")) 108 | this.fontWeight = fontWeight; 109 | } 110 | 111 | public String getFontExtension() { 112 | return fontExtension; 113 | } 114 | 115 | public void setFontExtension(String fontExtension) { 116 | if (fontExtension != null && !fontExtension.equals("") && !fontExtension.equals("null")) 117 | this.fontExtension = fontExtension; 118 | } 119 | 120 | public int getRadius() { 121 | return radius; 122 | } 123 | 124 | public float[] getOuterRadius() { 125 | return new float[]{radius, radius, radius, radius, radius, radius, radius, radius}; 126 | } 127 | 128 | public void setRadius(int radius) { 129 | this.radius = radius; 130 | } 131 | 132 | public int getSize() { 133 | return size; 134 | } 135 | 136 | public void setSize(int size) { 137 | this.size = size; 138 | } 139 | 140 | public int getBorderWidth() { 141 | return borderWidth; 142 | } 143 | 144 | public void setBorderWidth(int borderWidth) { 145 | this.borderWidth = borderWidth; 146 | } 147 | 148 | public int getTextAppearance() { 149 | return textAppearance; 150 | } 151 | 152 | public void setTextAppearance(int textAppearance) { 153 | this.textAppearance = textAppearance; 154 | } 155 | 156 | public int getTouchEffect() { 157 | return touchEffect; 158 | } 159 | 160 | public void setTouchEffect(int touchEffect) { 161 | this.touchEffect = touchEffect; 162 | } 163 | 164 | public boolean hasTouchEffect() { 165 | return this.touchEffect != Attributes.DEFAULT_TOUCH_EFFECT; 166 | } 167 | 168 | public interface AttributeChangeListener { 169 | public void onThemeChange(); 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /library/src/main/java/com/cengalabs/flatui/FlatUI.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.graphics.Typeface; 6 | import android.graphics.drawable.Drawable; 7 | import android.graphics.drawable.LayerDrawable; 8 | import android.graphics.drawable.PaintDrawable; 9 | import android.util.DisplayMetrics; 10 | import android.util.Log; 11 | import android.util.TypedValue; 12 | 13 | /** 14 | * This class contains some util methods and keeps theme constants. 15 | */ 16 | public class FlatUI { 17 | 18 | public static final String androidStyleNameSpace = "http://schemas.android.com/apk/res/android"; 19 | 20 | public static final int SAND = R.array.sand; 21 | public static final int ORANGE = R.array.orange; 22 | public static final int CANDY = R.array.candy; 23 | public static final int BLOSSOM = R.array.blossom; 24 | public static final int GRAPE = R.array.grape; 25 | public static final int DEEP = R.array.deep; 26 | public static final int SKY = R.array.sky; 27 | public static final int GRASS = R.array.grass; 28 | public static final int DARK = R.array.dark; 29 | public static final int SNOW = R.array.snow; 30 | public static final int SEA = R.array.sea; 31 | public static final int BLOOD = R.array.blood; 32 | 33 | /** 34 | * Converts the default values to dp to be compatible with different screen sizes 35 | * 36 | * @param context 37 | */ 38 | public static void initDefaultValues(Context context) { 39 | 40 | Attributes.DEFAULT_BORDER_WIDTH_PX = (int) dipToPx(context, Attributes.DEFAULT_BORDER_WIDTH_DP); 41 | Attributes.DEFAULT_RADIUS_PX = (int) dipToPx(context, Attributes.DEFAULT_RADIUS_DP); 42 | Attributes.DEFAULT_SIZE_PX = (int) dipToPx(context, Attributes.DEFAULT_SIZE_DP); 43 | } 44 | 45 | /** 46 | * Creates and returns the font file from given attributes. 47 | * 48 | * @param context 49 | * @param attributes 50 | * @return 51 | */ 52 | public static Typeface getFont(Context context, Attributes attributes) { 53 | 54 | String fontPath = "fonts/" + attributes.getFontFamily() 55 | + "_" + attributes.getFontWeight() 56 | + "." + attributes.getFontExtension(); 57 | 58 | try { 59 | return Typeface.createFromAsset(context.getAssets(), fontPath); 60 | } catch (Exception e) { 61 | Log.e("FlatUI", "Font file at " + fontPath + " cannot be found or the file is " + 62 | "not a valid font file. Please be sure that library assets are included " + 63 | "to project. If not, copy assets/fonts folder of the library to your " + 64 | "projects assets folder."); 65 | return null; 66 | } 67 | } 68 | 69 | public static Drawable getActionBarDrawable(Activity activity, int theme, boolean dark) { 70 | return getActionBarDrawable(activity, theme, dark, 0); 71 | } 72 | 73 | /** 74 | * Returns a suitable drawable for ActionBar with theme colors. 75 | * 76 | * @param theme selected theme 77 | * @param dark boolean for choosing dark colors or primary colors 78 | * @param borderBottom bottom border width 79 | * @return drawable to be used in ActionBar 80 | */ 81 | public static Drawable getActionBarDrawable(Activity activity, int theme, boolean dark, float borderBottom) { 82 | int[] colors = activity.getResources().getIntArray(theme); 83 | 84 | int color1 = colors[2]; 85 | int color2 = colors[1]; 86 | 87 | if (dark) { 88 | color1 = colors[1]; 89 | color2 = colors[0]; 90 | } 91 | 92 | borderBottom = dipToPx(activity, borderBottom); 93 | 94 | PaintDrawable front = new PaintDrawable(color1); 95 | PaintDrawable bottom = new PaintDrawable(color2); 96 | Drawable[] d = {bottom, front}; 97 | LayerDrawable drawable = new LayerDrawable(d); 98 | drawable.setLayerInset(1, 0, 0, 0, (int) borderBottom); 99 | return drawable; 100 | } 101 | 102 | /** 103 | * Sets the default theme of the application. The views which doesn't have any theme attribute 104 | * will have this defined default theme. 105 | *

106 | * IMPORTANT: This method should be called before setContentView method of the activity. 107 | * 108 | * @param theme 109 | */ 110 | public static void setDefaultTheme(int theme) { 111 | Attributes.DEFAULT_THEME = theme; 112 | } 113 | 114 | private static float dipToPx(Context context, float dp) { 115 | DisplayMetrics metrics = context.getResources().getDisplayMetrics(); 116 | return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics); 117 | } 118 | } -------------------------------------------------------------------------------- /library/src/main/java/com/cengalabs/flatui/TouchEffectAnimator.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.Path; 6 | import android.graphics.RectF; 7 | import android.view.MotionEvent; 8 | import android.view.View; 9 | import android.view.animation.Animation; 10 | import android.view.animation.DecelerateInterpolator; 11 | import android.view.animation.Transformation; 12 | 13 | /** 14 | * User: eluleci 15 | * Date: 25.09.2014 16 | * Time: 00:34 17 | * 18 | * This class adds touch effects to the given View. The effect animation is triggered by onTouchEvent 19 | * of the View and this class is injected into the onDraw function of the View to perform animation. 20 | * 21 | */ 22 | public class TouchEffectAnimator { 23 | 24 | private final int EASE_ANIM_DURATION = 200; 25 | private final int RIPPLE_ANIM_DURATION = 300; 26 | private final int MAX_RIPPLE_ALPHA = 255; 27 | 28 | private View mView; 29 | private int mClipRadius; 30 | private boolean hasRippleEffect = false; 31 | private int animDuration = EASE_ANIM_DURATION; 32 | 33 | private int requiredRadius; 34 | private float mDownX; 35 | private float mDownY; 36 | private float mRadius; 37 | private int mCircleAlpha = MAX_RIPPLE_ALPHA; 38 | private int mRectAlpha = 0; 39 | private Paint mCirclePaint = new Paint(); 40 | private Paint mRectPaint = new Paint(); 41 | private Path mCirclePath = new Path(); 42 | private Path mRectPath = new Path(); 43 | private boolean isTouchReleased = false; 44 | private boolean isAnimatingFadeIn = false; 45 | 46 | private Animation.AnimationListener animationListener = new Animation.AnimationListener() { 47 | @Override 48 | public void onAnimationStart(Animation animation) { 49 | isAnimatingFadeIn = true; 50 | } 51 | 52 | @Override 53 | public void onAnimationEnd(Animation animation) { 54 | isAnimatingFadeIn = false; 55 | if (isTouchReleased) fadeOutEffect(); 56 | } 57 | 58 | @Override 59 | public void onAnimationRepeat(Animation animation) { 60 | } 61 | }; 62 | 63 | public TouchEffectAnimator(View mView) { 64 | this.mView = mView; 65 | } 66 | 67 | public void setHasRippleEffect(boolean hasRippleEffect) { 68 | this.hasRippleEffect = hasRippleEffect; 69 | if (hasRippleEffect) animDuration = RIPPLE_ANIM_DURATION; 70 | } 71 | 72 | public void setAnimDuration(int animDuration) { 73 | this.animDuration = animDuration; 74 | } 75 | 76 | public void setEffectColor(int effectColor) { 77 | mCirclePaint.setColor(effectColor); 78 | mCirclePaint.setAlpha(mCircleAlpha); 79 | mRectPaint.setColor(effectColor); 80 | mRectPaint.setAlpha(mRectAlpha); 81 | } 82 | 83 | public void setClipRadius(int mClipRadius) { 84 | this.mClipRadius = mClipRadius; 85 | } 86 | 87 | public void onTouchEvent(final MotionEvent event) { 88 | 89 | if (event.getActionMasked() == MotionEvent.ACTION_CANCEL) { 90 | isTouchReleased = true; 91 | if (!isAnimatingFadeIn) { 92 | fadeOutEffect(); 93 | } 94 | } 95 | if (event.getActionMasked() == MotionEvent.ACTION_UP) { 96 | isTouchReleased = true; 97 | if (!isAnimatingFadeIn) { 98 | fadeOutEffect(); 99 | } 100 | } else if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { 101 | 102 | // gets the bigger value (width or height) to fit the circle 103 | requiredRadius = mView.getWidth() > mView.getHeight() ? mView.getWidth() : mView.getHeight(); 104 | 105 | // increasing radius for circle to reach from corner to other corner 106 | requiredRadius *= 1.2; 107 | 108 | isTouchReleased = false; 109 | mDownX = event.getX(); 110 | mDownY = event.getY(); 111 | 112 | mCircleAlpha = MAX_RIPPLE_ALPHA; 113 | mRectAlpha = 0; 114 | 115 | ValueGeneratorAnim valueGeneratorAnim = new ValueGeneratorAnim(new InterpolatedTimeCallback() { 116 | @Override 117 | public void onTimeUpdate(float interpolatedTime) { 118 | if (hasRippleEffect) 119 | mRadius = requiredRadius * interpolatedTime; 120 | mRectAlpha = (int) (interpolatedTime * MAX_RIPPLE_ALPHA); 121 | mView.invalidate(); 122 | } 123 | }); 124 | valueGeneratorAnim.setInterpolator(new DecelerateInterpolator()); 125 | valueGeneratorAnim.setDuration(animDuration); 126 | valueGeneratorAnim.setAnimationListener(animationListener); 127 | mView.startAnimation(valueGeneratorAnim); 128 | } 129 | } 130 | 131 | public void onDraw(final Canvas canvas) { 132 | 133 | if (hasRippleEffect) { 134 | mCirclePath.reset(); 135 | mCirclePaint.setAlpha(mCircleAlpha); 136 | mCirclePath.addRoundRect(new RectF(0, 0, mView.getWidth(), mView.getHeight()), 137 | mClipRadius, mClipRadius, Path.Direction.CW); 138 | 139 | canvas.clipPath(mCirclePath); 140 | canvas.drawCircle(mDownX, mDownY, mRadius, mCirclePaint); 141 | } 142 | 143 | mRectPath.reset(); 144 | if (hasRippleEffect && mCircleAlpha != 255) mRectAlpha = mCircleAlpha / 2; 145 | mRectPaint.setAlpha(mRectAlpha); 146 | canvas.drawRoundRect(new RectF(0, 0, mView.getWidth(), mView.getHeight()), mClipRadius, 147 | mClipRadius, mRectPaint); 148 | } 149 | 150 | private void fadeOutEffect() { 151 | ValueGeneratorAnim valueGeneratorAnim = new ValueGeneratorAnim(new InterpolatedTimeCallback() { 152 | @Override 153 | public void onTimeUpdate(float interpolatedTime) { 154 | mCircleAlpha = (int) (MAX_RIPPLE_ALPHA - (MAX_RIPPLE_ALPHA * interpolatedTime)); 155 | mRectAlpha = mCircleAlpha; 156 | mView.invalidate(); 157 | } 158 | }); 159 | valueGeneratorAnim.setDuration(animDuration); 160 | mView.startAnimation(valueGeneratorAnim); 161 | } 162 | 163 | class ValueGeneratorAnim extends Animation { 164 | 165 | private InterpolatedTimeCallback interpolatedTimeCallback; 166 | 167 | ValueGeneratorAnim(InterpolatedTimeCallback interpolatedTimeCallback) { 168 | this.interpolatedTimeCallback = interpolatedTimeCallback; 169 | } 170 | 171 | @Override 172 | protected void applyTransformation(float interpolatedTime, Transformation t) { 173 | this.interpolatedTimeCallback.onTimeUpdate(interpolatedTime); 174 | } 175 | } 176 | 177 | interface InterpolatedTimeCallback { 178 | public void onTimeUpdate(float interpolatedTime); 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /library/src/main/java/com/cengalabs/flatui/views/FlatAutoCompleteTextView.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui.views; 2 | 3 | /** 4 | * Created by Sherwin on 9/11/2014. 5 | */ 6 | 7 | import android.content.Context; 8 | import android.content.res.TypedArray; 9 | import android.graphics.Color; 10 | import android.graphics.Typeface; 11 | import android.graphics.drawable.GradientDrawable; 12 | import android.util.AttributeSet; 13 | import android.widget.AutoCompleteTextView; 14 | 15 | 16 | import com.cengalabs.flatui.Attributes; 17 | import com.cengalabs.flatui.FlatUI; 18 | import com.cengalabs.flatui.R; 19 | 20 | 21 | public class FlatAutoCompleteTextView extends AutoCompleteTextView implements Attributes.AttributeChangeListener { 22 | 23 | private Attributes attributes; 24 | 25 | private int style = 0; 26 | 27 | private boolean hasOwnTextColor; 28 | private boolean hasOwnHintColor; 29 | 30 | public FlatAutoCompleteTextView(Context context) { 31 | super(context); 32 | init(null); 33 | } 34 | 35 | public FlatAutoCompleteTextView(Context context, AttributeSet attrs) { 36 | super(context, attrs); 37 | init(attrs); 38 | } 39 | 40 | public FlatAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) { 41 | super(context, attrs, defStyle); 42 | init(attrs); 43 | } 44 | 45 | private void init(AttributeSet attrs) { 46 | 47 | if (attributes == null) 48 | attributes = new Attributes(this, getResources()); 49 | 50 | if (attrs != null) { 51 | 52 | // getting android default tags for textColor and textColorHint 53 | hasOwnTextColor = attrs.getAttributeValue(FlatUI.androidStyleNameSpace, "textColor") != null; 54 | hasOwnHintColor = attrs.getAttributeValue(FlatUI.androidStyleNameSpace, "textColorHint") != null; 55 | 56 | TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.fl_FlatAutoCompleteTextView); 57 | 58 | // getting common attributes 59 | int customTheme = a.getResourceId(R.styleable.fl_FlatAutoCompleteTextView_fl_theme, Attributes.DEFAULT_THEME); 60 | attributes.setThemeSilent(customTheme, getResources()); 61 | 62 | attributes.setFontFamily(a.getString(R.styleable.fl_FlatAutoCompleteTextView_fl_fontFamily)); 63 | attributes.setFontWeight(a.getString(R.styleable.fl_FlatAutoCompleteTextView_fl_fontWeight)); 64 | attributes.setFontExtension(a.getString(R.styleable.fl_FlatAutoCompleteTextView_fl_fontExtension)); 65 | 66 | attributes.setTextAppearance(a.getInt(R.styleable.fl_FlatAutoCompleteTextView_fl_textAppearance, Attributes.DEFAULT_TEXT_APPEARANCE)); 67 | attributes.setRadius(a.getDimensionPixelSize(R.styleable.fl_FlatAutoCompleteTextView_fl_cornerRadius, Attributes.DEFAULT_RADIUS_PX)); 68 | attributes.setBorderWidth(a.getDimensionPixelSize(R.styleable.fl_FlatAutoCompleteTextView_fl_borderWidth, Attributes.DEFAULT_BORDER_WIDTH_PX)); 69 | 70 | // getting view specific attributes 71 | style = a.getInt(R.styleable.fl_FlatAutoCompleteTextView_fl_autoFieldStyle, 0); 72 | 73 | a.recycle(); 74 | } 75 | 76 | GradientDrawable backgroundDrawable = new GradientDrawable(); 77 | backgroundDrawable.setCornerRadius(attributes.getRadius()); 78 | 79 | if (style == 0) { // flat 80 | if (!hasOwnTextColor) setTextColor(attributes.getColor(3)); 81 | backgroundDrawable.setColor(attributes.getColor(2)); 82 | backgroundDrawable.setStroke(0, attributes.getColor(2)); 83 | 84 | } else if (style == 1) { // box 85 | if (!hasOwnTextColor) setTextColor(attributes.getColor(2)); 86 | backgroundDrawable.setColor(Color.WHITE); 87 | backgroundDrawable.setStroke(attributes.getBorderWidth(), attributes.getColor(2)); 88 | 89 | } else if (style == 2) { // transparent 90 | if (!hasOwnTextColor) setTextColor(attributes.getColor(1)); 91 | backgroundDrawable.setColor(Color.TRANSPARENT); 92 | backgroundDrawable.setStroke(attributes.getBorderWidth(), attributes.getColor(2)); 93 | } 94 | 95 | setBackgroundDrawable(backgroundDrawable); 96 | 97 | if (!hasOwnHintColor) setHintTextColor(attributes.getColor(3)); 98 | 99 | if (attributes.getTextAppearance() == 1) setTextColor(attributes.getColor(0)); 100 | else if (attributes.getTextAppearance() == 2) setTextColor(attributes.getColor(3)); 101 | 102 | // check for IDE preview render 103 | if(!this.isInEditMode()) { 104 | Typeface typeface = FlatUI.getFont(getContext(), attributes); 105 | if (typeface != null) setTypeface(typeface); 106 | } 107 | } 108 | 109 | public Attributes getAttributes() { 110 | return attributes; 111 | } 112 | 113 | @Override 114 | public void onThemeChange() { 115 | init(null); 116 | } 117 | } 118 | 119 | -------------------------------------------------------------------------------- /library/src/main/java/com/cengalabs/flatui/views/FlatButton.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui.views; 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.Typeface; 8 | import android.graphics.drawable.Drawable; 9 | import android.graphics.drawable.LayerDrawable; 10 | import android.graphics.drawable.ShapeDrawable; 11 | import android.graphics.drawable.StateListDrawable; 12 | import android.graphics.drawable.shapes.RoundRectShape; 13 | import android.util.AttributeSet; 14 | import android.view.MotionEvent; 15 | import android.widget.Button; 16 | 17 | import com.cengalabs.flatui.Attributes; 18 | import com.cengalabs.flatui.FlatUI; 19 | import com.cengalabs.flatui.R; 20 | import com.cengalabs.flatui.TouchEffectAnimator; 21 | 22 | /** 23 | * User: eluleci 24 | * Date: 23.10.2013 25 | * Time: 22:18 26 | */ 27 | public class FlatButton extends Button implements Attributes.AttributeChangeListener { 28 | 29 | private Attributes attributes; 30 | 31 | // default values of specific attributes 32 | private int bottom = 0; 33 | 34 | private TouchEffectAnimator touchEffectAnimator; 35 | 36 | public FlatButton(Context context) { 37 | super(context); 38 | init(null); 39 | } 40 | 41 | public FlatButton(Context context, AttributeSet attrs) { 42 | super(context, attrs); 43 | init(attrs); 44 | } 45 | 46 | public FlatButton(Context context, AttributeSet attrs, int defStyle) { 47 | super(context, attrs, defStyle); 48 | init(attrs); 49 | } 50 | 51 | @Override 52 | public boolean onTouchEvent(final MotionEvent event) { 53 | if (attributes.hasTouchEffect() && touchEffectAnimator != null) 54 | touchEffectAnimator.onTouchEvent(event); 55 | return super.onTouchEvent(event); 56 | } 57 | 58 | @Override 59 | protected void onDraw(final Canvas canvas) { 60 | if (attributes.hasTouchEffect() && touchEffectAnimator != null) 61 | touchEffectAnimator.onDraw(canvas); 62 | super.onDraw(canvas); 63 | } 64 | 65 | private void init(AttributeSet attrs) { 66 | 67 | // saving padding values for using them after setting background drawable 68 | final int paddingTop = getPaddingTop(); 69 | final int paddingRight = getPaddingRight(); 70 | final int paddingLeft = getPaddingLeft(); 71 | final int paddingBottom = getPaddingBottom(); 72 | 73 | if (attributes == null) 74 | attributes = new Attributes(this, getResources()); 75 | 76 | if (attrs != null) { 77 | TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.fl_FlatButton); 78 | 79 | // getting common attributes 80 | int customTheme = a.getResourceId(R.styleable.fl_FlatButton_fl_theme, Attributes.DEFAULT_THEME); 81 | attributes.setThemeSilent(customTheme, getResources()); 82 | attributes.setTouchEffect(a.getInt(R.styleable.fl_FlatButton_fl_touchEffect, Attributes.DEFAULT_TOUCH_EFFECT)); 83 | 84 | attributes.setFontFamily(a.getString(R.styleable.fl_FlatButton_fl_fontFamily)); 85 | attributes.setFontWeight(a.getString(R.styleable.fl_FlatButton_fl_fontWeight)); 86 | attributes.setFontExtension(a.getString(R.styleable.fl_FlatButton_fl_fontExtension)); 87 | 88 | attributes.setTextAppearance(a.getInt(R.styleable.fl_FlatButton_fl_textAppearance, Attributes.DEFAULT_TEXT_APPEARANCE)); 89 | attributes.setRadius(a.getDimensionPixelSize(R.styleable.fl_FlatButton_fl_cornerRadius, Attributes.DEFAULT_RADIUS_PX)); 90 | 91 | // getting view specific attributes 92 | bottom = a.getDimensionPixelSize(R.styleable.fl_FlatButton_fl_blockButtonEffectHeight, bottom); 93 | 94 | a.recycle(); 95 | } 96 | 97 | if (attributes.hasTouchEffect()) { 98 | boolean hasRippleEffect = attributes.getTouchEffect() == Attributes.RIPPLE_TOUCH_EFFECT; 99 | touchEffectAnimator = new TouchEffectAnimator(this); 100 | touchEffectAnimator.setHasRippleEffect(hasRippleEffect); 101 | touchEffectAnimator.setEffectColor(attributes.getColor(1)); 102 | touchEffectAnimator.setClipRadius(attributes.getRadius()); 103 | } 104 | 105 | /*mPaint = new Paint(); 106 | mPaint.setColor(attributes.getColor(1)); 107 | mPaint.setAlpha(mAlpha);*/ 108 | 109 | // creating normal state drawable 110 | ShapeDrawable normalFront = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 111 | normalFront.getPaint().setColor(attributes.getColor(2)); 112 | 113 | ShapeDrawable normalBack = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 114 | normalBack.getPaint().setColor(attributes.getColor(1)); 115 | 116 | normalBack.setPadding(0, 0, 0, bottom); 117 | 118 | Drawable[] d = {normalBack, normalFront}; 119 | LayerDrawable normal = new LayerDrawable(d); 120 | 121 | // creating pressed state drawable 122 | ShapeDrawable pressedFront = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 123 | pressedFront.getPaint().setColor(attributes.getColor(1)); 124 | 125 | ShapeDrawable pressedBack = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 126 | pressedBack.getPaint().setColor(attributes.getColor(0)); 127 | if (bottom != 0) pressedBack.setPadding(0, 0, 0, bottom / 2); 128 | 129 | Drawable[] d2 = {pressedBack, pressedFront}; 130 | LayerDrawable pressed = new LayerDrawable(d2); 131 | 132 | // creating disabled state drawable 133 | ShapeDrawable disabledFront = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 134 | disabledFront.getPaint().setColor(attributes.getColor(3)); 135 | disabledFront.getPaint().setAlpha(0xA0); 136 | 137 | ShapeDrawable disabledBack = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 138 | disabledBack.getPaint().setColor(attributes.getColor(2)); 139 | 140 | Drawable[] d3 = {disabledBack, disabledFront}; 141 | LayerDrawable disabled = new LayerDrawable(d3); 142 | 143 | StateListDrawable states = new StateListDrawable(); 144 | 145 | if (!attributes.hasTouchEffect()) 146 | states.addState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled}, pressed); 147 | states.addState(new int[]{android.R.attr.state_focused, android.R.attr.state_enabled}, pressed); 148 | states.addState(new int[]{android.R.attr.state_enabled}, normal); 149 | states.addState(new int[]{-android.R.attr.state_enabled}, disabled); 150 | 151 | setBackgroundDrawable(states); 152 | setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); 153 | 154 | if (attributes.getTextAppearance() == 1) setTextColor(attributes.getColor(0)); 155 | else if (attributes.getTextAppearance() == 2) setTextColor(attributes.getColor(3)); 156 | else setTextColor(Color.WHITE); 157 | 158 | // check for IDE preview render 159 | if (!this.isInEditMode()) { 160 | Typeface typeface = FlatUI.getFont(getContext(), attributes); 161 | if (typeface != null) setTypeface(typeface); 162 | } 163 | } 164 | 165 | public Attributes getAttributes() { 166 | return attributes; 167 | } 168 | 169 | @Override 170 | public void onThemeChange() { 171 | init(null); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /library/src/main/java/com/cengalabs/flatui/views/FlatCheckBox.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui.views; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Color; 6 | import android.graphics.Typeface; 7 | import android.graphics.drawable.Drawable; 8 | import android.graphics.drawable.GradientDrawable; 9 | import android.graphics.drawable.InsetDrawable; 10 | import android.graphics.drawable.LayerDrawable; 11 | import android.graphics.drawable.PaintDrawable; 12 | import android.graphics.drawable.StateListDrawable; 13 | import android.util.AttributeSet; 14 | import android.widget.CheckBox; 15 | 16 | import com.cengalabs.flatui.Attributes; 17 | import com.cengalabs.flatui.FlatUI; 18 | import com.cengalabs.flatui.R; 19 | 20 | /** 21 | * User: eluleci 22 | * Date: 23.10.2013 23 | * Time: 22:18 24 | */ 25 | public class FlatCheckBox extends CheckBox implements Attributes.AttributeChangeListener { 26 | 27 | private Attributes attributes; 28 | 29 | private int dotMargin = 2; 30 | 31 | public FlatCheckBox(Context context) { 32 | super(context); 33 | init(null); 34 | } 35 | 36 | public FlatCheckBox(Context context, AttributeSet attrs) { 37 | super(context, attrs); 38 | init(attrs); 39 | } 40 | 41 | public FlatCheckBox(Context context, AttributeSet attrs, int defStyle) { 42 | super(context, attrs, defStyle); 43 | init(attrs); 44 | } 45 | 46 | private void init(AttributeSet attrs) { 47 | 48 | if (attributes == null) 49 | attributes = new Attributes(this, getResources()); 50 | 51 | if (attrs != null) { 52 | TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.fl_FlatCheckBox); 53 | 54 | // getting common attributes 55 | int customTheme = a.getResourceId(R.styleable.fl_FlatCheckBox_fl_theme, Attributes.DEFAULT_THEME); 56 | attributes.setThemeSilent(customTheme, getResources()); 57 | 58 | attributes.setFontFamily(a.getString(R.styleable.fl_FlatCheckBox_fl_fontFamily)); 59 | attributes.setFontWeight(a.getString(R.styleable.fl_FlatCheckBox_fl_fontWeight)); 60 | attributes.setFontExtension(a.getString(R.styleable.fl_FlatCheckBox_fl_fontExtension)); 61 | 62 | attributes.setSize(a.getDimensionPixelSize(R.styleable.fl_FlatCheckBox_fl_size, Attributes.DEFAULT_SIZE_PX)); 63 | attributes.setRadius(a.getDimensionPixelSize(R.styleable.fl_FlatCheckBox_fl_cornerRadius, Attributes.DEFAULT_RADIUS_PX)); 64 | attributes.setBorderWidth(attributes.getSize() / 10); 65 | 66 | // getting view specific attributes 67 | dotMargin = a.getDimensionPixelSize(R.styleable.fl_FlatCheckBox_fl_dotMargin, dotMargin); 68 | 69 | a.recycle(); 70 | } 71 | 72 | // creating unchecked-enabled state drawable 73 | GradientDrawable uncheckedEnabled = new GradientDrawable(); 74 | uncheckedEnabled.setCornerRadius(attributes.getRadius()); 75 | uncheckedEnabled.setSize(attributes.getSize(), attributes.getSize()); 76 | uncheckedEnabled.setColor(Color.TRANSPARENT); 77 | uncheckedEnabled.setStroke(attributes.getBorderWidth(), attributes.getColor(2)); 78 | 79 | // creating checked-enabled state drawable 80 | GradientDrawable checkedOutside = new GradientDrawable(); 81 | checkedOutside.setCornerRadius(attributes.getRadius()); 82 | checkedOutside.setSize(attributes.getSize(), attributes.getSize()); 83 | checkedOutside.setColor(Color.TRANSPARENT); 84 | checkedOutside.setStroke(attributes.getBorderWidth(), attributes.getColor(2)); 85 | 86 | PaintDrawable checkedCore = new PaintDrawable(attributes.getColor(2)); 87 | checkedCore.setCornerRadius(attributes.getRadius()); 88 | checkedCore.setIntrinsicHeight(attributes.getSize()); 89 | checkedCore.setIntrinsicWidth(attributes.getSize()); 90 | InsetDrawable checkedInside = new InsetDrawable(checkedCore, 91 | attributes.getBorderWidth() + dotMargin, attributes.getBorderWidth() + dotMargin, 92 | attributes.getBorderWidth() + dotMargin, attributes.getBorderWidth() + dotMargin); 93 | 94 | Drawable[] checkedEnabledDrawable = {checkedOutside, checkedInside}; 95 | LayerDrawable checkedEnabled = new LayerDrawable(checkedEnabledDrawable); 96 | 97 | // creating unchecked-enabled state drawable 98 | GradientDrawable uncheckedDisabled = new GradientDrawable(); 99 | uncheckedDisabled.setCornerRadius(attributes.getRadius()); 100 | uncheckedDisabled.setSize(attributes.getSize(), attributes.getSize()); 101 | uncheckedDisabled.setColor(Color.TRANSPARENT); 102 | uncheckedDisabled.setStroke(attributes.getBorderWidth(), attributes.getColor(3)); 103 | 104 | // creating checked-disabled state drawable 105 | GradientDrawable checkedOutsideDisabled = new GradientDrawable(); 106 | checkedOutsideDisabled.setCornerRadius(attributes.getRadius()); 107 | checkedOutsideDisabled.setSize(attributes.getSize(), attributes.getSize()); 108 | checkedOutsideDisabled.setColor(Color.TRANSPARENT); 109 | checkedOutsideDisabled.setStroke(attributes.getBorderWidth(), attributes.getColor(3)); 110 | 111 | PaintDrawable checkedCoreDisabled = new PaintDrawable(attributes.getColor(3)); 112 | checkedCoreDisabled.setCornerRadius(attributes.getRadius()); 113 | checkedCoreDisabled.setIntrinsicHeight(attributes.getSize()); 114 | checkedCoreDisabled.setIntrinsicWidth(attributes.getSize()); 115 | InsetDrawable checkedInsideDisabled = new InsetDrawable(checkedCoreDisabled, 116 | attributes.getBorderWidth() + dotMargin, attributes.getBorderWidth() + dotMargin, 117 | attributes.getBorderWidth() + dotMargin, attributes.getBorderWidth() + dotMargin); 118 | 119 | Drawable[] checkedDisabledDrawable = {checkedOutsideDisabled, checkedInsideDisabled}; 120 | LayerDrawable checkedDisabled = new LayerDrawable(checkedDisabledDrawable); 121 | 122 | 123 | StateListDrawable states = new StateListDrawable(); 124 | states.addState(new int[]{-android.R.attr.state_checked, android.R.attr.state_enabled}, uncheckedEnabled); 125 | states.addState(new int[]{android.R.attr.state_checked, android.R.attr.state_enabled}, checkedEnabled); 126 | states.addState(new int[]{-android.R.attr.state_checked, -android.R.attr.state_enabled}, uncheckedDisabled); 127 | states.addState(new int[]{android.R.attr.state_checked, -android.R.attr.state_enabled}, checkedDisabled); 128 | setButtonDrawable(states); 129 | 130 | // setting padding for avoiding text to appear on icon 131 | setPadding(attributes.getSize() / 4 * 5, 0, 0, 0); 132 | setTextColor(attributes.getColor(2)); 133 | 134 | // check for IDE preview render 135 | if(!this.isInEditMode()) { 136 | Typeface typeface = FlatUI.getFont(getContext(), attributes); 137 | if (typeface != null) setTypeface(typeface); 138 | } 139 | } 140 | 141 | public Attributes getAttributes() { 142 | return attributes; 143 | } 144 | 145 | @Override 146 | public void onThemeChange() { 147 | init(null); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /library/src/main/java/com/cengalabs/flatui/views/FlatEditText.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui.views; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Color; 6 | import android.graphics.Typeface; 7 | import android.graphics.drawable.GradientDrawable; 8 | import android.util.AttributeSet; 9 | import android.widget.EditText; 10 | 11 | import com.cengalabs.flatui.Attributes; 12 | import com.cengalabs.flatui.FlatUI; 13 | import com.cengalabs.flatui.R; 14 | 15 | /** 16 | * User: eluleci 17 | * Date: 24.10.2013 18 | * Time: 21:09 19 | */ 20 | public class FlatEditText extends EditText implements Attributes.AttributeChangeListener { 21 | 22 | private Attributes attributes; 23 | 24 | private int style = 0; 25 | 26 | private boolean hasOwnTextColor; 27 | private boolean hasOwnHintColor; 28 | 29 | public FlatEditText(Context context) { 30 | super(context); 31 | init(null); 32 | } 33 | 34 | public FlatEditText(Context context, AttributeSet attrs) { 35 | super(context, attrs); 36 | init(attrs); 37 | } 38 | 39 | public FlatEditText(Context context, AttributeSet attrs, int defStyle) { 40 | super(context, attrs, defStyle); 41 | init(attrs); 42 | } 43 | 44 | private void init(AttributeSet attrs) { 45 | 46 | if (attributes == null) 47 | attributes = new Attributes(this, getResources()); 48 | 49 | if (attrs != null) { 50 | 51 | // getting android default tags for textColor and textColorHint 52 | hasOwnTextColor = attrs.getAttributeValue(FlatUI.androidStyleNameSpace, "textColor") != null; 53 | hasOwnHintColor = attrs.getAttributeValue(FlatUI.androidStyleNameSpace, "textColorHint") != null; 54 | 55 | TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.fl_FlatEditText); 56 | 57 | // getting common attributes 58 | int customTheme = a.getResourceId(R.styleable.fl_FlatEditText_fl_theme, Attributes.DEFAULT_THEME); 59 | attributes.setThemeSilent(customTheme, getResources()); 60 | 61 | attributes.setFontFamily(a.getString(R.styleable.fl_FlatEditText_fl_fontFamily)); 62 | attributes.setFontWeight(a.getString(R.styleable.fl_FlatEditText_fl_fontWeight)); 63 | attributes.setFontExtension(a.getString(R.styleable.fl_FlatEditText_fl_fontExtension)); 64 | 65 | attributes.setTextAppearance(a.getInt(R.styleable.fl_FlatEditText_fl_textAppearance, Attributes.DEFAULT_TEXT_APPEARANCE)); 66 | attributes.setRadius(a.getDimensionPixelSize(R.styleable.fl_FlatEditText_fl_cornerRadius, Attributes.DEFAULT_RADIUS_PX)); 67 | attributes.setBorderWidth(a.getDimensionPixelSize(R.styleable.fl_FlatEditText_fl_borderWidth, Attributes.DEFAULT_BORDER_WIDTH_PX)); 68 | 69 | // getting view specific attributes 70 | style = a.getInt(R.styleable.fl_FlatEditText_fl_fieldStyle, 0); 71 | 72 | a.recycle(); 73 | } 74 | 75 | GradientDrawable backgroundDrawable = new GradientDrawable(); 76 | backgroundDrawable.setCornerRadius(attributes.getRadius()); 77 | 78 | if (style == 0) { // flat 79 | if (!hasOwnTextColor) setTextColor(attributes.getColor(3)); 80 | backgroundDrawable.setColor(attributes.getColor(2)); 81 | backgroundDrawable.setStroke(0, attributes.getColor(2)); 82 | 83 | } else if (style == 1) { // box 84 | if (!hasOwnTextColor) setTextColor(attributes.getColor(2)); 85 | backgroundDrawable.setColor(Color.WHITE); 86 | backgroundDrawable.setStroke(attributes.getBorderWidth(), attributes.getColor(2)); 87 | 88 | } else if (style == 2) { // transparent 89 | if (!hasOwnTextColor) setTextColor(attributes.getColor(1)); 90 | backgroundDrawable.setColor(Color.TRANSPARENT); 91 | backgroundDrawable.setStroke(attributes.getBorderWidth(), attributes.getColor(2)); 92 | } 93 | 94 | setBackgroundDrawable(backgroundDrawable); 95 | 96 | if (!hasOwnHintColor) setHintTextColor(attributes.getColor(3)); 97 | 98 | if (attributes.getTextAppearance() == 1) setTextColor(attributes.getColor(0)); 99 | else if (attributes.getTextAppearance() == 2) setTextColor(attributes.getColor(3)); 100 | 101 | // check for IDE preview render 102 | if(!this.isInEditMode()) { 103 | Typeface typeface = FlatUI.getFont(getContext(), attributes); 104 | if (typeface != null) setTypeface(typeface); 105 | } 106 | } 107 | 108 | public Attributes getAttributes() { 109 | return attributes; 110 | } 111 | 112 | @Override 113 | public void onThemeChange() { 114 | init(null); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /library/src/main/java/com/cengalabs/flatui/views/FlatRadioButton.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui.views; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Color; 6 | import android.graphics.Typeface; 7 | import android.graphics.drawable.Drawable; 8 | import android.graphics.drawable.GradientDrawable; 9 | import android.graphics.drawable.InsetDrawable; 10 | import android.graphics.drawable.LayerDrawable; 11 | import android.graphics.drawable.PaintDrawable; 12 | import android.graphics.drawable.StateListDrawable; 13 | import android.util.AttributeSet; 14 | import android.widget.RadioButton; 15 | 16 | import com.cengalabs.flatui.Attributes; 17 | import com.cengalabs.flatui.FlatUI; 18 | import com.cengalabs.flatui.R; 19 | 20 | /** 21 | * User: eluleci 22 | * Date: 23.10.2013 23 | * Time: 22:18 24 | */ 25 | public class FlatRadioButton extends RadioButton implements Attributes.AttributeChangeListener { 26 | 27 | private Attributes attributes; 28 | 29 | private int dotMargin = 2; 30 | 31 | public FlatRadioButton(Context context) { 32 | super(context); 33 | init(null); 34 | } 35 | 36 | public FlatRadioButton(Context context, AttributeSet attrs) { 37 | super(context, attrs); 38 | init(attrs); 39 | } 40 | 41 | public FlatRadioButton(Context context, AttributeSet attrs, int defStyle) { 42 | super(context, attrs, defStyle); 43 | init(attrs); 44 | } 45 | 46 | private void init(AttributeSet attrs) { 47 | 48 | if (attributes == null) 49 | attributes = new Attributes(this, getResources()); 50 | 51 | if (attrs != null) { 52 | TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.fl_FlatRadioButton); 53 | 54 | // getting common attributes 55 | int customTheme = a.getResourceId(R.styleable.fl_FlatRadioButton_fl_theme, Attributes.DEFAULT_THEME); 56 | attributes.setThemeSilent(customTheme, getResources()); 57 | 58 | attributes.setFontFamily(a.getString(R.styleable.fl_FlatRadioButton_fl_fontFamily)); 59 | attributes.setFontWeight(a.getString(R.styleable.fl_FlatRadioButton_fl_fontWeight)); 60 | attributes.setFontExtension(a.getString(R.styleable.fl_FlatRadioButton_fl_fontExtension)); 61 | 62 | attributes.setSize(a.getDimensionPixelSize(R.styleable.fl_FlatRadioButton_fl_size, Attributes.DEFAULT_SIZE_PX)); 63 | attributes.setRadius(attributes.getSize() / 2); 64 | attributes.setBorderWidth(a.getDimensionPixelSize(R.styleable.fl_FlatRadioButton_fl_borderWidth, Attributes.DEFAULT_BORDER_WIDTH_PX)); 65 | 66 | // getting view specific attributes 67 | dotMargin = a.getDimensionPixelSize(R.styleable.fl_FlatRadioButton_fl_dotMargin, dotMargin); 68 | 69 | a.recycle(); 70 | } 71 | 72 | // creating unchecked-enabled state drawable 73 | GradientDrawable uncheckedEnabled = new GradientDrawable(); 74 | uncheckedEnabled.setCornerRadius(attributes.getRadius()); 75 | uncheckedEnabled.setSize(attributes.getSize(), attributes.getSize()); 76 | uncheckedEnabled.setColor(Color.TRANSPARENT); 77 | uncheckedEnabled.setStroke(attributes.getBorderWidth(), attributes.getColor(2)); 78 | 79 | // creating checked-enabled state drawable 80 | GradientDrawable checkedOutside = new GradientDrawable(); 81 | checkedOutside.setCornerRadius(attributes.getSize()); 82 | checkedOutside.setSize(attributes.getSize(), attributes.getSize()); 83 | checkedOutside.setColor(Color.TRANSPARENT); 84 | checkedOutside.setStroke(attributes.getBorderWidth(), attributes.getColor(2)); 85 | 86 | PaintDrawable checkedCore = new PaintDrawable(attributes.getColor(2)); 87 | checkedCore.setCornerRadius(attributes.getSize()); 88 | checkedCore.setIntrinsicHeight(attributes.getSize()); 89 | checkedCore.setIntrinsicWidth(attributes.getSize()); 90 | InsetDrawable checkedInside = new InsetDrawable(checkedCore, 91 | attributes.getBorderWidth() + dotMargin, attributes.getBorderWidth() + dotMargin, 92 | attributes.getBorderWidth() + dotMargin, attributes.getBorderWidth() + dotMargin); 93 | 94 | Drawable[] checkedEnabledDrawable = {checkedOutside, checkedInside}; 95 | LayerDrawable checkedEnabled = new LayerDrawable(checkedEnabledDrawable); 96 | 97 | // creating unchecked-enabled state drawable 98 | GradientDrawable uncheckedDisabled = new GradientDrawable(); 99 | uncheckedDisabled.setCornerRadius(attributes.getRadius()); 100 | uncheckedDisabled.setSize(attributes.getSize(), attributes.getSize()); 101 | uncheckedDisabled.setColor(Color.TRANSPARENT); 102 | uncheckedDisabled.setStroke(attributes.getBorderWidth(), attributes.getColor(3)); 103 | 104 | // creating checked-disabled state drawable 105 | GradientDrawable checkedOutsideDisabled = new GradientDrawable(); 106 | checkedOutsideDisabled.setCornerRadius(attributes.getRadius()); 107 | checkedOutsideDisabled.setSize(attributes.getSize(), attributes.getSize()); 108 | checkedOutsideDisabled.setColor(Color.TRANSPARENT); 109 | checkedOutsideDisabled.setStroke(attributes.getBorderWidth(), attributes.getColor(3)); 110 | 111 | PaintDrawable checkedCoreDisabled = new PaintDrawable(attributes.getColor(3)); 112 | checkedCoreDisabled.setCornerRadius(attributes.getRadius()); 113 | checkedCoreDisabled.setIntrinsicHeight(attributes.getSize()); 114 | checkedCoreDisabled.setIntrinsicWidth(attributes.getSize()); 115 | InsetDrawable checkedInsideDisabled = new InsetDrawable(checkedCoreDisabled, 116 | attributes.getBorderWidth() + dotMargin, attributes.getBorderWidth() + dotMargin, 117 | attributes.getBorderWidth() + dotMargin, attributes.getBorderWidth() + dotMargin); 118 | 119 | Drawable[] checkedDisabledDrawable = {checkedOutsideDisabled, checkedInsideDisabled}; 120 | LayerDrawable checkedDisabled = new LayerDrawable(checkedDisabledDrawable); 121 | 122 | 123 | StateListDrawable states = new StateListDrawable(); 124 | states.addState(new int[]{-android.R.attr.state_checked, android.R.attr.state_enabled}, uncheckedEnabled); 125 | states.addState(new int[]{android.R.attr.state_checked, android.R.attr.state_enabled}, checkedEnabled); 126 | states.addState(new int[]{-android.R.attr.state_checked, -android.R.attr.state_enabled}, uncheckedDisabled); 127 | states.addState(new int[]{android.R.attr.state_checked, -android.R.attr.state_enabled}, checkedDisabled); 128 | setButtonDrawable(states); 129 | 130 | // setting padding for avoiding text to be appear on icon 131 | setPadding(attributes.getSize() / 4 * 5, 0, 0, 0); 132 | setTextColor(attributes.getColor(2)); 133 | 134 | // check for IDE preview render 135 | if(!this.isInEditMode()) { 136 | Typeface typeface = FlatUI.getFont(getContext(), attributes); 137 | if (typeface != null) setTypeface(typeface); 138 | } 139 | } 140 | 141 | public Attributes getAttributes() { 142 | return attributes; 143 | } 144 | 145 | @Override 146 | public void onThemeChange() { 147 | init(null); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /library/src/main/java/com/cengalabs/flatui/views/FlatSeekBar.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui.views; 2 | 3 | import android.R; 4 | import android.content.Context; 5 | import android.content.res.TypedArray; 6 | import android.graphics.drawable.ClipDrawable; 7 | import android.graphics.drawable.LayerDrawable; 8 | import android.graphics.drawable.PaintDrawable; 9 | import android.util.AttributeSet; 10 | import android.view.Gravity; 11 | import android.widget.SeekBar; 12 | 13 | import com.cengalabs.flatui.Attributes; 14 | 15 | /** 16 | * User: eluleci 17 | * Date: 24.10.2013 18 | * Time: 23:03 19 | */ 20 | public class FlatSeekBar extends SeekBar implements Attributes.AttributeChangeListener { 21 | 22 | private Attributes attributes; 23 | 24 | public FlatSeekBar(Context context) { 25 | super(context); 26 | init(null); 27 | } 28 | 29 | public FlatSeekBar(Context context, AttributeSet attrs) { 30 | super(context, attrs); 31 | init(attrs); 32 | } 33 | 34 | public FlatSeekBar(Context context, AttributeSet attrs, int defStyle) { 35 | super(context, attrs, defStyle); 36 | init(attrs); 37 | } 38 | 39 | private void init(AttributeSet attrs) { 40 | 41 | if (attributes == null) 42 | attributes = new Attributes(this, getResources()); 43 | 44 | if (attrs != null) { 45 | TypedArray a = getContext().obtainStyledAttributes(attrs, com.cengalabs.flatui.R.styleable.fl_FlatSeekBar); 46 | 47 | // getting common attributes 48 | int customTheme = a.getResourceId(com.cengalabs.flatui.R.styleable.fl_FlatSeekBar_fl_theme, Attributes.DEFAULT_THEME); 49 | attributes.setThemeSilent(customTheme, getResources()); 50 | 51 | attributes.setSize(a.getDimensionPixelSize(com.cengalabs.flatui.R.styleable.fl_FlatSeekBar_fl_size, Attributes.DEFAULT_SIZE_PX)); 52 | 53 | a.recycle(); 54 | } 55 | 56 | // setting thumb 57 | PaintDrawable thumb = new PaintDrawable(attributes.getColor(0)); 58 | thumb.setCornerRadius(attributes.getSize() * 9 / 8); 59 | thumb.setIntrinsicWidth(attributes.getSize() * 9 / 4); 60 | thumb.setIntrinsicHeight(attributes.getSize() * 9 / 4); 61 | setThumb(thumb); 62 | 63 | // progress 64 | PaintDrawable progress = new PaintDrawable(attributes.getColor(1)); 65 | progress.setCornerRadius(attributes.getSize()); 66 | progress.setIntrinsicHeight(attributes.getSize()); 67 | progress.setIntrinsicWidth(attributes.getSize()); 68 | progress.setDither(true); 69 | ClipDrawable progressClip = new ClipDrawable(progress, Gravity.LEFT, ClipDrawable.HORIZONTAL); 70 | 71 | // secondary progress 72 | PaintDrawable secondary = new PaintDrawable(attributes.getColor(2)); 73 | secondary.setCornerRadius(attributes.getSize()); 74 | secondary.setIntrinsicHeight(attributes.getSize()); 75 | ClipDrawable secondaryProgressClip = new ClipDrawable(secondary, Gravity.LEFT, ClipDrawable.HORIZONTAL); 76 | 77 | // background 78 | PaintDrawable background = new PaintDrawable(attributes.getColor(3)); 79 | background.setCornerRadius(attributes.getSize()); 80 | background.setIntrinsicHeight(attributes.getSize()); 81 | 82 | // applying drawable 83 | LayerDrawable ld = (LayerDrawable) getProgressDrawable(); 84 | ld.setDrawableByLayerId(R.id.background, background); 85 | ld.setDrawableByLayerId(R.id.progress, progressClip); 86 | ld.setDrawableByLayerId(R.id.secondaryProgress, secondaryProgressClip); 87 | } 88 | 89 | public Attributes getAttributes() { 90 | return attributes; 91 | } 92 | 93 | @Override 94 | public void onThemeChange() { 95 | init(null); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /library/src/main/java/com/cengalabs/flatui/views/FlatTextView.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui.views; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Color; 6 | import android.graphics.Typeface; 7 | import android.graphics.drawable.GradientDrawable; 8 | import android.util.AttributeSet; 9 | import android.widget.TextView; 10 | 11 | import com.cengalabs.flatui.Attributes; 12 | import com.cengalabs.flatui.FlatUI; 13 | import com.cengalabs.flatui.R; 14 | 15 | /** 16 | * User: eluleci 17 | * Date: 24.10.2013 18 | * Time: 21:09 19 | */ 20 | public class FlatTextView extends TextView implements Attributes.AttributeChangeListener { 21 | 22 | private Attributes attributes; 23 | 24 | private int textColor = 2; 25 | private int backgroundColor = Attributes.INVALID; 26 | private int customBackgroundColor = Attributes.INVALID; 27 | 28 | private boolean hasOwnTextColor; 29 | 30 | public FlatTextView(Context context) { 31 | super(context); 32 | init(null); 33 | } 34 | 35 | public FlatTextView(Context context, AttributeSet attrs) { 36 | super(context, attrs); 37 | init(attrs); 38 | } 39 | 40 | public FlatTextView(Context context, AttributeSet attrs, int defStyle) { 41 | super(context, attrs, defStyle); 42 | init(attrs); 43 | } 44 | 45 | private void init(AttributeSet attrs) { 46 | 47 | if (attributes == null) 48 | attributes = new Attributes(this, getResources()); 49 | 50 | if (attrs != null) { 51 | 52 | // getting android default tags for textColor and textColorHint 53 | String textColorAttribute = attrs.getAttributeValue(FlatUI.androidStyleNameSpace, "textColor"); 54 | int styleId = attrs.getStyleAttribute(); 55 | int[] attributesArray = new int[] { android.R.attr.textColor }; 56 | TypedArray styleTextColorTypedArray = getContext().obtainStyledAttributes(styleId, attributesArray); 57 | // color might have values from the entire integer range, so to find out if there is any color set, 58 | // checking if default value is returned is not enough. Thus we get color with two different 59 | // default values - if returned value is the same, it means color is set 60 | int styleTextColor1 = styleTextColorTypedArray.getColor(0, -1); 61 | int styleTextColor2 = styleTextColorTypedArray.getColor(0, 1); 62 | hasOwnTextColor = textColorAttribute != null || styleTextColor1 == styleTextColor2; 63 | styleTextColorTypedArray.recycle(); 64 | 65 | TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.fl_FlatTextView); 66 | 67 | // getting common attributes 68 | int customTheme = a.getResourceId(R.styleable.fl_FlatTextView_fl_theme, Attributes.DEFAULT_THEME); 69 | attributes.setThemeSilent(customTheme, getResources()); 70 | 71 | attributes.setFontFamily(a.getString(R.styleable.fl_FlatTextView_fl_fontFamily)); 72 | attributes.setFontWeight(a.getString(R.styleable.fl_FlatTextView_fl_fontWeight)); 73 | attributes.setFontExtension(a.getString(R.styleable.fl_FlatTextView_fl_fontExtension)); 74 | 75 | attributes.setRadius(a.getDimensionPixelSize(R.styleable.fl_FlatTextView_fl_cornerRadius, Attributes.DEFAULT_RADIUS_PX)); 76 | attributes.setBorderWidth(a.getDimensionPixelSize(R.styleable.fl_FlatTextView_fl_borderWidth, 0)); 77 | 78 | // getting view specific attributes 79 | textColor = a.getInt(R.styleable.fl_FlatTextView_fl_textColor, textColor); 80 | backgroundColor = a.getInt(R.styleable.fl_FlatTextView_fl_backgroundColor, backgroundColor); 81 | customBackgroundColor = a.getInt(R.styleable.fl_FlatTextView_fl_customBackgroundColor, customBackgroundColor); 82 | 83 | a.recycle(); 84 | } 85 | 86 | GradientDrawable gradientDrawable = new GradientDrawable(); 87 | if (backgroundColor != Attributes.INVALID) { 88 | gradientDrawable.setColor(attributes.getColor(backgroundColor)); 89 | } else if (customBackgroundColor != Attributes.INVALID) { 90 | gradientDrawable.setColor(customBackgroundColor); 91 | } else { 92 | gradientDrawable.setColor(Color.TRANSPARENT); 93 | } 94 | gradientDrawable.setCornerRadius(attributes.getRadius()); 95 | gradientDrawable.setStroke(attributes.getBorderWidth(), attributes.getColor(textColor)); 96 | setBackgroundDrawable(gradientDrawable); 97 | 98 | // setting the text color only if there is no android:textColor attribute used 99 | if (!hasOwnTextColor) setTextColor(attributes.getColor(textColor)); 100 | 101 | // check for IDE preview render 102 | if(!this.isInEditMode()) { 103 | Typeface typeface = FlatUI.getFont(getContext(), attributes); 104 | if (typeface != null) setTypeface(typeface); 105 | } 106 | } 107 | 108 | public Attributes getAttributes() { 109 | return attributes; 110 | } 111 | 112 | @Override 113 | public void onThemeChange() { 114 | init(null); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /library/src/main/java/com/cengalabs/flatui/views/FlatToggleButton.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui.views; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Color; 6 | import android.graphics.drawable.Drawable; 7 | import android.graphics.drawable.InsetDrawable; 8 | import android.graphics.drawable.LayerDrawable; 9 | import android.graphics.drawable.ShapeDrawable; 10 | import android.graphics.drawable.StateListDrawable; 11 | import android.graphics.drawable.shapes.RoundRectShape; 12 | import android.util.AttributeSet; 13 | import android.widget.ToggleButton; 14 | 15 | import com.cengalabs.flatui.Attributes; 16 | import com.cengalabs.flatui.R; 17 | 18 | /** 19 | * User: eluleci 20 | * Date: 23.10.2013 21 | * Time: 22:18 22 | */ 23 | public class FlatToggleButton extends ToggleButton implements Attributes.AttributeChangeListener { 24 | 25 | private Attributes attributes; 26 | 27 | private int space = 14; 28 | private int padding; 29 | 30 | public FlatToggleButton(Context context) { 31 | super(context); 32 | init(null); 33 | } 34 | 35 | public FlatToggleButton(Context context, AttributeSet attrs) { 36 | super(context, attrs); 37 | init(attrs); 38 | } 39 | 40 | public FlatToggleButton(Context context, AttributeSet attrs, int defStyle) { 41 | super(context, attrs, defStyle); 42 | init(attrs); 43 | } 44 | 45 | private void init(AttributeSet attrs) { 46 | 47 | if (attributes == null) 48 | attributes = new Attributes(this, getResources()); 49 | 50 | if (attrs != null) { 51 | TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.fl_FlatToggleButton); 52 | 53 | // getting common attributes 54 | int customTheme = a.getResourceId(R.styleable.fl_FlatToggleButton_fl_theme, Attributes.DEFAULT_THEME); 55 | attributes.setThemeSilent(customTheme, getResources()); 56 | 57 | attributes.setRadius(a.getDimensionPixelSize(R.styleable.fl_FlatToggleButton_fl_cornerRadius, Attributes.DEFAULT_RADIUS_PX)); 58 | 59 | space = a.getDimensionPixelSize(R.styleable.fl_FlatToggleButton_fl_space, space); 60 | padding = space / 10; 61 | 62 | a.recycle(); 63 | } 64 | 65 | // creating unchecked-enabled state drawable 66 | ShapeDrawable uncheckedEnabledFrontCore = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 67 | uncheckedEnabledFrontCore.getPaint().setColor(attributes.getColor(2)); 68 | InsetDrawable uncheckedEnabledFront = new InsetDrawable(uncheckedEnabledFrontCore, padding); 69 | 70 | ShapeDrawable uncheckedEnabledBack = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 71 | uncheckedEnabledBack.getPaint().setColor(Color.parseColor("#f2f2f2")); 72 | uncheckedEnabledBack.setIntrinsicWidth(space / 2 * 5); 73 | uncheckedEnabledBack.setIntrinsicHeight(space); 74 | uncheckedEnabledBack.setPadding(0, 0, space / 2 * 5, 0); 75 | 76 | Drawable[] d1 = {uncheckedEnabledBack, uncheckedEnabledFront}; 77 | LayerDrawable uncheckedEnabled = new LayerDrawable(d1); 78 | 79 | // creating checked-enabled state drawable 80 | ShapeDrawable checkedEnabledFrontCore = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 81 | checkedEnabledFrontCore.getPaint().setColor(attributes.getColor(2)); 82 | InsetDrawable checkedEnabledFront = new InsetDrawable(checkedEnabledFrontCore, padding); 83 | 84 | ShapeDrawable checkedEnabledBack = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 85 | checkedEnabledBack.getPaint().setColor(attributes.getColor(3)); 86 | checkedEnabledBack.setPadding(space / 2 * 5, 0, 0, 0); 87 | 88 | Drawable[] d2 = {checkedEnabledBack, checkedEnabledFront}; 89 | LayerDrawable checkedEnabled = new LayerDrawable(d2); 90 | 91 | // creating unchecked-disabled state drawable 92 | ShapeDrawable uncheckedDisabledFrontCore = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 93 | uncheckedDisabledFrontCore.getPaint().setColor(Color.parseColor("#d2d2d2")); 94 | InsetDrawable uncheckedDisabledFront = new InsetDrawable(uncheckedDisabledFrontCore, padding); 95 | 96 | ShapeDrawable uncheckedDisabledBack = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 97 | uncheckedDisabledBack.getPaint().setColor(Color.parseColor("#f2f2f2")); 98 | uncheckedDisabledBack.setPadding(0, 0, space / 2 * 5, 0); 99 | 100 | Drawable[] d3 = {uncheckedDisabledBack, uncheckedDisabledFront}; 101 | LayerDrawable uncheckedDisabled = new LayerDrawable(d3); 102 | 103 | // creating checked-disabled state drawable 104 | ShapeDrawable checkedDisabledFrontCore = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 105 | checkedDisabledFrontCore.getPaint().setColor(attributes.getColor(3)); 106 | InsetDrawable checkedDisabledFront = new InsetDrawable(checkedDisabledFrontCore, padding); 107 | 108 | ShapeDrawable checkedDisabledBack = new ShapeDrawable(new RoundRectShape(attributes.getOuterRadius(), null, null)); 109 | checkedDisabledBack.getPaint().setColor(Color.parseColor("#f2f2f2")); 110 | checkedDisabledBack.setPadding(space / 2 * 5, 0, 0, 0); 111 | 112 | Drawable[] d4 = {checkedDisabledBack, checkedDisabledFront}; 113 | LayerDrawable checkedDisabled = new LayerDrawable(d4); 114 | 115 | StateListDrawable states = new StateListDrawable(); 116 | 117 | states.addState(new int[]{-android.R.attr.state_checked, android.R.attr.state_enabled}, 118 | new InsetDrawable(uncheckedEnabled, padding * 2)); 119 | states.addState(new int[]{android.R.attr.state_checked, android.R.attr.state_enabled}, 120 | new InsetDrawable(checkedEnabled, padding * 2)); 121 | states.addState(new int[]{-android.R.attr.state_checked, -android.R.attr.state_enabled}, 122 | new InsetDrawable(uncheckedDisabled, padding * 2)); 123 | states.addState(new int[]{android.R.attr.state_checked, -android.R.attr.state_enabled}, 124 | new InsetDrawable(checkedDisabled, padding * 2)); 125 | 126 | setBackgroundDrawable(states); 127 | 128 | setText(""); 129 | setTextOff(""); 130 | setTextOn(""); 131 | 132 | setTextSize(0); 133 | } 134 | 135 | public Attributes getAttributes() { 136 | return attributes; 137 | } 138 | 139 | @Override 140 | public void onThemeChange() { 141 | init(null); 142 | } 143 | } -------------------------------------------------------------------------------- /library/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 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 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /library/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | #ad843d 6 | #d4a14a 7 | #fbbf58 8 | #fae8c8 9 | 10 | @color/sand_darker 11 | @color/sand_dark 12 | @color/sand_primary 13 | @color/sand_light 14 | 15 | 16 | 17 | #994628 18 | #cc5d35 19 | #ff7342 20 | #ffbfa8 21 | 22 | @color/orange_darker 23 | @color/orange_dark 24 | @color/orange_primary 25 | @color/orange_light 26 | 27 | 28 | 29 | #80363c 30 | #bf505a 31 | #f56773 32 | #f5c4c8 33 | 34 | @color/candy_darker 35 | @color/candy_dark 36 | @color/candy_primary 37 | @color/candy_light 38 | 39 | 40 | 41 | #8f5e76 42 | #b57795 43 | #e898bf 44 | #e8d1dc 45 | 46 | @color/blossom_darker 47 | @color/blossom_dark 48 | @color/blossom_primary 49 | @color/blossom_light 50 | 51 | 52 | 53 | #362f4a 54 | #4f456b 55 | #695b8e 56 | #b1a2db 57 | 58 | @color/grape_darker 59 | @color/grape_dark 60 | @color/grape_primary 61 | @color/grape_light 62 | 63 | 64 | 65 | #232b35 66 | #2d3845 67 | #2d3845 68 | #c7dbf4 69 | 70 | @color/deep_darker 71 | @color/deep_dark 72 | @color/deep_primary 73 | @color/deep_light 74 | 75 | 76 | 77 | #0b6978 78 | #0e8b9e 79 | #13b7d2 80 | #b9e4eb 81 | 82 | @color/sky_darker 83 | @color/sky_dark 84 | @color/sky_primary 85 | @color/sky_light 86 | 87 | 88 | 89 | #124c38 90 | #1e7d5b 91 | #2ab081 92 | #a8e3ce 93 | 94 | @color/grass_darker 95 | @color/grass_dark 96 | @color/grass_primary 97 | @color/grass_light 98 | 99 | 100 | 101 | #050505 102 | #202020 103 | #454545 104 | #a3a3a3 105 | 106 | @color/dark_darker 107 | @color/dark_dark 108 | @color/dark_primary 109 | @color/dark_light 110 | 111 | 112 | 113 | #c8c8c8 114 | #dddddd 115 | #e8e8e8 116 | #fafafa 117 | 118 | @color/snow_darker 119 | @color/snow_dark 120 | @color/snow_primary 121 | @color/snow_light 122 | 123 | 124 | 125 | #1a3b6c 126 | #1c52a2 127 | #2d72d9 128 | #d5e3f7 129 | 130 | @color/sea_darker 131 | @color/sea_dark 132 | @color/sea_primary 133 | @color/sea_light 134 | 135 | 136 | 137 | #732219 138 | #a63124 139 | #d94130 140 | #f2b6ae 141 | 142 | @color/blood_darker 143 | @color/blood_dark 144 | @color/blood_primary 145 | @color/blood_light 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /library/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | FlatUI Kit 3 | 4 | -------------------------------------------------------------------------------- /maven_push.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven' 2 | apply plugin: 'signing' 3 | 4 | def sonatypeRepositoryUrl 5 | if (isReleaseBuild()) { 6 | println 'RELEASE BUILD' 7 | sonatypeRepositoryUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" 8 | } else { 9 | println 'DEBUG BUILD' 10 | sonatypeRepositoryUrl = "https://oss.sonatype.org/content/repositories/snapshots/" 11 | } 12 | 13 | afterEvaluate { project -> 14 | uploadArchives { 15 | repositories { 16 | mavenDeployer { 17 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } 18 | 19 | pom.artifactId = POM_ARTIFACT_ID 20 | 21 | repository(url: sonatypeRepositoryUrl) { 22 | authentication(userName: nexusUsername, password: nexusPassword) 23 | } 24 | 25 | pom.project { 26 | name POM_NAME 27 | packaging POM_PACKAGING 28 | description POM_DESCRIPTION 29 | url POM_URL 30 | 31 | scm { 32 | url POM_SCM_URL 33 | connection POM_SCM_CONNECTION 34 | developerConnection POM_SCM_DEV_CONNECTION 35 | } 36 | 37 | licenses { 38 | license { 39 | name POM_LICENCE_NAME 40 | url POM_LICENCE_URL 41 | distribution POM_LICENCE_DIST 42 | } 43 | } 44 | 45 | developers { 46 | developer { 47 | id POM_DEVELOPER_ID 48 | name POM_DEVELOPER_NAME 49 | } 50 | } 51 | } 52 | } 53 | } 54 | } 55 | 56 | signing { 57 | required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") } 58 | sign configurations.archives 59 | } 60 | 61 | task androidJavadocs(type: Javadoc) { 62 | source = android.sourceSets.main.java 63 | } 64 | 65 | task androidJavadocsJar(type: Jar) { 66 | classifier = 'javadoc' 67 | //basename = artifact_id 68 | from androidJavadocs.destinationDir 69 | } 70 | 71 | task androidSourcesJar(type: Jar) { 72 | classifier = 'sources' 73 | //basename = artifact_id 74 | from android.sourceSets.main.java 75 | } 76 | 77 | artifacts { 78 | //archives packageReleaseJar 79 | archives androidSourcesJar 80 | archives androidJavadocsJar 81 | } 82 | } -------------------------------------------------------------------------------- /sample-images/flat_ui_theme_sand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/sample-images/flat_ui_theme_sand.png -------------------------------------------------------------------------------- /sample-images/showcase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/sample-images/showcase.png -------------------------------------------------------------------------------- /sample-images/themes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/sample-images/themes.png -------------------------------------------------------------------------------- /sample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'android' 2 | 3 | android { 4 | compileSdkVersion 19 5 | buildToolsVersion '19.1.0' 6 | defaultConfig { 7 | minSdkVersion 8 8 | targetSdkVersion 19 9 | versionCode 1 10 | versionName '1.0' 11 | } 12 | productFlavors { 13 | } 14 | buildTypes { 15 | } 16 | } 17 | 18 | dependencies { 19 | compile 'com.android.support:appcompat-v7:19.1.0' 20 | compile project(':library') 21 | } 22 | -------------------------------------------------------------------------------- /sample/proguard-rules.txt: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the ProGuard 5 | # include property in project.properties. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} -------------------------------------------------------------------------------- /sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sample/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/sample/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /sample/src/main/java/com/cengalabs/flatui/sample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui.sample; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.ActionBarActivity; 5 | import android.view.View; 6 | import android.widget.AdapterView; 7 | import android.widget.ArrayAdapter; 8 | import android.widget.AutoCompleteTextView; 9 | import android.widget.Spinner; 10 | 11 | import com.cengalabs.flatui.FlatUI; 12 | import com.cengalabs.flatui.views.FlatButton; 13 | import com.cengalabs.flatui.views.FlatCheckBox; 14 | import com.cengalabs.flatui.views.FlatEditText; 15 | import com.cengalabs.flatui.views.FlatRadioButton; 16 | import com.cengalabs.flatui.views.FlatSeekBar; 17 | import com.cengalabs.flatui.views.FlatTextView; 18 | import com.cengalabs.flatui.views.FlatToggleButton; 19 | 20 | import java.util.ArrayList; 21 | 22 | public class MainActivity extends ActionBarActivity { 23 | 24 | private final int APP_THEME = R.array.blood; 25 | 26 | private ArrayList flatTextViews = new ArrayList(); 27 | private ArrayList flatEditTexts = new ArrayList(); 28 | private ArrayList flatButtons = new ArrayList(); 29 | private ArrayList flatCheckBoxes = new ArrayList(); 30 | private ArrayList flatRadioButtons = new ArrayList(); 31 | private ArrayList flatToggleButtons = new ArrayList(); 32 | private FlatRadioButton radioCheckedEnabled; 33 | private FlatSeekBar flatSeekBar; 34 | 35 | private boolean isSpinnerSelectedBefore = false; 36 | 37 | @Override 38 | protected void onCreate(Bundle savedInstanceState) { 39 | super.onCreate(savedInstanceState); 40 | 41 | // converts the default values to dp to be compatible with different screen sizes 42 | FlatUI.initDefaultValues(this); 43 | 44 | // Default theme should be set before content view is added 45 | FlatUI.setDefaultTheme(APP_THEME); 46 | 47 | setContentView(R.layout.activity_main); 48 | 49 | // Getting action bar background and applying it 50 | getSupportActionBar().setBackgroundDrawable(FlatUI.getActionBarDrawable(this, APP_THEME, false, 2)); 51 | 52 | // titles 53 | flatTextViews.add((FlatTextView) findViewById(R.id.title_edittexts)); 54 | flatTextViews.add((FlatTextView) findViewById(R.id.title_seekbar)); 55 | flatTextViews.add((FlatTextView) findViewById(R.id.title_buttons)); 56 | flatTextViews.add((FlatTextView) findViewById(R.id.title_buttons_shape)); 57 | flatTextViews.add((FlatTextView) findViewById(R.id.title_buttons_text_appearance)); 58 | flatTextViews.add((FlatTextView) findViewById(R.id.title_buttons_touch_effect)); 59 | flatTextViews.add((FlatTextView) findViewById(R.id.title_checkbox)); 60 | flatTextViews.add((FlatTextView) findViewById(R.id.title_checkbox_enabled)); 61 | flatTextViews.add((FlatTextView) findViewById(R.id.title_checkbox_disabled)); 62 | flatTextViews.add((FlatTextView) findViewById(R.id.title_radiobutton)); 63 | flatTextViews.add((FlatTextView) findViewById(R.id.title_radiobutton_enabled)); 64 | flatTextViews.add((FlatTextView) findViewById(R.id.title_radiobutton_disabled)); 65 | flatTextViews.add((FlatTextView) findViewById(R.id.title_toggle_button)); 66 | flatTextViews.add((FlatTextView) findViewById(R.id.title_toggle_enabled)); 67 | flatTextViews.add((FlatTextView) findViewById(R.id.title_toggle_disabled)); 68 | flatTextViews.add((FlatTextView) findViewById(R.id.title_themes)); 69 | flatTextViews.add((FlatTextView) findViewById(R.id.title_themes_note)); 70 | 71 | // edit texts 72 | flatEditTexts.add((FlatEditText) findViewById(R.id.edittext_flat)); 73 | flatEditTexts.add((FlatEditText) findViewById(R.id.edittext_box)); 74 | flatEditTexts.add((FlatEditText) findViewById(R.id.edittext_transparentbox)); 75 | flatEditTexts.add((FlatEditText) findViewById(R.id.edittext_transparent)); 76 | 77 | // buttons 78 | flatButtons.add((FlatButton) findViewById(R.id.button_block)); 79 | flatButtons.add((FlatButton) findViewById(R.id.button_flat)); 80 | flatButtons.add((FlatButton) findViewById(R.id.button_light)); 81 | flatButtons.add((FlatButton) findViewById(R.id.button_white)); 82 | flatButtons.add((FlatButton) findViewById(R.id.button_dark_text)); 83 | flatButtons.add((FlatButton) findViewById(R.id.button_ease)); 84 | flatButtons.add((FlatButton) findViewById(R.id.button_ripple)); 85 | 86 | // check boxes 87 | flatCheckBoxes.add((FlatCheckBox) findViewById(R.id.checkbox_unchecked_enabled)); 88 | flatCheckBoxes.add((FlatCheckBox) findViewById(R.id.checkbox_checked_enabled)); 89 | flatCheckBoxes.add((FlatCheckBox) findViewById(R.id.checkbox_unchecked_disabled)); 90 | flatCheckBoxes.add((FlatCheckBox) findViewById(R.id.checkbox_checked_disabled)); 91 | 92 | // radio buttons 93 | flatRadioButtons.add((FlatRadioButton) findViewById(R.id.radio_unchecked_enabled)); 94 | flatRadioButtons.add((FlatRadioButton) findViewById(R.id.radio_unchecked_disabled)); 95 | flatRadioButtons.add((FlatRadioButton) findViewById(R.id.radio_checked_disabled)); 96 | radioCheckedEnabled = (FlatRadioButton) findViewById(R.id.radio_checked_enabled); 97 | flatRadioButtons.add(radioCheckedEnabled); 98 | radioCheckedEnabled.setChecked(true); 99 | 100 | // toggle buttons 101 | flatToggleButtons.add((FlatToggleButton) findViewById(R.id.toggle_unchecked_enabled)); 102 | flatToggleButtons.add((FlatToggleButton) findViewById(R.id.toggle_checked_enabled)); 103 | flatToggleButtons.add((FlatToggleButton) findViewById(R.id.toggle_unchecked_disabled)); 104 | flatToggleButtons.add((FlatToggleButton) findViewById(R.id.toggle_checked_disabled)); 105 | 106 | flatSeekBar = (FlatSeekBar) findViewById(R.id.seekbar); 107 | flatSeekBar.setProgress(30); 108 | flatSeekBar.setSecondaryProgress(40); 109 | 110 | /** 111 | * This part is an example of spinner usage. You can change the theme of this spinner by 112 | * editing the layout files spinner_button and simple_flat_list_item. 113 | */ 114 | Spinner spinner = (Spinner) findViewById(R.id.themes_spinner); 115 | 116 | // Create an ArrayAdapter using the string array and a custom spinner layout 117 | ArrayAdapter adapter = ArrayAdapter.createFromResource(this, 118 | R.array.themes_array, R.layout.spinner_button); 119 | 120 | // Specify the layout to use when the list of choices appears 121 | adapter.setDropDownViewResource(R.layout.simple_flat_list_item); 122 | 123 | spinner.setAdapter(adapter); 124 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 125 | @Override 126 | public void onItemSelected(AdapterView parent, View view, int position, long id) { 127 | 128 | // preventing the spinner to change the theme on start 129 | if (!isSpinnerSelectedBefore) { 130 | isSpinnerSelectedBefore = true; 131 | return; 132 | } 133 | 134 | int themeReference = APP_THEME; 135 | switch (position) { 136 | case 0: 137 | themeReference = FlatUI.SAND; 138 | break; 139 | case 1: 140 | themeReference = FlatUI.ORANGE; 141 | break; 142 | case 2: 143 | themeReference = FlatUI.CANDY; 144 | break; 145 | case 3: 146 | themeReference = FlatUI.BLOSSOM; 147 | break; 148 | case 4: 149 | themeReference = FlatUI.GRAPE; 150 | break; 151 | case 5: 152 | themeReference = FlatUI.DEEP; 153 | break; 154 | case 6: 155 | themeReference = FlatUI.SKY; 156 | break; 157 | case 7: 158 | themeReference = FlatUI.GRASS; 159 | break; 160 | case 8: 161 | themeReference = FlatUI.DARK; 162 | break; 163 | case 9: 164 | themeReference = FlatUI.SNOW; 165 | break; 166 | case 10: 167 | themeReference = FlatUI.SEA; 168 | break; 169 | case 11: 170 | themeReference = FlatUI.BLOOD; 171 | break; 172 | } 173 | changeTheme(themeReference); 174 | } 175 | 176 | @Override 177 | public void onNothingSelected(AdapterView parent) { 178 | 179 | } 180 | }); 181 | 182 | /** 183 | * Autocomplete textview. You can change the EditText color via theme but 184 | * you need to set a layout for the rows as shown below. This is the same 185 | * row that is used in the spinner example. 186 | */ 187 | AutoCompleteTextView actv = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1); 188 | 189 | String[] themes = getResources().getStringArray(R.array.themes_array); 190 | ArrayAdapter acAdapter = new ArrayAdapter(this, R.layout.simple_flat_list_item, themes); 191 | actv.setAdapter(acAdapter); 192 | } 193 | 194 | public void onChangeThemeButtonClicked(View v) { 195 | FlatButton button = (FlatButton) v; 196 | changeTheme(button.getAttributes().getTheme()); 197 | } 198 | 199 | private void changeTheme(int colorReference) { 200 | 201 | for (FlatTextView view : flatTextViews) { 202 | view.getAttributes().setTheme(colorReference, getResources()); 203 | } 204 | 205 | for (FlatEditText view : flatEditTexts) { 206 | view.getAttributes().setTheme(colorReference, getResources()); 207 | } 208 | 209 | for (FlatButton view : flatButtons) { 210 | view.getAttributes().setTheme(colorReference, getResources()); 211 | } 212 | 213 | for (FlatCheckBox view : flatCheckBoxes) { 214 | view.getAttributes().setTheme(colorReference, getResources()); 215 | } 216 | 217 | for (FlatRadioButton view : flatRadioButtons) { 218 | view.getAttributes().setTheme(colorReference, getResources()); 219 | } 220 | 221 | for (FlatToggleButton view : flatToggleButtons) { 222 | view.getAttributes().setTheme(colorReference, getResources()); 223 | } 224 | 225 | flatSeekBar.getAttributes().setTheme(colorReference, getResources()); 226 | 227 | runOnUiThread(new Runnable() { 228 | @Override 229 | public void run() { 230 | flatSeekBar.setProgress(30); 231 | flatSeekBar.setSecondaryProgress(40); 232 | } 233 | }); 234 | 235 | // if you are using standard action bar (not compatibility library) use this 236 | // getActionBar().setBackgroundDrawable(FlatUI.getActionBarDrawable(this, colorReference, false)); 237 | 238 | // if you are using ActionBar of Compatibility library, get drawable and set it manually 239 | getSupportActionBar().setBackgroundDrawable(FlatUI.getActionBarDrawable(this, colorReference, false)); 240 | 241 | setTitle("FlatUI Sample App"); 242 | } 243 | 244 | } 245 | -------------------------------------------------------------------------------- /sample/src/main/java/com/cengalabs/flatui/sample/RippleLinearLayout.java: -------------------------------------------------------------------------------- 1 | package com.cengalabs.flatui.sample; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.util.AttributeSet; 7 | import android.view.MotionEvent; 8 | import android.view.View; 9 | import android.widget.LinearLayout; 10 | 11 | import com.cengalabs.flatui.TouchEffectAnimator; 12 | 13 | /** 14 | * User: eluleci 15 | * Date: 25.09.2014 16 | * Time: 17:23 17 | */ 18 | public class RippleLinearLayout extends LinearLayout { 19 | 20 | private TouchEffectAnimator touchEffectAnimator; 21 | 22 | public RippleLinearLayout(Context context) { 23 | super(context); 24 | init(); 25 | } 26 | 27 | public RippleLinearLayout(Context context, AttributeSet attrs) { 28 | super(context, attrs); 29 | init(); 30 | } 31 | 32 | private void init() { 33 | 34 | // you should set a background to view for effect to be visible. in this sample, this 35 | // linear layout contains a transparent background which is set inside the XML 36 | 37 | // giving the view to animate on 38 | touchEffectAnimator = new TouchEffectAnimator(this); 39 | 40 | // enabling ripple effect. it only performs ease effect without enabling ripple effect 41 | touchEffectAnimator.setHasRippleEffect(true); 42 | 43 | // setting the effect color 44 | touchEffectAnimator.setEffectColor(Color.LTGRAY); 45 | 46 | // setting the duration 47 | touchEffectAnimator.setAnimDuration(1000); 48 | 49 | // setting radius to clip the effect. use it if you have a rounded background 50 | touchEffectAnimator.setClipRadius(20); 51 | 52 | // the view must contain an onClickListener to receive UP touch events. touchEffectAnimator 53 | // doesn't return any value in onTouchEvent for flexibility. so it is developers 54 | // responsibility to add a listener 55 | setOnClickListener(new OnClickListener() { 56 | @Override 57 | public void onClick(View view) { 58 | } 59 | }); 60 | } 61 | 62 | @Override 63 | public boolean onTouchEvent(final MotionEvent event) { 64 | // send the touch event to animator 65 | touchEffectAnimator.onTouchEvent(event); 66 | return super.onTouchEvent(event); 67 | } 68 | 69 | @Override 70 | protected void onDraw(Canvas canvas) { 71 | // let animator show the animation by applying changes to view's canvas 72 | touchEffectAnimator.onDraw(canvas); 73 | super.onDraw(canvas); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/sample/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/sample/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/sample/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eluleci/FlatUI/801ed131779bbaf6697aed5755d65280dc53fd3b/sample/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 16 | 17 | 20 | 21 | 25 | 26 | 27 | 28 | 40 | 41 | 48 | 49 | 60 | 61 | 72 | 73 | 84 | 85 | 97 | 98 | 107 | 108 | 109 | 110 | 111 | 112 | 123 | 124 | 131 | 132 | 138 | 139 | 140 | 141 | 142 | 143 | 154 | 155 | 162 | 163 | 173 | 174 | 178 | 179 | 188 | 189 | 197 | 198 | 199 | 200 | 210 | 211 | 215 | 216 | 224 | 225 | 232 | 233 | 241 | 242 | 243 | 244 | 254 | 255 | 259 | 260 | 269 | 270 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 297 | 298 | 305 | 306 | 311 | 312 | 321 | 322 | 327 | 328 | 337 | 338 | 348 | 349 | 350 | 351 | 352 | 353 | 358 | 359 | 368 | 369 | 374 | 375 | 385 | 386 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 416 | 417 | 424 | 425 | 430 | 431 | 440 | 441 | 445 | 446 | 450 | 451 | 461 | 462 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 484 | 485 | 494 | 495 | 499 | 500 | 504 | 505 | 516 | 517 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 550 | 551 | 558 | 559 | 564 | 565 | 574 | 575 | 580 | 581 | 588 | 589 | 597 | 598 | 599 | 600 | 601 | 602 | 607 | 608 | 617 | 618 | 623 | 624 | 632 | 633 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 655 | 656 | 665 | 666 | 675 | 676 | 677 | 678 | 685 | 686 | 690 | 691 | 701 | 702 | 712 | 713 | 714 | 715 | 719 | 720 | 730 | 731 | 741 | 742 | 743 | 744 | 748 | 749 | 759 | 760 | 770 | 771 | 772 | 773 | 777 | 778 | 788 | 789 | 799 | 800 | 801 | 802 | 806 | 807 | 817 | 818 | 828 | 829 | 830 | 831 | 835 | 836 | 846 | 847 | 857 | 858 | 859 | 860 | 864 | 865 | 875 | 876 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 898 | 899 | 907 | 908 | 915 | 916 | 917 | 918 | 925 | 926 | 930 | 931 | 932 | 933 | 939 | 940 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/simple_flat_list_item.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/spinner_button.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sample/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 |

5 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /sample/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /sample/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | #ff0a463a 6 | #ff1a8868 7 | #1abc9c 8 | #ff1bf0cf 9 | 10 | @color/theme1_darker_color 11 | @color/theme1_dark_color 12 | @color/theme1_primary_color 13 | @color/theme1_light_color 14 | 15 | 16 | 17 | #008AA1 18 | #FFFF34 19 | #10C6DC 20 | #ff6dffff 21 | 22 | 23 | @color/theme2_darker_color 24 | @color/theme2_dark_color 25 | @color/theme2_primary_color 26 | @color/theme2_light_color 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /sample/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | 7 | -------------------------------------------------------------------------------- /sample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | FlatUI 5 | Hello world! 6 | Settings 7 | 8 | 9 | Sand 10 | Orange 11 | Candy 12 | Blossom 13 | Grape 14 | Deep 15 | Sky 16 | Grass 17 | Dark 18 | Snow 19 | Sea 20 | Blood 21 | 22 | 23 | 24 | This TextView is placed into a LinearLayout which uses the TouchEffectAnimator class to 25 | perform this touch animation. This is the same class that is used on FlatButtons to achieve 26 | the same animation. You can look at the sample project to see the usage of this animator 27 | class and you can use it regardless of this FlatUI Library by just copying the 28 | TouchEffectAnimator class to your project. 29 | 30 | 31 | -------------------------------------------------------------------------------- /sample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':sample', ':library' 2 | --------------------------------------------------------------------------------