Skip to content
This repository was archived by the owner on Aug 7, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.3.41'
ext.kotlin_version = '1.5.10'
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.2'
classpath 'com.android.tools.build:gradle:4.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'

Expand All @@ -19,7 +19,7 @@ buildscript {
allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}

Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
14 changes: 6 additions & 8 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ apply plugin: 'com.github.dcendents.android-maven'
group='com.erkutaras.statelayout'

android {
compileSdkVersion 28
compileSdkVersion 30

defaultConfig {
minSdkVersion 14
targetSdkVersion 28
versionCode 26
versionName "1.4.4"
targetSdkVersion 30
versionCode 27
versionName "1.4.5"

vectorDrawables.useSupportLibrary = true
}
Expand All @@ -23,13 +23,11 @@ android {
}
}

buildFeatures.buildConfig = false
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
}
repositories {
mavenCentral()
implementation 'androidx.appcompat:appcompat:1.3.0'
}
43 changes: 34 additions & 9 deletions library/src/main/java/com/erkutaras/statelayout/StateLayout.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,33 @@ import android.widget.TextView
import androidx.annotation.LayoutRes
import androidx.annotation.RequiresApi
import androidx.annotation.StyleRes
import com.erkutaras.statelayout.StateLayout.State.*
import com.erkutaras.statelayout.StateLayout.State.CONTENT
import com.erkutaras.statelayout.StateLayout.State.EMPTY
import com.erkutaras.statelayout.StateLayout.State.ERROR
import com.erkutaras.statelayout.StateLayout.State.INFO
import com.erkutaras.statelayout.StateLayout.State.LOADING
import com.erkutaras.statelayout.StateLayout.State.LOADING_WITH_CONTENT
import com.erkutaras.statelayout.StateLayout.State.NONE

