CARVIEW |
Select Language
HTTP/2 200
date: Wed, 23 Jul 2025 05:47:28 GMT
content-type: text/html; charset=utf-8
vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With,Accept-Encoding, Accept, X-Requested-With
x-robots-tag: none
etag: W/"eef5dbf40285aa1f047b5b69ead0b6da"
cache-control: max-age=0, private, must-revalidate
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: no-referrer-when-downgrade
content-security-policy: default-src 'none'; base-uri 'self'; child-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com release-assets.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com copilotprodattachments.blob.core.windows.net/github-production-copilot-attachments/ github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/
server: github.com
content-encoding: gzip
accept-ranges: bytes
set-cookie: _gh_sess=Dyts6TAVXR4XwrIngsVYt9WpNBal5k2RgmsTy%2B2lqWmLO4TfRtnDuJ608YwCwTlaDfLqlF25TiZUWHIrGBlesCtP3IR50J%2FvhyBU8BixcFylvumtWf5XApooOZdYkPd1fzU%2BaMxbhS1d0jgKz%2F0iqS3NpBm522K%2FzyvKq8LTKAeYxTYqILMk9lYN9OcJqeKuVrhuHZCLulsNtlswUnJaxp11QcQNU3KZsNyXB7LXIgE7r8yg8oS1kx5WDlFwvId8EQnZutC3V1zoODbEmNimKg%3D%3D--3aC3IYOmUkhoJNK1--GoSPOxGDTigZSh1WeswOZA%3D%3D; Path=/; HttpOnly; Secure; SameSite=Lax
set-cookie: _octo=GH1.1.2141566019.1753249647; Path=/; Domain=github.com; Expires=Thu, 23 Jul 2026 05:47:27 GMT; Secure; SameSite=Lax
set-cookie: logged_in=no; Path=/; Domain=github.com; Expires=Thu, 23 Jul 2026 05:47:27 GMT; HttpOnly; Secure; SameSite=Lax
x-github-request-id: D47C:394F4C:466448:5CEE3B:6880776F
Live Templates · lopspower/CleanRxArchitecture Wiki · GitHub
Skip to content
Navigation Menu
{{ message }}
-
-
Notifications
You must be signed in to change notification settings - Fork 47
Live Templates
Lopez Mikhael edited this page Jun 5, 2020
·
2 revisions
File and Code Templates are available on Android Studio. It's a very powerful feature but not often used. When using an architecture such as this one it is essential to use it to increase your productivity especially for the creation of your scenes.
You can add File and Code Templates here: Preferences > Editor > File and Code Templates
After adding them, all you have to do is New and choose your template.
🎁 Bonus: RecyclerViewAdapter.kt
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}#end
data class ${NAME}(val loadingState: LoadingState = LoadingState.NONE,
val contentState: ContentState = ContentState.NONE,
val data: ${DataType}? = null,
val errorMessage: String? = null,
val snackMessage: String? = null) {
companion object {
fun createLoading() = ${NAME}(loadingState = LoadingState.LOADING, contentState = ContentState.CONTENT)
fun createRetryLoading() = ${NAME}(loadingState = LoadingState.RETRY, contentState = ContentState.ERROR)
fun createData(data: ${DataType}) = ${NAME}(contentState = ContentState.CONTENT, data = data)
fun createError(error: String) = ${NAME}(contentState = ContentState.ERROR, errorMessage = error)
fun createSnack(snackMessage: String) = ${NAME}(contentState = ContentState.CONTENT, snackMessage = snackMessage)
}
}
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}#end
import io.reactivex.Observable
interface ${NAME} : LoadDataView<${Scene_Name}ViewModel> {
fun intentLoadData(): Observable<${Param}>
fun intentRefreshData(): Observable<${Param}>
fun intentErrorRetry(): Observable<${Param}>
}
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}#end
import androidx.appcompat.app.AppCompatActivity
import javax.inject.Inject
class ${NAME}
@Inject internal constructor(private val activity: AppCompatActivity) {
fun routeToSample() {
//activity.startActivity(SampleActivity.newIntent(activity.applicationContext))
}
}
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}#end
import io.reactivex.Observable
import io.reactivex.Scheduler
import io.reactivex.Single
import io.reactivex.rxkotlin.addTo
import javax.inject.Inject
class ${NAME}
@Inject constructor(private val getData: ${GetDataUsecase},
private val router: ${Scene_Name}Router,
private val scheduler: Scheduler,
errorMessageFactory: ErrorMessageFactory)
: APresenter<${Scene_Name}View, ${Scene_Name}ViewModel>(errorMessageFactory) {
override fun attach(view: ${Scene_Name}View) {
val loadData = view.intentLoadData().flatMap { loadData(it) }
val refreshData = view.intentRefreshData().flatMap { refreshData(it) }
val retryData = view.intentErrorRetry().flatMap { retryData(it) }
subscribeViewModel(view, loadData, refreshData, retryData)
}
//region USE CASES TO VIEW MODEL
private fun getData(param: ${ParamUseCase}): Observable<${Scene_Name}ViewModel> =
getData.execute(param).toObservable()
.map { ${Scene_Name}ViewModel.createData(it) }
private fun loadData(param: ${ParamUseCase}): Observable<${Scene_Name}ViewModel> =
getData(param)
.startWith(${Scene_Name}ViewModel.createLoading())
.onErrorReturn { onError(it) }
private fun refreshData(param: ${ParamUseCase}): Observable<${Scene_Name}ViewModel> =
getData(param)
.onErrorReturn { ${Scene_Name}ViewModel.createSnack(getErrorMessage(it)) }
private fun retryData(param: ${ParamUseCase}): Observable<${Scene_Name}ViewModel> =
getData(param)
.startWith(${Scene_Name}ViewModel.createRetryLoading())
.onErrorResumeNext(DelayFunction<${Scene_Name}ViewModel>(scheduler))
.onErrorReturn { onError(it) }
//endregion
private fun onError(error: Throwable): ${Scene_Name}ViewModel =
${Scene_Name}ViewModel.createError(getErrorMessage(error))
}
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}#end
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.jakewharton.rxbinding3.swiperefreshlayout.refreshes
import com.jakewharton.rxbinding3.view.clicks
import io.reactivex.Observable
import javax.inject.Inject
class ${NAME} : ABaseDataFragment(R.layout.${Layout_ID}), ${Scene_Name}View {
companion object {
fun newInstance(): ${NAME} = ${NAME}()
}
@Inject
lateinit var presenter: ${Scene_Name}Presenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityComponent.inject(this)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initView()
}
override fun onResume() {
super.onResume()
presenter.attach(this)
}
override fun onPause() {
super.onPause()
presenter.detach()
}
private fun initView() {
}
//region INTENTS
override fun intentLoadData(): Observable<Unit> = Observable.just(Unit)
override fun intentRefreshData(): Observable<Unit> = swipeRefreshLayout.refreshes().map { Unit }
override fun intentErrorRetry(): Observable<Unit> = btnErrorRetry.clicks().map { Unit }
//endregion
//region RENDER
override fun render(viewModel: ${Scene_Name}ViewModel) {
TimberWrapper.d { "Render: " + viewModel }
showLoading(viewModel.loadingState == LoadingState.LOADING)
showRefreshingLoading(swipeRefreshLayout, false)
showRetryLoading(viewModel.loadingState == LoadingState.RETRY)
showContent(content, viewModel.contentState == ContentState.CONTENT)
showError(viewModel.contentState == ContentState.ERROR)
renderData(viewModel.data)
renderError(viewModel.errorMessage)
renderSnack(viewModel.snackMessage)
}
private fun renderData(data: ${Data_Type}?) {
data?.also {
// TODO
}
}
//endregion
}
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}#end
import android.content.Context
import android.content.Intent
import android.os.Bundle
class ${NAME} : ABaseActivity(R.layout.${Layout_ID}) {
companion object {
fun newIntent(context: Context): Intent =
Intent(context, ${NAME}::class.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initializeActivity(savedInstanceState)
}
private fun initializeActivity(savedInstanceState: Bundle?) {
if (savedInstanceState == null) {
addFragment(R.id.container, ${Scene_Name}Fragment.newInstance())
}
}
}
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}#end
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
class ${NAME} : RecyclerView.Adapter<${NAME}.ViewHolder>() {
var data: List<${Model}> = emptyList()
set(value) {
field = value
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.${Item_Layout_ID}, parent, false))
override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind(data[position])
override fun getItemCount() = data.size
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(item: ${Model}) = with(itemView) {
// TODO: Bind the data with View
}
}
}
Find this project useful? Support it by joining stargazers for this repository ⭐️
And follow me for my next creations 👍
CleanRxArchitecture by Lopez Mikhael is licensed under a Apache License 2.0.
Clone this wiki locally
You can’t perform that action at this time.