├── settings.gradle
├── .idea
└── copyright
│ └── profiles_settings.xml
├── app
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values-land
│ │ │ │ └── dimens.xml
│ │ │ ├── values-sw600dp-land
│ │ │ │ └── dimens.xml
│ │ │ ├── drawable
│ │ │ │ ├── sad_astronaut.png
│ │ │ │ ├── selector_circle_default.xml
│ │ │ │ └── selector_default.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── drawable-xhdpi
│ │ │ │ ├── drawer_shadow.9.png
│ │ │ │ ├── ic_info_white_24dp.png
│ │ │ │ ├── ic_star_white_24dp.png
│ │ │ │ ├── ic_favorite_white_24dp.png
│ │ │ │ ├── ic_settings_white_24dp.png
│ │ │ │ ├── ic_arrow_back_white_24dp.png
│ │ │ │ ├── ic_filter_list_white_24dp.png
│ │ │ │ ├── ic_fullscreen_white_24dp.png
│ │ │ │ ├── ic_more_vert_white_24dp.png
│ │ │ │ ├── ic_arrow_drop_up_white_18dp.png
│ │ │ │ ├── ic_arrow_drop_down_white_18dp.png
│ │ │ │ ├── ic_favorite_outline_white_24dp.png
│ │ │ │ ├── ic_keyboard_arrow_up_white_24dp.png
│ │ │ │ ├── ic_keyboard_arrow_down_white_24dp.png
│ │ │ │ └── ic_keyboard_arrow_down_white_36dp.png
│ │ │ ├── drawable-hdpi
│ │ │ │ ├── ic_info_white_24dp.png
│ │ │ │ ├── ic_star_white_24dp.png
│ │ │ │ ├── ic_favorite_white_24dp.png
│ │ │ │ ├── ic_more_vert_white_24dp.png
│ │ │ │ ├── ic_settings_white_24dp.png
│ │ │ │ ├── ic_arrow_back_white_24dp.png
│ │ │ │ ├── ic_filter_list_white_24dp.png
│ │ │ │ ├── ic_fullscreen_white_24dp.png
│ │ │ │ ├── ic_arrow_drop_up_white_18dp.png
│ │ │ │ ├── ic_arrow_drop_down_white_18dp.png
│ │ │ │ ├── ic_favorite_outline_white_24dp.png
│ │ │ │ ├── ic_keyboard_arrow_up_white_24dp.png
│ │ │ │ ├── ic_keyboard_arrow_down_white_24dp.png
│ │ │ │ └── ic_keyboard_arrow_down_white_36dp.png
│ │ │ ├── drawable-xxhdpi
│ │ │ │ ├── drawer_shadow.9.png
│ │ │ │ ├── ic_info_white_24dp.png
│ │ │ │ ├── ic_star_white_24dp.png
│ │ │ │ ├── ic_arrow_back_white_24dp.png
│ │ │ │ ├── ic_favorite_white_24dp.png
│ │ │ │ ├── ic_fullscreen_white_24dp.png
│ │ │ │ ├── ic_more_vert_white_24dp.png
│ │ │ │ ├── ic_settings_white_24dp.png
│ │ │ │ ├── ic_filter_list_white_24dp.png
│ │ │ │ ├── ic_arrow_drop_down_white_18dp.png
│ │ │ │ ├── ic_arrow_drop_up_white_18dp.png
│ │ │ │ ├── ic_favorite_outline_white_24dp.png
│ │ │ │ ├── ic_keyboard_arrow_up_white_24dp.png
│ │ │ │ ├── ic_keyboard_arrow_down_white_24dp.png
│ │ │ │ └── ic_keyboard_arrow_down_white_36dp.png
│ │ │ ├── drawable-xxxhdpi
│ │ │ │ ├── ic_info_white_24dp.png
│ │ │ │ ├── ic_star_white_24dp.png
│ │ │ │ ├── ic_favorite_white_24dp.png
│ │ │ │ ├── ic_more_vert_white_24dp.png
│ │ │ │ ├── ic_settings_white_24dp.png
│ │ │ │ ├── ic_arrow_back_white_24dp.png
│ │ │ │ ├── ic_filter_list_white_24dp.png
│ │ │ │ ├── ic_fullscreen_white_24dp.png
│ │ │ │ ├── ic_arrow_drop_up_white_18dp.png
│ │ │ │ ├── ic_arrow_drop_down_white_18dp.png
│ │ │ │ ├── ic_favorite_outline_white_24dp.png
│ │ │ │ ├── ic_keyboard_arrow_down_white_24dp.png
│ │ │ │ ├── ic_keyboard_arrow_down_white_36dp.png
│ │ │ │ └── ic_keyboard_arrow_up_white_24dp.png
│ │ │ ├── anim
│ │ │ │ ├── decelerate_interpolator.xml
│ │ │ │ ├── fade_in_shadow.xml
│ │ │ │ ├── fade_out_shadow.xml
│ │ │ │ ├── slide_in_left.xml
│ │ │ │ ├── slide_out_right.xml
│ │ │ │ ├── fade_in_right.xml
│ │ │ │ ├── fade_out_right.xml
│ │ │ │ └── zoom_in_exit.xml
│ │ │ ├── drawable-v21
│ │ │ │ ├── selector_default.xml
│ │ │ │ └── selector_circle_default.xml
│ │ │ ├── layout
│ │ │ │ ├── item_grid_header.xml
│ │ │ │ ├── toolbar.xml
│ │ │ │ ├── item_tile.xml
│ │ │ │ ├── frag_main.xml
│ │ │ │ ├── act_main.xml
│ │ │ │ └── zero_state_list.xml
│ │ │ ├── values-sw600dp
│ │ │ │ └── dimens.xml
│ │ │ ├── menu
│ │ │ │ └── act_main.xml
│ │ │ ├── values
│ │ │ │ ├── colors.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── attrs.xml
│ │ │ │ ├── styles.xml
│ │ │ │ └── strings.xml
│ │ │ ├── layout-land
│ │ │ │ └── zero_state_list.xml
│ │ │ ├── values-de
│ │ │ │ └── strings.xml
│ │ │ └── values-fr
│ │ │ │ └── strings.xml
│ │ ├── assets
│ │ │ └── fonts
│ │ │ │ ├── Roboto-Bold.ttf
│ │ │ │ ├── Roboto-Thin.ttf
│ │ │ │ ├── Roboto-Black.ttf
│ │ │ │ ├── Roboto-Italic.ttf
│ │ │ │ ├── Roboto-Light.ttf
│ │ │ │ ├── Roboto-Medium.ttf
│ │ │ │ ├── Roboto-Regular.ttf
│ │ │ │ ├── Roboto-BlackItalic.ttf
│ │ │ │ ├── Roboto-BoldItalic.ttf
│ │ │ │ ├── Roboto-LightItalic.ttf
│ │ │ │ ├── Roboto-ThinItalic.ttf
│ │ │ │ ├── Roboto-MediumItalic.ttf
│ │ │ │ ├── RobotoCondensed-Bold.ttf
│ │ │ │ ├── RobotoCondensed-Light.ttf
│ │ │ │ ├── RobotoCondensed-Italic.ttf
│ │ │ │ ├── RobotoCondensed-Regular.ttf
│ │ │ │ ├── RobotoCondensed-BoldItalic.ttf
│ │ │ │ └── RobotoCondensed-LightItalic.ttf
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── derek_s
│ │ │ │ └── hubble_gallery
│ │ │ │ ├── api
│ │ │ │ ├── ApiClient.java
│ │ │ │ ├── GetDetails.java
│ │ │ │ └── GetAlbum.java
│ │ │ │ ├── internal
│ │ │ │ └── di
│ │ │ │ │ ├── ActivityScope.java
│ │ │ │ │ ├── ActivityComponent.java
│ │ │ │ │ ├── AppComponent.java
│ │ │ │ │ └── AppModule.java
│ │ │ │ ├── base
│ │ │ │ ├── Constants.java
│ │ │ │ ├── ActBase.java
│ │ │ │ ├── FragBase.java
│ │ │ │ └── HubbleApplication.java
│ │ │ │ ├── ui
│ │ │ │ ├── widgets
│ │ │ │ │ ├── SquareImageView.java
│ │ │ │ │ ├── StretchyImageView.java
│ │ │ │ │ ├── PopOutCircularProgressDrawable.java
│ │ │ │ │ └── CircleProgressView.java
│ │ │ │ ├── adapters
│ │ │ │ │ ├── OnboardingFragmentPager.java
│ │ │ │ │ ├── RecyclerViewItemClickListener.java
│ │ │ │ │ └── MainGridAdapter.java
│ │ │ │ ├── fragments
│ │ │ │ │ ├── FragWelcomeOutline.java
│ │ │ │ │ └── FragWelcomeInfo.java
│ │ │ │ └── activities
│ │ │ │ │ └── ActWelcome.java
│ │ │ │ └── utils
│ │ │ │ ├── ui
│ │ │ │ ├── IndeterminateAnimator.java
│ │ │ │ ├── Toasty.java
│ │ │ │ ├── ToolbarTitle.java
│ │ │ │ ├── starfield
│ │ │ │ │ ├── Stars.java
│ │ │ │ │ └── StarField.java
│ │ │ │ └── FontFactory.java
│ │ │ │ ├── FavoriteUtils.java
│ │ │ │ ├── network
│ │ │ │ └── NetworkUtil.java
│ │ │ │ ├── ImageUtils.java
│ │ │ │ ├── Animation
│ │ │ │ └── SquareFlipper.java
│ │ │ │ └── svg
│ │ │ │ ├── SvgHelper.java
│ │ │ │ └── SvgView.java
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── derek_s
│ │ │ │ └── hubble_gallery
│ │ │ │ ├── nav_drawer
│ │ │ │ ├── dialog
│ │ │ │ │ ├── DialogAboutListener.kt
│ │ │ │ │ └── DialogAbout.kt
│ │ │ │ ├── model
│ │ │ │ │ ├── SectionObject.kt
│ │ │ │ │ └── SectionChildObject.kt
│ │ │ │ ├── views
│ │ │ │ │ └── NavigationView.kt
│ │ │ │ ├── adapters
│ │ │ │ │ ├── NavigationAdapterItem.kt
│ │ │ │ │ ├── SectionViewHolder.kt
│ │ │ │ │ ├── NavDrawerAdapter.kt
│ │ │ │ │ └── GroupViewHolder.kt
│ │ │ │ └── presenters
│ │ │ │ │ └── NavigationPresenter.kt
│ │ │ │ ├── _shared
│ │ │ │ └── model
│ │ │ │ │ ├── Tiles.kt
│ │ │ │ │ ├── TileObject.kt
│ │ │ │ │ └── DetailsObject.kt
│ │ │ │ ├── detailspage
│ │ │ │ └── DetailsContract.java
│ │ │ │ └── imageviewer
│ │ │ │ └── ImageViewerActivity.java
│ │ ├── res-details
│ │ │ ├── layout
│ │ │ │ ├── act_image_viewer.xml
│ │ │ │ ├── zero_state_details.xml
│ │ │ │ └── act_details.xml
│ │ │ └── menu
│ │ │ │ └── menu_act_details.xml
│ │ ├── res-welcome
│ │ │ └── layout
│ │ │ │ ├── act_welcome.xml
│ │ │ │ ├── frag_welcome_info.xml
│ │ │ │ └── frag_welcome_outline.xml
│ │ ├── res-navigation
│ │ │ └── layout
│ │ │ │ ├── frag_nav_drawer.xml
│ │ │ │ ├── item_section.xml
│ │ │ │ ├── item_group.xml
│ │ │ │ ├── dialog_about.xml
│ │ │ │ └── item_footer_nav_drawer.xml
│ │ └── AndroidManifest.xml
│ ├── debug
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── derek_s
│ │ │ │ └── hubble_gallery
│ │ │ │ └── base
│ │ │ │ └── HubbleApplicationDebug.java
│ │ └── AndroidManifest.xml
│ ├── release
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── derek_s
│ │ │ └── hubble_gallery
│ │ │ └── base
│ │ │ └── HubbleApplicationRelease.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── derek_s
│ │ └── hubble_gallery
│ │ └── ApplicationTest.java
├── .gitignore
├── proguard-rules.pro
└── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── .gitignore
├── README.md
├── gradlew.bat
└── gradlew
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 4
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values-sw600dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 5
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/Roboto-Thin.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/Roboto-Black.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/Roboto-Italic.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/Roboto-Light.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/Roboto-Medium.ttf
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sad_astronaut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable/sad_astronaut.png
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/api/ApiClient.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.api;
2 |
3 |
4 | public class ApiClient {
5 | }
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-BlackItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/Roboto-BlackItalic.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/Roboto-BoldItalic.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/Roboto-LightItalic.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-ThinItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/Roboto-ThinItalic.ttf
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/Roboto-MediumItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/Roboto-MediumItalic.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/RobotoCondensed-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/RobotoCondensed-Bold.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/RobotoCondensed-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/RobotoCondensed-Light.ttf
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/drawer_shadow.9.png
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/RobotoCondensed-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/RobotoCondensed-Italic.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/RobotoCondensed-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/RobotoCondensed-Regular.ttf
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_info_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_info_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_star_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_star_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/drawer_shadow.9.png
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/RobotoCondensed-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/RobotoCondensed-BoldItalic.ttf
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_info_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_info_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_star_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_star_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_info_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_info_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_star_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_star_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_info_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_info_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_star_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_star_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/RobotoCondensed-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/assets/fonts/RobotoCondensed-LightItalic.ttf
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_favorite_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_favorite_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_more_vert_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_more_vert_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_settings_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_settings_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_favorite_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_favorite_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_filter_list_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_filter_list_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_fullscreen_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_fullscreen_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_arrow_back_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_arrow_back_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_filter_list_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_filter_list_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_fullscreen_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_fullscreen_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_more_vert_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_more_vert_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_arrow_back_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_arrow_back_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_favorite_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_favorite_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_fullscreen_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_fullscreen_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_more_vert_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_more_vert_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_settings_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_settings_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_favorite_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_favorite_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_more_vert_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_more_vert_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_settings_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_settings_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_arrow_drop_up_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_arrow_drop_up_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_arrow_drop_up_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_arrow_drop_up_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_filter_list_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_filter_list_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_arrow_back_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_arrow_back_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_filter_list_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_filter_list_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_fullscreen_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_fullscreen_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_arrow_drop_down_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_arrow_drop_down_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_favorite_outline_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_favorite_outline_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_keyboard_arrow_up_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_keyboard_arrow_up_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_arrow_drop_down_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_arrow_drop_down_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_favorite_outline_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_favorite_outline_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_arrow_drop_down_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_arrow_drop_down_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_arrow_drop_up_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_arrow_drop_up_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_arrow_drop_up_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_arrow_drop_up_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_keyboard_arrow_down_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_keyboard_arrow_down_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_keyboard_arrow_down_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-hdpi/ic_keyboard_arrow_down_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_keyboard_arrow_up_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_keyboard_arrow_up_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_favorite_outline_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_favorite_outline_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_keyboard_arrow_up_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_keyboard_arrow_up_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_arrow_drop_down_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_arrow_drop_down_white_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_favorite_outline_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_favorite_outline_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_keyboard_arrow_down_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_keyboard_arrow_down_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_keyboard_arrow_down_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xhdpi/ic_keyboard_arrow_down_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_keyboard_arrow_down_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_keyboard_arrow_down_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_keyboard_arrow_down_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxhdpi/ic_keyboard_arrow_down_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_keyboard_arrow_down_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_keyboard_arrow_down_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_keyboard_arrow_down_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_keyboard_arrow_down_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_keyboard_arrow_up_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/derekcsm/hubble_gallery/master/app/src/main/res/drawable-xxxhdpi/ic_keyboard_arrow_up_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/nav_drawer/dialog/DialogAboutListener.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.nav_drawer.dialog
2 |
3 | interface DialogAboutListener {
4 | fun onShowIntroClicked()
5 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/decelerate_interpolator.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/nav_drawer/model/SectionObject.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.nav_drawer.model;
2 |
3 | class SectionObject : SectionChildObject() {
4 | var isExpandable: Boolean = false
5 | }
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Nov 09 19:12:23 PST 2016
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.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/debug/java/com/derek_s/hubble_gallery/base/HubbleApplicationDebug.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.base;
2 |
3 | public class HubbleApplicationDebug extends HubbleApplication {
4 |
5 | @Override
6 | public void onCreate() {
7 | super.onCreate();
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/internal/di/ActivityScope.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.internal.di;
2 |
3 | import javax.inject.Scope;
4 |
5 | /**
6 | * Objects that should only live on the activity should use this
7 | */
8 |
9 | @Scope
10 | public @interface ActivityScope {
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/selector_default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/_shared/model/Tiles.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery._shared.model
2 |
3 | import com.google.gson.Gson
4 | import java.util.*
5 |
6 | class Tiles {
7 |
8 | var tiles: ArrayList = ArrayList()
9 |
10 | fun serialize(): String {
11 | val gson = Gson()
12 | return gson.toJson(this)
13 | }
14 |
15 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_in_shadow.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_out_shadow.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_in_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_out_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/release/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/nav_drawer/model/SectionChildObject.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.nav_drawer.model;
2 |
3 | open class SectionChildObject {
4 |
5 | constructor() {
6 | }
7 |
8 | constructor(title: String, query: String) {
9 | this.sectionTitle = title
10 | this.query = query
11 | }
12 |
13 | var sectionTitle: String = ""
14 | var query: String = ""
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/selector_circle_default.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/release/java/com/derek_s/hubble_gallery/base/HubbleApplicationRelease.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.base;
2 |
3 | import com.crashlytics.android.Crashlytics;
4 |
5 | import io.fabric.sdk.android.Fabric;
6 |
7 | public class HubbleApplicationRelease extends HubbleApplication {
8 |
9 | @Override
10 | public void onCreate() {
11 | super.onCreate();
12 | Fabric.with(this, new Crashlytics());
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_grid_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/nav_drawer/views/NavigationView.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.nav_drawer.views
2 |
3 | import android.support.v7.widget.RecyclerView
4 | import com.derek_s.hubble_gallery.nav_drawer.model.SectionChildObject
5 |
6 | interface NavigationView {
7 | val recycler: RecyclerView
8 | get
9 |
10 | fun selectSection(section: SectionChildObject) {
11 | }
12 |
13 | fun deselectFavorites() {
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/derek_s/hubble_gallery/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
3 | # built application files
4 | *.apk
5 | *.ap_
6 | *.jks
7 |
8 | # files for the dex VM
9 | *.dex
10 |
11 | # Java class files
12 | *.class
13 |
14 | # generated files
15 | bin/
16 | gen/
17 |
18 | # Local configuration file (sdk path, etc)
19 | local.properties
20 |
21 | # Android Studio
22 | .idea/
23 | .gradle
24 | gradle
25 | /*/local.properties
26 | /*/out
27 | /*/*/build
28 | build
29 | /*/*/production
30 | *.iml
31 | *.iws
32 | *.ipr
33 | *~
34 | *.swp
35 |
36 | app/fabric.properties
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
3 | # built application files
4 | *.apk
5 | *.ap_
6 | *.jks
7 |
8 | # files for the dex VM
9 | *.dex
10 |
11 | # Java class files
12 | *.class
13 |
14 | # generated files
15 | bin/
16 | gen/
17 |
18 | # Local configuration file (sdk path, etc)
19 | local.properties
20 |
21 | # Android Studio
22 | .idea/
23 | .gradle
24 | gradle
25 | /*/local.properties
26 | /*/out
27 | /*/*/build
28 | build
29 | /*/*/production
30 | *.iml
31 | *.iws
32 | *.ipr
33 | *~
34 | *.swp
35 |
36 | fabric.properties
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_circle_default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 | -
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 24dp
4 | 12dp
5 | 80dp
6 |
7 |
8 | 400dp
9 | 52dp
10 |
11 |
12 | 3
13 |
14 |
15 | 32dp
16 | 48dp
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/_shared/model/TileObject.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery._shared.model
2 |
3 | import com.google.gson.Gson
4 |
5 | class TileObject {
6 |
7 | var id: String = ""
8 | var title: String = ""
9 | var href: String = ""
10 | var src: String = ""
11 |
12 | fun serialize(): String {
13 | val gson = Gson()
14 | return gson.toJson(this)
15 | }
16 |
17 | companion object {
18 | fun create(serializedData: String): TileObject {
19 | val gson = Gson()
20 | return gson.fromJson(serializedData, TileObject::class.java)
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_in_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
11 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/fade_out_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
11 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/toolbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res-details/layout/act_image_viewer.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/base/Constants.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.base;
2 |
3 | import android.os.Environment;
4 |
5 | public class Constants {
6 |
7 | public static final String MODE_KEY = "current_mode";
8 | public static final String PARAM_TILE_KEY = "tile_param";
9 | public static final String PARAM_DETAILS_KEY = "details_param";
10 | public static final String ONBOARDING_SHOWN = "onboarding_shown";
11 | public static final int LOADED_MODE = 0;
12 | public static final int FAVORITES_MODE = 1;
13 | public static final int SEARCH_MODE = 2;
14 |
15 | public static String imageDirectory() {
16 | return Environment.getExternalStorageDirectory() + "/Pictures/Hubble";
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/app/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 /Users/dereksmith/Documents/ADT/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 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/zoom_in_exit.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
14 |
15 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res-welcome/layout/act_welcome.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
12 |
13 |
14 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/detailspage/DetailsContract.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.detailspage;
2 |
3 | import android.content.Intent;
4 | import android.widget.ImageView;
5 |
6 | import com.derek_s.hubble_gallery._shared.model.DetailsObject;
7 | import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
8 |
9 | public interface DetailsContract {
10 |
11 | void showLoadingAnimation(boolean show, int type);
12 |
13 | void populateDetails(DetailsObject detailsObject);
14 |
15 | void showZeroState(boolean show);
16 |
17 | void generatePalette();
18 |
19 | void openActivityIntent(Intent intent);
20 |
21 | void openImageViewer();
22 |
23 | ImageView getIvDisplay();
24 |
25 | ObservableScrollView getScrollView();
26 |
27 | void updateMenu();
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/_shared/model/DetailsObject.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery._shared.model;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | class DetailsObject {
8 |
9 | @Expose
10 | var description: String = ""
11 |
12 | @Expose
13 | var names: String = ""
14 |
15 | @SerializedName("image_type")
16 | @Expose
17 | var imageType: String = ""
18 |
19 | @Expose
20 | var credit: String = ""
21 |
22 | fun serialize(): String {
23 | val gson = Gson()
24 | return gson.toJson(this)
25 | }
26 |
27 | companion object {
28 | fun create(serializedData: String): DetailsObject {
29 | val gson = Gson()
30 | return gson.fromJson(serializedData, DetailsObject::class.java)
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/app/src/main/res-navigation/layout/frag_nav_drawer.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
15 |
16 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/ui/widgets/SquareImageView.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.ui.widgets;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.ImageView;
6 |
7 | /**
8 | * Created by dereksmith on 15-03-01.
9 | */
10 | public class SquareImageView extends ImageView {
11 |
12 | public SquareImageView(Context context) {
13 | super(context);
14 | }
15 |
16 | public SquareImageView(Context context, AttributeSet attrs) {
17 | super(context, attrs);
18 | }
19 |
20 | public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
21 | super(context, attrs, defStyle);
22 | }
23 |
24 | @Override
25 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
26 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
27 |
28 | int width = getMeasuredWidth();
29 | setMeasuredDimension(width, width);
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/internal/di/ActivityComponent.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.internal.di;
2 |
3 | import com.derek_s.hubble_gallery.base.ActBase;
4 | import com.derek_s.hubble_gallery.base.FragBase;
5 | import com.derek_s.hubble_gallery.detailspage.DetailsActivity;
6 | import com.derek_s.hubble_gallery.home.ActHome;
7 | import com.derek_s.hubble_gallery.imageviewer.ImageViewerActivity;
8 | import com.derek_s.hubble_gallery.ui.activities.ActWelcome;
9 |
10 | import dagger.Component;
11 |
12 | /**
13 | * This component injects Activities and Fragments
14 | */
15 |
16 | @ActivityScope
17 | @Component(dependencies = {AppComponent.class})
18 | public interface ActivityComponent {
19 |
20 | void inject(ActBase app);
21 |
22 | void inject(DetailsActivity app);
23 |
24 | void inject(ActHome app);
25 |
26 | void inject(ImageViewerActivity app);
27 |
28 | void inject(ActWelcome app);
29 |
30 | void inject(FragBase app);
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/act_main.xml:
--------------------------------------------------------------------------------
1 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res-navigation/layout/item_section.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
13 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/base/ActBase.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.base;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.app.AppCompatActivity;
6 |
7 | import com.derek_s.hubble_gallery.internal.di.ActivityComponent;
8 | import com.derek_s.hubble_gallery.internal.di.DaggerActivityComponent;
9 |
10 | public abstract class ActBase extends AppCompatActivity {
11 |
12 | @Override
13 | protected void onCreate(@Nullable Bundle savedState) {
14 | super.onCreate(savedState);
15 |
16 | injectComponent(DaggerActivityComponent.builder()
17 | .appComponent(((HubbleApplication) getApplication()).getAppComponent())
18 | .build());
19 | }
20 |
21 | /**
22 | *
23 | * This method must be implemented
24 | *
25 | * component.inject(this)
26 | *
27 | * @param component
28 | */
29 | protected abstract void injectComponent(ActivityComponent component);
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/utils/ui/IndeterminateAnimator.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.utils.ui;
2 |
3 | import android.os.Handler;
4 | import android.view.View;
5 |
6 | import com.daimajia.androidanimations.library.Techniques;
7 | import com.daimajia.androidanimations.library.YoYo;
8 | import com.derek_s.hubble_gallery.ui.widgets.CircleProgressView;
9 |
10 | /**
11 | * Created by dereksmith on 15-03-22.
12 | */
13 | public class IndeterminateAnimator {
14 |
15 | public static void show(final CircleProgressView prog, Techniques technique) {
16 | prog.setVisibility(View.VISIBLE);
17 | YoYo.with(technique).duration(300).playOn(prog);
18 | }
19 |
20 | public static void stop(final CircleProgressView prog, Techniques technique) {
21 | YoYo.with(technique).duration(300).playOn(prog);
22 | new Handler().postDelayed(new Runnable() {
23 | @Override
24 | public void run() {
25 | prog.setVisibility(View.GONE);
26 | }
27 | }, 320);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/base/FragBase.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.base;
2 |
3 | import android.content.res.Resources;
4 | import android.os.Bundle;
5 | import android.support.v4.app.Fragment;
6 |
7 | import com.derek_s.hubble_gallery.internal.di.DaggerActivityComponent;
8 | import com.derek_s.hubble_gallery.utils.FavoriteUtils;
9 | import com.derek_s.hubble_gallery.utils.network.NetworkUtil;
10 |
11 | import javax.inject.Inject;
12 |
13 | public class FragBase extends Fragment {
14 |
15 | @Inject
16 | public Resources resources;
17 | @Inject
18 | public NetworkUtil networkUtil;
19 | @Inject
20 | public TinyDB db;
21 | @Inject
22 | public FavoriteUtils favoriteUtils;
23 |
24 | @Override
25 | public void onCreate(Bundle savedState) {
26 | super.onCreate(savedState);
27 | DaggerActivityComponent.builder()
28 | .appComponent(((HubbleApplication) getActivity().getApplication()).getAppComponent())
29 | .build()
30 | .inject(this);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/base/HubbleApplication.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.base;
2 |
3 | import android.app.Application;
4 |
5 | import com.crashlytics.android.Crashlytics;
6 | import com.derek_s.hubble_gallery.internal.di.AppComponent;
7 | import com.derek_s.hubble_gallery.internal.di.AppModule;
8 | import com.derek_s.hubble_gallery.internal.di.DaggerAppComponent;
9 |
10 | import io.fabric.sdk.android.Fabric;
11 |
12 | public class HubbleApplication extends Application {
13 |
14 | private AppComponent appComponent;
15 |
16 | @Override
17 | public void onCreate() {
18 | super.onCreate();
19 | Fabric.with(this, new Crashlytics());
20 | this.initializeInjector();
21 | }
22 |
23 | private void initializeInjector() {
24 | this.appComponent = DaggerAppComponent
25 | .builder()
26 | .appModule(new AppModule(this))
27 | .build();
28 |
29 | this.appComponent.inject(this);
30 | }
31 |
32 | public AppComponent getAppComponent() {
33 | return appComponent;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/ui/adapters/OnboardingFragmentPager.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.ui.adapters;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentPagerAdapter;
6 | import android.util.Log;
7 |
8 | import com.derek_s.hubble_gallery.ui.fragments.FragWelcomeInfo;
9 | import com.derek_s.hubble_gallery.ui.fragments.FragWelcomeOutline;
10 |
11 | /**
12 | * Created by dereksmith on 15-05-04.
13 | */
14 | public class OnboardingFragmentPager extends FragmentPagerAdapter {
15 | private String TAG = getClass().getSimpleName();
16 |
17 | public OnboardingFragmentPager(FragmentManager fm) {
18 | super(fm);
19 | }
20 |
21 | @Override
22 | public Fragment getItem(int position) {
23 | Log.i(TAG, "getItem pos: " + position);
24 | if (position == 0) {
25 | return new FragWelcomeOutline();
26 | } else {
27 | return FragWelcomeInfo.newInstance(position);
28 | }
29 | }
30 |
31 | @Override
32 | public int getCount() {
33 | return 5;
34 | }
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_tile.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/internal/di/AppComponent.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.internal.di;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.net.ConnectivityManager;
6 |
7 | import com.derek_s.hubble_gallery.base.HubbleApplication;
8 | import com.derek_s.hubble_gallery.base.TinyDB;
9 | import com.derek_s.hubble_gallery.detailspage.DetailsPresenter;
10 | import com.derek_s.hubble_gallery.utils.FavoriteUtils;
11 | import com.derek_s.hubble_gallery.utils.network.NetworkUtil;
12 | import com.google.gson.Gson;
13 |
14 | import javax.inject.Singleton;
15 |
16 | import dagger.Component;
17 |
18 | @Singleton
19 | @Component(modules = {AppModule.class})
20 | public interface AppComponent {
21 |
22 | Context context();
23 |
24 | Resources resources();
25 |
26 | ConnectivityManager provideConnectivityManager();
27 |
28 | NetworkUtil provideNetworkUtil();
29 |
30 | TinyDB provideTinyDB();
31 |
32 | DetailsPresenter provideActDetailsPresenter();
33 |
34 | FavoriteUtils provideFavoriteUtils();
35 |
36 | Gson provideGson();
37 |
38 | void inject(HubbleApplication app);
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ff131313
4 | #ff000000
5 | #00BCD4
6 |
7 | #ff151515
8 | #006064
9 |
10 |
11 | #89000000
12 | #de000000
13 | #de000000
14 | #89000000
15 | #1f000000
16 |
17 | #89ffffff
18 | #deffffff
19 | #deffffff
20 | #89ffffff
21 | #1fffffff
22 |
23 | #00BCD4
24 | #6700bcd4
25 | #2100bcd4
26 |
27 | #66000000
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/utils/ui/Toasty.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.utils.ui;
2 |
3 | import android.content.Context;
4 |
5 | import com.github.johnpersano.supertoasts.SuperToast;
6 |
7 | /**
8 | * Created by dereksmith on 15-04-11.
9 | */
10 | public class Toasty {
11 |
12 | public static int LENGTH_LONG = 3000;
13 | public static int LENGTH_MEDIUM = 2000;
14 | public static int LENGTH_SHORT = 1000;
15 |
16 | public static void show(Context c, String text, int duration) {
17 | SuperToast superToast = new SuperToast(c);
18 | superToast.setDuration(duration);
19 | superToast.setText(text);
20 | superToast.setAnimations(SuperToast.Animations.POPUP);
21 | superToast.setBackground(SuperToast.Background.GRAY);
22 | superToast.show();
23 | }
24 |
25 | public static void show(Context c, int textRes, int duration) {
26 | SuperToast superToast = new SuperToast(c);
27 | superToast.setDuration(duration);
28 | superToast.setText(c.getResources().getString(textRes));
29 | superToast.setAnimations(SuperToast.Animations.POPUP);
30 | superToast.setBackground(SuperToast.Background.GRAY);
31 | superToast.show();
32 | }
33 | }
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/nav_drawer/adapters/NavigationAdapterItem.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.nav_drawer.adapters
2 |
3 | import android.support.annotation.IntDef
4 | import com.bignerdranch.expandablerecyclerview.Model.ParentListItem
5 |
6 | class NavigationAdapterItem(`object`: Any?, viewType: Long, childObjectList: List?) :
7 | ParentListItem {
8 |
9 | @ViewType
10 | var viewType: Long = 0
11 | var `object`: Any?
12 | var childObjectList: List?
13 | var isSelected: Boolean = false
14 |
15 | init {
16 | this.`object` = `object`
17 | this.viewType = viewType
18 | this.childObjectList = childObjectList
19 | }
20 |
21 | override fun getChildItemList(): List? {
22 | return childObjectList
23 | }
24 |
25 | override fun isInitiallyExpanded(): Boolean {
26 | return isSelected
27 | }
28 |
29 | @Retention(AnnotationRetention.SOURCE)
30 | @IntDef(HEADER, STANDALONE_SECTION, SECTION, GROUP)
31 | annotation class ViewType
32 |
33 | companion object {
34 | const val HEADER: Long = 0
35 | const val STANDALONE_SECTION: Long = 1
36 | const val SECTION: Long = 2
37 | const val GROUP: Long = 3
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/res-details/layout/zero_state_details.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
20 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 8dp
5 | 72dp
6 | 24dp
7 | ?attr/actionBarSize
8 |
9 |
10 | 112sp
11 | 56sp
12 | 45sp
13 | 34sp
14 | 24sp
15 | 20sp
16 | 14sp
17 | 14sp
18 | 12sp
19 |
20 |
21 | 320
22 | 350
23 | - 0.6
24 |
25 |
26 | 300dp
27 | 48dp
28 |
29 |
30 | 2
31 |
32 |
33 | 24dp
34 | 32dp
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/frag_main.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
16 |
17 |
26 |
27 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/utils/ui/ToolbarTitle.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.utils.ui;
2 |
3 | import android.content.Context;
4 | import android.view.Gravity;
5 | import android.view.View;
6 | import android.view.animation.Animation;
7 | import android.view.animation.AnimationUtils;
8 | import android.widget.TextSwitcher;
9 | import android.widget.TextView;
10 | import android.widget.ViewSwitcher.ViewFactory;
11 |
12 | import com.derek_s.hubble_gallery.R;
13 |
14 | public class ToolbarTitle {
15 | private Context c;
16 | private ViewFactory mFactory = new ViewFactory() {
17 |
18 | @Override
19 | public View makeView() {
20 | TextView t = new TextView(c);
21 | t.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
22 | t.setTextAppearance(c, R.style.text_title_dark);
23 | t.setTypeface(FontFactory.getCondensedRegular(c));
24 | t.setAllCaps(true);
25 | return t;
26 | }
27 | };
28 |
29 | public TextSwitcher init(TextSwitcher switcher, Context context) {
30 | c = context;
31 | switcher.setFactory(mFactory);
32 |
33 | Animation in = AnimationUtils.loadAnimation(c,
34 | R.anim.fade_in_right);
35 | Animation out = AnimationUtils.loadAnimation(c,
36 | R.anim.fade_out_right);
37 |
38 | switcher.setInAnimation(in);
39 | switcher.setOutAnimation(out);
40 |
41 | return switcher;
42 | }
43 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Hubble Gallery (DEPRECATED)
2 | Discover and read about the Hubble Telescope's best images.
3 |
4 | 
5 |
6 | ----
7 | ### [Google Play listing →](https://play.google.com/store/apps/details?id=com.derek_s.hubble_gallery)
8 |
9 |
10 | Maintained by [derekcsm](http://derekcsm.xyz/)
11 |
12 | Contributions by:
13 |
14 | - [PedroVictorB](https://github.com/PedroVictorB)
15 |
16 | General code style
17 | -------
18 |
19 | - use 2 space `indents` and 4 space `continuation indents` for Java and Kotlin, and 2 space for indents & continuation in XML, we're slowing moving to that
20 | - try your best not to exceed horizontal line length
21 | - don't include "created by" or any other tags at top of classes, if you find any please remove them
22 |
23 | License
24 | -------
25 |
26 | Licensed under the Apache License, Version 2.0 (the "License");
27 | you may not use this file except in compliance with the License.
28 | You may obtain a copy of the License at
29 |
30 | http://www.apache.org/licenses/LICENSE-2.0
31 |
32 | Unless required by applicable law or agreed to in writing, software
33 | distributed under the License is distributed on an "AS IS" BASIS,
34 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35 | See the License for the specific language governing permissions and
36 | limitations under the License.
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/act_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
15 |
21 |
22 |
27 |
28 |
29 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/zero_state_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
22 |
23 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res-welcome/layout/frag_welcome_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
22 |
23 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res-navigation/layout/item_group.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
23 |
24 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/imageviewer/ImageViewerActivity.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.imageviewer;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 |
6 | import com.derek_s.hubble_gallery.R;
7 | import com.derek_s.hubble_gallery.base.ActBase;
8 | import com.derek_s.hubble_gallery.internal.di.ActivityComponent;
9 | import com.derek_s.hubble_gallery.ui.widgets.TouchImageView;
10 | import com.squareup.picasso.Picasso;
11 |
12 | import butterknife.Bind;
13 | import butterknife.ButterKnife;
14 |
15 | public class ImageViewerActivity extends ActBase {
16 |
17 | public static final String EXTRA_IMAGE_SRC = "extra_successful_src";
18 | @Bind(R.id.iv_fullscreen)
19 | TouchImageView ivFullscreen;
20 | private String imgSrc;
21 |
22 | @Override
23 | protected void onCreate(Bundle savedState) {
24 | super.onCreate(savedState);
25 | setContentView(R.layout.act_image_viewer);
26 | ButterKnife.bind(this);
27 |
28 | Intent intent = getIntent();
29 | if (intent != null) {
30 | imgSrc = intent.getStringExtra(EXTRA_IMAGE_SRC);
31 | }
32 |
33 | if (savedState != null)
34 | imgSrc = savedState.getString(EXTRA_IMAGE_SRC);
35 |
36 | Picasso.with(this).load(imgSrc).into(ivFullscreen);
37 | }
38 |
39 | @Override
40 | public void onSaveInstanceState(Bundle outState) {
41 | outState.putString(EXTRA_IMAGE_SRC, imgSrc);
42 | super.onSaveInstanceState(outState);
43 | }
44 |
45 | @Override
46 | protected void injectComponent(ActivityComponent component) {
47 | component.inject(this);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/ui/adapters/RecyclerViewItemClickListener.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.ui.adapters;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.GestureDetector;
6 | import android.view.MotionEvent;
7 | import android.view.View;
8 |
9 | /**
10 | * Credit to sam_chordas for the code and idea
11 | */
12 | public class RecyclerViewItemClickListener implements RecyclerView.OnItemTouchListener {
13 |
14 | private GestureDetector gestureDetector;
15 | private OnItemClickListener listener;
16 |
17 | public RecyclerViewItemClickListener(Context context, OnItemClickListener listener) {
18 | this.listener = listener;
19 | gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
20 | @Override
21 | public boolean onSingleTapUp(MotionEvent e) {
22 | return true;
23 | }
24 | });
25 | }
26 |
27 | @Override
28 | public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
29 |
30 | }
31 |
32 | @Override
33 | public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
34 | View childView = view.findChildViewUnder(e.getX(), e.getY());
35 | if (childView != null && listener != null && gestureDetector.onTouchEvent(e)) {
36 | listener.onItemClick(childView, view.getChildPosition(childView));
37 | return true;
38 | }
39 | return false;
40 | }
41 |
42 | @Override
43 | public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
44 | }
45 |
46 | public interface OnItemClickListener {
47 | void onItemClick(View v, int position);
48 | }
49 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/internal/di/AppModule.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.internal.di;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.content.res.Resources;
6 | import android.net.ConnectivityManager;
7 |
8 | import com.derek_s.hubble_gallery.base.TinyDB;
9 | import com.derek_s.hubble_gallery.utils.network.NetworkUtil;
10 | import com.google.gson.Gson;
11 |
12 | import javax.inject.Singleton;
13 |
14 | import dagger.Module;
15 | import dagger.Provides;
16 |
17 | /**
18 | * This module resolves everything on an AppContext, things that need to be instantiated
19 | * only once or need an App Context.
20 | */
21 |
22 | @Module
23 | public class AppModule {
24 |
25 | private final Application application;
26 |
27 | public AppModule(Application application) {
28 | this.application = application;
29 | }
30 |
31 | @Provides
32 | Context provideContext() {
33 | return application.getBaseContext();
34 | }
35 |
36 | @Provides
37 | @Singleton
38 | Resources provideResources(Context context) {
39 | return context.getResources();
40 | }
41 |
42 | @Provides
43 | @Singleton
44 | ConnectivityManager provideConnectivityManager() {
45 | return (ConnectivityManager) application.getSystemService(Context.CONNECTIVITY_SERVICE);
46 | }
47 |
48 | @Provides
49 | @Singleton
50 | NetworkUtil provideNetworkStateManager(ConnectivityManager connectivityManagerCompat, Context context) {
51 | return new NetworkUtil(connectivityManagerCompat, context);
52 | }
53 |
54 | @Provides
55 | @Singleton
56 | TinyDB provideTinyDb(Context context) {
57 | return new TinyDB(context);
58 | }
59 |
60 | @Provides
61 | @Singleton
62 | Gson provideGson() {
63 | return new Gson();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/res-details/menu/menu_act_details.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
12 |
13 |
19 |
20 |
25 |
26 |
31 |
32 |
37 |
38 |
43 |
44 |
49 |
50 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/utils/FavoriteUtils.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.utils;
2 |
3 | import com.derek_s.hubble_gallery._shared.model.TileObject;
4 | import com.derek_s.hubble_gallery._shared.model.Tiles;
5 | import com.derek_s.hubble_gallery.base.TinyDB;
6 | import com.google.gson.Gson;
7 |
8 | import javax.inject.Inject;
9 | import javax.inject.Singleton;
10 |
11 | @Singleton
12 | public class FavoriteUtils {
13 |
14 | private static final String FAVORITES_KEY = "favorites_key";
15 |
16 | @Inject
17 | TinyDB tinyDB;
18 | @Inject
19 | Gson gson;
20 |
21 | @Inject
22 | public FavoriteUtils() {
23 | }
24 |
25 | public void saveFavorite(TileObject tileObject) {
26 | Tiles currentFaves = getFavorites();
27 | if (currentFaves == null)
28 | currentFaves = new Tiles();
29 |
30 | currentFaves.getTiles().add(tileObject);
31 | tinyDB.putString(FAVORITES_KEY, currentFaves.serialize());
32 | }
33 |
34 | public Tiles getFavorites() {
35 | return gson.fromJson(tinyDB.getString(FAVORITES_KEY), Tiles.class);
36 | }
37 |
38 | public void removeFavorite(TileObject tileObject) {
39 | Tiles currentFaves = getFavorites();
40 |
41 | for (int i = 0; i < currentFaves.getTiles().size(); i++) {
42 | TileObject curTile = currentFaves.getTiles().get(i);
43 |
44 | if (curTile.getId().equals(tileObject.getId()))
45 | currentFaves.getTiles().remove(i);
46 | }
47 |
48 | tinyDB.putString(FAVORITES_KEY, currentFaves.serialize());
49 | }
50 |
51 | public boolean isFavorited(TileObject tileObject) {
52 | Tiles currentFaves = getFavorites();
53 |
54 | if (currentFaves == null)
55 | return false;
56 |
57 | for (TileObject curTile : currentFaves.getTiles()) {
58 | if (curTile.getId().equals(tileObject.getId()))
59 | return true;
60 | }
61 | return false;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/zero_state_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
18 |
19 |
26 |
27 |
35 |
36 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/utils/network/NetworkUtil.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.utils.network;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.net.NetworkInfo;
6 |
7 | import com.derek_s.hubble_gallery.R;
8 | import com.derek_s.hubble_gallery.utils.ui.Toasty;
9 |
10 | import javax.inject.Inject;
11 |
12 | public class NetworkUtil {
13 | public static int TYPE_WIFI = 1;
14 | public static int TYPE_MOBILE = 2;
15 | public static int TYPE_NOT_CONNECTED = 0;
16 |
17 | private final ConnectivityManager connectivityManager;
18 | private Context context;
19 |
20 | @Inject
21 | public NetworkUtil(ConnectivityManager connectivityManager, Context context) {
22 | this.connectivityManager = connectivityManager;
23 | this.context = context;
24 | }
25 |
26 | public int getConnectivityStatus() {
27 | NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
28 | if (null != activeNetwork) {
29 | if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
30 | return TYPE_WIFI;
31 |
32 | if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
33 | return TYPE_MOBILE;
34 | }
35 | return TYPE_NOT_CONNECTED;
36 | }
37 |
38 | public String getConnectivityStatusString() {
39 | int conn = getConnectivityStatus();
40 | String status = null;
41 | if (conn == NetworkUtil.TYPE_WIFI) {
42 | status = "Wifi enabled";
43 | } else if (conn == NetworkUtil.TYPE_MOBILE) {
44 | status = "Mobile data enabled";
45 | } else if (conn == NetworkUtil.TYPE_NOT_CONNECTED) {
46 | status = "Not connected to Internet";
47 | }
48 | return status;
49 | }
50 |
51 | public void toastNoConnection() {
52 | Toasty.show(context, R.string.no_connection, Toasty.LENGTH_MEDIUM);
53 | }
54 |
55 | public boolean isConnected() {
56 | int conn = getConnectivityStatus();
57 | return conn != NetworkUtil.TYPE_NOT_CONNECTED;
58 | }
59 | }
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/nav_drawer/adapters/SectionViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.nav_drawer.adapters
2 |
3 | import android.content.Context
4 | import android.support.v4.content.ContextCompat
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import android.widget.TextView
9 | import butterknife.bindView
10 | import com.bignerdranch.expandablerecyclerview.ViewHolder.ChildViewHolder
11 | import com.derek_s.hubble_gallery.R
12 | import com.derek_s.hubble_gallery.nav_drawer.model.SectionChildObject
13 | import com.derek_s.hubble_gallery.utils.ui.FontFactory
14 |
15 | class SectionViewHolder private constructor(itemView: View) : ChildViewHolder(itemView) {
16 |
17 | val tvTitle: TextView by bindView(R.id.tv_title)
18 |
19 | init {
20 | beautifyViews()
21 | }
22 |
23 | fun beautifyViews() {
24 | tvTitle.typeface = FontFactory.getRegular(itemView.context)
25 | }
26 |
27 | fun onBind(section: SectionChildObject, listener: NavDrawerAdapter.NavAdapterListener,
28 | pos: Int, selectedQuery: String) {
29 | tvTitle.text = section.sectionTitle
30 |
31 | if (section.query.equals(selectedQuery)) {
32 | tvTitle.setBackgroundColor(ContextCompat.getColor(itemView.context, R.color.focused_color));
33 | tvTitle.setTextColor(ContextCompat.getColor(itemView.context, R.color.seleted_item_color));
34 | } else {
35 | tvTitle.setBackgroundResource(R.drawable.selector_default);
36 | tvTitle.setTextColor(ContextCompat.getColor(itemView.context, R.color.body_dark_theme));
37 | }
38 |
39 | tvTitle.setOnClickListener {
40 | listener.onSectionClicked(section)
41 | listener.setSelectedQuery(section.query)
42 | }
43 | }
44 |
45 | companion object {
46 | fun create(context: Context, viewGroup: ViewGroup): SectionViewHolder {
47 | return SectionViewHolder(LayoutInflater.from(context).inflate(R.layout.item_section,
48 | viewGroup, false))
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
28 |
31 |
32 |
33 |
36 |
42 |
45 |
46 |
47 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res-navigation/layout/dialog_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
24 |
25 |
31 |
32 |
33 |
34 |
37 |
38 |
46 |
47 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/app/src/main/res-welcome/layout/frag_welcome_outline.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
25 |
26 |
42 |
43 |
55 |
56 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/nav_drawer/adapters/NavDrawerAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.nav_drawer.adapters
2 |
3 | import android.content.Context
4 | import android.view.ViewGroup
5 | import com.bignerdranch.expandablerecyclerview.Adapter.ExpandableRecyclerAdapter
6 | import com.bignerdranch.expandablerecyclerview.Model.ParentListItem
7 | import com.derek_s.hubble_gallery.nav_drawer.model.SectionChildObject
8 | import java.util.*
9 |
10 | class NavDrawerAdapter(context: Context, parentItemList: ArrayList,
11 | listener: NavAdapterListener) :
12 | ExpandableRecyclerAdapter(parentItemList) {
13 |
14 | private val TAG = "NavDrawerAdapter"
15 | private val mContext: Context
16 | private val listener: NavAdapterListener
17 |
18 | private var selectedQuery = "entire";
19 |
20 | init {
21 | mContext = context
22 | this.listener = listener
23 | }
24 |
25 | override fun onCreateParentViewHolder(parentViewGroup: ViewGroup): GroupViewHolder? {
26 | return GroupViewHolder.create(mContext, parentViewGroup)
27 | }
28 |
29 | override fun onCreateChildViewHolder(childViewGroup: ViewGroup): SectionViewHolder? {
30 | return SectionViewHolder.create(mContext, childViewGroup)
31 | }
32 |
33 | override fun onBindParentViewHolder(parentViewHolder: GroupViewHolder, position: Int,
34 | parentListItem: ParentListItem) {
35 | parentViewHolder.onBind(parentListItem as NavigationAdapterItem, listener, position, selectedQuery)
36 | }
37 |
38 | override fun onBindChildViewHolder(childViewHolder: SectionViewHolder, position: Int,
39 | childListItem: Any) {
40 | childViewHolder.onBind(childListItem as SectionChildObject, listener, position, selectedQuery)
41 | }
42 |
43 | fun setSelectedQuery(query: String) {
44 | selectedQuery = query
45 | notifyDataSetChanged()
46 | }
47 |
48 | fun getSelectedQuery(): String {
49 | return selectedQuery
50 | }
51 |
52 | interface NavAdapterListener {
53 | fun onSectionClicked(section: SectionChildObject)
54 |
55 | fun setSelectedQuery(selectedQuery: String)
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/ui/fragments/FragWelcomeOutline.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.ui.fragments;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.TextView;
9 |
10 | import com.daimajia.androidanimations.library.Techniques;
11 | import com.daimajia.androidanimations.library.YoYo;
12 | import com.derek_s.hubble_gallery.R;
13 | import com.derek_s.hubble_gallery.base.FragBase;
14 | import com.derek_s.hubble_gallery.utils.svg.SvgView;
15 | import com.derek_s.hubble_gallery.utils.ui.FontFactory;
16 |
17 | import butterknife.Bind;
18 | import butterknife.ButterKnife;
19 |
20 | public class FragWelcomeOutline extends FragBase {
21 |
22 | @Bind(R.id.hubble_outline)
23 | SvgView hubbleOutline;
24 | @Bind(R.id.tv_app_title)
25 | TextView tvTitle;
26 | @Bind(R.id.tv_scroll_down)
27 | TextView tvScrollDown;
28 | Handler showTitleHandler;
29 |
30 | @Override
31 | public void onCreate(Bundle savedState) {
32 | super.onCreate(savedState);
33 | }
34 |
35 | @Override
36 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
37 | Bundle savedState) {
38 | View rootView = inflater.inflate(R.layout.frag_welcome_outline, container, false);
39 | ButterKnife.bind(this, rootView);
40 |
41 | /*
42 | show initial intro animation
43 | */
44 | YoYo.with(Techniques.FadeIn).duration(800).playOn(hubbleOutline);
45 | hubbleOutline.setSvgResource(R.raw.hubble_outline);
46 | hubbleOutline.setVisibility(View.VISIBLE);
47 | tvTitle.setTypeface(FontFactory.getCondensedLight(getActivity()));
48 | tvScrollDown.setTypeface(FontFactory.getCondensedRegular(getActivity()));
49 |
50 | showTitleHandler = new Handler();
51 | showTitleHandler.postDelayed(new Runnable() {
52 | @Override
53 | public void run() {
54 | tvTitle.setVisibility(View.VISIBLE);
55 | YoYo.with(Techniques.FadeInUp).duration(1000).playOn(tvTitle);
56 | tvScrollDown.setVisibility(View.VISIBLE);
57 | YoYo.with(Techniques.FadeIn).duration(1000).playOn(tvScrollDown);
58 | }
59 | }, 4000);
60 |
61 | return rootView;
62 | }
63 |
64 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/api/GetDetails.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.api;
2 |
3 | import android.os.AsyncTask;
4 | import android.util.Log;
5 |
6 | import com.derek_s.hubble_gallery._shared.model.DetailsObject;
7 |
8 | import org.jsoup.Jsoup;
9 | import org.jsoup.nodes.Document;
10 | import org.jsoup.nodes.Element;
11 | import org.jsoup.select.Elements;
12 |
13 | import java.io.IOException;
14 |
15 | public class GetDetails extends AsyncTask {
16 |
17 | private static String TAG = "GetDetails";
18 | String newsUrl;
19 | String href;
20 | private OnTaskComplete onTaskComplete;
21 |
22 | public GetDetails(String href) {
23 | this.href = href;
24 | Log.i(TAG, "href: " + href);
25 | }
26 |
27 | public void setGetDetailsCompleteListener(OnTaskComplete onTaskComplete) {
28 | this.onTaskComplete = onTaskComplete;
29 | }
30 |
31 | @Override
32 | protected void onPreExecute() {
33 | super.onPreExecute();
34 | }
35 |
36 | @Override
37 | protected DetailsObject doInBackground(Void... arg0) {
38 | DetailsObject detailsObject = new DetailsObject();
39 | try {
40 | Document doc;
41 | Element infoHolder = null;
42 |
43 | if (!href.contains("newscenter")) {
44 | // get the newscenter url
45 | doc = Jsoup.connect("http://hubble.stsci.edu" + href).timeout(8 * 1000).get();
46 | infoHolder = doc.getElementsByClass("info-holder").first();
47 | }
48 |
49 | if (infoHolder != null) {
50 | newsUrl = infoHolder.attr("href");
51 | } else {
52 | // probably from a redirect
53 | newsUrl = href;
54 | }
55 | Log.i(TAG, "newsUrl " + newsUrl);
56 |
57 | // with the new url then get the info
58 | doc = Jsoup.connect("http://hubble.stsci.edu" + newsUrl).get();
59 |
60 | Elements p = doc.getElementsByTag("p");
61 | detailsObject.setDescription(p.toString());
62 |
63 | } catch (IOException e) {
64 | e.printStackTrace();
65 | }
66 | return detailsObject;
67 | }
68 |
69 | @Override
70 | protected void onPostExecute(DetailsObject result) {
71 | onTaskComplete.setTaskComplete(result, newsUrl);
72 | }
73 |
74 | public interface OnTaskComplete {
75 | void setTaskComplete(DetailsObject result, String newsUrl);
76 | }
77 |
78 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/utils/ImageUtils.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.utils;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.drawable.BitmapDrawable;
6 | import android.widget.ImageView;
7 |
8 | import com.derek_s.hubble_gallery.R;
9 | import com.derek_s.hubble_gallery.base.Constants;
10 | import com.derek_s.hubble_gallery.utils.ui.Toasty;
11 |
12 | import java.io.File;
13 | import java.io.FileNotFoundException;
14 | import java.io.FileOutputStream;
15 | import java.io.IOException;
16 |
17 | /**
18 | * Created by dereksmith on 15-04-11.
19 | */
20 | public class ImageUtils {
21 |
22 | public static String saveImage(ImageView imageView, String imgUrl, Context context, boolean toastOnSuccess) {
23 | String savedUri = null;
24 |
25 | if (null != imgUrl && imgUrl.length() > 0) {
26 | int endIndex = imgUrl.lastIndexOf("/");
27 | if (endIndex != -1) {
28 | imgUrl = imgUrl.substring(endIndex, imgUrl.length());
29 | }
30 | } else {
31 | Toasty.show(context, R.string.error_saving_image, Toasty.LENGTH_LONG);
32 | return savedUri;
33 | }
34 |
35 | BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
36 | Bitmap bitmap = drawable.getBitmap();
37 |
38 | if (bitmap == null) {
39 | Toasty.show(context, R.string.error_saving_image, Toasty.LENGTH_LONG);
40 | return savedUri;
41 | }
42 |
43 | new File(Constants.imageDirectory()).mkdirs();
44 | File image = new File(Constants.imageDirectory(), imgUrl);
45 |
46 | boolean success = false;
47 | // Encode the file as a PNG image.
48 | FileOutputStream outStream;
49 | try {
50 |
51 | outStream = new FileOutputStream(image);
52 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
53 | /* 100 to keep full quality of the image */
54 | outStream.flush();
55 | outStream.close();
56 | success = true;
57 | } catch (FileNotFoundException e) {
58 | e.printStackTrace();
59 | } catch (IOException e) {
60 | e.printStackTrace();
61 | }
62 |
63 | if (success) {
64 | if (toastOnSuccess)
65 | Toasty.show(context, R.string.image_saved, Toasty.LENGTH_MEDIUM);
66 | return imgUrl;
67 | } else {
68 | Toasty.show(context, R.string.error_saving_image, Toasty.LENGTH_LONG);
69 | return null;
70 | }
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/ui/widgets/StretchyImageView.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.ui.widgets;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.ImageView;
6 |
7 | // This works around the issue described here: http://stackoverflow.com/a/12675430/265521
8 | public class StretchyImageView extends ImageView {
9 |
10 | public StretchyImageView(Context context) {
11 | super(context);
12 | }
13 |
14 | public StretchyImageView(Context context, AttributeSet attrs) {
15 | super(context, attrs);
16 | }
17 |
18 | public StretchyImageView(Context context, AttributeSet attrs, int defStyle) {
19 | super(context, attrs, defStyle);
20 | }
21 |
22 | @Override
23 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
24 | // Call super() so that resolveUri() is called.
25 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
26 |
27 | // If there's no drawable we can just use the result from super.
28 | if (getDrawable() == null)
29 | return;
30 |
31 | final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
32 | final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
33 |
34 | int w = getDrawable().getIntrinsicWidth();
35 | int h = getDrawable().getIntrinsicHeight();
36 | if (w <= 0)
37 | w = 1;
38 | if (h <= 0)
39 | h = 1;
40 |
41 | // Desired aspect ratio of the view's contents (not including padding)
42 | float desiredAspect = (float) w / (float) h;
43 |
44 | // We are allowed to change the view's width
45 | boolean resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
46 |
47 | // We are allowed to change the view's height
48 | boolean resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
49 |
50 | int pleft = getPaddingLeft();
51 | int pright = getPaddingRight();
52 | int ptop = getPaddingTop();
53 | int pbottom = getPaddingBottom();
54 |
55 | // Get the sizes that ImageView decided on.
56 | int widthSize = getMeasuredWidth();
57 | int heightSize = getMeasuredHeight();
58 |
59 | if (resizeWidth && !resizeHeight) {
60 | // Resize the width to the height, maintaining aspect ratio.
61 | int newWidth = (int) (desiredAspect * (heightSize - ptop - pbottom)) + pleft + pright;
62 | setMeasuredDimension(newWidth, heightSize);
63 | } else if (resizeHeight && !resizeWidth) {
64 | int newHeight = (int) ((widthSize - pleft - pright) / desiredAspect) + ptop + pbottom;
65 | setMeasuredDimension(widthSize, newHeight);
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/ui/adapters/MainGridAdapter.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.ui.adapters;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | import com.derek_s.hubble_gallery.R;
13 | import com.derek_s.hubble_gallery._shared.model.TileObject;
14 | import com.derek_s.hubble_gallery.utils.ui.FontFactory;
15 | import com.squareup.picasso.Picasso;
16 |
17 | import java.util.ArrayList;
18 |
19 | import butterknife.Bind;
20 | import butterknife.ButterKnife;
21 |
22 | public class MainGridAdapter extends RecyclerView.Adapter {
23 |
24 | private static LayoutInflater inflater = null;
25 | public ArrayList mTiles;
26 | Context context;
27 |
28 |
29 | public MainGridAdapter(Activity activity, Context context) {
30 |
31 | this.mTiles = new ArrayList<>();
32 | this.context = context;
33 | inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
34 | }
35 |
36 |
37 | @Override
38 | public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
39 |
40 | View view = inflater.inflate(R.layout.item_tile, parent, false);
41 |
42 | return new RecyclerViewHolder(view);
43 | }
44 |
45 | @Override
46 | public void onBindViewHolder(RecyclerViewHolder holder, int position) {
47 |
48 | holder.tvTitle.setTypeface(FontFactory.getCondensedRegular(context));
49 | holder.tvTitle.setText(mTiles.get(position).getTitle());
50 | Picasso.with(context).load(mTiles.get(position).getSrc()).into(holder.ivTile);
51 |
52 | }
53 |
54 |
55 | @Override
56 | public int getItemCount() {
57 | return mTiles.size();
58 | }
59 |
60 | public void addItems(ArrayList tiles) {
61 | mTiles.addAll(tiles);
62 | notifyDataSetChanged();
63 | }
64 |
65 | public void clear() {
66 | mTiles.clear();
67 | notifyDataSetChanged();
68 | }
69 |
70 | public TileObject getItemAtPosition(int position) {
71 | return mTiles.get(position);
72 | }
73 |
74 | public static class RecyclerViewHolder extends RecyclerView.ViewHolder {
75 |
76 | @Bind(R.id.iv_tile)
77 | ImageView ivTile;
78 | @Bind(R.id.tv_title)
79 | TextView tvTitle;
80 |
81 | public RecyclerViewHolder(View view) {
82 | super(view);
83 | ButterKnife.bind(this, view);
84 | }
85 |
86 |
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/nav_drawer/dialog/DialogAbout.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.nav_drawer.dialog
2 |
3 | import android.content.Context
4 | import android.content.pm.PackageInfo
5 | import android.text.Html
6 | import android.text.method.LinkMovementMethod
7 | import android.view.View
8 | import android.widget.TextView
9 | import com.afollestad.materialdialogs.MaterialDialog
10 | import com.afollestad.materialdialogs.Theme
11 | import com.derek_s.hubble_gallery.R
12 | import com.derek_s.hubble_gallery.utils.ui.FontFactory
13 |
14 | class DialogAbout(context: Context, listener: DialogAboutListener) {
15 |
16 | private val context: Context
17 | private val listener: DialogAboutListener
18 | private var dialog: MaterialDialog? = null
19 |
20 | private var tvTitle: TextView? = null
21 | private var tvVersion: TextView? = null
22 | private var tvBody: TextView? = null
23 |
24 | init {
25 | this.context = context
26 | this.listener = listener
27 | }
28 |
29 | fun getDialog(): MaterialDialog {
30 | if (dialog == null) {
31 | return MaterialDialog.Builder(context)
32 | .customView(R.layout.dialog_about, false)
33 | .backgroundColorRes(R.color.background)
34 | .theme(Theme.DARK)
35 | .forceStacking(true)
36 | .positiveText(context.resources.getString(R.string.show_intro))
37 | .onPositive { materialDialog, dialogAction -> listener.onShowIntroClicked() }
38 | .build()
39 | } else {
40 | return dialog!!
41 | }
42 | }
43 |
44 | fun show() {
45 | dialog = getDialog();
46 | dialog!!.show()
47 |
48 | findViews(dialog!!.customView)
49 | beautifyViews()
50 |
51 | var pInfo: PackageInfo = context.packageManager.getPackageInfo(context.getPackageName(), 0)
52 | var version = pInfo.versionName;
53 | tvVersion!!.text = "V " + version
54 |
55 | tvBody!!.movementMethod = LinkMovementMethod.getInstance()
56 | tvBody!!.text = removeHtmlBottomPadding(Html.fromHtml(context.resources.getString(R.string.about_body)))
57 | }
58 |
59 | private fun removeHtmlBottomPadding(mText: CharSequence?): CharSequence? {
60 | var text: CharSequence = mText ?: return null
61 | if (text.length == 0)
62 | return text
63 |
64 | while (text[text.length - 1] == '\n') {
65 | text = text.subSequence(0, text.length - 1)
66 | }
67 | return text
68 | }
69 |
70 | private fun findViews(dView: View?) {
71 | if (dView == null)
72 | return
73 |
74 | tvTitle = dView.findViewById(R.id.tv_title) as TextView
75 | tvVersion = dView.findViewById(R.id.tv_version) as TextView
76 | tvBody = dView.findViewById(R.id.tv_body) as TextView
77 | }
78 |
79 | private fun beautifyViews() {
80 | tvTitle!!.typeface = FontFactory.getCondensedRegular(context)
81 | tvVersion!!.typeface = FontFactory.getMedium(context)
82 | tvBody!!.typeface = FontFactory.getRegular(context)
83 | }
84 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/api/GetAlbum.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.api;
2 |
3 | import android.os.AsyncTask;
4 |
5 | import com.derek_s.hubble_gallery._shared.model.TileObject;
6 | import com.derek_s.hubble_gallery.ui.fragments.FragMain;
7 |
8 | import org.jsoup.Jsoup;
9 | import org.jsoup.nodes.Document;
10 | import org.jsoup.nodes.Element;
11 | import org.jsoup.select.Elements;
12 |
13 | import java.io.IOException;
14 | import java.util.ArrayList;
15 |
16 | public class GetAlbum extends AsyncTask> {
17 |
18 | int limit;
19 | int page;
20 | String query;
21 | boolean hiRes = false;
22 | private OnTaskComplete onTaskComplete;
23 |
24 | public GetAlbum(int limit, int page, String query, boolean hiRes) {
25 | this.limit = limit;
26 | this.page = page;
27 | this.query = query;
28 | this.hiRes = hiRes;
29 | FragMain.currentPage = page;
30 | }
31 |
32 | public void setGetAlbumCompleteListener(OnTaskComplete onTaskComplete) {
33 | this.onTaskComplete = onTaskComplete;
34 | }
35 |
36 | @Override
37 | protected void onPreExecute() {
38 | super.onPreExecute();
39 | }
40 |
41 | @Override
42 | protected ArrayList doInBackground(Void... arg0) {
43 | ArrayList mArray = new ArrayList<>();
44 | try {
45 | Document doc = null;
46 |
47 | if (hiRes) {
48 | doc = Jsoup.connect("http://hubble.stsci.edu/gallery/album/" + query + "/npp/" + limit + "/hires/true/" + "+" + page).get();
49 | } else {
50 | doc = Jsoup.connect("http://hubble.stsci.edu/gallery/album/" + query + "/npp/" + limit + "/" + "+" + page).get();
51 | }
52 | Elements links = doc.select("div#ListBlock");
53 | for (int i = 0; i < limit; i++) {
54 | try {
55 | Element link = links.select("a").get(i);
56 | Element img = link.select("img").first();
57 |
58 | //Log.i("apod", "src: " + img.attr("src"));
59 |
60 | TileObject t = new TileObject();
61 | t.setId(link.id());
62 | t.setTitle(link.attr("title"));
63 | t.setHref(link.attr("href"));
64 |
65 | // uses higher res image for thumbnails
66 | String src = img.attr("src");
67 | if (src.contains(".gif"))
68 | src = src.replace(".gif", ".jpg");
69 | src = src.replace("-thumb", "-web");
70 |
71 | t.setSrc(src);
72 |
73 | mArray.add(t);
74 | } catch (IndexOutOfBoundsException e) {
75 | // stop the iteration
76 | i = limit;
77 | }
78 | }
79 |
80 | } catch (IOException e) {
81 | e.printStackTrace();
82 | }
83 | return mArray;
84 | }
85 |
86 | @Override
87 | protected void onPostExecute(ArrayList result) {
88 | onTaskComplete.setTaskComplete(result);
89 | }
90 |
91 | public interface OnTaskComplete {
92 | void setTaskComplete(ArrayList result);
93 | }
94 |
95 |
96 | }
--------------------------------------------------------------------------------
/app/src/main/res-navigation/layout/item_footer_nav_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
20 |
21 |
33 |
34 |
42 |
43 |
44 |
45 |
49 |
50 |
62 |
63 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/utils/Animation/SquareFlipper.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.utils.Animation;
2 |
3 | import android.graphics.Camera;
4 | import android.graphics.Matrix;
5 | import android.view.View;
6 | import android.view.animation.Animation;
7 | import android.view.animation.DecelerateInterpolator;
8 | import android.view.animation.Transformation;
9 |
10 | import com.daimajia.androidanimations.library.Techniques;
11 | import com.daimajia.androidanimations.library.YoYo;
12 |
13 | public class SquareFlipper {
14 | boolean stop = false;
15 | boolean justStarted = false;
16 | private View flippingView;
17 | private FlipAnimator flipAnimator;
18 |
19 | public void startAnimation(final View view) {
20 | if (flipAnimator != null) {
21 | flipAnimator.cancel();
22 | flipAnimator = null;
23 | }
24 | stop = false;
25 | justStarted = true;
26 | flippingView = view;
27 | flippingView.setVisibility(View.VISIBLE);
28 | flippingView.setAlpha(0);
29 |
30 | flipAnimator = new FlipAnimator();
31 | flipAnimator.setDuration(600);
32 | flipAnimator.setRepeatCount(-1);
33 | flipAnimator.setFillAfter(true);
34 | flipAnimator.setInterpolator(new DecelerateInterpolator());
35 | view.startAnimation(flipAnimator);
36 | }
37 |
38 | public void stopAnimation() {
39 | stop = true;
40 | }
41 |
42 | public class FlipAnimator extends Animation {
43 |
44 | private Camera camera;
45 | private float centerX;
46 | private float centerY;
47 |
48 | public FlipAnimator() {
49 | setFillAfter(true);
50 | }
51 |
52 | @Override
53 | public void initialize(int width, int height, int parentWidth, int parentHeight) {
54 | super.initialize(width, height, parentWidth, parentHeight);
55 | camera = new Camera();
56 | this.centerX = width / 2;
57 | this.centerY = height / 2;
58 | }
59 |
60 | @Override
61 | protected void applyTransformation(float interpolatedTime, Transformation t) {
62 | // Angle around the y-axis of the rotation at the given time. It is
63 | // calculated both in radians and in the equivalent degrees.
64 | final double radians = Math.PI * interpolatedTime;
65 | float degrees = (float) (180.0 * radians / Math.PI);
66 |
67 | if (interpolatedTime > 0.4 && interpolatedTime < 0.6) {
68 | if (justStarted) {
69 | flippingView.setAlpha(1.0f);
70 | YoYo.with(Techniques.FadeIn).duration(200).playOn(flippingView);
71 | justStarted = false;
72 | } else if (stop) {
73 | flippingView.setVisibility(View.INVISIBLE);
74 | flippingView.clearAnimation();
75 | }
76 | }
77 |
78 | final Matrix matrix = t.getMatrix();
79 |
80 | camera.save();
81 | camera.translate(0.0f, 0.0f, (float) (150.0 * Math.sin(radians)));
82 | camera.rotateX(true ? degrees : 0);
83 | camera.getMatrix(matrix);
84 | camera.restore();
85 |
86 | matrix.preTranslate(-centerX, -centerY);
87 | matrix.postTranslate(centerX, centerY);
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/utils/ui/starfield/Stars.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.utils.ui.starfield;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 |
6 | import java.util.ArrayList;
7 | import java.util.Iterator;
8 | import java.util.Random;
9 |
10 | public class Stars {
11 | public static final int LEFT = 0;
12 | public static final int RIGHT = 1;
13 | public static final int RANDOM = 2;
14 | private final ArrayList poss;
15 | private final ArrayList old;
16 | private float size;
17 | private float speed;
18 | private int number;
19 | private Random r = new Random();
20 | private int mWidth, mHeight;
21 |
22 | public Stars(float size, float speed, int number, int width, int height) {
23 | this.size = size;
24 | this.speed = speed;
25 | this.number = number;
26 | mWidth = width;
27 | mHeight = height;
28 |
29 | poss = new ArrayList();
30 | old = new ArrayList();
31 | }
32 |
33 | public void step(int direction) {
34 | if (r.nextInt(number) == 0) {
35 | int size = old.size();
36 | if (size > 0) {
37 | poss.add(old.remove(size - 1));
38 | } else {
39 | if (direction == RANDOM) {
40 | direction = r.nextInt(RANDOM); // Random direction
41 | }
42 | poss.add(new Pos(-1, 0, direction));
43 | }
44 | }
45 | int width = mWidth;
46 | int height = mHeight;
47 |
48 | synchronized (poss) {
49 | Iterator itr = poss.iterator();
50 | while (itr.hasNext()) {
51 | Pos pos = itr.next();
52 |
53 | switch (pos.mDirection) {
54 | case RIGHT:
55 | if (pos.x > width) {
56 | pos.x = -1;
57 | old.add(pos);
58 | itr.remove();
59 | continue;
60 | }
61 |
62 | if (pos.x < 0) {
63 | pos.x = 0;
64 | pos.y = r.nextInt() % height;
65 | }
66 | break;
67 | case LEFT:
68 | if (pos.x < 0) {
69 | pos.x = mWidth + 1;
70 | old.add(pos);
71 | itr.remove();
72 | continue;
73 | }
74 |
75 | if (pos.x > mWidth) {
76 | pos.x = mWidth;
77 | pos.y = r.nextInt() % height;
78 | }
79 | break;
80 | }
81 | pos.updatePos(speed);
82 | }
83 | }
84 | }
85 |
86 | public void draw(Canvas c, int width, int offset, Paint p) {
87 | for (Pos pos : poss) {
88 | if (pos.x + size > offset && pos.x < offset + width) {
89 | c.drawRect(pos.x - offset, pos.y, pos.x - offset + size, pos.y + size, p);
90 | }
91 | }
92 | }
93 |
94 | private static class Pos {
95 | private float x, y;
96 | private int mDirection;
97 |
98 | public Pos(float x, float y, int direction) {
99 | this.x = x;
100 | this.y = y;
101 | mDirection = direction;
102 | }
103 |
104 | public void updatePos(float move) {
105 | switch (mDirection) {
106 | case RIGHT:
107 | x += move;
108 | break;
109 | case LEFT:
110 | x -= move;
111 | break;
112 | }
113 | }
114 | }
115 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/utils/svg/SvgHelper.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.utils.svg;
2 |
3 | /**
4 | * Created by dereksmith on 15-05-04.
5 | */
6 |
7 | import android.content.Context;
8 | import android.graphics.Canvas;
9 | import android.graphics.Matrix;
10 | import android.graphics.Paint;
11 | import android.graphics.Path;
12 | import android.graphics.PathMeasure;
13 | import android.graphics.Rect;
14 | import android.graphics.RectF;
15 | import android.graphics.Region;
16 | import android.util.Log;
17 |
18 | import com.caverock.androidsvg.PreserveAspectRatio;
19 | import com.caverock.androidsvg.SVG;
20 | import com.caverock.androidsvg.SVGParseException;
21 |
22 | import java.util.ArrayList;
23 | import java.util.List;
24 |
25 | public class SvgHelper {
26 | private static final String LOG_TAG = "SVG";
27 |
28 | private final List mPaths = new ArrayList();
29 | private final Paint mSourcePaint;
30 |
31 | private SVG mSvg;
32 |
33 | public SvgHelper(Paint sourcePaint) {
34 | mSourcePaint = sourcePaint;
35 | }
36 |
37 | public void load(Context context, int svgResource) {
38 | if (mSvg != null) return;
39 | try {
40 | mSvg = SVG.getFromResource(context, svgResource);
41 | mSvg.setDocumentPreserveAspectRatio(PreserveAspectRatio.UNSCALED);
42 | } catch (SVGParseException e) {
43 | Log.e(LOG_TAG, "Could not load specified SVG resource", e);
44 | }
45 | }
46 |
47 | public List getPathsForViewport(final int width, final int height) {
48 | mPaths.clear();
49 |
50 | Canvas canvas = new Canvas() {
51 | private final Matrix mMatrix = new Matrix();
52 |
53 | @Override
54 | public int getWidth() {
55 | return width;
56 | }
57 |
58 | @Override
59 | public int getHeight() {
60 | return height;
61 | }
62 |
63 | @Override
64 | public void drawPath(Path path, Paint paint) {
65 | Path dst = new Path();
66 |
67 | //noinspection deprecation
68 | getMatrix(mMatrix);
69 | path.transform(mMatrix, dst);
70 |
71 | mPaths.add(new SvgPath(dst, new Paint(mSourcePaint)));
72 | }
73 | };
74 |
75 | RectF viewBox = mSvg.getDocumentViewBox();
76 | float scale = Math.min(width / viewBox.width(), height / viewBox.height());
77 |
78 | canvas.translate(
79 | (width - viewBox.width() * scale) / 2.0f,
80 | (height - viewBox.height() * scale) / 2.0f);
81 | canvas.scale(scale, scale);
82 |
83 | mSvg.renderToCanvas(canvas);
84 |
85 | return mPaths;
86 | }
87 |
88 | public static class SvgPath {
89 | private static final Region sRegion = new Region();
90 | private static final Region sMaxClip = new Region(
91 | Integer.MIN_VALUE, Integer.MIN_VALUE,
92 | Integer.MAX_VALUE, Integer.MAX_VALUE);
93 |
94 | final Path path;
95 | final Path renderPath = new Path();
96 | final Paint paint;
97 | final float length;
98 | final Rect bounds;
99 | final PathMeasure measure;
100 |
101 | SvgPath(Path path, Paint paint) {
102 | this.path = path;
103 | this.paint = paint;
104 |
105 | measure = new PathMeasure(path, false);
106 | this.length = measure.getLength();
107 |
108 | sRegion.setPath(path, sMaxClip);
109 | bounds = sRegion.getBounds();
110 | }
111 | }
112 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/ui/fragments/FragWelcomeInfo.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.ui.fragments;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.text.Html;
6 | import android.text.method.LinkMovementMethod;
7 | import android.util.Log;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.TextView;
12 |
13 | import com.derek_s.hubble_gallery.R;
14 | import com.derek_s.hubble_gallery.base.FragBase;
15 | import com.derek_s.hubble_gallery.home.ActHome;
16 | import com.derek_s.hubble_gallery.utils.ui.FontFactory;
17 |
18 | import butterknife.Bind;
19 | import butterknife.ButterKnife;
20 |
21 | public class FragWelcomeInfo extends FragBase {
22 | private static final String CURRENT_PAGE = "current_page";
23 | private static String TAG = "FragWelcomeInfo";
24 | private static String PAGE_KEY = "page_number";
25 | private static int pagePos = 1;
26 | @Bind(R.id.tv_welcome_info)
27 | TextView tvInfo;
28 | @Bind(R.id.tv_enter)
29 | TextView tvEnter;
30 |
31 | public static FragWelcomeInfo newInstance(int position) {
32 | final FragWelcomeInfo fragment = new FragWelcomeInfo();
33 | // Supply int position as an argument.
34 | Bundle args = new Bundle();
35 | args.putInt(PAGE_KEY, position);
36 | fragment.setArguments(args);
37 |
38 | return fragment;
39 | }
40 |
41 | @Override
42 | public void onCreate(Bundle savedInstanceState) {
43 | super.onCreate(savedInstanceState);
44 | if (savedInstanceState == null) {
45 | pagePos = getArguments() != null ? getArguments().getInt(PAGE_KEY) : 1;
46 | } else {
47 | pagePos = savedInstanceState.getInt(CURRENT_PAGE);
48 | }
49 | }
50 |
51 | @Override
52 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
53 | Bundle savedInstanceState) {
54 | View rootView = inflater.inflate(R.layout.frag_welcome_info, container, false);
55 | ButterKnife.bind(this, rootView);
56 |
57 | tvInfo.setTypeface(FontFactory.getCondensedRegular(getActivity()));
58 | tvInfo.setVisibility(View.VISIBLE);
59 | tvEnter.setVisibility(View.INVISIBLE);
60 |
61 | Log.i(TAG, "onCreateView pagePos = " + pagePos);
62 |
63 | switch (pagePos) {
64 | case (1):
65 | tvInfo.setText(getActivity().getResources().getText(R.string.info_1));
66 | break;
67 | case (2):
68 | tvInfo.setText(getActivity().getResources().getText(R.string.info_2));
69 | break;
70 | case (3):
71 | tvInfo.setText(Html.fromHtml(getActivity().getResources().getString(R.string.info_3)));
72 | tvInfo.setMovementMethod(LinkMovementMethod.getInstance());
73 | break;
74 | case (4):
75 | tvInfo.setVisibility(View.INVISIBLE);
76 | tvEnter.setTypeface(FontFactory.getCondensedLight(getActivity()));
77 | tvEnter.setVisibility(View.VISIBLE);
78 | tvEnter.setOnClickListener(new View.OnClickListener() {
79 | @Override
80 | public void onClick(View v) {
81 | Intent i = new Intent(getActivity(), ActHome.class);
82 | i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
83 | startActivity(i);
84 | getActivity().overridePendingTransition(android.R.anim.fade_in, R.anim.zoom_in_exit);
85 | }
86 | });
87 | break;
88 | }
89 |
90 | return rootView;
91 | }
92 |
93 | @Override
94 | public void onSaveInstanceState(Bundle outState) {
95 | outState.putInt(CURRENT_PAGE, pagePos);
96 | super.onSaveInstanceState(outState);
97 | }
98 |
99 |
100 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/utils/ui/starfield/StarField.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.utils.ui.starfield;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Color;
5 | import android.graphics.Paint;
6 | import android.os.Handler;
7 | import android.view.SurfaceHolder;
8 |
9 | public class StarField {
10 |
11 | private static final int TILES_NORMAL = 1;
12 | private static final int TILES_LARGE = 5;
13 | private static final int TILES_HUGE = 7;
14 | private static final float AMMOUNT_FEW = 3f;
15 | private static final float AMMOUNT_NORMAL = 2f;
16 | private static final float AMMOUNT_LOTS = 0.2f;
17 | Paint mPaintFill = new Paint();
18 | Paint mPaintStar = new Paint();
19 | Paint mPaintText = new Paint();
20 | private String TAG = getClass().getSimpleName();
21 | private SurfaceHolder surfaceHolder;
22 | private boolean mVisible = true;
23 | private Handler mHandler = new Handler();
24 | private int mWidth, mHeight, xWidth;
25 | private int mOffsetSpan;
26 | private int mOffset = 1;
27 | private int mTiles = TILES_NORMAL;
28 | private int mDirection = Stars.RIGHT;
29 | private float mAmmount = AMMOUNT_NORMAL;
30 | private Stars[] stars;
31 | private boolean firstTime = true;
32 | private Runnable mDraw = new Runnable() {
33 | @Override
34 | public void run() {
35 | drawFrame();
36 | }
37 | };
38 |
39 | public StarField(SurfaceHolder surfaceHolder, int mWidth, int mHeight) {
40 | this.surfaceHolder = surfaceHolder;
41 |
42 | this.mWidth = mWidth;
43 | this.mHeight = mHeight;
44 |
45 | mPaintFill.setStyle(Paint.Style.FILL);
46 | mPaintFill.setColor(Color.BLACK);
47 |
48 | mPaintStar.setStyle(Paint.Style.FILL);
49 | mPaintStar.setColor(Color.WHITE);
50 | mPaintStar.setAntiAlias(true);
51 | }
52 |
53 | public void start() {
54 | drawFrame();
55 | }
56 |
57 | public void stop() {
58 | mVisible = false;
59 | mHandler.removeCallbacks(mDraw);
60 | }
61 |
62 | private void updateXWidthAndOffsetSpan() {
63 | xWidth = mWidth * mTiles;
64 | mOffsetSpan = mWidth * (mTiles - 1);
65 | }
66 |
67 | private void drawFrame() {
68 | Canvas c = null;
69 | if (firstTime) {
70 | firstTime = false;
71 | updateXWidthAndOffsetSpan();
72 | try {
73 | c = surfaceHolder.lockCanvas();
74 | if (c != null) {
75 | c.drawRect(0, 0, mWidth, mHeight, mPaintFill);
76 | c.drawText("Loading", 5, 75, mPaintText);
77 | }
78 | } finally {
79 | if (c != null) surfaceHolder.unlockCanvasAndPost(c);
80 | c = null;
81 | }
82 | Stars far = new Stars(1f, 1f, Math.round(3 * mAmmount), xWidth, mHeight);
83 | Stars middle = new Stars(2.1f, 1.5f, Math.round(5 * mAmmount), xWidth, mHeight);
84 | Stars near = new Stars(2.9f, 2.5f, Math.round(7 * mAmmount), xWidth, mHeight);
85 | Stars close = new Stars(4f, 15f, Math.round(40 * mAmmount), xWidth, mHeight);
86 |
87 | stars = new Stars[]{far, middle, near, close};
88 |
89 | int steps = mWidth * 2;
90 | for (Stars star : stars) {
91 | for (int i = 0; i < steps; i++) {
92 | star.step(mDirection);
93 | }
94 | }
95 | }
96 |
97 | try {
98 | c = surfaceHolder.lockCanvas();
99 | if (c != null) {
100 | c.drawRect(0, 0, mWidth, mHeight, mPaintFill);
101 |
102 | for (Stars star : stars) {
103 | star.step(mDirection);
104 | star.draw(c, mWidth, mOffset, mPaintStar);
105 | }
106 | }
107 | } finally {
108 | if (c != null) surfaceHolder.unlockCanvasAndPost(c);
109 | }
110 |
111 | mHandler.removeCallbacks(mDraw);
112 | if (mVisible) {
113 | mHandler.postDelayed(mDraw, 40);
114 | }
115 | }
116 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
16 |
17 |
18 |
23 |
24 |
27 |
28 |
31 |
32 |
35 |
36 |
37 |
38 |
44 |
45 |
51 |
52 |
56 |
57 |
61 |
62 |
66 |
67 |
71 |
72 |
76 |
77 |
81 |
82 |
86 |
87 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/ui/activities/ActWelcome.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.ui.activities;
2 |
3 | import android.graphics.Color;
4 | import android.graphics.Point;
5 | import android.os.Build;
6 | import android.os.Bundle;
7 | import android.support.v4.app.Fragment;
8 | import android.view.Display;
9 | import android.view.SurfaceView;
10 | import android.view.View;
11 | import android.view.Window;
12 | import android.view.WindowManager;
13 | import android.widget.RelativeLayout;
14 |
15 | import com.derek_s.hubble_gallery.R;
16 | import com.derek_s.hubble_gallery.base.ActBase;
17 | import com.derek_s.hubble_gallery.internal.di.ActivityComponent;
18 | import com.derek_s.hubble_gallery.ui.adapters.OnboardingFragmentPager;
19 | import com.derek_s.hubble_gallery.utils.ui.starfield.StarField;
20 |
21 | import butterknife.Bind;
22 | import butterknife.ButterKnife;
23 | import fr.castorflex.android.verticalviewpager.VerticalViewPager;
24 |
25 | public class ActWelcome extends ActBase {
26 |
27 | @Bind(R.id.rl_onboarding)
28 | RelativeLayout rlOnboarding;
29 | @Bind(R.id.sv_starfield)
30 | SurfaceView svStarfield;
31 | @Bind(R.id.vertical_pager)
32 | VerticalViewPager verticalViewPager;
33 | int width;
34 | int height;
35 | boolean fromOnCreate = false;
36 | private StarField starField;
37 |
38 | @Override
39 | protected void onCreate(Bundle savedInstanceState) {
40 | super.onCreate(savedInstanceState);
41 | fromOnCreate = true;
42 | setContentView(R.layout.act_welcome);
43 | ButterKnife.bind(this);
44 |
45 | setWindowAttributes();
46 | setWindowSizes();
47 |
48 | starField = new StarField(svStarfield.getHolder(), width, height);
49 | starField.start();
50 |
51 | // remove all fragments from manager
52 | if (getSupportFragmentManager().getFragments() != null)
53 | for (Fragment fragment : getSupportFragmentManager().getFragments()) {
54 | getSupportFragmentManager().beginTransaction().remove(fragment).commit();
55 | }
56 |
57 | verticalViewPager.setAdapter(new OnboardingFragmentPager(getSupportFragmentManager()));
58 | verticalViewPager.setOffscreenPageLimit(5);
59 | }
60 |
61 | @Override
62 | public void onPause() {
63 | starField.stop();
64 | super.onPause();
65 | }
66 |
67 | @Override
68 | public void onResume() {
69 | if (fromOnCreate) {
70 | fromOnCreate = false;
71 | } else {
72 | setWindowSizes();
73 | starField = new StarField(svStarfield.getHolder(), width, height);
74 | starField.start();
75 | }
76 | super.onResume();
77 | }
78 |
79 | private void setWindowSizes() {
80 | Display display = getWindowManager().getDefaultDisplay();
81 | Point size = new Point();
82 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
83 | display.getRealSize(size);
84 | } else {
85 | display.getSize(size);
86 | }
87 | width = size.x;
88 | height = size.y;
89 | }
90 |
91 | private void setWindowAttributes() {
92 | Window window = getWindow();
93 |
94 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
95 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
96 | window.setStatusBarColor(Color.TRANSPARENT);
97 | window.setNavigationBarColor(Color.TRANSPARENT);
98 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
99 | window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
100 | window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
101 | }
102 |
103 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
104 | getWindow().getDecorView().setSystemUiVisibility(
105 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
106 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
107 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
108 | }
109 | }
110 |
111 | @Override
112 | protected void injectComponent(ActivityComponent activityComponent) {
113 | activityComponent.inject(this);
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/nav_drawer/adapters/GroupViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.nav_drawer.adapters
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.os.Build
6 | import android.support.v4.content.ContextCompat
7 | import android.view.LayoutInflater
8 | import android.view.View
9 | import android.view.ViewGroup
10 | import android.view.animation.RotateAnimation
11 | import android.widget.ImageView
12 | import android.widget.TextView
13 | import butterknife.bindView
14 | import com.bignerdranch.expandablerecyclerview.ViewHolder.ParentViewHolder
15 | import com.derek_s.hubble_gallery.R
16 | import com.derek_s.hubble_gallery.nav_drawer.model.SectionChildObject
17 | import com.derek_s.hubble_gallery.utils.ui.FontFactory
18 |
19 | class GroupViewHolder private constructor(itemView: View) : ParentViewHolder(itemView) {
20 |
21 | val tvTitle: TextView by bindView(R.id.tv_title)
22 | val ivExpand: ImageView by bindView(R.id.iv_expand)
23 |
24 | private val INITIAL_POSITION = 0.0f
25 | private val ROTATED_POSITION = 180f
26 |
27 | init {
28 | beautifyViews()
29 | }
30 |
31 | fun beautifyViews() {
32 | tvTitle.typeface = FontFactory.getMedium(itemView.context)
33 | }
34 |
35 | fun onBind(item: NavigationAdapterItem, listener: NavDrawerAdapter.NavAdapterListener,
36 | pos: Int, selectedQuery: String) {
37 | var section: SectionChildObject = item.`object` as SectionChildObject
38 |
39 | if (section.query.equals(selectedQuery)) {
40 | tvTitle.setBackgroundColor(ContextCompat.getColor(itemView.context, R.color.focused_color));
41 | tvTitle.setTextColor(ContextCompat.getColor(itemView.context, R.color.seleted_item_color));
42 | } else {
43 | tvTitle.setBackgroundResource(R.drawable.selector_default);
44 | tvTitle.setTextColor(ContextCompat.getColor(itemView.context, R.color.body_dark_theme));
45 | }
46 |
47 | tvTitle.text = section.sectionTitle
48 | tvTitle.setOnClickListener {
49 | listener.onSectionClicked(section)
50 | listener.setSelectedQuery(section.query)
51 | tvTitle.setBackgroundColor(ContextCompat.getColor(itemView.context, R.color.focused_color));
52 | tvTitle.setTextColor(ContextCompat.getColor(itemView.context, R.color.seleted_item_color));
53 | }
54 |
55 | if (item.childObjectList == null) {
56 | ivExpand.visibility = View.GONE
57 | } else {
58 | ivExpand.visibility = View.VISIBLE
59 | ivExpand.setOnClickListener {
60 | if (isExpanded) {
61 | collapseView()
62 | } else {
63 | expandView()
64 | }
65 | }
66 | }
67 | }
68 |
69 | @SuppressLint("NewApi")
70 | override fun setExpanded(expanded: Boolean) {
71 | super.setExpanded(expanded)
72 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
73 | if (expanded) {
74 | ivExpand.rotation = ROTATED_POSITION
75 | } else {
76 | ivExpand.rotation = INITIAL_POSITION
77 | }
78 | }
79 | }
80 |
81 | override fun onExpansionToggled(expanded: Boolean) {
82 | super.onExpansionToggled(expanded)
83 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
84 | val rotateAnimation: RotateAnimation
85 | if (expanded) {
86 | // rotate clockwise
87 | rotateAnimation = RotateAnimation(ROTATED_POSITION,
88 | INITIAL_POSITION,
89 | RotateAnimation.RELATIVE_TO_SELF, 0.5f,
90 | RotateAnimation.RELATIVE_TO_SELF, 0.5f)
91 | } else {
92 | // rotate counterclockwise
93 | rotateAnimation = RotateAnimation(-1 * ROTATED_POSITION,
94 | INITIAL_POSITION,
95 | RotateAnimation.RELATIVE_TO_SELF, 0.5f,
96 | RotateAnimation.RELATIVE_TO_SELF, 0.5f)
97 | }
98 |
99 | rotateAnimation.duration = 200
100 | rotateAnimation.fillAfter = true
101 | ivExpand.startAnimation(rotateAnimation)
102 | }
103 | }
104 |
105 | override fun shouldItemViewClickToggleExpansion(): Boolean {
106 | return false
107 | }
108 |
109 | companion object {
110 | fun create(context: Context, viewGroup: ViewGroup): GroupViewHolder {
111 | return GroupViewHolder(LayoutInflater.from(context).inflate(R.layout.item_group,
112 | viewGroup, false))
113 | }
114 | }
115 |
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/app/src/main/res-details/layout/act_details.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
13 |
16 |
17 |
23 |
24 |
33 |
34 |
35 |
36 |
44 |
45 |
59 |
60 |
68 |
69 |
85 |
86 |
87 |
88 |
89 |
90 |
100 |
101 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | maven { url 'https://maven.fabric.io/public' }
4 | mavenCentral()
5 | }
6 |
7 | dependencies {
8 | //noinspection GradleDynamicVersion
9 | classpath 'io.fabric.tools:gradle:1.+'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | apply plugin: 'com.android.application'
15 | apply plugin: 'kotlin-android'
16 | apply plugin: 'io.fabric'
17 |
18 | repositories {
19 | maven { url 'https://maven.fabric.io/public' }
20 | maven { url "https://jitpack.io" }
21 | mavenCentral()
22 | }
23 |
24 | kapt {
25 | generateStubs = true
26 | }
27 |
28 | android {
29 | compileSdkVersion 23
30 | buildToolsVersion "23.0.3"
31 |
32 | def verName = "1.5.1"
33 | def verCode = 21
34 |
35 | defaultConfig {
36 | applicationId 'com.derek_s.hubble_gallery'
37 | minSdkVersion 16
38 | targetSdkVersion 22
39 | versionCode verCode
40 | versionName verName
41 | multiDexEnabled = true
42 | }
43 |
44 | buildTypes {
45 | release {
46 | minifyEnabled false
47 | }
48 | }
49 |
50 | sourceSets {
51 | main.res.srcDirs = ['src/main/res',
52 | 'src/main/res-details',
53 | 'src/main/res-navigation',
54 | 'src/main/res-welcome']
55 | main.java.srcDirs = ['src/main/kotlin',
56 | 'src/main/java']
57 | }
58 |
59 | packagingOptions {
60 | exclude 'META-INF/DEPENDENCIES.txt'
61 | exclude 'META-INF/LICENSE.txt'
62 | exclude 'META-INF/NOTICE.txt'
63 | exclude 'META-INF/NOTICE'
64 | exclude 'META-INF/LICENSE'
65 | exclude 'META-INF/DEPENDENCIES'
66 | exclude 'META-INF/notice.txt'
67 | exclude 'META-INF/license.txt'
68 | exclude 'META-INF/dependencies.txt'
69 | exclude 'META-INF/LGPL2.1'
70 | exclude 'AndroidManifest.xml'
71 | exclude 'META-INF/services/javax.annotation.processing.Processor'
72 | }
73 |
74 | lintOptions {
75 | disable 'InvalidPackage'
76 | }
77 | }
78 |
79 | dependencies {
80 | compile fileTree(dir: 'libs', include: ['*.jar'])
81 |
82 | // Google - Android
83 | compile "com.android.support:support-v4:$android_support_version"
84 | compile "com.android.support:appcompat-v7:$android_support_version"
85 | compile "com.android.support:palette-v7:$android_support_version"
86 | compile "com.android.support:multidex:$multidex_version"
87 |
88 | // kotlin related
89 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
90 | provided "org.glassfish:javax.annotation:$javaxannotations_version"
91 |
92 | // general
93 | compile "com.google.dagger:dagger:$dagger_version"
94 | kapt "com.google.dagger:dagger-compiler:$dagger_version"
95 | compile "com.jakewharton:kotterknife:$kotterknife_version"
96 | compile "com.jakewharton:butterknife:$butterknife_version"
97 | kapt "com.jakewharton:butterknife:$butterknife_version"
98 | compile "com.google.code.gson:gson:$gson_version"
99 | compile "com.squareup.picasso:picasso:$picasso_version"
100 | compile "com.nineoldandroids:library:$nineoldandroids_version"
101 | provided "javax.annotation:jsr250-api:$jsr250_version"
102 | provided "org.projectlombok:lombok:$lombok_version"
103 | kapt "org.projectlombok:lombok:$lombok_version"
104 |
105 | // network
106 | compile "org.jsoup:jsoup:$jsoup_version"
107 |
108 | // UI
109 | compile "com.bignerdranch.android:expandablerecyclerview:$expandablerecycler_version"
110 | compile "com.github.ksoichiro:android-observablescrollview:$observablescrollview_version"
111 | compile "com.daimajia.easing:library:$daimajiaeasing_version"
112 | compile "com.daimajia.androidanimations:library:$androidanimations_version"
113 | compile "com.github.johnpersano:supertoasts:$supertoasts_version"
114 | compile "com.github.castorflex.verticalviewpager:library:$verticalviewpager_version"
115 | compile "com.caverock:androidsvg:$androidsvg_version"
116 | compile("com.github.afollestad.material-dialogs:core:$materialdialogs_version") {
117 | transitive = true
118 | }
119 |
120 | compile("com.crashlytics.sdk.android:crashlytics:$crashlytics_version") {
121 | transitive = true;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/utils/ui/FontFactory.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.utils.ui;
2 |
3 | import android.content.Context;
4 | import android.graphics.Typeface;
5 |
6 | import com.derek_s.hubble_gallery.R;
7 |
8 | /**
9 | * Created by dereksmith on 15-03-07.
10 | */
11 | public class FontFactory {
12 |
13 | /*
14 | To use: tv1.setTypeface(FontFactory.getRegular(getContext());
15 | */
16 |
17 | private static Typeface t1;
18 | private static Typeface t2;
19 | private static Typeface t3;
20 | private static Typeface t4;
21 | private static Typeface t5;
22 | private static Typeface t6;
23 | private static Typeface t7;
24 | private static Typeface t8;
25 | private static Typeface t9;
26 | private static Typeface t10;
27 | private static Typeface t11;
28 | private static Typeface t12;
29 | private static Typeface t13;
30 | private static Typeface t14;
31 | private static Typeface t15;
32 | private static Typeface t16;
33 | private static Typeface t17;
34 | private static Typeface t18;
35 |
36 | public static Typeface getBlack(Context c) {
37 | if (t1 == null) {
38 | t1 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_black));
39 | }
40 | return t1;
41 | }
42 |
43 | public static Typeface getBlackItalic(Context c) {
44 | if (t2 == null) {
45 | t2 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_black_italic));
46 | }
47 | return t2;
48 | }
49 |
50 | public static Typeface getBold(Context c) {
51 | if (t3 == null) {
52 | t3 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_bold));
53 | }
54 | return t3;
55 | }
56 |
57 | public static Typeface getBoldItalic(Context c) {
58 | if (t4 == null) {
59 | t4 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_bold_italic));
60 | }
61 | return t4;
62 | }
63 |
64 | public static Typeface getItalic(Context c) {
65 | if (t5 == null) {
66 | t5 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_italic));
67 | }
68 | return t5;
69 | }
70 |
71 | public static Typeface getLight(Context c) {
72 | if (t6 == null) {
73 | t6 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_light));
74 | }
75 | return t6;
76 | }
77 |
78 | public static Typeface getLightItalic(Context c) {
79 | if (t7 == null) {
80 | t7 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_light_italic));
81 | }
82 | return t7;
83 | }
84 |
85 | public static Typeface getMedium(Context c) {
86 | if (t8 == null) {
87 | t8 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_medium));
88 | }
89 | return t8;
90 | }
91 |
92 | public static Typeface getMediumItalic(Context c) {
93 | if (t9 == null) {
94 | t9 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_medium_italic));
95 | }
96 | return t9;
97 | }
98 |
99 | public static Typeface getRegular(Context c) {
100 | if (t10 == null) {
101 | t10 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_regular));
102 | }
103 | return t10;
104 | }
105 |
106 | public static Typeface getThin(Context c) {
107 | if (t11 == null) {
108 | t11 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_thin));
109 | }
110 | return t11;
111 | }
112 |
113 | public static Typeface getThinItalic(Context c) {
114 | if (t12 == null) {
115 | t12 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_thin_italic));
116 | }
117 | return t12;
118 | }
119 |
120 | public static Typeface getCondensedBold(Context c) {
121 | if (t13 == null) {
122 | t13 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_condensed_bold));
123 | }
124 | return t13;
125 | }
126 |
127 | public static Typeface getCondensedBoldItalic(Context c) {
128 | if (t14 == null) {
129 | t14 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_condensed_bold_italic));
130 | }
131 | return t14;
132 | }
133 |
134 | public static Typeface getCondensedItalic(Context c) {
135 | if (t15 == null) {
136 | t15 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_condensed_italic));
137 | }
138 | return t15;
139 | }
140 |
141 | public static Typeface getCondensedLight(Context c) {
142 | if (t16 == null) {
143 | t16 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_condensed_light));
144 | }
145 | return t16;
146 | }
147 |
148 | public static Typeface getCondensedLightItalic(Context c) {
149 | if (t17 == null) {
150 | t17 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_condensed_light_italic));
151 | }
152 | return t17;
153 | }
154 |
155 | public static Typeface getCondensedRegular(Context c) {
156 | if (t18 == null) {
157 | t18 = Typeface.createFromAsset(c.getAssets(), c.getString(R.string.roboto_condensed_regular));
158 | }
159 | return t18;
160 | }
161 |
162 | }
--------------------------------------------------------------------------------
/app/src/main/res/values-de/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hubble Gallerie
4 | Über
5 | Zu Favoriten hinzufügen
6 | Link kopieren
7 | Dummy Knopf
8 | Eintreten
9 | Fehler beim Laden des Bildes
10 | Fehler beim Speichern des Bildes
11 | Favoriten
12 | Beste Auflösung
13 | Vollbild
14 | Bilder gespeichert in /Pictures/Hubble
15 | Das Weltraumteleskop \"Hubble\" wurde 1990 in eine niedrige Erdumlaufbahn (low earth orbit) gestartet. Es ist bis heute in Betrieb. Hubble verfügt über ein 2,4-Meter-Spiegelteleskop uns über vier Hauptinstrumente, die im nahen Ultraviolettbereich, im infraroten Himmelsbeobachtungen ermöglichen.
16 | Hubbles Umlaufbahn befindet sich außerhalb der Erdatmosphäre, so dass atmosphärische Aberrationen entfallen. Dies ermöglicht äußerst hochauflösende Aufnahmen mit vernachlässigbarem Hintergrundleuchten. Hubble hat einige der detailreichsten Aufnahmen im sichtbaren Wellenlängenbereich gemacht über die wir bis heute verfügen. Hubble erlaubt damit Tiefe Einblicke in Raum und Zeit. Zahlreiche Beobachtungen von Hubble haben zu Durchbrüchen in der Astrophysik geführt, so konnte bspw. die Expansionsrate des Universums sehr genau bestimmt werden.
17 | Am beliebtesten
18 | Schließen
19 | Öffnen
20 | Kein Internetzugriff
21 | Im Browser öffnen
22 |
23 | Neu laden
24 | Aus Favoriten entfernen
25 | Erneut versuchen
26 | Bild speichern
27 | Herunterscrollen
28 | Suchen
29 |
30 | Bild teilen
31 | Link teilen
32 | Einführung anzeigen
33 | Sortiere nach
34 | Quelltext zeigen
35 | Details
36 | Bildbetrachter
37 | Willkommen
38 | Entdecke Bilder und speichere sie als Favorit. Sie werden dann hier erscheinen.
39 | Du hast bisher keine Favoriten gesetzt.
40 | Ich bin sicher, du findest einige Favoriten!
43 | Entwickelt von Derek Smith,
44 | folge mir auf Twitter @drkcsm, um \"Hallo\" zu sagen. Oder noch besser: Schicke mir etwas Taschengeld anpaypal.me/derekcsm
45 | und hilf mit, dass dieses Projekt weitergeführt wird! <3
46 |
47 |
48 |
49 | Beiträge von:
50 |
51 | - PedroVictorB
52 |
53 |
54 |
55 |
56 |
57 | Hubble Gallerie ist ein Open Source Projekt
58 | github.com/derekcsm/hubble_gallery
59 | Bewertungen im Play Store sind willkommen! Wenn Du daran interessiert bist, etwas zu dem Projekt beizutragen wäre das klasse!
60 | Bitte beachte die Richtlinien in README und ich werde Deinen Beitrag in das Projekt aufnehmen.
61 |
62 |
63 |
64 | Der Inhalt dieser App wird bereitgestellt von HubbleSite,
65 | betrieben vom Space Telescope Science Institute\'s Office of Public Outreach.
66 |
67 |
68 |
69 | Diese ist keine offizielle App. Es besteht keinerlei Verbindung zu NASA oder JPL.
70 | Der gesamte Quellcode dieses Projektes wurde lizenziert unter der
71 | Apache License Version 2.0.
72 |
73 |
74 | ]]>
75 | Open Source Projekt. Entwickelt von@drkcsm.
77 | Wenn Du in Spendierlaune bist, sende etwas Taschengeld an paypal.me/derekcsm und hilf, das Projekt am Laugen zu halten! ]]>
78 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/ui/widgets/PopOutCircularProgressDrawable.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.ui.widgets;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorListenerAdapter;
5 | import android.animation.ObjectAnimator;
6 | import android.graphics.Canvas;
7 | import android.graphics.Color;
8 | import android.graphics.Paint;
9 | import android.graphics.Rect;
10 | import android.view.animation.AccelerateDecelerateInterpolator;
11 |
12 | /**
13 | * @author Hannes Dorfmann
14 | */
15 | public class PopOutCircularProgressDrawable extends CircularProgressDrawable {
16 |
17 | // TODO make private and final
18 | public static float POPOUT_SHOW_DURATION = 800;
19 | public static float POPOUT_HIDE_DURATION = ANGLE_ANIMATOR_DURATION;
20 |
21 | private boolean mPopOut = true;
22 | private int mPopOutColor;
23 | private float mTargetRadius;
24 | private float mCurrentRadius;
25 | private float mCircleCenterX;
26 | private float mCircleCenterY;
27 | private ObjectAnimator mShowPopOutAnimator;
28 | private ObjectAnimator mHidePopOutAnimator;
29 | private float mProgress = 0f;
30 | private int mHidePopOutProgress = 255;
31 | private boolean mPopOutComplete = false;
32 | private boolean mPopOutFading = true;
33 | private boolean mOriginalPopOutFading;
34 | private Paint mPaint = new Paint();
35 |
36 | public PopOutCircularProgressDrawable(int popOutColor, int[] colors, float strokeWidth,
37 | float popOutStrokeWidth, float speed, int minSweepAngle, int maxSweepAngle,
38 | boolean popOutFading, Style style) {
39 |
40 | super(colors, strokeWidth, speed, minSweepAngle, maxSweepAngle, style);
41 | mPopOutColor = popOutColor;
42 | mPopOutFading = popOutFading;
43 | mOriginalPopOutFading = popOutFading;
44 | mPaint.setAntiAlias(true);
45 | mPaint.setStyle(Paint.Style.STROKE);
46 | mPaint.setStrokeWidth(popOutStrokeWidth);
47 | mPaint.setColor(mPopOutColor);
48 |
49 | int diff = (int) ((popOutStrokeWidth - strokeWidth) / 2 + 0.5f);
50 |
51 | setCirclePadding(diff, diff, diff, diff);
52 | }
53 |
54 | @Override
55 | protected void onBoundsChange(Rect bounds) {
56 | super.onBoundsChange(bounds);
57 |
58 | mCircleCenterX = bounds.exactCenterX();
59 | mCircleCenterY = bounds.exactCenterY();
60 | mTargetRadius = (bounds.height() - mPaint.getStrokeWidth()) / 2;
61 | }
62 |
63 | public int getPopOutColor() {
64 | return mPaint.getColor();
65 | }
66 |
67 | public PopOutCircularProgressDrawable setPopOutColor(int color) {
68 | mPopOutColor = color;
69 | mPaint.setColor(color);
70 | return this;
71 | }
72 |
73 | public PopOutCircularProgressDrawable setPopOut(boolean enabled) {
74 | mPopOut = enabled;
75 | return this;
76 | }
77 |
78 | public boolean isPopOutEnabled() {
79 | return mPopOut;
80 | }
81 |
82 | @Override
83 | public void reset() {
84 | super.reset();
85 | mPopOutComplete = false;
86 | mCurrentRadius = 0;
87 | mPaint.setAlpha(255);
88 | mPaint.setColor(mPopOutColor);
89 | mPopOutFading = mOriginalPopOutFading;
90 | }
91 |
92 |
93 | private void startPopOutAnimation() {
94 | stop();
95 |
96 | mShowPopOutAnimator =
97 | ObjectAnimator.ofFloat(this, "progress", 0f, 1f).setDuration(
98 | (int) (POPOUT_SHOW_DURATION / getSpeed() + 0.5));
99 | mShowPopOutAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
100 |
101 | mShowPopOutAnimator.addListener(new AnimatorListenerAdapter() {
102 | @Override
103 | public void onAnimationCancel(Animator animation) {
104 | reset();
105 | }
106 |
107 | @Override
108 | public void onAnimationEnd(Animator animation) {
109 | startCircleAndPopHiding();
110 | }
111 | });
112 |
113 | mShowPopOutAnimator.start();
114 | }
115 |
116 | @Override
117 | public void draw(Canvas canvas) {
118 | super.draw(canvas);
119 | canvas.drawCircle(mCircleCenterX, mCircleCenterY, mCurrentRadius, mPaint);
120 | }
121 |
122 | public float getProgress() {
123 | return mProgress;
124 | }
125 |
126 | @Override
127 | public void setProgress(float progress) {
128 | mProgress = progress;
129 |
130 | if (mPopOutFading) {
131 | int targetAlpha = Color.alpha(mPopOutColor);
132 | int currentAlpha = (int) (mapPoint(progress, 0, 0.85f, targetAlpha / 10, targetAlpha) + 0.5);
133 | mPaint.setAlpha(currentAlpha);
134 | if (currentAlpha >= targetAlpha) {
135 | mPopOutFading = false;
136 | }
137 | }
138 |
139 | mCurrentRadius = mapPoint(progress, 0, 1, 0, mTargetRadius);
140 | if (progress == 1f) {
141 | mPopOutComplete = true;
142 | }
143 | invalidateSelf();
144 | }
145 |
146 | public float getHidePopOut() {
147 | return mHidePopOutProgress;
148 | }
149 |
150 | public void setHidePopOut(int progress) {
151 | mHidePopOutProgress = progress;
152 | mPaint.setAlpha(progress);
153 | invalidateSelf();
154 | }
155 |
156 | protected void startCircleAndPopHiding() {
157 | super.start();
158 | mHidePopOutAnimator =
159 | ObjectAnimator.ofInt(this, "hidePopOut", Color.alpha(mPopOutColor), 0).setDuration(
160 | (int) (POPOUT_HIDE_DURATION / getSpeed() + 0.5f));
161 |
162 | mHidePopOutAnimator.addListener(new AnimatorListenerAdapter() {
163 | @Override
164 | public void onAnimationCancel(Animator animation) {
165 | reset();
166 | }
167 | });
168 | mHidePopOutAnimator.start();
169 | }
170 |
171 | @Override
172 | public void start() {
173 | if (!mPopOutComplete) {
174 | startPopOutAnimation();
175 | } else {
176 | startCircleAndPopHiding();
177 | }
178 | }
179 |
180 | @Override
181 | public void stop() {
182 | if (mShowPopOutAnimator != null) {
183 | mShowPopOutAnimator.cancel();
184 | }
185 |
186 | if (mHidePopOutAnimator != null) {
187 | mHidePopOutAnimator.cancel();
188 | }
189 |
190 | super.stop();
191 | }
192 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hubble Gallery
5 | Hubble
6 | Welcome
7 |
8 |
9 | Favorites
10 | Search
11 | About
12 | Review & share
13 |
14 | Sort by
15 | Most popular
16 | Highest resolution
17 | Details
18 |
19 |
20 | Set image as…
21 | Share image
22 | Save image
23 | Open in browser
24 | Share link
25 | Copy link
26 | Add to favorites
27 | Remove from favorites
28 |
29 | Error during image saving
30 | Image saved to /Pictures/Hubble
31 | Show image fullscreen
32 |
33 |
34 | Explore and favorite images, they\'ll show up here
35 | You have no favorites… yet
36 | I\'m sure you\'ll find some favorites!
37 |
38 |
39 | No internet connection
40 | Retry
41 | Reload
42 | Error loading image
43 |
44 |
45 | Scroll down
46 | Enter
47 | The Hubble Space Telescope was launched into
48 | low Earth orbit in 1990, and remains in operation. With a 2.4-meter (7.9 ft) mirror, Hubble\'s
49 | four main instruments observe in the near ultraviolet, visible, and near infrared spectra.
50 |
51 | Hubble\'s orbit outside the distortion of Earth\'s atmosphere allows it to take
52 | extremely high-resolution images with negligible background light. Hubble has recorded some of
53 | the most detailed visible-light images ever, allowing a deep view into space and time. Many
54 | Hubble observations have led to breakthroughs in astrophysics, such as accurately determining
55 | the rate of expansion of the universe.
56 |
57 | open source project.
61 | Maintained by @drkcsm. If you\'re feeling generous,
62 | send some grocery money to paypal.me/derekcsm
63 | to help keep this project going!
64 | ]]>
65 |
66 |
67 | Built by —
68 | View source code
69 | Show intro
70 |
73 | Maintained by Derek Smith,
74 | follow me on Twitter @drkcsm to say hi. Or
75 | even better, send some grocery money to paypal.me/derekcsm
76 | to help keep this project going! <3
77 |
78 |
79 |
80 | Contributions from:
81 |
82 | - PedroVictorB
83 |
84 |
85 |
86 |
87 |
88 | Hubble gallery is an open source project
89 | github.com/derekcsm/hubble_gallery
90 | stars are much appreciated. If you\'re interested in contributing that\'s awesome! Please see
91 | the README guidelines and I\'d be more than happy to help merge your PR into the project.
92 |
93 |
94 |
95 | The content showcased in this app comes from HubbleSite,
96 | run by the Space Telescope Science Institute\'s Office of Public Outreach.
97 |
98 |
99 |
100 | This is not an official app, I have no affiliation with NASA or JPL. All source code for
101 | this project is licensed under the
102 | Apache License Version 2.0.
103 |
104 |
105 | ]]>
106 |
107 |
108 | fonts/Roboto-Black.ttf
109 | fonts/Roboto-BlackItalic.ttf
110 | fonts/Roboto-Bold.ttf
111 | fonts/Roboto-BoldItalic.ttf
112 | fonts/Roboto-Regular.ttf
113 | fonts/Roboto-Thin.ttf
114 | fonts/Roboto-ThinItalic.ttf
115 | fonts/Roboto-Italic.ttf
116 | fonts/Roboto-Light.ttf
117 | fonts/Roboto-LightItalic.ttf
118 | fonts/Roboto-Medium.ttf
119 | fonts/Roboto-MediumItalic.ttf
120 |
121 | fonts/RobotoCondensed-Bold.ttf
122 | fonts/RobotoCondensed-BoldItalic.ttf
123 | fonts/RobotoCondensed-Italic.ttf
124 | fonts/RobotoCondensed-Light.ttf
125 | fonts/RobotoCondensed-LightItalic.ttf
126 | fonts/RobotoCondensed-Regular.ttf
127 |
128 | Open
129 | Close
130 |
131 | ImageViewer
132 | Dummy Button
133 | DUMMY\nCONTENT
134 |
135 |
136 |
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/ui/widgets/CircleProgressView.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.ui.widgets;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.drawable.Drawable;
8 | import android.os.Parcel;
9 | import android.os.Parcelable;
10 | import android.util.AttributeSet;
11 | import android.util.DisplayMetrics;
12 | import android.view.View;
13 |
14 | import com.derek_s.hubble_gallery.R;
15 |
16 |
17 | /**
18 | * Simplest custom view possible, using CircularProgressDrawable
19 | */
20 | public class CircleProgressView extends View {
21 |
22 | private CircularProgressDrawable mDrawable;
23 |
24 | public CircleProgressView(Context context) {
25 | this(context, null);
26 | }
27 |
28 | public CircleProgressView(Context context, AttributeSet attrs) {
29 | this(context, attrs, 0);
30 | }
31 |
32 | public CircleProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
33 | super(context, attrs, defStyleAttr);
34 | init(context, attrs, defStyleAttr);
35 | }
36 |
37 | private void init(Context context, AttributeSet attrs, int defStyleAttr) {
38 |
39 | TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CircleProgressView);
40 |
41 | int color = a.getColor(R.styleable.CircleProgressView_cpvColor, Color.LTGRAY);
42 |
43 | int popOutColor = a.getColor(R.styleable.CircleProgressView_cpvPopOutColor, 0);
44 |
45 | // The colors
46 | int colorsId = a.getResourceId(R.styleable.CircleProgressView_cpvColors, 0);
47 |
48 | // The stroke size
49 | int strokeSize =
50 | a.getDimensionPixelSize(R.styleable.CircleProgressView_cpvStrokeWidth, dpToPx(context, 5));
51 |
52 | // popOut stroke width
53 | int popOutStrokeWidth =
54 | a.getDimensionPixelSize(R.styleable.CircleProgressView_cpvPopOutStrokeWidth,
55 | dpToPx(context, 7));
56 |
57 | // How long should it take to make a complete circle
58 | int circleAnimDuration = a.getInt(R.styleable.CircleProgressView_cpvCircleAnimDuration, 2000);
59 |
60 | // How long should it take to sweep the tail
61 | int sweepAnimDuration = a.getInt(R.styleable.CircleProgressView_cpvSweepAnimDuration, 600);
62 |
63 | float speed = a.getFloat(R.styleable.CircleProgressView_cpvSpeed, 1.0f);
64 |
65 | int minSweepAngle = a.getInteger(R.styleable.CircleProgressView_cpvMinSweepAngle, 20);
66 | int maxSweepAngle = a.getInteger(R.styleable.CircleProgressView_cpvMaxSweepAngle, 300);
67 |
68 | a.recycle();
69 |
70 | int[] colors = null;
71 | if (colorsId != 0) {
72 | colors = context.getResources().getIntArray(colorsId);
73 | }
74 |
75 | if (colors == null) {
76 | colors = new int[1];
77 | colors[0] = color;
78 | }
79 |
80 | if (popOutColor == 0) {
81 | // No Popout
82 | mDrawable =
83 | new CircularProgressDrawable(colors, (float) strokeSize, speed, minSweepAngle,
84 | maxSweepAngle, CircularProgressDrawable.Style.ROUNDED);
85 | } else {
86 | // Use PopOut
87 | mDrawable =
88 | new PopOutCircularProgressDrawable(popOutColor, colors, (float) strokeSize,
89 | popOutStrokeWidth, speed, minSweepAngle, maxSweepAngle, true,
90 | CircularProgressDrawable.Style.ROUNDED);
91 | }
92 | mDrawable.setCallback(this);
93 | }
94 |
95 | public int dpToPx(Context context, int dp) {
96 | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
97 | return (int) ((dp * displayMetrics.density) + 0.5);
98 | }
99 |
100 | @Override
101 | protected void onVisibilityChanged(View changedView, int visibility) {
102 | super.onVisibilityChanged(changedView, visibility);
103 |
104 | if (mDrawable == null) {
105 | return;
106 | }
107 |
108 | if (visibility == VISIBLE) {
109 | mDrawable.start();
110 | } else {
111 | mDrawable.stop();
112 | }
113 | }
114 |
115 | @Override
116 | protected void onSizeChanged(int w, int h, int oldw, int oldh) {
117 | super.onSizeChanged(w, h, oldw, oldh);
118 | mDrawable.setBounds(0, 0, w, h);
119 | }
120 |
121 | @Override
122 | public void draw(Canvas canvas) {
123 | super.draw(canvas);
124 | mDrawable.draw(canvas);
125 | }
126 |
127 | @Override
128 | protected boolean verifyDrawable(Drawable who) {
129 | return who == mDrawable || super.verifyDrawable(who);
130 | }
131 |
132 | @Override
133 | protected void onDetachedFromWindow() {
134 | super.onDetachedFromWindow();
135 | mDrawable.stop();
136 | }
137 |
138 |
139 | /*
140 | * @Override public Parcelable onSaveInstanceState() { //begin boilerplate code that allows parent
141 | * classes to save state Parcelable superState = super.onSaveInstanceState();
142 | *
143 | * SavedState ss = new SavedState(superState); //end
144 | *
145 | * ss.color = mDrawable.getColor(); ss.sweepAnimDuration = mDrawable.getSweepAnimationDuration();
146 | * ss.circleAnimDuration = mDrawable.getCircleAnimationDuration(); ss.strokeSize =
147 | * mDrawable.getStrokeWidth();
148 | *
149 | * return ss; }
150 | *
151 | * @Override public void onRestoreInstanceState(Parcelable state) { //begin boilerplate code so
152 | * parent classes can restore state if(!(state instanceof SavedState)) {
153 | * super.onRestoreInstanceState(state); return; }
154 | *
155 | * SavedState ss = (SavedState)state; super.onRestoreInstanceState(ss.getSuperState()); //end
156 | *
157 | * mDrawable.setCircleAnimationDuration(ss.circleAnimDuration);
158 | * mDrawable.setSweepAnimationDuration(ss.sweepAnimDuration); mDrawable.setColor(ss.color);
159 | * mDrawable.setStrokeWidth(ss.strokeSize); }
160 | */
161 |
162 | static class SavedState extends BaseSavedState {
163 | // required field that makes Parcelables from a Parcel
164 | public static final Creator CREATOR =
165 | new Creator() {
166 | public SavedState createFromParcel(Parcel in) {
167 | return new SavedState(in);
168 | }
169 |
170 | public SavedState[] newArray(int size) {
171 | return new SavedState[size];
172 | }
173 | };
174 | int color;
175 | float strokeSize;
176 | int circleAnimDuration;
177 | int sweepAnimDuration;
178 |
179 | SavedState(Parcelable superState) {
180 | super(superState);
181 | }
182 |
183 | private SavedState(Parcel in) {
184 | super(in);
185 | this.color = in.readInt();
186 | this.strokeSize = in.readFloat();
187 | this.circleAnimDuration = in.readInt();
188 | this.sweepAnimDuration = in.readInt();
189 | }
190 |
191 | @Override
192 | public void writeToParcel(Parcel out, int flags) {
193 | super.writeToParcel(out, flags);
194 | out.writeInt(this.color);
195 | out.writeFloat(this.strokeSize);
196 | out.writeInt(this.circleAnimDuration);
197 | out.writeInt(this.sweepAnimDuration);
198 | }
199 | }
200 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/derek_s/hubble_gallery/utils/svg/SvgView.java:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.utils.svg;
2 |
3 | /**
4 | * Created by dereksmith on 15-05-04.
5 | */
6 |
7 | import android.animation.ObjectAnimator;
8 | import android.content.Context;
9 | import android.content.res.TypedArray;
10 | import android.graphics.Canvas;
11 | import android.graphics.DashPathEffect;
12 | import android.graphics.Paint;
13 | import android.graphics.PathEffect;
14 | import android.util.AttributeSet;
15 | import android.util.Log;
16 | import android.view.View;
17 | import android.view.animation.LinearInterpolator;
18 |
19 | import com.derek_s.hubble_gallery.R;
20 |
21 | import java.util.ArrayList;
22 | import java.util.List;
23 |
24 | @SuppressWarnings({"ForLoopReplaceableByForEach", "UnusedDeclaration"})
25 | public class SvgView extends View {
26 | private static final String LOG_TAG = "IntroView";
27 |
28 | private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
29 |
30 | private final SvgHelper mSvg = new SvgHelper(mPaint);
31 | private final Object mSvgLock = new Object();
32 | private int mSvgResource;
33 | private List mPaths = new ArrayList<>(0);
34 | private Thread mLoader;
35 |
36 | private float mPhase;
37 | private float mWait;
38 | private float mDrag;
39 |
40 | private int mDuration;
41 | private float mFadeFactor;
42 |
43 | private int mRadius;
44 |
45 | private ObjectAnimator mSvgAnimator;
46 | private ObjectAnimator mWaitAnimator;
47 |
48 | private OnReadyListener mListener;
49 |
50 | public SvgView(Context context, AttributeSet attrs) {
51 | this(context, attrs, 0);
52 | }
53 |
54 | public SvgView(Context context, AttributeSet attrs, int defStyle) {
55 | super(context, attrs, defStyle);
56 |
57 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IntroView, defStyle, 0);
58 | try {
59 | if (a != null) {
60 | mPaint.setStrokeWidth(a.getFloat(R.styleable.IntroView_strokeWidth, 1.0f));
61 | mPaint.setColor(a.getColor(R.styleable.IntroView_strokeColor, 0xff000000));
62 | mPhase = a.getFloat(R.styleable.IntroView_phase, 1.0f);
63 | mDuration = a.getInt(R.styleable.IntroView_duration, 4000);
64 | mFadeFactor = a.getFloat(R.styleable.IntroView_fadeFactor, 10.0f);
65 | mRadius = a.getDimensionPixelSize(R.styleable.IntroView_waitRadius, 50);
66 | }
67 | } finally {
68 | if (a != null) a.recycle();
69 | }
70 |
71 | init();
72 | }
73 |
74 | private static PathEffect createPathEffect(float pathLength, float phase, float offset) {
75 | return new DashPathEffect(new float[]{pathLength, pathLength},
76 | Math.max(phase * pathLength, offset));
77 | }
78 |
79 | private void init() {
80 | mPaint.setStyle(Paint.Style.STROKE);
81 |
82 | // Note: using a software layer here is an optimization. This view works with
83 | // hardware accelerated rendering but every time a path is modified (when the
84 | // dash path effect is modified), the graphics pipeline will rasterize the path
85 | // again in a new texture. Since we are dealing with dozens of paths, it is much
86 | // more efficient to rasterize the entire view into a single re-usable texture
87 | // instead. Ideally this should be toggled using a heuristic based on the number
88 | // and or dimensions of paths to render.
89 | // Note that PathDashPathEffects can lead to clipping issues with hardware rendering.
90 | setLayerType(LAYER_TYPE_SOFTWARE, null);
91 |
92 | mSvgAnimator = ObjectAnimator.ofFloat(this, "phase", 0.0f, 1.0f).setDuration(mDuration);
93 |
94 | mWaitAnimator = ObjectAnimator.ofFloat(this, "wait", 1.0f, 0.0f).setDuration(mDuration);
95 | mWaitAnimator.setRepeatMode(ObjectAnimator.RESTART);
96 | mWaitAnimator.setRepeatCount(ObjectAnimator.INFINITE);
97 | mWaitAnimator.setInterpolator(new LinearInterpolator());
98 | mWaitAnimator.start();
99 | }
100 |
101 | public void setSvgResource(int resource) {
102 | if (mSvgResource == 0) {
103 | mSvgResource = resource;
104 | }
105 | }
106 |
107 | @Override
108 | protected void onDraw(Canvas canvas) {
109 | super.onDraw(canvas);
110 |
111 | synchronized (mSvgLock) {
112 | canvas.save();
113 | canvas.translate(getPaddingLeft(), getPaddingTop() - getPaddingBottom());
114 | final int count = mPaths.size();
115 | for (int i = 0; i < count; i++) {
116 | SvgHelper.SvgPath svgPath = mPaths.get(i);
117 |
118 | // We use the fade factor to speed up the alpha animation
119 | int alpha = (int) (Math.min(mPhase * mFadeFactor, 1.0f) * 255.0f);
120 | svgPath.paint.setAlpha(alpha);
121 |
122 | canvas.drawPath(svgPath.renderPath, svgPath.paint);
123 | }
124 | canvas.restore();
125 | }
126 |
127 | canvas.save();
128 | canvas.translate(0.0f, getHeight() - getPaddingBottom() - mRadius * 3.0f);
129 |
130 | canvas.restore();
131 | }
132 |
133 | @Override
134 | protected void onSizeChanged(final int w, final int h, int oldw, int oldh) {
135 | super.onSizeChanged(w, h, oldw, oldh);
136 |
137 | if (mLoader != null) {
138 | try {
139 | mLoader.join();
140 | } catch (InterruptedException e) {
141 | Log.e(LOG_TAG, "Unexpected error", e);
142 | }
143 | }
144 |
145 | mLoader = new Thread(new Runnable() {
146 | @Override
147 | public void run() {
148 | mSvg.load(getContext(), mSvgResource);
149 | synchronized (mSvgLock) {
150 | mPaths = mSvg.getPathsForViewport(
151 | w - getPaddingLeft() - getPaddingRight(),
152 | h - getPaddingTop() - getPaddingBottom());
153 | updatePathsPhaseLocked();
154 | }
155 | post(new Runnable() {
156 | @Override
157 | public void run() {
158 | invokeReadyListener();
159 | if (mSvgAnimator.isRunning()) mSvgAnimator.cancel();
160 | mSvgAnimator.start();
161 | }
162 | });
163 | }
164 | }, "SVG Loader");
165 | mLoader.start();
166 | }
167 |
168 | private void invokeReadyListener() {
169 | if (mListener != null) mListener.onReady();
170 | }
171 |
172 | public void setOnReadyListener(OnReadyListener listener) {
173 | mListener = listener;
174 | }
175 |
176 | private void updatePathsPhaseLocked() {
177 | final int count = mPaths.size();
178 | for (int i = 0; i < count; i++) {
179 | SvgHelper.SvgPath svgPath = mPaths.get(i);
180 | svgPath.renderPath.reset();
181 | svgPath.measure.getSegment(0.0f, svgPath.length * mPhase, svgPath.renderPath, true);
182 | // Required only for Android 4.4 and earlier
183 | svgPath.renderPath.rLineTo(0.0f, 0.0f);
184 | }
185 | }
186 |
187 | public float getPhase() {
188 | return mPhase;
189 | }
190 |
191 | public void setPhase(float phase) {
192 | mPhase = phase;
193 | synchronized (mSvgLock) {
194 | updatePathsPhaseLocked();
195 | }
196 | invalidate();
197 | }
198 |
199 | public float getWait() {
200 | return mWait;
201 | }
202 |
203 | public void setWait(float wait) {
204 | mWait = wait;
205 |
206 | invalidate();
207 | }
208 |
209 | public interface OnReadyListener {
210 | void onReady();
211 | }
212 |
213 |
214 | }
--------------------------------------------------------------------------------
/app/src/main/res/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Gallerie Hubble
5 | Hubble
6 | Bienvenue
7 |
8 |
9 | Favoris
10 | Chercher
11 | À Propos
12 | Noter et Partager
13 |
14 | Ranger
15 | Les + populaires d\'abord
16 | Les + hautes résolutions d\'abord
17 | Détails
18 |
19 |
20 | Définir comme…
21 | Partager l\'image
22 | Sauvegarder l\'image
23 | Ouvrir dans le navigateur
24 | Partager le lien
25 | Copier le lien
26 | Ajouter aux favoris
27 | Effacer des favoris
28 |
29 | Erreur lors de la sauvegarde de l\'image
30 | Image sauvegarée à /Pictures/Hubble
31 | Montrer l\'image en plein écran
32 |
33 |
34 | Découvrez et mettez en favoris des images, elles seront affichées ici
35 | Vous n\'avez aucune image favorite pour l\'instant
36 | Je suis sûr que vous trouverez des images favorites dans la collection!
37 |
38 |
39 | Pas de connection Internet
40 | Réessayez
41 | Rechargez
42 | Erreur lors du chargement de l\'image
43 |
44 |
45 | Faites glisser vers le haut
46 | Entrer
47 | Le Téléscope Spacial Hubble a été lancé en orbite terrienne basse en 1990,
48 | et est actuellement toujours en service. Avec un miroir de 2,4 mètres (7.9 pieds), les quatre principaux instruments de
49 | Hubble font des mesures et observent aux alentours de l\'ultraviolet, du visible et des spectres infrarouges.
50 |
51 | L\'orbite de Hubble se trouve en dehors du champ de distorsion de l\'atmosphère terrestre lui permet de
52 | prendre des images en très grande résolution avec une lumière de fond négligeable. Hubble a enregistré quelques-unes des
53 | images les plus détaillées visibles à l\'oeil nu jamais enregistrées, ceci permettant d\'avoir une image précie de
54 | l\'espace et du temps. Les observations via Hubble ont permis des découvertes capitales en astrophysique, comme le calcul
55 | précis de la vitesse d\'expansion de l\'univers.
56 |
57 | projet open source.
61 | Maintenu par @drkcsm. Si vous vous sentez généreux,
62 | faites un petit don à paypal.me/derekcsm
63 | pour aider ce projet à continuer d\'exister!
64 | ]]>
65 |
66 |
67 | Développé par —
68 | Voir le code source
69 | Jouer l\'intro
70 |
72 | Maintenu par Derek Smith,
73 | suivez moi sur Twitter @drkcsm pour me faire un petit coucou. Ou encore
74 | mieux, faites un petit don à paypal.me/derekcsm
75 | pour aider ce projet à continuer d\'exister! <3
76 |
77 |
78 | Contributions de :
79 |
80 | - PedroVictorB
81 |
82 |
83 |
84 | Gallerie Hubble est un projet open source
85 | github.com/derekcsm/hubble_gallery
86 | la mise en favoris est très appréciée. Si vous voulez contribuer, SUPER!! Veuillez lire le guide dans
87 | le README et je serais plus que content d\'inclure vos PR dans le projet.
88 |
89 |
90 | Le contenu de cette application vient de HubbleSite.org,
91 | site hébergé par le Space Telescope Science Institute\'s Office of Public Outreach.
92 |
93 |
94 | Ce n\'est pas une application officielle, je n\'ai aucune affiliation avec la NASA ou le JPL. Tout le code source de
95 | ce projet est licencié sous les termes de la
96 | Licence Apache Version 2.0.
97 |
98 | ]]>
99 |
100 |
101 | fonts/Roboto-Black.ttf
102 | fonts/Roboto-BlackItalic.ttf
103 | fonts/Roboto-Bold.ttf
104 | fonts/Roboto-BoldItalic.ttf
105 | fonts/Roboto-Regular.ttf
106 | fonts/Roboto-Thin.ttf
107 | fonts/Roboto-ThinItalic.ttf
108 | fonts/Roboto-Italic.ttf
109 | fonts/Roboto-Light.ttf
110 | fonts/Roboto-LightItalic.ttf
111 | fonts/Roboto-Medium.ttf
112 | fonts/Roboto-MediumItalic.ttf
113 |
114 | fonts/RobotoCondensed-Bold.ttf
115 | fonts/RobotoCondensed-BoldItalic.ttf
116 | fonts/RobotoCondensed-Italic.ttf
117 | fonts/RobotoCondensed-Light.ttf
118 | fonts/RobotoCondensed-LightItalic.ttf
119 | fonts/RobotoCondensed-Regular.ttf
120 |
121 | Ouvrir
122 | Fermer
123 |
124 | ImageViewer
125 | Dummy Button
126 | DUMMY\nCONTENT
127 |
128 |
129 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/com/derek_s/hubble_gallery/nav_drawer/presenters/NavigationPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.derek_s.hubble_gallery.nav_drawer.presenters
2 |
3 | import android.content.Context
4 | import android.os.Bundle
5 | import android.support.v7.widget.LinearLayoutManager
6 | import com.bignerdranch.expandablerecyclerview.Model.ParentListItem
7 | import com.derek_s.hubble_gallery.nav_drawer.adapters.NavDrawerAdapter
8 | import com.derek_s.hubble_gallery.nav_drawer.adapters.NavigationAdapterItem
9 | import com.derek_s.hubble_gallery.nav_drawer.model.SectionChildObject
10 | import com.derek_s.hubble_gallery.nav_drawer.views.NavigationView
11 | import java.util.*
12 |
13 | class NavigationPresenter constructor(view: NavigationView, context: Context) :
14 | NavDrawerAdapter.NavAdapterListener {
15 |
16 | final val TAG = "NavigationPresenter"
17 | var view: NavigationView
18 | var context: Context
19 | var mAdapter: NavDrawerAdapter? = null
20 |
21 | val KEY_SELECTED_QUERY = "selected_query"
22 |
23 | init {
24 | this.view = view
25 | this.context = context
26 | }
27 |
28 | fun restoreState(savedState: Bundle?) {
29 | if (savedState == null)
30 | return
31 |
32 | if (savedState.containsKey(KEY_SELECTED_QUERY))
33 | mAdapter!!.setSelectedQuery(savedState.getString(KEY_SELECTED_QUERY))
34 | }
35 |
36 | fun getSelectedQuery(): String? {
37 | return mAdapter!!.getSelectedQuery()
38 | }
39 |
40 | fun populateAdapter() {
41 | var drawerItems = ArrayList()
42 |
43 | drawerItems.add(NavigationAdapterItem(SectionChildObject("Entire Collection", "entire"),
44 | NavigationAdapterItem.STANDALONE_SECTION, null))
45 |
46 | drawerItems.add(NavigationAdapterItem(SectionChildObject("Hubble Heritage", "heritage"),
47 | NavigationAdapterItem.STANDALONE_SECTION, null))
48 |
49 | /**
50 | * the universe
51 | */
52 | var universeItems = ArrayList()
53 | universeItems.add(createChildObject("Distant Galaxies", "the_universe/distant_galaxies"))
54 | universeItems.add(createChildObject("GOODS", "the_universe/goods"))
55 | universeItems.add(createChildObject("Hubble Deep Field", "the_universe/hubble_deep_field"))
56 | universeItems.add(createChildObject("Hubble Ultra Deep Field", "the_universe/hubble_ultra_deep_field"))
57 | universeItems.add(createChildObject("Intergalactic Gas", "the_universe/intergalactic_gas"))
58 | universeItems.add(createChildObject("Medium Deep Survey", "the_universe/medium_deep_survey"))
59 |
60 | drawerItems.add(NavigationAdapterItem(SectionChildObject("The Universe", "the_universe"),
61 | NavigationAdapterItem.GROUP, universeItems))
62 |
63 | /**
64 | * exotic
65 | */
66 | var exoticItems = ArrayList()
67 | exoticItems.add(createChildObject("Black Hole", "exotic/black_hole"))
68 | exoticItems.add(createChildObject("Dark Matter", "exotic/dark_matter"))
69 | exoticItems.add(createChildObject("Gamma Ray Burst", "exotic/gamma_ray_burst"))
70 | exoticItems.add(createChildObject("Gravitational Lens", "exotic/gravitational_lens"))
71 |
72 | drawerItems.add(NavigationAdapterItem(SectionChildObject("Exotic", "exotic"),
73 | NavigationAdapterItem.GROUP, exoticItems))
74 |
75 | /**
76 | * galaxies
77 | */
78 | var galaxyItems = ArrayList()
79 | galaxyItems.add(createChildObject("Cluster", "galaxy/cluster"))
80 | galaxyItems.add(createChildObject("Dwarf", "galaxy/dwarf"))
81 | galaxyItems.add(createChildObject("Elliptical", "galaxy/elliptical"))
82 | galaxyItems.add(createChildObject("Interacting", "galaxy/interacting"))
83 | galaxyItems.add(createChildObject("Irregular", "galaxy/irregular"))
84 | galaxyItems.add(createChildObject("Magellanic Cloud", "galaxy/magellanic_cloud"))
85 | galaxyItems.add(createChildObject("Quasar/Active Nucleus", "galaxy/quasar_active_nucleus"))
86 |
87 | drawerItems.add(NavigationAdapterItem(SectionChildObject("Galaxies", "galaxy"),
88 | NavigationAdapterItem.GROUP, galaxyItems))
89 |
90 | /**
91 | * nebulae
92 | */
93 | var nebulaItems = ArrayList()
94 | nebulaItems.add(createChildObject("Dark", "nebula/dark"))
95 | nebulaItems.add(createChildObject("Emission", "nebula/emission"))
96 | nebulaItems.add(createChildObject("Planetary", "nebula/planetary"))
97 | nebulaItems.add(createChildObject("Reflection", "nebula/reflection"))
98 | nebulaItems.add(createChildObject("Supernova Remnant", "nebula/supernova_remnant"))
99 |
100 | drawerItems.add(NavigationAdapterItem(SectionChildObject("Nebulae", "nebula"),
101 | NavigationAdapterItem.GROUP, nebulaItems))
102 |
103 | /**
104 | * solar system
105 | */
106 | var solarSystemItems = ArrayList()
107 | solarSystemItems.add(createChildObject("Asteroid", "solar_system/comet"))
108 | solarSystemItems.add(createChildObject("Comet", "solar_system/emission"))
109 | solarSystemItems.add(createChildObject("Jupiter", "solar_system/jupiter"))
110 | solarSystemItems.add(createChildObject("Kuiper Belt Object", "solar_system/kuiper_belt_object"))
111 | solarSystemItems.add(createChildObject("Mars", "solar_system/mars"))
112 | solarSystemItems.add(createChildObject("Neptune", "solar_system/neptune"))
113 | solarSystemItems.add(createChildObject("Planetary Moon", "solar_system/planetary_moon"))
114 | solarSystemItems.add(createChildObject("Planetary Ring", "solar_system/planetary_ring"))
115 | solarSystemItems.add(createChildObject("Pluto", "solar_system/pluto"))
116 | solarSystemItems.add(createChildObject("Saturn", "solar_system/saturn"))
117 | solarSystemItems.add(createChildObject("Uranus", "solar_system/uranus"))
118 | solarSystemItems.add(createChildObject("Venus", "solar_system/venus"))
119 | solarSystemItems.add(createChildObject("Weather/Atmosphere", "solar_system/weather_atmosphere"))
120 |
121 | drawerItems.add(NavigationAdapterItem(SectionChildObject("Solar System", "solar_system"),
122 | NavigationAdapterItem.GROUP, solarSystemItems))
123 |
124 | /**
125 | * stars
126 | */
127 | var starItems = ArrayList()
128 | starItems.add(createChildObject("Brown Dwarf", "star/brown_dwarf"))
129 | starItems.add(createChildObject("Massive Star", "star/massive_star"))
130 | starItems.add(createChildObject("Nova", "star/nova"))
131 | starItems.add(createChildObject("Protostellar Jet", "star/protostellar_jet"))
132 | starItems.add(createChildObject("Protoplanetary Disk", "star/protoplanetary_disk"))
133 | starItems.add(createChildObject("Pulsar", "star/pulsar"))
134 | starItems.add(createChildObject("Star Cluster", "star/star_cluster"))
135 | starItems.add(createChildObject("Star Field", "star/star_field"))
136 | starItems.add(createChildObject("Supernova", "star/supernova"))
137 | starItems.add(createChildObject("Variable Star", "star/variable_star"))
138 | starItems.add(createChildObject("White Dwarf", "star/white_dwarf"))
139 |
140 | drawerItems.add(NavigationAdapterItem(SectionChildObject("Stars", "star"),
141 | NavigationAdapterItem.GROUP, starItems))
142 |
143 |
144 | mAdapter = NavDrawerAdapter(context, drawerItems, this)
145 |
146 | view.recycler.layoutManager = LinearLayoutManager(context)
147 | view.recycler.adapter = mAdapter
148 | }
149 |
150 | private fun createChildObject(title: String, query: String): SectionChildObject {
151 | return SectionChildObject(title, query)
152 | }
153 |
154 | override fun onSectionClicked(section: SectionChildObject) {
155 | view.selectSection(section)
156 | }
157 |
158 | override fun setSelectedQuery(query: String) {
159 | mAdapter!!.setSelectedQuery(query)
160 | }
161 | }
162 |
--------------------------------------------------------------------------------