├── .circleci └── config.yml ├── .gitignore ├── .idea ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── gradle.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── github │ │ └── imanx │ │ └── sample │ │ └── MainActivity.kt │ └── res │ ├── drawable-hdpi │ ├── ic_info_black_48dp.png │ └── ic_signal_wifi_off_black_48dp.png │ ├── drawable-mdpi │ ├── ic_info_black_48dp.png │ └── ic_signal_wifi_off_black_48dp.png │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable-xhdpi │ ├── ic_info_black_48dp.png │ └── ic_signal_wifi_off_black_48dp.png │ ├── drawable-xxhdpi │ ├── ic_info_black_48dp.png │ └── ic_signal_wifi_off_black_48dp.png │ ├── drawable-xxxhdpi │ ├── ic_info_black_48dp.png │ └── ic_signal_wifi_off_black_48dp.png │ ├── drawable │ └── ic_launcher_background.xml │ ├── layout │ ├── activity_main.xml │ ├── empty.xml │ ├── failure.xml │ ├── item.xml │ └── loading.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 │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── s_empty.jpg ├── s_failure.jpg ├── s_load.jpg ├── s_normal.jpg ├── settings.gradle └── statelayout ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src └── main ├── AndroidManifest.xml ├── java └── com │ └── github │ └── imanx │ ├── Animation.java │ ├── OnChangeStateViewListener.java │ ├── State.java │ └── StateLayout.java └── res └── values ├── attrs.xml └── strings.xml /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Android CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-android/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | working_directory: ~/app 9 | docker: 10 | - image: circleci/android:api-28-alpha 11 | environment: 12 | JVM_OPTS: -Xmx3200m 13 | branches: 14 | only: 15 | - release # list of branches to build 16 | steps: 17 | - checkout 18 | - restore_cache: 19 | key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} 20 | # - run: 21 | # name: Chmod permissions #if permission for Gradlew Dependencies fail, use this. 22 | # command: sudo chmod +x ./gradlew 23 | - run: 24 | name: Download Dependencies 25 | command: ./gradlew androidDependencies 26 | - save_cache: 27 | paths: 28 | - ~/.gradle 29 | key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} 30 | - run: 31 | name: Run Presentation Module Unit Tests 32 | command: ./gradlew :app:testDebugUnitTest 33 | - store_artifacts: 34 | path: app/build/reports 35 | - store_test_results: 36 | path: app/build/test-results 37 | - run: 38 | name: Run Domain Module Unit Tests 39 | command: ./gradlew :app:test 40 | - store_artifacts: 41 | path: app/build/reports 42 | - store_test_results: 43 | path: app/build/test-results 44 | - run: 45 | name: Run Data Module Unit Tests 46 | command: ./gradlew :app:testDebugUnitTest 47 | - store_artifacts: 48 | path: app/build/reports 49 | - store_test_results: 50 | path: app/build/test-results 51 | - run: 52 | name: Run Lint Test 53 | command: ./gradlew lint 54 | - store_artifacts: 55 | path: app/build/reports 56 | - run: 57 | name: Release... 58 | command: ./gradlew clean assembleRelease --no-daemon --stacktrace 59 | - store_artifacts: 60 | path: app/build/outputs/apk/ 61 | destination: apks/ 62 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches/build_file_checksums.ser 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | .DS_Store 9 | /build 10 | /captures 11 | .externalNativeBuild 12 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 18 | 19 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 35 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # StateLayout 2 | A ViewGroup for Simple Handle Diff State on Android 3 | This help you show and change View bassed your app state 4 | 5 | 6 | `StateLayout` has four state for handle: 7 | 8 | * Failure : when failure happen 9 | * Empty: when empty happen 10 | * Loading : when loading happen 11 | * Normal : when you will show content. 12 | 13 | 14 | # Shots of diff state 15 | 16 | ![screenshot](https://github.com/ImanX/StateLayout/blob/master/s_load.jpg?raw=true) 17 | ![screenshot](https://github.com/ImanX/StateLayout/blob/master/s_empty.jpg?raw=true) 18 | ![screenshot](https://github.com/ImanX/StateLayout/blob/master/s_failure.jpg?raw=true) 19 | ![screenshot](https://github.com/ImanX/StateLayout/blob/master/s_normal.jpg?raw=true) 20 | 21 | 22 | # Getting start 23 | You can import this library by `Gradle` 24 | ``` 25 | implementation 'com.github.imanx:statelayout:0.0.6' 26 | ``` 27 | 28 | # Usage 29 | 30 | You should create your desire layouts for `empty`, `failure`, `loading` statuses and put them all in to `StateLayout` xml file. 31 | 32 | ```xml 33 | 34 | 48 | 49 | 50 | 54 | 55 | 57 | 58 | 59 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | ``` 73 | 74 | ## State enums: 75 | - Loading 76 | - Failure 77 | - Empty 78 | - Normal 79 | 80 | return state view 81 | ```Kotlin 82 | getStateView(State state) 83 | ``` 84 | 85 | change state view 86 | ```Kotlin 87 | setState(State state) 88 | ``` 89 | 90 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | android { 8 | compileSdkVersion 28 9 | defaultConfig { 10 | applicationId "com.github.imanx.sample" 11 | minSdkVersion 16 12 | targetSdkVersion 28 13 | versionCode 1 14 | versionName "1.0" 15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | 24 | android { 25 | lintOptions { 26 | abortOnError false 27 | } 28 | } 29 | } 30 | 31 | dependencies { 32 | implementation fileTree(dir: 'libs', include: ['*.jar']) 33 | implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 34 | implementation 'com.android.support:appcompat-v7:28.0.0' 35 | implementation 'com.squareup.picasso:picasso:2.71828' 36 | 37 | implementation project(':statelayout') 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/imanx/sample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.github.imanx.sample 2 | 3 | import android.content.Context 4 | import android.support.v7.app.AppCompatActivity 5 | import android.os.Bundle 6 | import android.util.Log 7 | import android.view.View 8 | import android.view.ViewGroup 9 | import android.widget.ArrayAdapter 10 | import android.widget.Button 11 | import android.widget.TextView 12 | import com.github.imanx.State 13 | import kotlinx.android.synthetic.main.activity_main.* 14 | import java.util.* 15 | import kotlin.collections.ArrayList 16 | 17 | class MainActivity : AppCompatActivity() { 18 | 19 | override fun onCreate(savedInstanceState: Bundle?) { 20 | super.onCreate(savedInstanceState) 21 | setContentView(R.layout.activity_main) 22 | 23 | 24 | 25 | 26 | 27 | doWork(); 28 | 29 | val view = state_view.getStateView(State.Empty) 30 | view.findViewById(R.id.txt_view).text = "No Content for display :( " 31 | 32 | 33 | val failureView = state_view.getStateView(State.Failure); 34 | failureView.findViewById