├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── github │ │ └── zieiony │ │ └── guide │ │ ├── ActivityAnnotation.java │ │ ├── ChartViewActivity.java │ │ ├── FlowLayoutActivity.java │ │ ├── InvalidEditTextActivity.kt │ │ ├── LandscapeDrawableActivity.kt │ │ ├── MainActivity.kt │ │ ├── MoodToggleActivity.kt │ │ ├── ProgressTextViewActivity.java │ │ ├── SampleActivity.kt │ │ └── SampleItem.kt │ └── res │ ├── color │ ├── color_accent_selector.xml │ ├── graph_itemcolor.xml │ └── text_color_selector.xml │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ └── ic_launcher_background.xml │ ├── layout │ ├── activity_chartview.xml │ ├── activity_flowlayout.xml │ ├── activity_invalidedittext.xml │ ├── activity_landscapedrawable.xml │ ├── activity_main.xml │ ├── activity_moodtoggle.xml │ ├── activity_progresstextview.xml │ └── row_sample.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── chartview ├── .gitignore ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── github │ │ └── zieiony │ │ └── guide │ │ └── chartview │ │ ├── ChartView.java │ │ ├── ChartView2.java │ │ └── ChartView3.kt │ └── res │ └── values │ └── attrs.xml ├── flowlayout ├── .gitignore ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── github │ │ └── zieiony │ │ └── guide │ │ └── flowlayout │ │ ├── FlowLayout.java │ │ ├── FlowLayout2.java │ │ └── FlowLayout3.java │ └── res │ └── values │ └── attrs.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images ├── chartview.png ├── distributionfunction.png ├── flowlayout.png ├── itemdrawable.png ├── landscapedrawable.png └── moodtoggle.png ├── invalidedittext ├── .gitignore ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── github │ │ └── zieiony │ │ └── guide │ │ └── invalidedittext │ │ └── InvalidEditText.kt │ └── res │ └── values │ └── attrs.xml ├── landscapedrawable ├── .gitignore ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── github │ └── zieiony │ └── guide │ └── landscapedrawable │ ├── Cloud.kt │ ├── ItemDrawable.kt │ ├── Land.kt │ ├── LandscapeDrawable.kt │ ├── LandscapeItem.kt │ ├── MathUtils.java │ ├── Sky.kt │ ├── Stars.kt │ └── Tree.kt ├── moodtoggle ├── .gitignore ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── github │ │ └── zieiony │ │ └── guide │ │ └── moodtoggle │ │ └── MoodToggle.kt │ └── res │ └── drawable │ ├── ic_sentiment_dissatisfied_black_24dp.xml │ ├── ic_sentiment_neutral_black_24dp.xml │ └── ic_sentiment_satisfied_black_24dp.xml ├── progresstextview ├── .gitignore ├── build.gradle ├── result.png └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── github │ │ └── zieiony │ │ └── guide │ │ └── progresstextview │ │ ├── ProgressTextView_Bad.kt │ │ ├── ProgressTextView_Good.kt │ │ └── ProgressTextView_Medium.kt │ └── res │ └── values │ └── attrs.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | .cxx 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GuideToCustomViews 2 | The ultimate guide to Android custom views 3 | 4 | I've been designing, writing and publishing Android custom views for the past 5 years now. I guess it's about time to sum it up and share the results. 5 | 6 | Here you will find the topics related to custom views and a couple of case studies. Code samples will be in Java and Kotlin randomly and the code will be as simple as possible to demonstrate ideas and techniques better. I want this place to be more of a tutorial wiki than a documentation. You can find the documentation on [developer.android.com/](https://developer.android.com/). 7 | 8 | I'll try to add an article or two per week. If there's something missing and you think that I should write about - raise an issue and tell me. If you wish, there's a larger repository with my custom views [here](https://github.com/ZieIony/Carbon). 9 | 10 | ### Topics 11 | 12 | 1. [Basics](https://github.com/ZieIony/GuideToCustomViews/wiki/Basics) 13 | 1. [What to extend](https://github.com/ZieIony/GuideToCustomViews/wiki/What-to-extend) 14 | 1. [Prefix everything](https://github.com/ZieIony/GuideToCustomViews/wiki/Prefix-everything) 15 | 16 | ##### Code 17 | 18 | 1. [Constructors](https://github.com/ZieIony/GuideToCustomViews/wiki/Constructors) 19 | 1. [Measuring](https://github.com/ZieIony/GuideToCustomViews/wiki/Measuring) 20 | 1. [Custom states](https://github.com/ZieIony/GuideToCustomViews/wiki/Custom-states) 21 | 1. [State saving](https://github.com/ZieIony/GuideToCustomViews/wiki/State-saving) 22 | 1. [Edit mode](https://github.com/ZieIony/GuideToCustomViews/wiki/Edit-mode) 23 | 1. [Drawables](https://github.com/ZieIony/GuideToCustomViews/wiki/Drawables) 24 | 25 | ##### Attributes and styles 26 | 27 | 1. [Using attributes](https://github.com/ZieIony/GuideToCustomViews/wiki/Using-attributes) 28 | 1. [Custom attributes](https://github.com/ZieIony/GuideToCustomViews/wiki/Custom-attributes) 29 | 1. [Custom layout attributes](https://github.com/ZieIony/GuideToCustomViews/wiki/Custom-layout-attributes) 30 | 31 | ##### Accessibility 32 | 33 | 1. [Basic accessibility](https://github.com/ZieIony/GuideToCustomViews/wiki/Basic-accessibility) 34 | 1. [Content description and events](https://github.com/ZieIony/GuideToCustomViews/wiki/Content-description-and-events) 35 | 36 | ### Case studies 37 | 38 | ##### ProgressTextView 39 | 40 | 41 | 42 | A progress bar that also has a text. The text should be drawn in one color on the 'done' part of the progress and in another color on the 'remaining' part. 43 | 44 | See: [guide](https://github.com/ZieIony/GuideToCustomViews/wiki/ProgressTextView), [code](https://github.com/ZieIony/GuideToCustomViews/tree/master/progresstextview). 45 | 46 | ##### ChartView 47 | 48 | 49 | 50 | A simple bar chart with color state lists and bar selecting with clicks. 51 | 52 | Topics covered: drawing on canvas, state lists, touch events. 53 | 54 | See: [code](https://github.com/ZieIony/GuideToCustomViews/tree/master/chartview). 55 | 56 | A more complete version of the view can be found [here](https://github.com/ZieIony/Carbon/blob/master/carbon/src/main/java/carbon/beta/ChartView.java) 57 | 58 | ##### FlowLayout 59 | 60 | 61 | 62 | A layout that displays its children in rows, side to side and then in another line. 63 | 64 | Topics covered: measuring, laying out, custom layout attributes, right to left support. 65 | 66 | See: [code](https://github.com/ZieIony/GuideToCustomViews/tree/master/flowlayout). 67 | 68 | ##### InvalidEditText 69 | 70 | An EditText with support for an invalid state attribute. 71 | 72 | Topics covered: custom states. 73 | 74 | See: [guide](https://github.com/ZieIony/GuideToCustomViews/wiki/InvalidEditText), [code](https://github.com/ZieIony/GuideToCustomViews/tree/master/invalidedittext). 75 | 76 | ##### MoodToggle 77 | 78 | 79 | 80 | A very simple toggle with accessibility support. 81 | 82 | Topics covered: basic accessibility. 83 | 84 | See: [guide](https://github.com/ZieIony/GuideToCustomViews/wiki/MoodToggle), [code](https://github.com/ZieIony/GuideToCustomViews/tree/master/moodtoggle). 85 | 86 | ##### LandscapeDrawable 87 | 88 | 89 | 90 | An animated Drawable depicting a landscape with customizable items: trees, clouds, stars, a sun, and fog. 91 | 92 | Topics covered: drawing on Canvas, custom drawables. 93 | 94 | See: [guide](https://github.com/ZieIony/GuideToCustomViews/wiki/LandscapeDrawable), [code](https://github.com/ZieIony/GuideToCustomViews/tree/master/landscapedrawable). 95 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | apply plugin: 'kotlin-kapt' 5 | 6 | android { 7 | compileSdkVersion 29 8 | buildToolsVersion "29.0.2" 9 | 10 | dataBinding { 11 | enabled = true 12 | } 13 | defaultConfig { 14 | applicationId "com.github.zieiony.guide" 15 | minSdkVersion 16 16 | targetSdkVersion 29 17 | versionCode 1 18 | versionName "1.0" 19 | } 20 | compileOptions { 21 | sourceCompatibility JavaVersion.VERSION_1_8 22 | targetCompatibility JavaVersion.VERSION_1_8 23 | } 24 | } 25 | 26 | dependencies { 27 | implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 28 | implementation 'androidx.appcompat:appcompat:1.1.0' 29 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 30 | implementation 'androidx.recyclerview:recyclerview:1.1.0' 31 | implementation 'com.google.android.material:material:1.1.0-beta02' 32 | 33 | implementation 'com.github.ZieIony:randomdata:4e90951628' 34 | implementation 'com.github.ZieIony:carbon:e2aadf6002' 35 | 36 | implementation project(path: ':progresstextview') 37 | implementation project(path: ':chartview') 38 | implementation project(path: ':flowlayout') 39 | implementation project(path: ':invalidedittext') 40 | implementation project(path: ':moodtoggle') 41 | implementation project(path: ':landscapedrawable') 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/zieiony/guide/ActivityAnnotation.java: -------------------------------------------------------------------------------- 1 | package com.github.zieiony.guide; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface ActivityAnnotation { 8 | String title(); 9 | 10 | int layout(); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/zieiony/guide/ChartViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.github.zieiony.guide; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.os.Bundle; 5 | 6 | import androidx.annotation.Nullable; 7 | 8 | import com.github.zieiony.guide.chartview.ChartView; 9 | import com.github.zieiony.guide.chartview.ChartView2; 10 | import com.github.zieiony.guide.chartview.ChartView3; 11 | 12 | import tk.zielony.randomdata.RandomData; 13 | import tk.zielony.randomdata.common.FloatGenerator; 14 | import tk.zielony.randomdata.food.StringFruitGenerator; 15 | 16 | @ActivityAnnotation(layout = R.layout.activity_chartview, title = "ChartView") 17 | public class ChartViewActivity extends SampleActivity { 18 | 19 | @SuppressLint("ClickableViewAccessibility") 20 | @Override 21 | protected void onCreate(@Nullable Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | 24 | RandomData randomData = new RandomData(); 25 | randomData.addGenerator(new StringFruitGenerator()); 26 | randomData.addGenerator(new FloatGenerator(0, 100).withMatcher(field -> field.getName().equals("value"))); 27 | 28 | ChartView.Item[] items = randomData.generateArray(ChartView.Item.class, 10); 29 | final ChartView graphView1 = findViewById(R.id.chartView1); 30 | graphView1.setItems(items); 31 | graphView1.setItemSpacing(4); 32 | 33 | ChartView2.Item[] items2 = randomData.generateArray(ChartView2.Item.class, 10); 34 | final ChartView2 chartView2 = findViewById(R.id.chartView2); 35 | chartView2.setItems(items2); 36 | 37 | ChartView3.Item[] items3 = randomData.generateArray(ChartView3.Item.class, 10); 38 | final ChartView3 chartView3 = findViewById(R.id.chartView3); 39 | chartView3.setItems(items3); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/zieiony/guide/FlowLayoutActivity.java: -------------------------------------------------------------------------------- 1 | package com.github.zieiony.guide; 2 | 3 | @ActivityAnnotation(layout = R.layout.activity_flowlayout, title = "FlowLayout") 4 | public class FlowLayoutActivity extends SampleActivity { 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/zieiony/guide/InvalidEditTextActivity.kt: -------------------------------------------------------------------------------- 1 | package com.github.zieiony.guide 2 | 3 | import android.os.Bundle 4 | import android.text.Editable 5 | import android.text.TextWatcher 6 | import kotlinx.android.synthetic.main.activity_invalidedittext.* 7 | 8 | @ActivityAnnotation(layout = R.layout.activity_invalidedittext, title = "InvalidEditText") 9 | class InvalidEditTextActivity : SampleActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | 13 | invalidEditText.addTextChangedListener(object : TextWatcher { 14 | override fun afterTextChanged(s: Editable) { 15 | invalidEditText.valid = s.length >= 6 16 | } 17 | 18 | override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { 19 | } 20 | 21 | override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/zieiony/guide/LandscapeDrawableActivity.kt: -------------------------------------------------------------------------------- 1 | package com.github.zieiony.guide 2 | 3 | import android.os.Bundle 4 | import com.github.zieiony.guide.landscapedrawable.* 5 | import kotlinx.android.synthetic.main.activity_landscapedrawable.* 6 | 7 | @ActivityAnnotation(layout = R.layout.activity_landscapedrawable, title = "LandscapeDrawable") 8 | class LandscapeDrawableActivity : SampleActivity() { 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | cloud.setImageDrawable( 12 | ItemDrawable( 13 | Cloud(8, color = resources.getColor(R.color.landscape_cloudColor)) 14 | ) 15 | ) 16 | tree.setImageDrawable( 17 | ItemDrawable(Tree(wind = 1f)) 18 | ) 19 | sky.setImageDrawable( 20 | ItemDrawable( 21 | Sky( 22 | 4, 23 | cloudSize = resources.getDimension(R.dimen.landscape_cloudSize), 24 | cloudColor = resources.getColor(R.color.landscape_cloudColor), 25 | puffCount = 8, 26 | wind = resources.getDimension(R.dimen.landscape_windStrength) 27 | ) 28 | ) 29 | ) 30 | stars.setImageDrawable( 31 | ItemDrawable( 32 | Stars( 33 | 40, 34 | resources.getDimension(R.dimen.landscape_starSize), 35 | resources.getColor(R.color.landscape_starColor) 36 | ) 37 | ) 38 | ) 39 | land.setImageDrawable( 40 | ItemDrawable( 41 | Land( 42 | resources.getColor(R.color.landscape_landscapeColor), 43 | resources.getColor(R.color.landscape_fogColor), 44 | resources.getDimension(R.dimen.landscape_landscapeHeight) / 4 45 | ) 46 | ) 47 | ) 48 | landscape.background = LandscapeDrawable( 49 | 40, 50 | resources.getDimension(R.dimen.landscape_starSize), 51 | resources.getColor(R.color.landscape_starColor), 52 | 4, 53 | cloudSize = resources.getDimension(R.dimen.landscape_cloudSize), 54 | cloudColor = resources.getColor(R.color.landscape_cloudColor), 55 | fogColor = resources.getColor(R.color.landscape_fogColor), 56 | landscapeColor = resources.getColor(R.color.landscape_landscapeColor), 57 | skyColor = resources.getColor(R.color.landscape_skyColor), 58 | sunColor = resources.getColor(R.color.landscape_sunColor), 59 | skyHeight = resources.getDimension(R.dimen.landscape_skyHeight), 60 | planesCount = 5, 61 | windStrength = resources.getDimension(R.dimen.landscape_windStrength), 62 | sunSize = resources.getDimension(R.dimen.landscape_sunSize), 63 | landscapeHeight = resources.getDimension(R.dimen.landscape_landscapeHeight), 64 | treeHeight = resources.getDimension(R.dimen.landscape_treeHeight), 65 | maxWind = resources.getDimension(R.dimen.landscape_maxWind) 66 | ) 67 | } 68 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/zieiony/guide/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.github.zieiony.guide 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import androidx.appcompat.app.AppCompatActivity 6 | import androidx.recyclerview.widget.LinearLayoutManager 7 | import carbon.component.DataBindingComponent 8 | import carbon.component.PaddingItem 9 | import carbon.component.PaddingRow 10 | import carbon.recycler.RowArrayAdapter 11 | import carbon.recycler.RowFactory 12 | import kotlinx.android.synthetic.main.activity_main.* 13 | import java.io.Serializable 14 | 15 | class MainActivity : AppCompatActivity() { 16 | override fun onCreate(savedInstanceState: Bundle?) { 17 | super.onCreate(savedInstanceState) 18 | setContentView(R.layout.activity_main) 19 | 20 | val adapter: RowArrayAdapter = RowArrayAdapter(SampleItem::class.java, RowFactory { parent -> 21 | DataBindingComponent(parent, R.layout.row_sample) 22 | }) 23 | adapter.addFactory(PaddingItem::class.java) { PaddingRow(it) } 24 | adapter.setOnItemClickedListener(SampleItem::class.java, { view, item, position -> 25 | val activityClass = (item as SampleItem).activityClass 26 | val intent = Intent(view.context, activityClass) 27 | startActivity(intent) 28 | }) 29 | 30 | recycler.layoutManager = LinearLayoutManager(this) 31 | recycler.adapter = adapter 32 | 33 | adapter.items = arrayOf( 34 | PaddingItem(resources.getDimensionPixelSize(R.dimen.carbon_paddingHalf)), 35 | SampleItem(ProgressTextViewActivity::class.java), 36 | SampleItem(ChartViewActivity::class.java), 37 | SampleItem(FlowLayoutActivity::class.java), 38 | SampleItem(InvalidEditTextActivity::class.java), 39 | SampleItem(MoodToggleActivity::class.java), 40 | SampleItem(LandscapeDrawableActivity::class.java), 41 | PaddingItem(resources.getDimensionPixelSize(R.dimen.carbon_paddingHalf)) 42 | ) 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/zieiony/guide/MoodToggleActivity.kt: -------------------------------------------------------------------------------- 1 | package com.github.zieiony.guide 2 | 3 | @ActivityAnnotation(layout = R.layout.activity_moodtoggle, title = "MoodToggle") 4 | class MoodToggleActivity : SampleActivity() -------------------------------------------------------------------------------- /app/src/main/java/com/github/zieiony/guide/ProgressTextViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.github.zieiony.guide; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.os.Bundle; 5 | 6 | import androidx.annotation.Nullable; 7 | 8 | import com.github.zieiony.guide.progresstextview.ProgressTextView_Bad; 9 | import com.github.zieiony.guide.progresstextview.ProgressTextView_Good; 10 | import com.github.zieiony.guide.progresstextview.ProgressTextView_Medium; 11 | 12 | @ActivityAnnotation(layout = R.layout.activity_progresstextview, title = "ProgressTextView") 13 | public class ProgressTextViewActivity extends SampleActivity { 14 | 15 | @SuppressLint("ClickableViewAccessibility") 16 | @Override 17 | protected void onCreate(@Nullable Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | 20 | final ProgressTextView_Bad progress = findViewById(R.id.prgressTextView_bad); 21 | progress.setOnTouchListener((v, event) -> { 22 | progress.setProgress(event.getX() / v.getWidth()); 23 | return true; 24 | }); 25 | 26 | final ProgressTextView_Medium progress2 = findViewById(R.id.prgressTextView_medium); 27 | progress2.setOnTouchListener((v, event) -> { 28 | progress2.setProgress(event.getX() / v.getWidth()); 29 | return true; 30 | }); 31 | 32 | final ProgressTextView_Good progress3 = findViewById(R.id.prgressTextView_good); 33 | progress3.setOnTouchListener((v, event) -> { 34 | progress3.setProgress(event.getX() / v.getWidth()); 35 | return true; 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/zieiony/guide/SampleActivity.kt: -------------------------------------------------------------------------------- 1 | package com.github.zieiony.guide 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import carbon.widget.Toolbar 6 | 7 | abstract class SampleActivity : AppCompatActivity() { 8 | override fun onCreate(savedInstanceState: Bundle?) { 9 | super.onCreate(savedInstanceState) 10 | 11 | javaClass.getAnnotation(ActivityAnnotation::class.java)?.let { 12 | setContentView(it.layout) 13 | findViewById(R.id.toolbar)?.title = it.title 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/zieiony/guide/SampleItem.kt: -------------------------------------------------------------------------------- 1 | package com.github.zieiony.guide 2 | 3 | import android.app.Activity 4 | import java.io.Serializable 5 | 6 | open class SampleItem : Serializable { 7 | var activityClass: Class? = null 8 | private set 9 | var name: String? = null 10 | private set 11 | var icon = 0 12 | private set 13 | 14 | @JvmOverloads 15 | constructor(activityClass: Class, icon: Int = 0) : super( 16 | ) { 17 | this.activityClass = activityClass 18 | this.name = activityClass.getAnnotation(ActivityAnnotation::class.java)?.title 19 | this.icon = icon 20 | } 21 | } -------------------------------------------------------------------------------- /app/src/main/res/color/color_accent_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/color/graph_itemcolor.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/color/text_color_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_chartview.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 20 | 21 | 29 | 30 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_flowlayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 20 | 21 |