diff --git a/build.gradle b/build.gradle index 9dc9efe..121e30b 100644 --- a/build.gradle +++ b/build.gradle @@ -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' @@ -19,7 +19,7 @@ buildscript { allprojects { repositories { google() - jcenter() + mavenCentral() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a1e6491..3292fa5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -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 diff --git a/library/build.gradle b/library/build.gradle index b88a3a2..cad96b2 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -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 } @@ -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' } diff --git a/library/src/main/java/com/erkutaras/statelayout/StateLayout.kt b/library/src/main/java/com/erkutaras/statelayout/StateLayout.kt index bff720e..e3fc338 100644 --- a/library/src/main/java/com/erkutaras/statelayout/StateLayout.kt +++ b/library/src/main/java/com/erkutaras/statelayout/StateLayout.kt @@ -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 @@ -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) } @@ -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) @@ -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) } } @@ -321,6 +344,7 @@ class StateLayout: FrameLayout { } companion object { + @JvmStatic fun provideLoadingStateInfo() = StateInfo(state = LOADING) @@ -344,6 +368,7 @@ class StateLayout: FrameLayout { } interface OnStateLayoutListener { + fun onStateLayoutInfoButtonClick() } @@ -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 diff --git a/sample/build.gradle b/sample/build.gradle index 358b60e..c6faad7 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -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" @@ -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' } diff --git a/sample/src/main/java/com/erkutaras/statelayout/sample/AnimationLoadingSampleActivity.kt b/sample/src/main/java/com/erkutaras/statelayout/sample/AnimationLoadingSampleActivity.kt index d5ecbc2..2ad8a0b 100644 --- a/sample/src/main/java/com/erkutaras/statelayout/sample/AnimationLoadingSampleActivity.kt +++ b/sample/src/main/java/com/erkutaras/statelayout/sample/AnimationLoadingSampleActivity.kt @@ -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. @@ -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 @@ -66,6 +73,5 @@ class AnimationLoadingSampleActivity : SampleBaseActivity(), StateLayout.OnState onStateLayoutListener.onStateLayoutInfoButtonClick() } } - } -} \ No newline at end of file +} diff --git a/sample/src/main/java/com/erkutaras/statelayout/sample/CustomSampleActivity.kt b/sample/src/main/java/com/erkutaras/statelayout/sample/CustomSampleActivity.kt index 17f7bbf..acdae92 100644 --- a/sample/src/main/java/com/erkutaras/statelayout/sample/CustomSampleActivity.kt +++ b/sample/src/main/java/com/erkutaras/statelayout/sample/CustomSampleActivity.kt @@ -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. @@ -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?) { @@ -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() } } @@ -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() + } } -} \ No newline at end of file +} diff --git a/sample/src/main/java/com/erkutaras/statelayout/sample/StateLayoutSampleActivity.kt b/sample/src/main/java/com/erkutaras/statelayout/sample/StateLayoutSampleActivity.kt index e883022..e2a6397 100644 --- a/sample/src/main/java/com/erkutaras/statelayout/sample/StateLayoutSampleActivity.kt +++ b/sample/src/main/java/com/erkutaras/statelayout/sample/StateLayoutSampleActivity.kt @@ -8,35 +8,42 @@ 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.ActivityStateLayoutSampleBinding private const val WEB_URL = "http://www.erkutaras.com/" class StateLayoutSampleActivity : SampleBaseActivity(), StateLayout.OnStateLayoutListener { + private lateinit var binding: ActivityStateLayoutSampleBinding + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_state_layout_sample) + binding = ActivityStateLayoutSampleBinding.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_sample 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 @@ -63,6 +70,6 @@ class StateLayoutSampleActivity : SampleBaseActivity(), StateLayout.OnStateLayou onStateLayoutListener.onStateLayoutInfoButtonClick() } } - } } +