Giter Site home page Giter Site logo

janishar / android-kotlin-mvp-architecture Goto Github PK

View Code? Open in Web Editor NEW
699.0 39.0 195.0 309 KB

This repository contains a detailed sample app that implements MVP architecture in Kotlin using Dagger2, Room, RxJava2, FastAndroidNetworking and PlaceholderView

License: Apache License 2.0

Kotlin 100.00%
mvp-architecture mvp mvp-android dagger2 fast-android-networking placeholderview room database rxjava2 rxjava

android-kotlin-mvp-architecture's Introduction

Deprecated


This Project is [Deprecated] goto latest project: Modern Android Development - WhereIsMyMotivation


Deprecated

Android Kotlin MVP Architecture: Sample App

This repository contains a detailed sample app that implements MVP architecture in Kotlin using Dagger2, Room, RxJava, FastAndroidNetworking, PlaceHolderView and AndroidDebugDatabase




Architecture Blueprint

Blueprint

Project Structure

Structure

About The Author

You can connect with me here:

Read the below listed articles. They describe the MVP concepts and the Project structure.

  1. MVP: Part 1
  2. MVP: Part 2
  3. MVP: Part 3
  4. Extension with Interactors and Repositories

The app has following packages:

  1. data: It contains all the data accessing and manipulating components.
  2. di: Dependency providing classes using Dagger2.
  3. ui: View classes along with their corresponding Presenters.
  4. utils: Utility classes.

Classes have been designed in such a way that it could be inherited and maximize the code reuse.

Library reference resources:

  1. Dagger2: https://github.com/janishar/android-dagger2-example
  2. PlaceHolderView: https://github.com/janishar/PlaceHolderView
  3. Calligraphy: https://github.com/chrisjenx/Calligraphy
  4. GreenDao: http://greenrobot.org/greendao/
  5. ButterKnife: http://jakewharton.github.io/butterknife/

Concept reference resources:

  1. Introduction to Dagger 2: Part 1
  2. Introduction to Dagger 2: Part 2
  3. Android Dagger2: Critical things to know before you implement
  4. Android Tinder Swipe View Example
  5. RxJava Anatomy: What is RxJava, how RxJava is designed, and how RxJava works.

Looking for MVVM Architecture - Check here

License

   Copyright (C) 2022 JANISHAR ALI ANWAR

   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.

Contributing to Android Kotlin MVP Architecture

All pull requests are welcome, make sure to follow the contribution guidelines when you submit pull request.

android-kotlin-mvp-architecture's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

android-kotlin-mvp-architecture's Issues

can you tell me where to put FirebaseEventListener inside this MVP project?

Hi, I have small doubt on using android FirebaseEventListener inside my project. I don't know where to put it inside MVP architecture, But am sure it is a kind of database Interactor, that get data from firebase db. What I planned to do is creating another class same like preference,database,api reference is enough to satisfy the firebase request coming from the view. Is it ok, if not, can you tell me what kind of class(singleton/not) i have to create and where to put that class.

Adding a new activity

I am trying to add a new activity it is giving me error on this please help !
`
@module
class SignupActivityModule {
@provides
internal fun provideSignupInteractor(interactor: SignupInteractor): SignupMVPInteractor = interactor

@Provides
internal fun provideSignupPresenter(presenter: SignupPresenter<SignupMVPView,SignupMVPInteractor>)
        : SignupMVPPresenter<SignupMVPView, SignupMVPInteractor> = presenter

} interface SignupMVPView : MVPView {
fun showValidationMessage(errorCode: Int)
fun openMainActivity()
fun showResponseToast(response:String)
} class SignupActivity : BaseActivity(), SignupMVPView {
@Inject
internal lateinit var presenter: SignupMVPPresenter<SignupMVPView, SignupMVPInteractor>
override fun showResponseToast(response: String) {
toast(message = response)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_signup)
presenter.onAttach(this)
}
override fun onDestroy() {
presenter.onDetach()
super.onDestroy()
}
override fun showValidationMessage(errorCode: Int) {
}
override fun openMainActivity() {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}
override fun onFragmentAttached() {
}
override fun onFragmentDetached(tag: String) {
}
fun toast(message: CharSequence) =
Toast.makeText(this@SignupActivity, message, Toast.LENGTH_SHORT).show()
} class SignupPresenter<V : SignupMVPView, I : SignupMVPInteractor> @Inject internal constructor(interactor: I, schedulerProvider: SchedulerProvider, disposable: CompositeDisposable) : BasePresenter<V, I>(interactor = interactor, schedulerProvider = schedulerProvider, compositeDisposable = disposable), SignupMVPPresenter<V, I> {
override fun onServerSignupClicked(username: String, password: String, confirmPassword: String, fullName: String, phone: String, role: String) {
when {
username.isEmpty() -> getView()?.showValidationMessage(AppConstants.EMPTY_EMAIL_ERROR)
password.isEmpty() -> getView()?.showValidationMessage(AppConstants.EMPTY_PASSWORD_ERROR)
else -> {
getView()?.showProgress()
interactor?.let {
compositeDisposable.add(it.doServerSignupApiCall(username, password, confirmPassword, fullName, phone, role)
.compose(schedulerProvider.ioToMainObservableScheduler())
.subscribe({ loginResponse ->
getView()?.showResponseToast(loginResponse.message!!)
}, { err -> println(err) }))
}}}}} interface SignupMVPPresenter<V : SignupMVPView, I : SignupMVPInteractor> : MVPPresenter<V, I> {
fun onServerSignupClicked(username: String, password: String, confirmPassword: String, fullName: String, phone: String, role: String)
} interface SignupMVPInteractor : MVPInteractor {
fun doServerSignupApiCall(username: String, password: String, confirmPassword: String, fullName: String, phone: String, role: String): Observable
} class SignupInteractor @Inject internal constructor(preferenceHelper: PreferenceHelper, apiHelper: ApiHelper) : BaseInteractor(preferenceHelper, apiHelper), SignupMVPInteractor {
override fun doServerSignupApiCall(username: String, password: String,
confirmPassword: String, fullName: String,
phone: String, role: String) =
apiHelper.performServerSignup(SignupRequest.ServerSignupRequest(username = username,
password = password, confirPassword = confirmPassword, fullName = fullName,
phone = phone, role = role))

}`

