├── domain ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ └── strings.xml │ │ ├── drawable-hdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ │ └── ic_launcher.png │ │ └── drawable-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── amulyakhare │ │ └── domain │ │ ├── interactor │ │ ├── GetBookListUseCase.java │ │ ├── DownloadBookUseCase.java │ │ ├── GetBookDetailUseCase.java │ │ └── impl │ │ │ ├── GetBookDetailUseCaseImpl.java │ │ │ ├── GetBookListUseCaseImpl.java │ │ │ └── DownloadBookUseCaseImpl.java │ │ ├── repository │ │ └── BookRepository.java │ │ └── model │ │ └── Book.java ├── proguard-rules.pro ├── build.gradle └── domain.iml ├── ui ├── .gitignore ├── src │ ├── androidTest │ │ ├── resources │ │ │ └── org.robolectric.Config.properties │ │ └── java │ │ │ └── com │ │ │ └── amulyakhare │ │ │ └── bookstore │ │ │ └── test │ │ │ └── book │ │ │ └── BookListActivityTest.java │ └── main │ │ ├── res │ │ ├── drawable-hdpi │ │ │ ├── book1.jpg │ │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── values │ │ │ ├── styles.xml │ │ │ ├── dimens.xml │ │ │ └── strings.xml │ │ ├── values-w820dp │ │ │ └── dimens.xml │ │ ├── layout │ │ │ ├── activity_home.xml │ │ │ ├── book_list_item_layout.xml │ │ │ └── activity_book_detail.xml │ │ └── menu │ │ │ ├── menu_home.xml │ │ │ └── menu_book_detail.xml │ │ ├── java │ │ └── com │ │ │ └── amulyakhare │ │ │ └── bookstore │ │ │ └── ui │ │ │ ├── book │ │ │ ├── detail │ │ │ │ ├── IBookDetailView.java │ │ │ │ ├── BookDetailActivity.java │ │ │ │ └── BookDetailPresenter.java │ │ │ └── list │ │ │ │ ├── IBookListView.java │ │ │ │ ├── BookListItemView.java │ │ │ │ ├── BookListPresenter.java │ │ │ │ └── BookListActivity.java │ │ │ ├── application │ │ │ ├── IPresenter.java │ │ │ ├── BookStoreApplication.java │ │ │ ├── BookStoreBaseActivity.java │ │ │ └── BookStoreModule.java │ │ │ ├── navigation │ │ │ └── Navigator.java │ │ │ └── model │ │ │ ├── mapper │ │ │ └── BookModelMapper.java │ │ │ └── BookModel.java │ │ └── AndroidManifest.xml ├── proguard-rules.pro ├── build.gradle └── ui.iml ├── framework ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ └── strings.xml │ │ ├── drawable-hdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ │ └── ic_launcher.png │ │ └── drawable-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── amulyakhare │ │ └── framework │ │ └── data │ │ └── BookDataRepository.java ├── proguard-rules.pro ├── build.gradle └── framework.iml ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── README.md ├── .gitignore ├── BookStore.iml ├── gradle.properties ├── gradlew.bat └── gradlew /domain/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /ui/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /framework/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':ui', ':domain', ':framework' 2 | -------------------------------------------------------------------------------- /domain/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | domain 3 | 4 | -------------------------------------------------------------------------------- /framework/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | framework 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ui/src/androidTest/resources/org.robolectric.Config.properties: -------------------------------------------------------------------------------- 1 | # Robolectric doesn't know how to support SDK 19 yet. 2 | emulateSdk=18 3 | reportSdk=18 -------------------------------------------------------------------------------- /ui/src/main/res/drawable-hdpi/book1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/ui/src/main/res/drawable-hdpi/book1.jpg -------------------------------------------------------------------------------- /ui/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/ui/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /ui/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/ui/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /ui/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/ui/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ui/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/ui/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /domain/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/domain/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /domain/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/domain/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /domain/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/domain/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /domain/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/domain/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /framework/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/framework/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /framework/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/framework/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /framework/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/framework/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /framework/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amulyakhare/Android-Clean-Architecture-BookStore/HEAD/framework/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /domain/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ui/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ui/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 10 15:27:10 PDT 2013 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-all.zip 7 | -------------------------------------------------------------------------------- /domain/src/main/java/com/amulyakhare/domain/interactor/GetBookListUseCase.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.domain.interactor; 2 | 3 | /** 4 | * @author amulya 5 | * @datetime 16 Nov 2014, 3:34 PM 6 | */ 7 | public interface GetBookListUseCase { 8 | 9 | public void execute(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /domain/src/main/java/com/amulyakhare/domain/interactor/DownloadBookUseCase.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.domain.interactor; 2 | 3 | /** 4 | * @author amulya 5 | * @datetime 16 Nov 2014, 5:00 PM 6 | */ 7 | public interface DownloadBookUseCase { 8 | 9 | public void execute(String url); 10 | } 11 | -------------------------------------------------------------------------------- /domain/src/main/java/com/amulyakhare/domain/interactor/GetBookDetailUseCase.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.domain.interactor; 2 | 3 | /** 4 | * @author amulya 5 | * @datetime 16 Nov 2014, 4:51 PM 6 | */ 7 | public interface GetBookDetailUseCase { 8 | 9 | public void execute(int id); 10 | } 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A sample android application built based on principles of Uncle Bob's Clean Architecture as described [here](http://vimeo.com/43612849). Some of the code inspiration comes from this [awesome article](http://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/) and [github repo](https://github.com/android10/Android-CleanArchitecture). 2 | 3 | WORK IN PROGRESS! 4 | -------------------------------------------------------------------------------- /framework/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/book/detail/IBookDetailView.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.book.detail; 2 | 3 | import com.amulyakhare.bookstore.ui.model.BookModel; 4 | 5 | /** 6 | * @author amulya 7 | * @datetime 16 Nov 2014, 4:45 PM 8 | */ 9 | public interface IBookDetailView { 10 | 11 | public void renderBookDetail(BookModel bookDetailModel); 12 | } 13 | -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/application/IPresenter.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.application; 2 | 3 | /** 4 | * @author amulya 5 | * @datetime 16 Nov 2014, 3:17 PM 6 | */ 7 | public interface IPresenter { 8 | 9 | public void onInit(); 10 | 11 | public void onResume(); 12 | 13 | public void onPause(); 14 | 15 | public void onDestroy(); 16 | } 17 | -------------------------------------------------------------------------------- /ui/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AppStore 5 | Books 6 | Hello world! 7 | Settings 8 | Details 9 | 10 | 11 | -------------------------------------------------------------------------------- /ui/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /domain/src/main/java/com/amulyakhare/domain/repository/BookRepository.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.domain.repository; 2 | 3 | import com.amulyakhare.domain.model.Book; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author amulya 9 | * @datetime 16 Nov 2014, 3:46 PM 10 | */ 11 | public interface BookRepository { 12 | 13 | public List getBookList(); 14 | 15 | public Book getBook(int id); 16 | } 17 | -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/book/list/IBookListView.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.book.list; 2 | 3 | import com.amulyakhare.bookstore.ui.model.BookModel; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author amulya 9 | * @datetime 16 Nov 2014, 3:22 PM 10 | */ 11 | public interface IBookListView { 12 | 13 | public void renderBookList(List bookItemModelList); 14 | } 15 | -------------------------------------------------------------------------------- /ui/src/main/res/layout/activity_home.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /ui/src/main/res/menu/menu_home.xml: -------------------------------------------------------------------------------- 1 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /ui/src/main/res/menu/menu_book_detail.xml: -------------------------------------------------------------------------------- 1 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Windows thumbnail db 19 | Thumbs.db 20 | 21 | # OSX files 22 | .DS_Store 23 | 24 | # Eclipse project files 25 | .classpath 26 | .project 27 | 28 | # Android Studio 29 | .idea 30 | #.idea/workspace.xml - remove # and delete .idea if it better suit your needs. 31 | .gradle 32 | build/ -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/navigation/Navigator.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.navigation; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | 6 | import com.amulyakhare.bookstore.ui.book.detail.BookDetailActivity_; 7 | 8 | /** 9 | * @author amulya 10 | * @datetime 16 Nov 2014, 5:22 PM 11 | */ 12 | public class Navigator { 13 | 14 | public static final String BOOK_ID = "BOOK_ID"; 15 | 16 | public void navigateToDetail(Context context, int bookId) { 17 | Intent intent = new Intent(context, BookDetailActivity_.class); 18 | intent.putExtra(BOOK_ID, bookId); 19 | context.startActivity(intent); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /domain/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/gardev/android/adt-bundle-linux/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /ui/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/gardev/android/adt-bundle-linux/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /framework/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/gardev/android/adt-bundle-linux/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /framework/src/main/java/com/amulyakhare/framework/data/BookDataRepository.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.framework.data; 2 | 3 | import com.amulyakhare.domain.model.Book; 4 | import com.amulyakhare.domain.repository.BookRepository; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author amulya 11 | * @datetime 16 Nov 2014, 3:53 PM 12 | */ 13 | public class BookDataRepository implements BookRepository { 14 | 15 | @Override 16 | public List getBookList() { 17 | List bookList = new ArrayList(); 18 | for (int i = 0; i < 3; i++) { 19 | bookList.add(new Book()); 20 | } 21 | return bookList; 22 | } 23 | 24 | @Override 25 | public Book getBook(int id) { 26 | return new Book(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /BookStore.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/application/BookStoreApplication.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.application; 2 | 3 | import android.app.Application; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | import dagger.ObjectGraph; 9 | 10 | /** 11 | * @author amulya 12 | * @datetime 16 Nov 2014, 3:58 PM 13 | */ 14 | public class BookStoreApplication extends Application { 15 | 16 | private ObjectGraph graph; 17 | 18 | @Override 19 | public void onCreate() { 20 | super.onCreate(); 21 | graph = ObjectGraph.create(getModules().toArray()); 22 | } 23 | 24 | protected List getModules() { 25 | return Arrays.asList( 26 | (Object) new BookStoreModule(this) 27 | ); 28 | } 29 | 30 | public void updateGraph(ObjectGraph graph) { 31 | this.graph = graph; 32 | } 33 | 34 | public void inject(Object object) { 35 | graph.inject(object); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ui/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/model/mapper/BookModelMapper.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.model.mapper; 2 | 3 | import com.amulyakhare.bookstore.R; 4 | import com.amulyakhare.bookstore.ui.model.BookModel; 5 | import com.amulyakhare.domain.model.Book; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * @author amulya 12 | * @datetime 16 Nov 2014, 3:13 PM 13 | */ 14 | public class BookModelMapper { 15 | 16 | public List transform(List bookList) { 17 | List modelList = new ArrayList(); 18 | if (bookList != null) { 19 | for (Book book : bookList) { 20 | modelList.add(transform(book)); 21 | } 22 | } 23 | return modelList; 24 | } 25 | 26 | public BookModel transform(Book book) { 27 | return new BookModel( 28 | book.getId(), 29 | R.drawable.book1, 30 | book.getTitle(), 31 | book.getAuthor(), 32 | book.getDetail(), 33 | book.getDownloadUrl() 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /domain/src/main/java/com/amulyakhare/domain/interactor/impl/GetBookDetailUseCaseImpl.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.domain.interactor.impl; 2 | 3 | import com.amulyakhare.domain.interactor.GetBookDetailUseCase; 4 | import com.amulyakhare.domain.model.Book; 5 | import com.amulyakhare.domain.repository.BookRepository; 6 | 7 | import javax.inject.Inject; 8 | 9 | import de.greenrobot.event.EventBus; 10 | 11 | /** 12 | * @author amulya 13 | * @datetime 16 Nov 2014, 4:51 PM 14 | */ 15 | public class GetBookDetailUseCaseImpl implements GetBookDetailUseCase { 16 | 17 | private BookRepository bookRepository; 18 | 19 | private EventBus eventBus; 20 | 21 | @Inject 22 | public GetBookDetailUseCaseImpl(BookRepository bookRepository, EventBus eventBus) { 23 | this.bookRepository = bookRepository; 24 | this.eventBus = eventBus; 25 | } 26 | 27 | @Override 28 | public void execute(int id) { 29 | Book book = bookRepository.getBook(id); 30 | GetBookDetailEvent event = new GetBookDetailEvent(); 31 | event.book = book; 32 | eventBus.post(event); 33 | } 34 | 35 | public static class GetBookDetailEvent { 36 | public Book book; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/model/BookModel.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.model; 2 | 3 | /** 4 | * @author amulya 5 | * @datetime 16 Nov 2014, 3:13 PM 6 | */ 7 | public class BookModel { 8 | 9 | private int id; 10 | 11 | private int icon; 12 | 13 | private String title; 14 | 15 | private String author; 16 | 17 | private String detail; 18 | 19 | private String downloadUrl; 20 | 21 | public BookModel(int id, int icon, String title, String author, String detail, String downloadUrl) { 22 | this.id = id; 23 | this.icon = icon; 24 | this.title = title; 25 | this.author = author; 26 | this.detail = detail; 27 | this.downloadUrl = downloadUrl; 28 | } 29 | 30 | public int getIcon() { 31 | return icon; 32 | } 33 | 34 | public String getTitle() { 35 | return title; 36 | } 37 | 38 | public String getAuthor() { 39 | return author; 40 | } 41 | 42 | public String getDetail() { 43 | return detail; 44 | } 45 | 46 | public String getDownloadUrl() { 47 | return downloadUrl; 48 | } 49 | 50 | public int getId() { 51 | return id; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/book/list/BookListItemView.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.book.list; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.widget.FrameLayout; 6 | import android.widget.ImageView; 7 | import android.widget.TextView; 8 | 9 | import com.amulyakhare.bookstore.R; 10 | import com.amulyakhare.bookstore.ui.model.BookModel; 11 | 12 | import org.androidannotations.annotations.EViewGroup; 13 | import org.androidannotations.annotations.ViewById; 14 | 15 | /** 16 | * @author amulya 17 | * @datetime 16 Nov 2014, 12:50 PM 18 | */ 19 | @EViewGroup(R.layout.book_list_item_layout) 20 | public class BookListItemView extends FrameLayout { 21 | 22 | @ViewById 23 | ImageView bookIcon; 24 | 25 | @ViewById 26 | TextView bookTitle; 27 | 28 | @ViewById 29 | TextView bookAuthor; 30 | 31 | public BookListItemView(Context context) { 32 | super(context); 33 | } 34 | 35 | public View renderBookItem(BookModel bookItemModel) { 36 | bookIcon.setImageResource(bookItemModel.getIcon()); 37 | bookTitle.setText(bookItemModel.getTitle()); 38 | bookAuthor.setText(bookItemModel.getAuthor()); 39 | return this; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ui/src/main/res/layout/book_list_item_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 22 | 23 | 32 | 33 | -------------------------------------------------------------------------------- /domain/src/main/java/com/amulyakhare/domain/interactor/impl/GetBookListUseCaseImpl.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.domain.interactor.impl; 2 | 3 | import com.amulyakhare.domain.interactor.GetBookListUseCase; 4 | import com.amulyakhare.domain.model.Book; 5 | import com.amulyakhare.domain.repository.BookRepository; 6 | 7 | import java.util.List; 8 | 9 | import javax.inject.Inject; 10 | 11 | import de.greenrobot.event.EventBus; 12 | 13 | /** 14 | * @author amulya 15 | * @datetime 16 Nov 2014, 3:35 PM 16 | */ 17 | public class GetBookListUseCaseImpl implements GetBookListUseCase { 18 | 19 | private BookRepository bookRepository; 20 | 21 | private EventBus eventBus; 22 | 23 | @Inject 24 | public GetBookListUseCaseImpl(BookRepository bookRepository, EventBus eventBus) { 25 | this.bookRepository = bookRepository; 26 | this.eventBus = eventBus; 27 | } 28 | 29 | @Override 30 | public void execute() { 31 | List bookList = bookRepository.getBookList(); 32 | GetBookListUseCaseEvent event = new GetBookListUseCaseEvent(); 33 | event.bookList = bookList; 34 | eventBus.post(event); 35 | } 36 | 37 | public static class GetBookListUseCaseEvent { 38 | public List bookList; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/application/BookStoreBaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.application; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.ActionBarActivity; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author amulya 11 | * @datetime 13 Nov 2014, 5:08 PM 12 | */ 13 | public class BookStoreBaseActivity extends ActionBarActivity { 14 | 15 | private List presenterList = new ArrayList(); 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | ((BookStoreApplication) getApplication()).inject(this); 21 | } 22 | 23 | public void registerPresenter(IPresenter presenter) { 24 | presenter.onInit(); 25 | presenterList.add(presenter); 26 | } 27 | 28 | @Override 29 | protected void onPause() { 30 | super.onPause(); 31 | for (IPresenter presenter : presenterList) { 32 | presenter.onPause(); 33 | } 34 | } 35 | 36 | @Override 37 | protected void onResume() { 38 | super.onResume(); 39 | for (IPresenter presenter : presenterList) { 40 | presenter.onResume(); 41 | } 42 | } 43 | 44 | @Override 45 | protected void onDestroy() { 46 | super.onDestroy(); 47 | for (IPresenter presenter : presenterList) { 48 | presenter.onDestroy(); 49 | } 50 | presenterList.clear(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /framework/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'android-apt' 3 | 4 | android { 5 | compileSdkVersion 21 6 | buildToolsVersion "21.1.1" 7 | 8 | defaultConfig { 9 | applicationId "com.amulyakhare.framework" 10 | minSdkVersion 10 11 | targetSdkVersion 21 12 | versionCode 1 13 | versionName "1.0" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | } 22 | 23 | dependencies { 24 | compile fileTree(dir: 'libs', include: ['*.jar']) 25 | compile 'com.android.support:appcompat-v7:21.0.0' 26 | compile 'com.google.code.gson:gson:2.2.4' 27 | compile project(':domain') 28 | // test 29 | androidTestCompile 'org.hamcrest:hamcrest-integration:1.1' 30 | androidTestCompile 'org.hamcrest:hamcrest-core:1.1' 31 | androidTestCompile 'org.hamcrest:hamcrest-library:1.1' 32 | 33 | androidTestCompile('junit:junit:4.+') { 34 | exclude module: 'hamcrest-core' 35 | } 36 | androidTestCompile('org.mockito:mockito-all:1.9.0') 37 | androidTestCompile('org.robolectric:robolectric:2.3') { 38 | exclude module: 'classworlds' 39 | exclude module: 'commons-logging' 40 | exclude module: 'httpclient' 41 | exclude module: 'maven-artifact' 42 | exclude module: 'maven-artifact-manager' 43 | exclude module: 'maven-error-diagnostics' 44 | exclude module: 'maven-model' 45 | exclude module: 'maven-project' 46 | exclude module: 'maven-settings' 47 | exclude module: 'plexus-container-default' 48 | exclude module: 'plexus-interpolation' 49 | exclude module: 'plexus-utils' 50 | exclude module: 'support-v4' 51 | exclude module: 'wagon-file' 52 | exclude module: 'wagon-http-lightweight' 53 | exclude module: 'wagon-provider-api' 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/book/list/BookListPresenter.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.book.list; 2 | 3 | import com.amulyakhare.bookstore.ui.application.IPresenter; 4 | import com.amulyakhare.bookstore.ui.model.BookModel; 5 | import com.amulyakhare.bookstore.ui.model.mapper.BookModelMapper; 6 | import com.amulyakhare.domain.interactor.GetBookListUseCase; 7 | import com.amulyakhare.domain.interactor.impl.GetBookListUseCaseImpl; 8 | 9 | import java.util.List; 10 | 11 | import javax.inject.Inject; 12 | 13 | import de.greenrobot.event.EventBus; 14 | 15 | /** 16 | * @author amulya 17 | * @datetime 16 Nov 2014, 3:15 PM 18 | */ 19 | public class BookListPresenter implements IPresenter { 20 | 21 | private GetBookListUseCase getBookListUseCase; 22 | 23 | private EventBus eventBus; 24 | 25 | private BookModelMapper bookModelMapper; 26 | 27 | private IBookListView bookListView; 28 | 29 | @Override 30 | public void onInit() { 31 | eventBus.register(this); 32 | } 33 | 34 | @Inject 35 | public BookListPresenter(GetBookListUseCase getBookListUseCase, 36 | EventBus eventBus, 37 | BookModelMapper bookModelMapper) { 38 | this.getBookListUseCase = getBookListUseCase; 39 | this.eventBus = eventBus; 40 | this.bookModelMapper = bookModelMapper; 41 | } 42 | 43 | public void setView(IBookListView bookListView) { 44 | this.bookListView = bookListView; 45 | } 46 | 47 | @Override 48 | public void onResume() { 49 | 50 | } 51 | 52 | public void showBookList() { 53 | getBookListUseCase.execute(); 54 | } 55 | 56 | public void onEvent(GetBookListUseCaseImpl.GetBookListUseCaseEvent event) { 57 | List modelList = bookModelMapper.transform(event.bookList); 58 | bookListView.renderBookList(modelList); 59 | } 60 | 61 | @Override 62 | public void onPause() { 63 | 64 | } 65 | 66 | @Override 67 | public void onDestroy() { 68 | eventBus.unregister(this); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /domain/src/main/java/com/amulyakhare/domain/model/Book.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.domain.model; 2 | 3 | /** 4 | * @author amulya 5 | * @datetime 16 Nov 2014, 3:39 PM 6 | */ 7 | public class Book { 8 | 9 | private int id; 10 | private String title; 11 | private String author; 12 | private String downloadUrl; 13 | private String detail; 14 | 15 | public Book() { 16 | this.id = 1; 17 | this.title = "The Jungle Book"; 18 | this.author = "Rudyard Kipling"; 19 | this.downloadUrl = "http://www.google.com"; 20 | this.detail = "The Jungle Book (1894) is a collection of stories by English author Rudyard Kipling. The stories were first published in magazines in 1893–94. The original publications contain illustrations, some by Rudyard's father, John Lockwood Kipling. Kipling was born in India and spent the first six years of his childhood there. After about ten years in England, he went back to India and worked there for about six-and-a-half years. These stories were written when Kipling lived in Vermont. There is evidence that it was written for his daughter Josephine, who died in 1899 aged six, after a rare first edition of the book with a poignant handwritten note by the author to his young daughter was discovered at the National Trust's Wimpole Hall in Cambridgeshire in 2010."; 21 | } 22 | 23 | public int getId() { 24 | return id; 25 | } 26 | 27 | public void setId(int id) { 28 | this.id = id; 29 | } 30 | 31 | public String getTitle() { 32 | return title; 33 | } 34 | 35 | public void setTitle(String title) { 36 | this.title = title; 37 | } 38 | 39 | public String getAuthor() { 40 | return author; 41 | } 42 | 43 | public void setAuthor(String author) { 44 | this.author = author; 45 | } 46 | 47 | public String getDetail() { 48 | return detail; 49 | } 50 | 51 | public String getDownloadUrl() { 52 | return downloadUrl; 53 | } 54 | 55 | public void setDownloadUrl(String downloadUrl) { 56 | this.downloadUrl = downloadUrl; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/book/detail/BookDetailActivity.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.book.detail; 2 | 3 | import android.content.Intent; 4 | import android.widget.Button; 5 | import android.widget.ImageView; 6 | import android.widget.TextView; 7 | 8 | import com.amulyakhare.bookstore.R; 9 | import com.amulyakhare.bookstore.ui.application.BookStoreBaseActivity; 10 | import com.amulyakhare.bookstore.ui.model.BookModel; 11 | import com.amulyakhare.bookstore.ui.navigation.Navigator; 12 | 13 | import org.androidannotations.annotations.AfterViews; 14 | import org.androidannotations.annotations.Click; 15 | import org.androidannotations.annotations.EActivity; 16 | import org.androidannotations.annotations.ViewById; 17 | 18 | import javax.inject.Inject; 19 | 20 | @EActivity(R.layout.activity_book_detail) 21 | public class BookDetailActivity extends BookStoreBaseActivity implements IBookDetailView { 22 | 23 | @ViewById 24 | ImageView bookIcon; 25 | 26 | @ViewById 27 | TextView bookTitle; 28 | 29 | @ViewById 30 | TextView bookAuthor; 31 | 32 | @ViewById 33 | TextView bookDetail; 34 | 35 | @ViewById 36 | Button downloadBtn; 37 | 38 | @Inject 39 | BookDetailPresenter bookDetailPresenter; 40 | 41 | @Click(R.id.download_btn) 42 | void onDownloadClick() { 43 | BookModel model = (BookModel) downloadBtn.getTag(); 44 | bookDetailPresenter.onDownloadClick(model.getDownloadUrl()); 45 | } 46 | 47 | @AfterViews 48 | void onViewInit() { 49 | Intent intent = getIntent(); 50 | int bookId = intent.getIntExtra(Navigator.BOOK_ID, 0); 51 | registerPresenter(bookDetailPresenter); 52 | bookDetailPresenter.setView(this); 53 | bookDetailPresenter.showDetail(bookId); 54 | } 55 | 56 | @Override 57 | public void renderBookDetail(BookModel model) { 58 | bookIcon.setImageResource(model.getIcon()); 59 | bookTitle.setText(model.getTitle()); 60 | bookAuthor.setText(model.getAuthor()); 61 | bookDetail.setText(model.getDetail()); 62 | downloadBtn.setTag(model); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /domain/src/main/java/com/amulyakhare/domain/interactor/impl/DownloadBookUseCaseImpl.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.domain.interactor.impl; 2 | 3 | import com.amulyakhare.domain.interactor.DownloadBookUseCase; 4 | 5 | import de.greenrobot.event.EventBus; 6 | 7 | /** 8 | * @author amulya 9 | * @datetime 16 Nov 2014, 5:00 PM 10 | */ 11 | public class DownloadBookUseCaseImpl implements DownloadBookUseCase { 12 | 13 | private static final int STATUS_IN_PROGRESS = 0; 14 | private static final int STATUS_SUCCESS = 1; 15 | private static final int STATUS_FAILED = 2; 16 | private EventBus eventBus; 17 | 18 | public DownloadBookUseCaseImpl(EventBus eventBus) { 19 | this.eventBus = eventBus; 20 | } 21 | 22 | @Override 23 | public void execute(String url) { 24 | Thread thread = new Thread(new Runnable() { 25 | @Override 26 | public void run() { 27 | for (int i = 0; i < 10; i++) { 28 | try { 29 | Thread.sleep(1500); 30 | } catch (InterruptedException e) { 31 | e.printStackTrace(); 32 | } 33 | DownloadBookEvent event = new DownloadBookEvent(); 34 | event.status = STATUS_IN_PROGRESS; 35 | event.progress = (int) (((i + 1) / 10.0f) * 100); 36 | eventBus.post(event); 37 | } 38 | DownloadBookEvent event = new DownloadBookEvent(); 39 | event.status = STATUS_SUCCESS; 40 | event.progress = 100; 41 | eventBus.post(event); 42 | } 43 | }); 44 | thread.start(); 45 | } 46 | public static class DownloadBookEvent { 47 | public int progress; 48 | private int status; 49 | 50 | public boolean inProgress() { 51 | return (status == STATUS_IN_PROGRESS); 52 | } 53 | 54 | public boolean isSuccess() { 55 | return (status == STATUS_SUCCESS); 56 | } 57 | 58 | public boolean isFailed() { 59 | return (status == STATUS_FAILED); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /domain/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'android-apt' 3 | 4 | android { 5 | compileSdkVersion 21 6 | buildToolsVersion "21.1.1" 7 | 8 | defaultConfig { 9 | applicationId "com.amulyakhare.domain" 10 | minSdkVersion 10 11 | targetSdkVersion 21 12 | versionCode 1 13 | versionName "1.0" 14 | testPackageName 'com.amulyakhare.domain.test' 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | } 23 | 24 | ext.daggerVersion = '1.2.2'; 25 | ext.androidAnnotationsVersion = '3.2'; 26 | 27 | configurations { 28 | apt 29 | } 30 | 31 | dependencies { 32 | apt "org.androidannotations:androidannotations:${androidAnnotationsVersion}" 33 | compile "org.androidannotations:androidannotations-api:${androidAnnotationsVersion}" 34 | apt "com.squareup.dagger:dagger-compiler:${daggerVersion}" 35 | compile "com.squareup.dagger:dagger:${daggerVersion}" 36 | compile 'de.greenrobot:eventbus:2.2.1' 37 | compile fileTree(dir: 'libs', include: ['*.jar']) 38 | 39 | // test 40 | androidTestCompile 'org.hamcrest:hamcrest-integration:1.1' 41 | androidTestCompile 'org.hamcrest:hamcrest-core:1.1' 42 | androidTestCompile 'org.hamcrest:hamcrest-library:1.1' 43 | 44 | androidTestCompile('junit:junit:4.+') { 45 | exclude module: 'hamcrest-core' 46 | } 47 | androidTestCompile('org.mockito:mockito-all:1.9.0') 48 | androidTestCompile('org.robolectric:robolectric:2.3') { 49 | exclude module: 'classworlds' 50 | exclude module: 'commons-logging' 51 | exclude module: 'httpclient' 52 | exclude module: 'maven-artifact' 53 | exclude module: 'maven-artifact-manager' 54 | exclude module: 'maven-error-diagnostics' 55 | exclude module: 'maven-model' 56 | exclude module: 'maven-project' 57 | exclude module: 'maven-settings' 58 | exclude module: 'plexus-container-default' 59 | exclude module: 'plexus-interpolation' 60 | exclude module: 'plexus-utils' 61 | exclude module: 'support-v4' 62 | exclude module: 'wagon-file' 63 | exclude module: 'wagon-http-lightweight' 64 | exclude module: 'wagon-provider-api' 65 | } 66 | androidTestCompile "com.squareup.dagger:dagger-compiler:${daggerVersion}" 67 | compile 'com.android.support:appcompat-v7:21.0.0' 68 | } -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/book/detail/BookDetailPresenter.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.book.detail; 2 | 3 | import com.amulyakhare.bookstore.ui.application.IPresenter; 4 | import com.amulyakhare.bookstore.ui.model.BookModel; 5 | import com.amulyakhare.bookstore.ui.model.mapper.BookModelMapper; 6 | import com.amulyakhare.domain.interactor.DownloadBookUseCase; 7 | import com.amulyakhare.domain.interactor.impl.DownloadBookUseCaseImpl; 8 | import com.amulyakhare.domain.interactor.GetBookDetailUseCase; 9 | import com.amulyakhare.domain.interactor.impl.GetBookDetailUseCaseImpl; 10 | 11 | import javax.inject.Inject; 12 | 13 | import de.greenrobot.event.EventBus; 14 | 15 | /** 16 | * @author amulya 17 | * @datetime 16 Nov 2014, 4:46 PM 18 | */ 19 | public class BookDetailPresenter implements IPresenter { 20 | 21 | private IBookDetailView bookDetailView; 22 | 23 | private EventBus eventBus; 24 | 25 | private BookModelMapper bookModelMapper; 26 | 27 | private GetBookDetailUseCase getBookDetailUseCase; 28 | 29 | private DownloadBookUseCase downloadBookUseCase; 30 | 31 | @Inject 32 | public BookDetailPresenter(EventBus eventBus, 33 | BookModelMapper bookModelMapper, 34 | GetBookDetailUseCase getBookDetailUseCase, 35 | DownloadBookUseCase downloadBookUseCase) { 36 | this.eventBus = eventBus; 37 | this.bookModelMapper = bookModelMapper; 38 | this.getBookDetailUseCase = getBookDetailUseCase; 39 | this.downloadBookUseCase = downloadBookUseCase; 40 | } 41 | 42 | @Override 43 | public void onInit() { 44 | eventBus.register(this); 45 | } 46 | 47 | @Override 48 | public void onResume() { 49 | 50 | } 51 | 52 | public void setView(IBookDetailView bookDetailView) { 53 | this.bookDetailView = bookDetailView; 54 | } 55 | 56 | public void showDetail(int bookId) { 57 | getBookDetailUseCase.execute(bookId); 58 | } 59 | 60 | public void onDownloadClick(String url) { 61 | downloadBookUseCase.execute(url); 62 | } 63 | 64 | public void onEvent(GetBookDetailUseCaseImpl.GetBookDetailEvent event) { 65 | BookModel model = bookModelMapper.transform(event.book); 66 | bookDetailView.renderBookDetail(model); 67 | } 68 | 69 | public void onEventMainThread(DownloadBookUseCaseImpl.DownloadBookEvent event) { 70 | if (event.inProgress()) { 71 | 72 | } 73 | else if (event.isSuccess()) { 74 | 75 | } 76 | else if (event.isFailed()) { 77 | 78 | } 79 | } 80 | 81 | @Override 82 | public void onPause() { 83 | 84 | } 85 | 86 | @Override 87 | public void onDestroy() { 88 | eventBus.unregister(this); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /ui/src/main/java/com/amulyakhare/bookstore/ui/book/list/BookListActivity.java: -------------------------------------------------------------------------------- 1 | package com.amulyakhare.bookstore.ui.book.list; 2 | 3 | import android.view.View; 4 | import android.view.ViewGroup; 5 | import android.widget.BaseAdapter; 6 | import android.widget.ListView; 7 | 8 | import com.amulyakhare.bookstore.R; 9 | import com.amulyakhare.bookstore.ui.application.BookStoreBaseActivity; 10 | import com.amulyakhare.bookstore.ui.model.BookModel; 11 | import com.amulyakhare.bookstore.ui.navigation.Navigator; 12 | 13 | import org.androidannotations.annotations.AfterViews; 14 | import org.androidannotations.annotations.EActivity; 15 | import org.androidannotations.annotations.ItemClick; 16 | import org.androidannotations.annotations.ViewById; 17 | 18 | import java.util.List; 19 | 20 | import javax.inject.Inject; 21 | 22 | @EActivity(R.layout.activity_home) 23 | public class BookListActivity extends BookStoreBaseActivity implements IBookListView { 24 | 25 | @ViewById 26 | ListView bookList; 27 | 28 | @Inject 29 | BookListPresenter bookListPresenter; 30 | 31 | @Inject 32 | Navigator navigator; 33 | 34 | BookListAdapter bookListAdapter; 35 | 36 | @AfterViews 37 | void onViewInit() { 38 | registerPresenter(bookListPresenter); 39 | bookListPresenter.setView(this); 40 | bookListPresenter.showBookList(); 41 | } 42 | 43 | @ItemClick(R.id.book_list) 44 | void onBookItemClick(BookModel bookItemModel) { 45 | navigator.navigateToDetail(this, bookItemModel.getId()); 46 | } 47 | 48 | @Override 49 | public void renderBookList(List bookItemModelList) { 50 | if (bookListAdapter == null) { 51 | bookListAdapter = new BookListAdapter(); 52 | bookListAdapter.setData(bookItemModelList); 53 | bookList.setAdapter(bookListAdapter); 54 | } else { 55 | bookListAdapter.setData(bookItemModelList); 56 | bookListAdapter.notifyDataSetChanged(); 57 | } 58 | } 59 | 60 | private static class BookListAdapter extends BaseAdapter { 61 | 62 | private List itemList; 63 | 64 | public void setData(List itemList) { 65 | this.itemList = itemList; 66 | } 67 | 68 | @Override 69 | public int getCount() { 70 | return itemList.size(); 71 | } 72 | 73 | @Override 74 | public BookModel getItem(int position) { 75 | return itemList.get(position); 76 | } 77 | 78 | @Override 79 | public long getItemId(int position) { 80 | return position; 81 | } 82 | 83 | @Override 84 | public View getView(int position, View view, ViewGroup parent) { 85 | BookListItemView itemView = (BookListItemView) view; 86 | if (itemView == null) { 87 | itemView = BookListItemView_.build(parent.getContext()); 88 | } 89 | return itemView.renderBookItem(getItem(position)); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ui/src/main/res/layout/activity_book_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 15 | 16 | 22 | 23 | 32 | 33 | 43 | 44 | 45 | 46 | 53 | 54 |