/**
* Created by erkutaras on 9.09.2018.
*/
class StateLayout: FrameLayout {
class StateLayout : FrameLayout {

private var contentLayout: View? = null
private var loadingLayout: View? = null
private var infoLayout: View? = null
private var loadingWithContentLayout: View? = null

private var state: State = NONE
var state: State = NONE
private set

@LayoutRes
private var loadingLayoutRes: Int = R.layout.layout_state_loading

@LayoutRes
private var infoLayoutRes: Int = R.layout.layout_state_info

@LayoutRes
private var loadingWithContentLayoutRes: Int = R.layout.layout_state_loading_with_content

Expand All @@ -48,7 +57,8 @@ class StateLayout: FrameLayout {
}

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int)
: super(context, attrs, defStyleAttr, defStyleRes) {
obtainCustomAttributes(attrs, defStyleAttr, defStyleRes)
}

Expand All @@ -58,7 +68,10 @@ class StateLayout: FrameLayout {
state = State.values()[getInteger(R.styleable.StateLayout_sl_state, NONE.ordinal)]
loadingLayoutRes = getResourceId(R.styleable.StateLayout_sl_loadingLayout, R.layout.layout_state_loading)
infoLayoutRes = getResourceId(R.styleable.StateLayout_sl_infoLayout, R.layout.layout_state_info)
loadingWithContentLayoutRes = getResourceId(R.styleable.StateLayout_sl_loadingWithContentLayout, R.layout.layout_state_loading_with_content)
loadingWithContentLayoutRes = getResourceId(
R.styleable.StateLayout_sl_loadingWithContentLayout,
R.layout.layout_state_loading_with_content
)

getResourceId(R.styleable.StateLayout_sl_loadingAnimation, 0).notZero {
loadingAnimation = AnimationUtils.loadAnimation(context, it)
Expand Down Expand Up @@ -135,13 +148,23 @@ class StateLayout: FrameLayout {

private fun updateLoadingVisibility(visibility: Int) =
when (visibility) {
View.VISIBLE -> loadingLayout.visible { it.startViewAnimation(R.id.customView_state_layout_loading, loadingAnimation) }
View.VISIBLE -> loadingLayout.visible {
it.startViewAnimation(
R.id.customView_state_layout_loading,
loadingAnimation
)
}
else -> loadingLayout.gone { it.clearViewAnimation(R.id.customView_state_layout_loading) }
}

private fun updateLoadingWithContentVisibility(visibility: Int) =
when (visibility) {
View.VISIBLE -> loadingWithContentLayout.visible { it.startViewAnimation(R.id.customView_state_layout_with_content, loadingWithContentAnimation) }
View.VISIBLE -> loadingWithContentLayout.visible {
it.startViewAnimation(
R.id.customView_state_layout_with_content,
loadingWithContentAnimation
)
}
else -> loadingWithContentLayout.gone { it.clearViewAnimation(R.id.customView_state_layout_with_content) }
}

Expand Down Expand Up @@ -321,6 +344,7 @@ class StateLayout: FrameLayout {
}

companion object {

@JvmStatic
fun provideLoadingStateInfo() = StateInfo(state = LOADING)

Expand All @@ -344,6 +368,7 @@ class StateLayout: FrameLayout {
}

interface OnStateLayoutListener {

fun onStateLayoutInfoButtonClick()
}

Expand All @@ -356,9 +381,9 @@ class StateLayout: FrameLayout {
val infoTitle: String? = null,
val infoMessage: String? = null,
val infoButtonText: String? = null,
val state: StateLayout.State = INFO,
val state: State = INFO,
@Deprecated("onInfoButtonClick is more convenient")
val onStateLayoutListener: StateLayout.OnStateLayoutListener? = null,
val onStateLayoutListener: OnStateLayoutListener? = null,
val onInfoButtonClick: (() -> Unit)? = null,
val loadingAnimation: Animation? = null,
val loadingWithContentAnimation: Animation? = null
Expand Down
16 changes: 8 additions & 8 deletions sample/build.gradle
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 28
compileSdkVersion 30
defaultConfig {
applicationId "com.erkutaras.statelayout.sample"
minSdkVersion 14
targetSdkVersion 28
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand All @@ -19,15 +18,16 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

buildFeatures.viewBinding = true
}

dependencies {
implementation project(':library')
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.1.0-alpha06'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0-rc01'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Toast
import com.erkutaras.statelayout.StateLayout
import kotlinx.android.synthetic.main.activity_state_layout_sample.*
import com.erkutaras.statelayout.sample.databinding.ActivityAnimationLoadingSampleBinding

/**
* Created by erkutaras on 2.02.2019.
Expand All @@ -17,29 +17,36 @@ private const val WEB_URL = "https://github.com/erkutaras"

class AnimationLoadingSampleActivity : SampleBaseActivity(), StateLayout.OnStateLayoutListener {

private lateinit var binding: ActivityAnimationLoadingSampleBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_animation_loading_sample)
binding = ActivityAnimationLoadingSampleBinding.inflate(layoutInflater)
setContentView(binding.root)

webView.webViewClient = SampleWebViewClient(stateLayout, this)
webView.loadUrl(WEB_URL)
binding.webView.webViewClient = SampleWebViewClient(binding.stateLayout, this)
binding.webView.loadUrl(WEB_URL)
}

override fun getMenuResId(): Int = R.menu.menu_animation_loading

override fun onStateLayoutInfoButtonClick() {
webView.loadUrl(WEB_URL)
binding.webView.loadUrl(WEB_URL)
Toast.makeText(this, "Refreshing Page...", Toast.LENGTH_SHORT).show()
}

override fun onBackPressed() {
if (webView.canGoBack()) webView.goBack()
else super.onBackPressed()
if (binding.webView.canGoBack()) {
binding.webView.goBack()
} else {
super.onBackPressed()
}
}

private class SampleWebViewClient(val stateLayout: StateLayout,
val onStateLayoutListener: StateLayout.OnStateLayoutListener)
: WebViewClient() {
private class SampleWebViewClient(
val stateLayout: StateLayout,
val onStateLayoutListener: StateLayout.OnStateLayoutListener
) : WebViewClient() {

var hasError: Boolean = false

Expand All @@ -66,6 +73,5 @@ class AnimationLoadingSampleActivity : SampleBaseActivity(), StateLayout.OnState
onStateLayoutListener.onStateLayoutInfoButtonClick()
}
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ package com.erkutaras.statelayout.sample

import android.graphics.Bitmap
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.webkit.*
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.erkutaras.statelayout.StateLayout
import kotlinx.android.synthetic.main.activity_custom_sample.*
import kotlinx.android.synthetic.main.layout_custom_info.*
import kotlinx.android.synthetic.main.layout_custom_loading.*
import android.webkit.WebChromeClient
import android.webkit.WebResourceError
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Button
import android.widget.ProgressBar
import android.widget.TextView
import com.erkutaras.statelayout.sample.databinding.ActivityCustomSampleBinding

/**
* Created by erkutaras on 21.12.2018.
Expand All @@ -19,19 +19,26 @@ private const val WEB_URL = "https://medium.com/@erkutaras"

class CustomSampleActivity : SampleBaseActivity() {

private lateinit var binding: ActivityCustomSampleBinding
private var hasError: Boolean = false
private val contentLoadingProgressBar: ProgressBar
by lazy { binding.root.findViewById(R.id.contentLoadingProgressBar) }
private val textviewProgress: TextView by lazy { binding.root.findViewById(R.id.textView_progress) }
private val buttonRefresh: Button by lazy { binding.root.findViewById(R.id.button_refresh) }
private val buttonClose: Button by lazy { binding.root.findViewById(R.id.button_close) }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_custom_sample)
binding = ActivityCustomSampleBinding.inflate(layoutInflater)
setContentView(binding.root)

webView.webViewClient = object : WebViewClient() {
binding.webView.webViewClient = object : WebViewClient() {

override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
hasError = false
if (url.equals(WEB_URL)) stateLayout.loading()
else stateLayout.loadingWithContent()
if (url.equals(WEB_URL)) binding.stateLayout.loading()
else binding.stateLayout.loadingWithContent()
}

override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
Expand All @@ -40,13 +47,13 @@ class CustomSampleActivity : SampleBaseActivity() {
showInfoState()
}
}
webView.webChromeClient = object : WebChromeClient() {
binding.webView.webChromeClient = object : WebChromeClient() {
override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress)
contentLoadingProgressBar.progress = newProgress
textView_progress.text = "$newProgress%"
textviewProgress.text = "$newProgress%"

if (!hasError && newProgress == 100) stateLayout.content()
if (!hasError && newProgress == 100) binding.stateLayout.content()
if (hasError && newProgress == 100) showInfoState()
}
}
Expand All @@ -56,17 +63,20 @@ class CustomSampleActivity : SampleBaseActivity() {
override fun getMenuResId(): Int = R.menu.menu_custom

private fun showInfoState() {
stateLayout.info()
button_refresh.setOnClickListener { loadUrl() }
button_close.setOnClickListener { finish() }
binding.stateLayout.info()
buttonRefresh.setOnClickListener { loadUrl() }
buttonClose.setOnClickListener { finish() }
}

private fun loadUrl() {
webView.loadUrl(WEB_URL)
binding.webView.loadUrl(WEB_URL)
}

override fun onBackPressed() {
if (webView.canGoBack()) webView.goBack()
else super.onBackPressed()
if (binding.webView.canGoBack()) {
binding.webView.goBack()
} else {
super.onBackPressed()
}
}
}
}
Loading