I am following same as login but getting error in activity builder

`@Module
abstract class ActivityBuilder {

@ContributesAndroidInjector(modules = [(SplashActivityModule::class)])
abstract fun bindSplashActivity(): SplashMVPActivity

@ContributesAndroidInjector(modules = [(SignupActivity::class)])
abstract fun bindSignupActivity(): SignupActivity

@ContributesAndroidInjector(modules = [(MainActivityModule::class), (RateUsDialogFragmentProvider::class), (AboutFragmentProvider::class)])
abstract fun bindMainActivity(): MainActivity

@ContributesAndroidInjector(modules = [(LoginActivityModule::class)])
abstract fun bindLoginActivity(): LoginActivity

@ContributesAndroidInjector(modules = [(BlogFragmentProvider::class), (OpenSourceFragmentProvider::class)])
abstract fun bindFeedActivity(): FeedActivity}`

I am getting this error
di\builder\ActivityBuilder.java:17: error: .ui.signup.view.SignupActivity is not a @module
@dagger.android.ContributesAndroidInjector(modules = {.ui.signup.view.SignupActivity.class})
^
5issue
6issue
7issue
8issue
1issue
2issue
3issue
4issue
code is in png images also

How to call onFragmentAttached

I have an activity and as soon as it starts I want to add a frament, how to call the onFragmentAttached method
Thank you

MVP Plugin

I clone this app, and I'd like to create a new class by this structure, is there any plugin to create it easily.

Thanks.
Screen Shot 2020-09-17 at 13 51 23

How to pass addQueryParameter dynamically to API from View/MVPView class?

Hi,

I'm new in Android and started to learn Kotlin directly but knows OOPs concept very well. I love your MVP architecture, you managed all code very well. I was started one fresh android application and using your MVP structure but I don't know how to pass query string parameter using your code.

One of my API looks like this:
http://www.example.com/Product/GetProducts?searchBy={searchBy}&categoryIds={categoryIds}

I need to pass {searchBy} and {categoryIds} tokens from View class.

Can you please let me know how to do that? It would be very helpful.

Thanks,
K

ApiHeader token refresh

I use your architecture. I need to update my access token in api header. How can I do that?

CalledFromWrongThreadException

hi @amitshekhariitbhu i got exception
the effect of this exception is list on the recyclerview difficult to show, i must open close app again and again for showing list

Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
        at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7271)
        at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1127)
        at android.view.View.requestLayout(View.java:19902)
        at android.view.View.requestLayout(View.java:19902)
        at android.view.View.requestLayout(View.java:19902)
        at android.view.View.requestLayout(View.java:19902)
        at android.view.View.requestLayout(View.java:19902)
        at android.view.View.requestLayout(View.java:19902)
        at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
        at android.view.View.requestLayout(View.java:19902)
        at android.view.View.requestLayout(View.java:19902)
        at android.view.View.requestLayout(View.java:19902)
        at android.support.v7.widget.RecyclerView.requestLayout(RecyclerView.java:4090)
        at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:5182)
        at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:11785)
        at android.support.v7.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:6961)
        at id.co.next_innovation.okfood.ui.home.view.group_menu.GroupMenuAdapter.addGroupMenuToList$app_debug(GroupMenuAdapter.kt:34)
        at id.co.next_innovation.okfood.ui.home.view.HomeActivity.showGroupMenu(HomeActivity.kt:94)
        at id.co.next_innovation.okfood.ui.home.presenter.HomePresenter$onViewPrepared$$inlined$let$lambda$1.accept(HomePresenter.kt:31)
        at id.co.next_innovation.okfood.ui.home.presenter.HomePresenter$onViewPrepared$$inlined$let$lambda$1.accept(HomePresenter.kt:17)

here my code

override fun onViewPrepared() {
        getView()?.showProgress()
        interactor?.let {
            it.getGroupMenu()
                    .compose(schedulerProvider.ioToMainObservableScheduler())
                    .subscribe({ groupMenuResponse ->
                        getView()?.let {
                            it.hideProgress()
                            it.showGroupMenu(groupMenuResponse.data)
                        }
                    },  { err -> Timber.e(err) })

            it.getType()
                    .compose(schedulerProvider.ioToMainObservableScheduler())
                    .subscribe({ typeResponse ->
                        getView()?.let {
                            it.showType(typeResponse.data)
                        }
                    })
        }
    }
class GroupMenuAdapter(private val groupMenuList: MutableList<GroupMenu>) : RecyclerView.Adapter<GroupMenuAdapter.GroupMenuViewHolder>() {

    override fun getItemCount() = this.groupMenuList.size

    override fun onBindViewHolder(holder: GroupMenuViewHolder, position: Int) = holder.let {
        it.clear()
        it.onBind(position)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = GroupMenuViewHolder(LayoutInflater.from(parent.context).inflate(
            R.layout.adapter_group_menu, parent, false))


    internal fun addGroupMenuToList(menus: List<GroupMenu>) {
        this.groupMenuList.addAll(menus)
        notifyDataSetChanged()
    }

    inner class GroupMenuViewHolder(view: View) : RecyclerView.ViewHolder(view) {

        fun clear() {
            itemView.group_menu_icon.setImageDrawable(null)
            itemView.group_menu_name.text = ""
        }

        fun onBind(position: Int) {

            val (id, name, icon) = groupMenuList[position]

            inflateData(id, name, icon)
            //setItemClickListener(blogUrl)
        }

        private fun inflateData(id: Int?, name: String?, icon: String?) {
            name?.let { itemView.group_menu_name.text = it }
            icon?.let {
                itemView.group_menu_icon.loadImage(it)
            }
        }
    }


}
    override fun showGroupMenu(groupMenus: DataGroupMenu?) = groupMenus?.let {
        groupMenuAdapter.addGroupMenuToList(it.groupMenu)
    }

Internet permissions

Hi,

Tell me please, how it is possible to use internet inside this application if the AndroidManifest.xml file doesn't contain <users-permission for internet ?

Missing a file .

Where is the DaggerAppComponent file?

DaggerAppComponent.builder()
.application(this)
.build()
.inject(this)

apiHeader not updated after login

Hi, I am using your architecture
I got some error when user success login, I save the token from response and use it as header
I've already save it to preference but the apiHeaders.token not updated it and still null

Here my login presenter
`override fun doLogin(nrp: String, password: String) {
interactor?.let {
compositeDisposable.add(
it.doLogin(LoginRequest.ServerLoginRequest(username = nrp, password = password))
.compose(schedulerProvider.ioToMainObservableScheduler())
.subscribe({res ->
getView()?.let {v ->
v.loginSuccess()
}

                    interactor?.setToken("${res.tokenType} ${res.accessToken}").let {
                        loadUserInfo()
                    }

                }, {err ->
                    val anError = err as ANError
                    if (anError.errorCode == 401) {
                        getView()?.loginFailure("NRP atau password tidak sesuai")
                    }
                })
        )
    }
}

override fun loadUserInfo() {
    interactor?.let {
        compositeDisposable.add(
            it.loadUser()
                .compose(schedulerProvider.ioToMainObservableScheduler())
                .subscribe ({d ->
                    interactor?.setUserInfo(d.data)
                    getView()?.userInfoSuccess()
                }, {err ->

                })
        )
    }
}`

LoginInteractor
`override fun doLogin(request: LoginRequest.ServerLoginRequest): Observable = apiHelper.performServerLogin(request)

override fun loadUser(): Observable<DataUserResponse> = apiHelper.performInfoUser()

override fun sendToken(request: LoginRequest.UpdateFcmRequest): Observable<DefaultResponse> = apiHelper.performUpdateFcm(request)

override fun setToken(token: String) {
    preferenceHelper.setToken(token)
}`

AppModule.kt
@Provides @Singleton internal fun provideProtectedApiHeader(@AcceptHeader accept: String, preferenceHelper: PreferenceHelper) : ApiHeader.ProtectedApiHeader = ApiHeader.ProtectedApiHeader(accept = accept, token = preferenceHelper.getToken())

thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.