diff --git a/buildSrc/components.json b/buildSrc/components.json index dd37cd970..b4a04ac9e 100755 --- a/buildSrc/components.json +++ b/buildSrc/components.json @@ -2105,5 +2105,34 @@ "samples": [], "has_mirror": false, "mirror_repo": "" + }, + { + "id": "common-tools", + "version": "0.5.0", + "unstable_version": 0, + "stable": false, + "dir": "common-tools", + "libs": [ + { + "name": "status-bar-switcher", + "dir": "lib-status-bar-switcher", + "artifact_name": "status-bar-switcher", + "third_party_dependencies": [ + { + "name": "androidx.palette:palette-ktx", + "type": "implementation" + } + ], + "android_standard_dependencies": [] + } + ], + "samples": [ + { + "name": "common-tools-sample", + "dir": "sample" + } + ], + "has_mirror": false, + "mirror_repo": "" } ] \ No newline at end of file diff --git a/buildSrc/config.gradle b/buildSrc/config.gradle index ecc1a60d8..0b85cc53a 100755 --- a/buildSrc/config.gradle +++ b/buildSrc/config.gradle @@ -43,6 +43,7 @@ ext { "androidx.core:core" : "1.2.0", //https://bit.ly/2yYY82h "androidx.core:core-ktx" : "1.2.0", //http://bit.ly/2qY7ffW "androidx.constraintlayout:constraintlayout" : "2.0.0-beta4", //http://bit.ly/2S1WoNg + "androidx.palette:palette-ktx" : "1.0.0", //https://bit.ly/30afhnJ "androidx.appcompat:appcompat" : "1.1.0", //http://bit.ly/2zjueqh "androidx.lifecycle:lifecycle-runtime-ktx" : "2.2.0", //https://bit.ly/3anEaR2 "androidx.multidex:multidex" : "2.0.1", //http://bit.ly/2r6uX9G diff --git a/common-tools/README.md b/common-tools/README.md new file mode 100755 index 000000000..cbe995bde --- /dev/null +++ b/common-tools/README.md @@ -0,0 +1,6 @@ +# Common tools + +## Модули + +- [Status bar switcher](lib-status-bar-switcher) +- [Пример](sample) \ No newline at end of file diff --git a/common-tools/RELEASE_NOTES.md b/common-tools/RELEASE_NOTES.md new file mode 100644 index 000000000..519b7b019 --- /dev/null +++ b/common-tools/RELEASE_NOTES.md @@ -0,0 +1,7 @@ +# Common tools Release Notes + +- [0.5.0-alpha](#050-alpha) + +## 0.5.0-alpha +##### Common tools +* TODO \ No newline at end of file diff --git a/common-tools/lib-status-bar-switcher/.gitignore b/common-tools/lib-status-bar-switcher/.gitignore new file mode 100755 index 000000000..796b96d1c --- /dev/null +++ b/common-tools/lib-status-bar-switcher/.gitignore @@ -0,0 +1 @@ +/build diff --git a/common-tools/lib-status-bar-switcher/README.md b/common-tools/lib-status-bar-switcher/README.md new file mode 100644 index 000000000..acc498183 --- /dev/null +++ b/common-tools/lib-status-bar-switcher/README.md @@ -0,0 +1,23 @@ +# Status bar switcher + +Сущность для автоматического переключения цвета статус-бара в зависимости от цвета контента, находящегося под ним. + +# Использование +[Пример использования для определенного экрана](../sample) + +Для того, чтобы цвет статус-бара переключался автоматически для каждого экрана, нужно воспользоваться ActivityLifecycleCallbacks: + +```kotlin +object : Application.ActivityLifecycleCallbacks() { + + //... + + override fun onActivityResumed(activity: Activity) { + statusBarSwitcher.attach(activity) + } + + override fun onActivityStopped(activity: Activity) { + statusBarSwitcher.detach() + } +} +``` \ No newline at end of file diff --git a/common-tools/lib-status-bar-switcher/build.gradle b/common-tools/lib-status-bar-switcher/build.gradle new file mode 100644 index 000000000..aec5f43ed --- /dev/null +++ b/common-tools/lib-status-bar-switcher/build.gradle @@ -0,0 +1 @@ +apply from: "$rootDir/buildSrc/baseBuild.gradle" \ No newline at end of file diff --git a/common-tools/lib-status-bar-switcher/src/main/AndroidManifest.xml b/common-tools/lib-status-bar-switcher/src/main/AndroidManifest.xml new file mode 100644 index 000000000..64426bba8 --- /dev/null +++ b/common-tools/lib-status-bar-switcher/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/common-tools/lib-status-bar-switcher/src/main/java/ru/surfstudio/android/common/tools/statusbarswitcher/StatusBarSwitcher.kt b/common-tools/lib-status-bar-switcher/src/main/java/ru/surfstudio/android/common/tools/statusbarswitcher/StatusBarSwitcher.kt new file mode 100644 index 000000000..1a7a20576 --- /dev/null +++ b/common-tools/lib-status-bar-switcher/src/main/java/ru/surfstudio/android/common/tools/statusbarswitcher/StatusBarSwitcher.kt @@ -0,0 +1,160 @@ +/* + Copyright (c) 2020-present, SurfStudio LLC. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +package ru.surfstudio.android.common.tools.statusbarswitcher + +import android.app.Activity +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Rect +import android.os.AsyncTask +import android.os.Build +import android.util.DisplayMetrics +import android.view.View +import android.view.ViewTreeObserver +import androidx.annotation.ColorInt +import androidx.core.view.OnApplyWindowInsetsListener +import androidx.core.view.ViewCompat +import androidx.palette.graphics.Palette +import kotlin.math.sqrt + +/** + * Helper class for switching status bar color automatically. + * + * Status bar color calculation based on the underlying content brightness. + */ +class StatusBarSwitcher(private val displayMetrics: DisplayMetrics) { + + private val colorFilter = Palette.Filter { _, _ -> true } + + private val width: Int + get() = displayMetrics.widthPixels + + private var attachedActivity: Activity? = null + + private val decorView: View? + get() = attachedActivity?.window?.decorView + + private var statusBarHeight: Int = 0 + + private val statusBarHeightListener = OnApplyWindowInsetsListener { _, insets -> + statusBarHeight = insets.stableInsetTop + insets + } + + private var hasStatusBarListenerAttached: Boolean = false + + private val onPreDrawListener = ViewTreeObserver.OnPreDrawListener { + if (statusBarHeight != 0) { + val bitmap = Bitmap.createBitmap(width, statusBarHeight, Bitmap.Config.RGB_565) + val canvas = Canvas(bitmap) + val statusBarRect = Rect(0, 0, width, statusBarHeight) + canvas.clipRect(statusBarRect) + decorView?.draw(canvas) + + Palette.from(bitmap) + .clearFilters() + .addFilter(colorFilter) + .tryGenerate { palette -> + val dominantColor = palette.getDominantColor(Color.WHITE) + val isLightStatusBar = isBrightColor(dominantColor) + attachedActivity?.let { setLightStatusBar(it, isLightStatusBar) } + } + } + true + } + + /** + * Sets status bar height manually. + */ + fun setStatusBarHeight(statusBarHeight: Int) { + this.statusBarHeight = statusBarHeight + } + + /** + * Attaches [StatusBarSwitcher] to the [activity]. + * + * @param shouldDetectStatusBarHeight defines whether status bar height should be calculated + * automatically. + */ + fun attach( + activity: Activity, + shouldDetectStatusBarHeight: Boolean = true + ) { + val decorView = activity.window.decorView + decorView.viewTreeObserver.addOnPreDrawListener(onPreDrawListener) + if (shouldDetectStatusBarHeight) { + ViewCompat.setOnApplyWindowInsetsListener(decorView, statusBarHeightListener) + hasStatusBarListenerAttached = true + } + attachedActivity = activity + } + + /** + * Detaches [StatusBarSwitcher] from the latest activity. + */ + fun detach() { + val activity = attachedActivity ?: return + attachedActivity = null + + val decorView = activity.window.decorView ?: return + if (hasStatusBarListenerAttached) { + ViewCompat.setOnApplyWindowInsetsListener(decorView, null) + hasStatusBarListenerAttached = false + } + decorView.viewTreeObserver.removeOnPreDrawListener(onPreDrawListener) + } + + /** + * Defines brightness of color. + * + * @return true, if color is bright; false otherwise. + */ + private fun isBrightColor(@ColorInt color: Int): Boolean { + val rgb = intArrayOf(Color.red(color), Color.green(color), Color.blue(color)) + val brightness = sqrt( + rgb[0] * rgb[0] * .241 + + rgb[1] * rgb[1] * .691 + + rgb[2] * rgb[2] * .068 + ) + return brightness >= 200 + } + + private fun Palette.Builder.tryGenerate(onGeneratedAction: (Palette) -> Unit): AsyncTask { + return this.generate { palette: Palette? -> + palette ?: return@generate + onGeneratedAction(palette) + } + } + + companion object { + + /** + * Toggles status bar color for the defined [activity]. + */ + fun setLightStatusBar(activity: Activity, isLightStatusBar: Boolean) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + val window = activity.window + val decorView = window?.decorView ?: return + val systemUiVisibilityFlags = decorView.systemUiVisibility + decorView.systemUiVisibility = when { + isLightStatusBar -> systemUiVisibilityFlags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR + else -> systemUiVisibilityFlags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv() + } + } + } + } +} \ No newline at end of file diff --git a/common-tools/sample/.gitignore b/common-tools/sample/.gitignore new file mode 100755 index 000000000..796b96d1c --- /dev/null +++ b/common-tools/sample/.gitignore @@ -0,0 +1 @@ +/build diff --git a/common-tools/sample/build.gradle b/common-tools/sample/build.gradle new file mode 100755 index 000000000..5cb584729 --- /dev/null +++ b/common-tools/sample/build.gradle @@ -0,0 +1,18 @@ +import ru.surfstudio.android.build.DependencyConfigurator + +apply from: "$rootDir/buildSrc/androidSample.gradle" + +android { + defaultConfig { + applicationId "ru.surfstudio.android.common.tools.sample" + } +} + +dependencies { + DependencyConfigurator.projectImplementation(project, "status-bar-switcher") + DependencyConfigurator.projectImplementation(project, "sample-common") + DependencyConfigurator.projectImplementation(project, "imageloader") + DependencyConfigurator.projectImplementation(project, "easyadapter") + + DependencyConfigurator.kapt(project, "com.google.dagger:dagger-compiler") +} \ No newline at end of file diff --git a/common-tools/sample/src/main/AndroidManifest.xml b/common-tools/sample/src/main/AndroidManifest.xml new file mode 100755 index 000000000..af6a8b4af --- /dev/null +++ b/common-tools/sample/src/main/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/main/MainActivity.kt b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/main/MainActivity.kt new file mode 100644 index 000000000..6665e9abf --- /dev/null +++ b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/main/MainActivity.kt @@ -0,0 +1,24 @@ +package ru.surfstudio.android.common.tools.sample.screen.main + +import android.content.Intent +import android.os.Bundle +import android.widget.Button +import androidx.appcompat.app.AppCompatActivity +import kotlinx.android.synthetic.main.activity_main.* +import ru.surfstudio.android.common.tools.sample.R +import ru.surfstudio.android.common.tools.sample.screen.status_bar_switcher.StatusBarSwitcherActivityView + +class MainActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + setOnClickListener(open_status_bar_switcher_btn, StatusBarSwitcherActivityView::class.java) + } + + private fun setOnClickListener(btn: Button, activityClass: Class<*>) { + btn.setOnClickListener { + startActivity(Intent(this, activityClass)) + } + } +} diff --git a/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherActivityRoute.kt b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherActivityRoute.kt new file mode 100644 index 000000000..d62dd98b4 --- /dev/null +++ b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherActivityRoute.kt @@ -0,0 +1,11 @@ +package ru.surfstudio.android.common.tools.sample.screen.status_bar_switcher + +import android.content.Context +import android.content.Intent +import ru.surfstudio.android.core.ui.navigation.activity.route.ActivityRoute + +class StatusBarSwitcherActivityRoute : ActivityRoute() { + + override fun prepareIntent(context: Context) = + Intent(context, StatusBarSwitcherActivityView::class.java) +} \ No newline at end of file diff --git a/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherActivityView.kt b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherActivityView.kt new file mode 100644 index 000000000..13da325cd --- /dev/null +++ b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherActivityView.kt @@ -0,0 +1,79 @@ +package ru.surfstudio.android.common.tools.sample.screen.status_bar_switcher + +import android.os.Bundle +import android.os.PersistableBundle +import android.view.View +import androidx.core.view.ViewCompat +import androidx.core.view.marginTop +import kotlinx.android.synthetic.main.activity_status_bar_switcher.* +import ru.surfstudio.android.common.tools.sample.R +import ru.surfstudio.android.common.tools.sample.screen.status_bar_switcher.controller.ImageItemController +import ru.surfstudio.android.common.tools.statusbarswitcher.StatusBarSwitcher +import ru.surfstudio.android.core.mvp.activity.BaseRenderableActivityView +import ru.surfstudio.android.core.mvp.configurator.BaseActivityViewConfigurator +import ru.surfstudio.android.easyadapter.EasyAdapter +import ru.surfstudio.android.easyadapter.ItemList +import ru.surfstudio.android.utilktx.ktx.ui.view.setTopMargin +import javax.inject.Inject + +internal class StatusBarSwitcherActivityView : BaseRenderableActivityView() { + + @Inject + lateinit var presenter: StatusBarSwitcherPresenter + + private val easyAdapter = EasyAdapter() + private val itemController = ImageItemController() + + override fun createConfigurator(): BaseActivityViewConfigurator<*, *, *> = + StatusBarSwitcherScreenConfigurator(intent) + + override fun getScreenName() = "StatusBarSwitcherActivityView" + + override fun getContentView() = R.layout.activity_status_bar_switcher + + override fun getPresenters() = arrayOf(presenter) + + override fun onCreate( + savedInstanceState: Bundle?, + persistentState: PersistableBundle?, + viewRecreated: Boolean + ) { + ViewCompat.setOnApplyWindowInsetsListener(window.decorView) { _, insets -> + status_bar_switcher_back_btn.setTopMargin(status_bar_switcher_back_btn.marginTop + insets.stableInsetTop) + presenter.setStatusBarHeight(insets.stableInsetTop) + insets + } + setFullscreenMode() + initViews() + } + + fun attachStatusBarSwitcher(statusBarSwitcher: StatusBarSwitcher) { + statusBarSwitcher.attach(this) + } + + private fun initViews() { + status_bar_switcher_rv.adapter = easyAdapter + + status_bar_switcher_back_btn.setOnClickListener { presenter.closeScreen() } + status_bar_switcher_mode_btn.setOnClickListener { presenter.toggleStatusBarSwitchingMode() } + } + + override fun renderInternal(sm: StatusBarSwitcherScreenModel) { + val switchModeTextRes = when { + sm.isAutoSwitchingEnabled -> R.string.status_bar_auto_switch_mode_btn_enabled_text + else -> R.string.status_bar_auto_switch_mode_btn_disabled_text + } + status_bar_switcher_mode_btn.text = getString(switchModeTextRes) + + val itemList = ItemList().addAll(sm.sampleList, itemController) + easyAdapter.setItems(itemList) + } + + private fun setFullscreenMode() { + val decorView = window?.decorView ?: return + val systemUiVisibilityFlags = decorView.systemUiVisibility + decorView.systemUiVisibility = systemUiVisibilityFlags or + View.SYSTEM_UI_FLAG_LAYOUT_STABLE or + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + } +} diff --git a/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherPresenter.kt b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherPresenter.kt new file mode 100644 index 000000000..2398ac99f --- /dev/null +++ b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherPresenter.kt @@ -0,0 +1,62 @@ +package ru.surfstudio.android.common.tools.sample.screen.status_bar_switcher + +import ru.surfstudio.android.common.tools.statusbarswitcher.StatusBarSwitcher +import ru.surfstudio.android.core.mvp.presenter.BasePresenter +import ru.surfstudio.android.core.mvp.presenter.BasePresenterDependency +import ru.surfstudio.android.dagger.scope.PerScreen +import javax.inject.Inject + +@PerScreen +internal class StatusBarSwitcherPresenter @Inject constructor( + basePresenterDependency: BasePresenterDependency, + private val statusBarSwitcher: StatusBarSwitcher +) : BasePresenter(basePresenterDependency) { + + private val screenModel = StatusBarSwitcherScreenModel() + + override fun onFirstLoad() { + view.render(screenModel) + } + + override fun onResume() { + super.onResume() + if (screenModel.statusBarHeight != 0 && screenModel.isAutoSwitchingEnabled) { + attachStatusBarSwitcher() + } + } + + override fun onPause() { + super.onPause() + statusBarSwitcher.detach() + } + + fun setStatusBarHeight(statusBarHeight: Int) { + val shouldEnableStatusBarSwitcher = screenModel.statusBarHeight == 0 && screenModel.isAutoSwitchingEnabled + screenModel.statusBarHeight = statusBarHeight + if (shouldEnableStatusBarSwitcher) { + attachStatusBarSwitcher() + } + } + + fun toggleStatusBarSwitchingMode() { + val newIsAutoSwitchingEnabled = !screenModel.isAutoSwitchingEnabled + screenModel.isAutoSwitchingEnabled = newIsAutoSwitchingEnabled + + if (newIsAutoSwitchingEnabled) { + attachStatusBarSwitcher() + } else { + statusBarSwitcher.detach() + } + + view.render(screenModel) + } + + fun closeScreen() { + finish() + } + + private fun attachStatusBarSwitcher() { + statusBarSwitcher.setStatusBarHeight(screenModel.statusBarHeight) + view.attachStatusBarSwitcher(statusBarSwitcher) + } +} \ No newline at end of file diff --git a/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherScreenConfigurator.kt b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherScreenConfigurator.kt new file mode 100755 index 000000000..1800b6471 --- /dev/null +++ b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherScreenConfigurator.kt @@ -0,0 +1,49 @@ +package ru.surfstudio.android.common.tools.sample.screen.status_bar_switcher + +import android.content.Context +import android.content.Intent +import dagger.Component +import dagger.Module +import dagger.Provides +import ru.surfstudio.android.common.tools.statusbarswitcher.StatusBarSwitcher +import ru.surfstudio.android.core.mvp.configurator.ScreenComponent +import ru.surfstudio.android.dagger.scope.PerScreen +import ru.surfstudio.android.sample.dagger.ui.base.configurator.DefaultActivityScreenConfigurator +import ru.surfstudio.android.sample.dagger.ui.base.dagger.activity.DefaultActivityComponent +import ru.surfstudio.android.sample.dagger.ui.base.dagger.screen.DefaultActivityScreenModule +import ru.surfstudio.android.sample.dagger.ui.base.dagger.screen.DefaultCustomScreenModule +import ru.surfstudio.android.utilktx.ktx.ui.context.getDisplayMetrics + +internal class StatusBarSwitcherScreenConfigurator(intent: Intent) : DefaultActivityScreenConfigurator(intent) { + + @PerScreen + @Component( + dependencies = [DefaultActivityComponent::class], + modules = [DefaultActivityScreenModule::class, StatusBarSwitcherScreenModule::class] + ) + internal interface StatusBarSwitcherScreenComponent : ScreenComponent + + @Module + internal class StatusBarSwitcherScreenModule( + route: StatusBarSwitcherActivityRoute + ) : DefaultCustomScreenModule(route) { + + @Provides + @PerScreen + internal fun provideStatusBarSwitcher(context: Context): StatusBarSwitcher { + return StatusBarSwitcher(context.getDisplayMetrics()) + } + } + + override fun createScreenComponent( + defaultActivityComponent: DefaultActivityComponent, + defaultActivityScreenModule: DefaultActivityScreenModule, + intent: Intent + ): ScreenComponent<*> { + return DaggerStatusBarSwitcherScreenConfigurator_StatusBarSwitcherScreenComponent.builder() + .defaultActivityComponent(defaultActivityComponent) + .defaultActivityScreenModule(defaultActivityScreenModule) + .statusBarSwitcherScreenModule(StatusBarSwitcherScreenModule(StatusBarSwitcherActivityRoute())) + .build() + } +} diff --git a/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherScreenModel.kt b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherScreenModel.kt new file mode 100644 index 000000000..2dda6906c --- /dev/null +++ b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/StatusBarSwitcherScreenModel.kt @@ -0,0 +1,22 @@ +package ru.surfstudio.android.common.tools.sample.screen.status_bar_switcher + +import ru.surfstudio.android.common.tools.sample.R +import ru.surfstudio.android.common.tools.sample.screen.status_bar_switcher.data.Item +import ru.surfstudio.android.core.mvp.model.ScreenModel + +internal data class StatusBarSwitcherScreenModel( + var isAutoSwitchingEnabled: Boolean = true, + var statusBarHeight: Int = 0, + val sampleList: List = listOf( + Item.Image("https://placekitten.com/408/287"), + Item.Image("https://placekitten.com/200/287"), + Item.Image("https://placekitten.com/200/286"), + Item.Image("https://placekitten.com/96/140"), + Item.Color(R.color.statusBarSwitcherSampleColor1), + Item.Space(), + Item.Color(R.color.statusBarSwitcherSampleColor2), + Item.Space(), + Item.Color(R.color.statusBarSwitcherSampleColor3), + Item.Space() + ) +) : ScreenModel() \ No newline at end of file diff --git a/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/controller/ImageItemController.kt b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/controller/ImageItemController.kt new file mode 100644 index 000000000..5a247af62 --- /dev/null +++ b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/controller/ImageItemController.kt @@ -0,0 +1,58 @@ +package ru.surfstudio.android.common.tools.sample.screen.status_bar_switcher.controller + +import android.view.ViewGroup +import android.widget.ImageView +import androidx.core.content.ContextCompat +import androidx.core.view.updateLayoutParams +import ru.surfstudio.android.common.tools.sample.R +import ru.surfstudio.android.common.tools.sample.screen.status_bar_switcher.data.Item +import ru.surfstudio.android.easyadapter.controller.BindableItemController +import ru.surfstudio.android.easyadapter.holder.BindableViewHolder +import ru.surfstudio.android.imageloader.ImageLoader + +internal class ImageItemController : BindableItemController() { + + override fun createViewHolder(parent: ViewGroup) = Holder(parent) + + override fun getItemId(item: Item) = "ImageItemController$item" + + class Holder(parent: ViewGroup) : BindableViewHolder(parent, R.layout.item_image) { + + private val imageView = itemView as ImageView + + private val context get() = itemView.context.applicationContext + + override fun bind(item: Item) { + imageView.background = null + imageView.setImageDrawable(null) + when (item) { + is Item.Image -> renderImage(item) + is Item.Color -> renderColor(item) + is Item.Space -> renderSpace() + } + } + + private fun renderImage(item: Item.Image) { + updateImageViewHeight(context.resources.getDimensionPixelOffset(R.dimen.imageItemHeight)) + ImageLoader.with(context) + .url(item.url) + .centerCrop() + .into(imageView) + } + + private fun renderColor(item: Item.Color) { + updateImageViewHeight(context.resources.getDimensionPixelOffset(R.dimen.colorItemHeight)) + imageView.setBackgroundColor(ContextCompat.getColor(context, item.color)) + } + + private fun renderSpace() { + updateImageViewHeight(context.resources.getDimensionPixelOffset(R.dimen.spaceItemHeight)) + } + + private fun updateImageViewHeight(newHeight: Int) { + imageView.updateLayoutParams { + height = newHeight + } + } + } +} \ No newline at end of file diff --git a/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/data/Item.kt b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/data/Item.kt new file mode 100644 index 000000000..aa903c02d --- /dev/null +++ b/common-tools/sample/src/main/java/ru/surfstudio/android/common/tools/sample/screen/status_bar_switcher/data/Item.kt @@ -0,0 +1,10 @@ +package ru.surfstudio.android.common.tools.sample.screen.status_bar_switcher.data + +import androidx.annotation.ColorRes + +internal sealed class Item { + + data class Color(@ColorRes val color: Int) : Item() + data class Image(val url: String) : Item() + class Space : Item() +} \ No newline at end of file diff --git a/common-tools/sample/src/main/res/drawable-v21/bg_round_button.xml b/common-tools/sample/src/main/res/drawable-v21/bg_round_button.xml new file mode 100644 index 000000000..1b3a1ff92 --- /dev/null +++ b/common-tools/sample/src/main/res/drawable-v21/bg_round_button.xml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/common-tools/sample/src/main/res/drawable/bg_round_button.xml b/common-tools/sample/src/main/res/drawable/bg_round_button.xml new file mode 100644 index 000000000..0d1f0e034 --- /dev/null +++ b/common-tools/sample/src/main/res/drawable/bg_round_button.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/common-tools/sample/src/main/res/drawable/ic_baseline_arrow_back_24.xml b/common-tools/sample/src/main/res/drawable/ic_baseline_arrow_back_24.xml new file mode 100644 index 000000000..1fe523c43 --- /dev/null +++ b/common-tools/sample/src/main/res/drawable/ic_baseline_arrow_back_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/common-tools/sample/src/main/res/layout/activity_main.xml b/common-tools/sample/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..2b846f385 --- /dev/null +++ b/common-tools/sample/src/main/res/layout/activity_main.xml @@ -0,0 +1,15 @@ + + + +