Commit 634a070f authored by Vladislav Bogdashkin's avatar Vladislav Bogdashkin 🎣

added on click Model event to the common Adapter

parent 89ffc571
...@@ -75,6 +75,7 @@ dependencies { ...@@ -75,6 +75,7 @@ dependencies {
//image loading store and cashe by url: Picasso //image loading store and cashe by url: Picasso
implementation "com.squareup.picasso:picasso:$picassoVersion" implementation "com.squareup.picasso:picasso:$picassoVersion"
implementation 'jp.wasabeef:picasso-transformations:2.2.1'
//Logger: Timber //Logger: Timber
implementation "com.jakewharton.timber:timber:$timberVersion" implementation "com.jakewharton.timber:timber:$timberVersion"
......
package com.biganto.visual.roompark.domain.interactor
import com.biganto.visual.roompark.domain.model.ArticleModel
import io.reactivex.Single
import javax.inject.Inject
/**
* Created by Vladislav Bogdashkin on 09.10.2019.
*/
class ArticleInteractor @Inject constructor(
) {
fun fetchArticles(articleId: Int): Single<ArticleModel> = Single.just(
when (articleId) {
else -> error("unknown feedId")
}
)
}
package com.biganto.visual.roompark.presentation.screen.article
import com.biganto.visual.roompark.conductor.BigantoBaseContract
/**
* Created by Vladislav Bogdashkin on 30.09.2019.
*/
interface ArticleScreen : BigantoBaseContract<ArticleScreenViewState> {
}
package com.biganto.visual.roompark.presentation.screen.article
import android.text.Html
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.MultiAutoCompleteTextView
import butterknife.BindView
import com.biganto.visual.roompark.R
import com.biganto.visual.roompark.base.RoomParkApplication
import com.biganto.visual.roompark.base.RoomParkMainActivity
import com.biganto.visual.roompark.conductor.BigantoBaseController
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.textview.MaterialTextView
import com.squareup.picasso.Picasso
import jp.wasabeef.picasso.transformations.BlurTransformation
import timber.log.Timber
import javax.inject.Inject
/**
* Created by Vladislav Bogdashkin on 30.09.2019.
*/
class ArticleScreenController :
BigantoBaseController<ArticleScreenViewState
, ArticleScreen
, ArticleScreenPresenter>()
, ArticleScreen {
override fun injectDependencies() {
getComponent()
}
@Inject
override lateinit var injectedPresenter: ArticleScreenPresenter
@BindView(R.id.articleTitle)
lateinit var title:MaterialTextView
@BindView(R.id.articleHeaderBlock)
lateinit var headerBlock: ViewGroup
@BindView(R.id.articleContent)
lateinit var contentView: MaterialTextView
val blurPreview:ImageView by lazy {
headerBlock.findViewById(R.id.articlePreviewBlurred)
}
val articlePreview:ImageView by lazy {
headerBlock.findViewById(R.id.articlePreview)
}
val articleDate:MaterialTextView by lazy {
headerBlock.findViewById(R.id.articleDate)
}
val closeButton:FloatingActionButton by lazy {
headerBlock.findViewById(R.id.articleCloseButton)
}
private fun setToolbar(){
toolBar.hideAll()
toolBar.appBar.setExpanded(false,false)
// toolBar.collapsingToolbarLayout.title = "ИЗБРАННОЕ"
// toolBar.appBar.liftOnScrollTargetViewId = R.id.Article_cards_recycler_view
toolBar.appBar.setLiftable(false)
toolBar.appBarScrollable(false)
// ArticleRecyclerView.isNestedScrollingEnabled = false
}
private fun bindRecycler() {
}
override fun onViewBound(v: View) {
setToolbar()
bindRecycler()
}
override fun render(viewState: ArticleScreenViewState) {
super.render(viewState)
Timber.d("Render state $viewState")
when(viewState){
is ArticleScreenViewState.Idle -> render(viewState)
is ArticleScreenViewState.ArticleLoaded -> render(viewState)
}
}
private fun render(viewState: ArticleScreenViewState.Idle){
}
private fun render(viewState: ArticleScreenViewState.ArticleLoaded) {
title.text = viewState.item.title
contentView.text = Html.fromHtml(viewState.item.htmlBody)
articleDate.text = viewState.item.published.toString()
Picasso.get()
.load(viewState.item.previewUrl)
.transform(BlurTransformation(activity,40,4))
.into(blurPreview)
Picasso.get()
.load(viewState.item.previewUrl)
.into(articlePreview)
}
private fun getComponent() = DaggerArticleScreenComponent.factory()
.create(RoomParkApplication.component,activity as RoomParkMainActivity)
.inject(this)
override fun getLayoutId(): Int = R.layout.feed_read_screen
}
\ No newline at end of file
package com.biganto.visual.roompark.presentation.screen.article
import android.content.Context
import com.biganto.visual.roompark.base.RoomParkMainActivity
import com.biganto.visual.roompark.di.dagger.AppComponent
import com.biganto.visual.roompark.di.dagger.PerScreen
import dagger.Binds
import dagger.BindsInstance
import dagger.Component
import dagger.Module
@PerScreen
@Component(
modules = [ArticleScreenModule::class],
dependencies = [AppComponent::class])
interface ArticleScreenComponent {
@Component.Factory
interface Factory{
fun create(
appComponent: AppComponent
,@BindsInstance activity: RoomParkMainActivity
): ArticleScreenComponent
}
val presenter: ArticleScreenPresenter
fun inject(controller: ArticleScreenController)
}
@Module
abstract class ArticleScreenModule{
@PerScreen
@Binds
abstract fun provideContext(activity: RoomParkMainActivity): Context
}
package com.biganto.visual.roompark.presentation.screen.article
import com.biganto.visual.roompark.conductor.BigantoBasePresenter
import com.biganto.visual.roompark.domain.interactor.ArticleInteractor
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import timber.log.Timber
import javax.inject.Inject
/**
* Created by Vladislav Bogdashkin on 30.09.2019.
*/
class ArticleScreenPresenter @Inject constructor(
private val interactor: ArticleInteractor
)
: BigantoBasePresenter<ArticleScreen, ArticleScreenViewState>() {
override fun bindIntents() {
val prefetchCards = interactor.fetchArticles(2)
.map { ArticleScreenViewState.ArticleLoaded(it) }
val state = restoreStateObservable
.mergeWith(prefetchCards)
.doOnError{ Timber.e(it)}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
subscribeViewState(state.cast(ArticleScreenViewState::class.java), ArticleScreen::render)
}
}
\ No newline at end of file
package com.biganto.visual.roompark.presentation.screen.article
import com.biganto.visual.roompark.conductor.BigantoBaseViewState
import com.biganto.visual.roompark.domain.model.ArticleModel
/**
* Created by Vladislav Bogdashkin on 30.09.2019.
*/
sealed class ArticleScreenViewState : BigantoBaseViewState() {
class Idle : ArticleScreenViewState()
class ArticleLoaded(val item: ArticleModel) : ArticleScreenViewState()
}
\ No newline at end of file
package com.biganto.visual.roompark.presentation.screen.favorites package com.biganto.visual.roompark.presentation.screen.favorites
import com.biganto.visual.roompark.conductor.BigantoBaseContract import com.biganto.visual.roompark.conductor.BigantoBaseContract
import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreenViewState
/** /**
* Created by Vladislav Bogdashkin on 30.09.2019. * Created by Vladislav Bogdashkin on 30.09.2019.
......
...@@ -8,6 +8,9 @@ import com.biganto.visual.roompark.R ...@@ -8,6 +8,9 @@ import com.biganto.visual.roompark.R
import com.biganto.visual.roompark.base.RoomParkApplication import com.biganto.visual.roompark.base.RoomParkApplication
import com.biganto.visual.roompark.base.RoomParkMainActivity import com.biganto.visual.roompark.base.RoomParkMainActivity
import com.biganto.visual.roompark.conductor.BigantoBaseController import com.biganto.visual.roompark.conductor.BigantoBaseController
import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreen
import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreenPresenter
import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreenViewState
import com.biganto.visual.roompark.presentation.screen.favorites.util.FavoritesListAdapter import com.biganto.visual.roompark.presentation.screen.favorites.util.FavoritesListAdapter
import com.biganto.visual.roompark.util.view_utils.grid.CeilsDecoration import com.biganto.visual.roompark.util.view_utils.grid.CeilsDecoration
import timber.log.Timber import timber.log.Timber
......
...@@ -4,6 +4,10 @@ import android.content.Context ...@@ -4,6 +4,10 @@ import android.content.Context
import com.biganto.visual.roompark.base.RoomParkMainActivity import com.biganto.visual.roompark.base.RoomParkMainActivity
import com.biganto.visual.roompark.di.dagger.AppComponent import com.biganto.visual.roompark.di.dagger.AppComponent
import com.biganto.visual.roompark.di.dagger.PerScreen import com.biganto.visual.roompark.di.dagger.PerScreen
import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreenComponent
import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreenController
import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreenModule
import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreenPresenter
import dagger.Binds import dagger.Binds
import dagger.BindsInstance import dagger.BindsInstance
import dagger.Component import dagger.Component
......
...@@ -2,6 +2,8 @@ package com.biganto.visual.roompark.presentation.screen.favorites ...@@ -2,6 +2,8 @@ package com.biganto.visual.roompark.presentation.screen.favorites
import com.biganto.visual.roompark.conductor.BigantoBasePresenter import com.biganto.visual.roompark.conductor.BigantoBasePresenter
import com.biganto.visual.roompark.domain.interactor.FavoritesInteractor import com.biganto.visual.roompark.domain.interactor.FavoritesInteractor
import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreen
import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreenViewState
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import timber.log.Timber import timber.log.Timber
......
...@@ -2,6 +2,7 @@ package com.biganto.visual.roompark.presentation.screen.favorites ...@@ -2,6 +2,7 @@ package com.biganto.visual.roompark.presentation.screen.favorites
import com.biganto.visual.roompark.conductor.BigantoBaseViewState import com.biganto.visual.roompark.conductor.BigantoBaseViewState
import com.biganto.visual.roompark.domain.model.EstateModel import com.biganto.visual.roompark.domain.model.EstateModel
import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreenViewState
/** /**
* Created by Vladislav Bogdashkin on 30.09.2019. * Created by Vladislav Bogdashkin on 30.09.2019.
......
...@@ -9,7 +9,9 @@ import com.biganto.visual.roompark.domain.model.ArticlePreviewModel ...@@ -9,7 +9,9 @@ import com.biganto.visual.roompark.domain.model.ArticlePreviewModel
import com.biganto.visual.roompark.presentation.screen.settings.util.CommonRecyclerAdapter import com.biganto.visual.roompark.presentation.screen.settings.util.CommonRecyclerAdapter
import com.biganto.visual.roompark.presentation.screen.settings.util.CommonViewHolder import com.biganto.visual.roompark.presentation.screen.settings.util.CommonViewHolder
import com.biganto.visual.roompark.util.extensions.setGone import com.biganto.visual.roompark.util.extensions.setGone
import com.jakewharton.rxbinding3.view.clicks
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import io.reactivex.subjects.PublishSubject
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
...@@ -28,7 +30,6 @@ class ArticlesAdapter : CommonRecyclerAdapter<ArticleViewHolder, ArticlePreviewM ...@@ -28,7 +30,6 @@ class ArticlesAdapter : CommonRecyclerAdapter<ArticleViewHolder, ArticlePreviewM
class ArticleViewHolder(itemView: View) : CommonViewHolder<ArticlePreviewModel>(itemView) { class ArticleViewHolder(itemView: View) : CommonViewHolder<ArticlePreviewModel>(itemView) {
private val dateFormatter = SimpleDateFormat("dd / MM / yyyy", Locale.getDefault()) private val dateFormatter = SimpleDateFormat("dd / MM / yyyy", Locale.getDefault())
@BindView(R.id.imageHolder) lateinit var preview: ImageView @BindView(R.id.imageHolder) lateinit var preview: ImageView
...@@ -36,6 +37,8 @@ class ArticleViewHolder(itemView: View) : CommonViewHolder<ArticlePreviewModel>( ...@@ -36,6 +37,8 @@ class ArticleViewHolder(itemView: View) : CommonViewHolder<ArticlePreviewModel>(
@BindView(R.id.feed_title_info_text_view) lateinit var articleTitle: TextView @BindView(R.id.feed_title_info_text_view) lateinit var articleTitle: TextView
@BindView(R.id.feed_read) lateinit var articleIsRead:View @BindView(R.id.feed_read) lateinit var articleIsRead:View
override fun onViewBound(model: ArticlePreviewModel) { override fun onViewBound(model: ArticlePreviewModel) {
articleDate.text = dateFormatter.format(model.published) articleDate.text = dateFormatter.format(model.published)
articleTitle.text = model.title articleTitle.text = model.title
......
...@@ -12,7 +12,7 @@ import com.biganto.visual.roompark.base.RoomParkApplication ...@@ -12,7 +12,7 @@ import com.biganto.visual.roompark.base.RoomParkApplication
import com.biganto.visual.roompark.base.RoomParkMainActivity import com.biganto.visual.roompark.base.RoomParkMainActivity
import com.biganto.visual.roompark.conductor.BigantoBaseController import com.biganto.visual.roompark.conductor.BigantoBaseController
import com.biganto.visual.roompark.presentation.screen.deals.DealsScreenController import com.biganto.visual.roompark.presentation.screen.deals.DealsScreenController
import com.biganto.visual.roompark.presentation.screen.favorites.FavoritesScreenController import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreenController
import com.biganto.visual.roompark.presentation.screen.feeds.FeedsScreenController import com.biganto.visual.roompark.presentation.screen.feeds.FeedsScreenController
import com.biganto.visual.roompark.presentation.screen.settings.SettingsScreenController import com.biganto.visual.roompark.presentation.screen.settings.SettingsScreenController
import com.biganto.visual.roompark.presentation.screen.to_flat.FindFlatScreenController import com.biganto.visual.roompark.presentation.screen.to_flat.FindFlatScreenController
......
...@@ -11,7 +11,7 @@ import com.biganto.visual.roompark.base.ICollapsingToolBar ...@@ -11,7 +11,7 @@ import com.biganto.visual.roompark.base.ICollapsingToolBar
import com.biganto.visual.roompark.base.RoomParkApplication import com.biganto.visual.roompark.base.RoomParkApplication
import com.biganto.visual.roompark.base.RoomParkMainActivity import com.biganto.visual.roompark.base.RoomParkMainActivity
import com.biganto.visual.roompark.presentation.screen.deals.DealsScreenController import com.biganto.visual.roompark.presentation.screen.deals.DealsScreenController
import com.biganto.visual.roompark.presentation.screen.favorites.FavoritesScreenController import com.biganto.visual.roompark.presentation.screen.article.FavoritesScreenController
import com.biganto.visual.roompark.presentation.screen.feeds.FeedsScreenController import com.biganto.visual.roompark.presentation.screen.feeds.FeedsScreenController
import com.biganto.visual.roompark.presentation.screen.home.DaggerHomeScreenComponent import com.biganto.visual.roompark.presentation.screen.home.DaggerHomeScreenComponent
import com.biganto.visual.roompark.presentation.screen.home.HomeScreenPresenter import com.biganto.visual.roompark.presentation.screen.home.HomeScreenPresenter
......
...@@ -13,6 +13,9 @@ import com.biganto.visual.roompark.domain.model.PushSwitchModel ...@@ -13,6 +13,9 @@ import com.biganto.visual.roompark.domain.model.PushSwitchModel
import com.biganto.visual.roompark.util.extensions.bytesToSize import com.biganto.visual.roompark.util.extensions.bytesToSize
import com.google.android.material.switchmaterial.SwitchMaterial import com.google.android.material.switchmaterial.SwitchMaterial
import com.google.android.material.textview.MaterialTextView import com.google.android.material.textview.MaterialTextView
import com.jakewharton.rxbinding3.view.clicks
import io.reactivex.Observable
import io.reactivex.subjects.PublishSubject
import timber.log.Timber import timber.log.Timber
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.full.valueParameters import kotlin.reflect.full.valueParameters
...@@ -22,8 +25,9 @@ import kotlin.reflect.jvm.javaType ...@@ -22,8 +25,9 @@ import kotlin.reflect.jvm.javaType
* Created by Vladislav Bogdashkin on 16.10.2019. * Created by Vladislav Bogdashkin on 16.10.2019.
*/ */
abstract class CommonRecyclerAdapter<VH:CommonViewHolder<M>,M> : RecyclerView.Adapter<VH>() { abstract class CommonRecyclerAdapter<VH:CommonViewHolder<M>,M:Any> : RecyclerView.Adapter<VH>() {
private val onModelClicked = PublishSubject.create<M>()
private var list: MutableList<M> = mutableListOf() private var list: MutableList<M> = mutableListOf()
...@@ -53,17 +57,24 @@ abstract class CommonRecyclerAdapter<VH:CommonViewHolder<M>,M> : RecyclerView.Ad ...@@ -53,17 +57,24 @@ abstract class CommonRecyclerAdapter<VH:CommonViewHolder<M>,M> : RecyclerView.Ad
override fun onBindViewHolder(holder: VH, position: Int) { override fun onBindViewHolder(holder: VH, position: Int) {
holder.bindModel(list[position]) holder.bindModel(list[position])
holder.onClicked()
.subscribe(onModelClicked)
} }
} }
abstract class CommonViewHolder<M>(itemView: View): RecyclerView.ViewHolder(itemView) { abstract class CommonViewHolder<M:Any>(itemView: View): RecyclerView.ViewHolder(itemView) {
abstract fun onViewBound(model: M) abstract fun onViewBound(model: M)
fun bindModel(model: M){ fun bindModel(model: M){
ButterKnife.bind(this, itemView) ButterKnife.bind(this, itemView)
bindModel = model
onViewBound(model) onViewBound(model)
} }
fun onClicked(): Observable<M> = itemView.clicks().map { bindModel }
private lateinit var bindModel: M
} }
class PushListAdapter : CommonRecyclerAdapter<PushViewHolder,PushSwitchModel>() { class PushListAdapter : CommonRecyclerAdapter<PushViewHolder,PushSwitchModel>() {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
android:orientation="vertical"> android:orientation="vertical">
<ImageView <ImageView
android:id="@+id/imageView5" android:id="@+id/articlePreviewBlurred"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginBottom="32dp" android:layout_marginBottom="32dp"
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
app:srcCompat="@drawable/default_image_placeholder" /> app:srcCompat="@drawable/default_image_placeholder" />
<ImageView <ImageView
android:id="@+id/imageView4" android:id="@+id/articlePreview"
android:layout_width="125dp" android:layout_width="125dp"
android:layout_height="125dp" android:layout_height="125dp"
android:layout_marginStart="27dp" android:layout_marginStart="27dp"
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
app:srcCompat="@drawable/ic_favorites" /> app:srcCompat="@drawable/ic_favorites" />
<TextView <TextView
android:id="@+id/feed_date_text_view2" android:id="@+id/articleDate"
style="@style/Feed.Notice" style="@style/Feed.Notice"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
...@@ -40,10 +40,10 @@ ...@@ -40,10 +40,10 @@
android:visibility="visible" android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView4" /> app:layout_constraintStart_toEndOf="@+id/articlePreview" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floatingActionButton" android:id="@+id/articleCloseButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<include <include
android:id="@+id/articleHeaderBlock"
layout="@layout/feed_read_header" layout="@layout/feed_read_header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<com.google.android.material.textview.MaterialTextView <com.google.android.material.textview.MaterialTextView
android:id="@+id/articleTitle"
style="@style/Header_TextView.Main_Header" style="@style/Header_TextView.Main_Header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:text="В ЖК «РУМЯНЦЕВО-ПАРК» ИПОТЕЧНАЯ СТАВКА - 6,5%" /> android:text="В ЖК «РУМЯНЦЕВО-ПАРК» ИПОТЕЧНАЯ СТАВКА - 6,5%" />
<MultiAutoCompleteTextView
android:paddingStart="16dp" <com.google.android.material.textview.MaterialTextView
android:paddingEnd="16dp" android:id="@+id/articleContent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:text="С марта 2019 года для всех покупателей квартир в жилом комплексе бизнес-класса «Румянцево-Парк» от компании Lexion Development, доступна минимальная ипотечная ставка от банка-партнера ПАО Банк ВТБ в размере 6,5% по программе субсидирования ипотеки от застройщика. android:text="С марта 2019 года для всех покупателей квартир в жилом комплексе бизнес-класса «Румянцево-Парк» от компании Lexion Development, доступна минимальная ипотечная ставка от банка-партнера ПАО Банк ВТБ в размере 6,5% по программе субсидирования ипотеки от застройщика.
Минимальная процентная ставка действительна при покупке любого типа квартир в жилом комплексе – от студий 23,8 кв. м до четырехкомнатных квартир площадью 102,7 кв. м. Минимальный первоначальный взнос составляет от 20%. Минимальная процентная ставка действительна при покупке любого типа квартир в жилом комплексе – от студий 23,8 кв. м до четырехкомнатных квартир площадью 102,7 кв. м. Минимальный первоначальный взнос составляет от 20%.
Более подробная информация доступна в офисе продаж по телефону: +7 (495) 127-86-86" /> Более подробная информация доступна в офисе продаж по телефону: +7 (495) 127-86-86" />
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment