Git Product home page Git Product logo

bookshelf-app's Introduction

Bookshelf-App

See on Google Play

This is a sample app which I used some features.

Eg1 Eg2 Eg3 Eg4

Activity Transition Multi Select
Activity Transition Multi Select

Features

  1. MVP Design Pattern
  2. Room Database
  3. Dagger2
  4. RxJava
  5. Shared Element Activity Transition
  6. Circular Reveal Animation
  7. Multi Select With Recycler View

MVP Design Pattern

MVP was used as design pattern in this app. You can see the sample usage below.

   interface SplashActivityContract {

    interface View {

        fun finishActivity()

        fun showErrorMessage()

    }

    interface Presenter {

        fun setView(view: View)

        fun created()
    }
    
    class SplashActivityPresenter @Inject constructor() : SplashActivityContract.Presenter 
    .
    .
    .
    
    class SplashActivity : AppCompatActivity(), SplashActivityContract.View 
    .
    .
    .
}

Room Database

Room Database was used as local database in this app. You can see the sample usage below.

//Sample Entity (Table) class
@Entity(tableName = DatabaseKeys.CATEGORIES)
data class CategoryTable(

    @ColumnInfo(name = DatabaseKeys.CATEGORY_NAME)
    var name: String

) : Serializable {

    @PrimaryKey(autoGenerate = true)
    var categoryId: Int?= null

}

//Sample Dao class
@Dao
interface CategoryDao {

    @Query(DatabaseQueries.GET_ALL_CATEGORIES)
    fun getAllCategories(): Single<List<CategoryTable>>

    @Query(DatabaseQueries.GET_CATEGORY_COUNT)
    fun getCategoryCount(): Single<Int>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(categoryTable: CategoryTable): Single<Long>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertAll(categoryTableList: List<CategoryTable>)

    @Update
    fun update(categoryTable: CategoryTable)

    @Delete
    fun delete(categoryTable: CategoryTable)

    @Delete
    fun deleteAll(categoryTableList: List<CategoryTable>): Completable

    @Query(DatabaseQueries.DELETE_ALL_CATEGORIES)
    fun deleteAll()

}

//Sample Database Class
@Database(entities = [CategoryTable::class, BookTable::class, CategoryBookJoinTable::class], 
          version = 1)
abstract class AppRoomDatabase : RoomDatabase() {

    abstract fun categoryDao(): CategoryDao

    abstract fun bookDao(): BookDao

    abstract fun categoryBookJoinDao(): CategoryBookJoinDao
}

//Sample code to build database
Room.databaseBuilder(
            context,
            AppRoomDatabase::class.java,
            DatabaseKeys.DATABASE_NAME
        ).build()

Dagger2

Dagger2 was used for dependency injection in this app. You can see the sample usage below.

@Module
class AppModule(context: Context) {

    private var mContext = context

    @Provides
    fun provideContext(): Context {
        return this.mContext
    }

}

@Module
class AppRoomDatabaseModule {

    @Provides
    fun provideAppRoomDatabase(context: Context): AppRoomDatabase {
        return Room.databaseBuilder(
            context,
            AppRoomDatabase::class.java,
            DatabaseKeys.DATABASE_NAME
        ).build()
    }
}

@Singleton
@Component(
    modules = [
        (AppModule::class),
        (AppRoomDatabaseModule::class)]
)
interface SplashActivityComponent {

    fun inject(activity: SplashActivity)

}

//Splash Activity onCreate

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)

        DaggerSplashActivityComponent.builder()
            .appModule(AppModule(this))
            .appRoomDatabaseModule(AppRoomDatabaseModule())
            .build()
            .inject(this)
           
    }

RxJava

RxJava was used as reactive programming approach in this app. You can see the sample usage below.

class CategoryDataManagement(
    categoryDao: CategoryDao
    )  {


    private val mCategoryDao = categoryDao
 
    fun getAllICategoriesFromDB(): Single<List<CategoryTable>> {
        return mCategoryDao.getAllCategories()
    }

    fun getCategoryCountFromDB(): Single<Int> {
        return mCategoryDao.getCategoryCount()
    }

    fun getAllCategoriesFromFile(): ArrayList<CategoryTable>? {

        this.mCategoryFileManager.loadStringCategoryNameArrayFromAsset()?.let {
            return this.mCategoryTypeConverter.getConvertedCategoryListFromJsonArray(it)
        }
        return null
    }

    fun <T> insertAll(itemList: List<T>): Completable? {
        return Completable.fromAction {
            mCategoryDao.insertAll(itemList as List<CategoryTable>)
        }
    }

    fun deleteAll(): Completable? {
        return Completable.fromAction {
            mCategoryDao.deleteAll()
        }
    }
}

class SplashActivityPresenter @Inject constructor() : SplashActivityContract.Presenter {

    @Inject
    lateinit var mCategoryDataManagement: CategoryDataManagement

    @SuppressLint("CheckResult")
    override fun created() {

        Handler().postDelayed({
            this.mCategoryDataManagement.getAllCategoriesFromFile()?.let { categoryListFromFile ->

                if (categoryListFromFile.isNotEmpty()) {
                    mCategoryDataManagement.getCategoryCountFromDB()
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe({
                            if (it < categoryListFromFile.size) {
                                mCategoryDataManagement.deleteAll()?.andThen(
                                    mCategoryDataManagement.insertAll(categoryListFromFile)
                                )?.subscribeOn(Schedulers.io())
                                    ?.observeOn(AndroidSchedulers.mainThread())
                                    ?.subscribe({
                                        continueWithMainActivity()

                                    }, {
                                        continueWithError()
                                    })

                            } else {
                                continueWithMainActivity()
                            }

                        }, {
                            continueWithError()
                        })
                } else
                    continueWithError()

            }
        }, 1000)


    }
.
.
.
}

Shared Element Activity Transition

Shared Element Activity Transition was used between Main-Book Activity. You can see the sample usage below.

activity_main.xml

<com.github.clans.fab.FloatingActionButton
                android:id="@+id/fab_add_book"
                android:layout_width="@dimen/fab_size_normal"
                android:layout_height="@dimen/fab_size_normal"
                android:layout_alignParentEnd="true"
                android:layout_alignParentRight="true"
                android:layout_alignParentBottom="true"
                android:layout_marginEnd="@dimen/fab_margin"
                android:layout_marginRight="@dimen/fab_margin"
                android:layout_marginBottom="@dimen/fab_margin"
                android:src="@drawable/ic_add_book"
                android:transitionName="fab"
                app:fab_colorNormal="@color/pigment_green"
                app:fab_colorPressed="@color/pigment_green"
                app:fab_progress_color="@color/spring_green"
                app:fab_showShadow="true"
                tools:ignore="UnusedAttribute"/>

activity_book.xml

<com.github.clans.fab.FloatingActionButton
                android:id="@+id/fab_add_book"
                android:layout_width="@dimen/fab_size_normal"
                android:layout_height="@dimen/fab_size_normal"
                android:layout_alignParentEnd="true"
                android:layout_alignParentRight="true"
                android:layout_alignParentBottom="true"
                android:layout_marginEnd="@dimen/fab_margin"
                android:layout_marginRight="@dimen/fab_margin"
                android:layout_marginBottom="@dimen/fab_margin"
                android:src="@drawable/ic_add_book"
                android:transitionName="fab"
                app:fab_colorNormal="@color/pigment_green"
                app:fab_colorPressed="@color/pigment_green"
                app:fab_progress_color="@color/spring_green"
                app:fab_showShadow="true"
                tools:ignore="UnusedAttribute"/>

Intent

fun intentBookActivity(view: FloatingActionButton) {
        val intent = Intent(mActivity, BookActivity::class.java)
        var options: ActivityOptions? = null
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            options = ActivityOptions.makeSceneTransitionAnimation(
                    mActivity,
                    android.util.Pair.create<View, String>(view, "fab")
            )
        }

        mActivity.startActivityForResult(intent, options?.toBundle())
    }

Circular Reveal Animation

Circular Reveal Animation was used in Book Activity on float action button and main view. You can see the sample usage below.

fun createCircularRevealAnimation(
       view: View, centerX: Int, centerY: Int, startRadius: Float,
       finalRadius: Float, duration: Int?, animationCallback: AnimationCallback
   ) {
       var anim: Animator? = null
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
           anim = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, finalRadius)
       }

       anim?.addListener(object : AnimatorListenerAdapter() {
           override fun onAnimationEnd(animation: Animator?) {
               super.onAnimationEnd(animation)
               animationCallback.onAnimationEnd(animation)
           }
       })
       duration?.let {
           anim?.duration = it.toLong()
       }

       anim?.start()

   }
Activity Transition
Activity Transition

Multi Select With Recycler View

Multi Select With Recycler View was used for deleting multi book process. You can see the sample gif below.

Multi Select
Multi Select

bookshelf-app's People

Contributors

ismailgungor avatar

Watchers

James Cloos avatar Mehmet Ergül avatar

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.