Repository: boredream/DesignResCollection Branch: master Commit: 79c7ca036255 Files: 699 Total size: 1.3 MB Directory structure: gitextract_frklmp72/ ├── .gitattributes ├── .gitignore ├── DesignResCollection_MVC/ │ ├── README.md │ ├── app/ │ │ ├── build.gradle │ │ ├── proguard.cfg │ │ └── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── boredream/ │ │ │ └── designrescollection/ │ │ │ └── ApplicationTest.java │ │ ├── main/ │ │ │ ├── AndroidManifest.xml │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── boredream/ │ │ │ │ └── designrescollection/ │ │ │ │ ├── activity/ │ │ │ │ │ ├── AboutActivity.java │ │ │ │ │ ├── FeedBackActivity.java │ │ │ │ │ ├── LoginActivity.java │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ ├── RegisterStep1Activity.java │ │ │ │ │ ├── RegisterStep2Activity.java │ │ │ │ │ ├── SettingActivity.java │ │ │ │ │ ├── UserInfoEditActivity.java │ │ │ │ │ └── UsernameModifyActivity.java │ │ │ │ ├── adapter/ │ │ │ │ │ ├── DesignResAdapter.java │ │ │ │ │ └── MoreRecyclerAdapter.java │ │ │ │ ├── base/ │ │ │ │ │ ├── BaseActivity.java │ │ │ │ │ ├── BaseApplication.java │ │ │ │ │ ├── BaseEntity.java │ │ │ │ │ └── BaseFragment.java │ │ │ │ ├── constants/ │ │ │ │ │ └── CommonConstants.java │ │ │ │ ├── entity/ │ │ │ │ │ ├── Comment.java │ │ │ │ │ ├── DesignRes.java │ │ │ │ │ ├── FeedBack.java │ │ │ │ │ └── User.java │ │ │ │ ├── fragment/ │ │ │ │ │ ├── HomeFragment.java │ │ │ │ │ └── UserFragment.java │ │ │ │ ├── net/ │ │ │ │ │ ├── GlideHelper.java │ │ │ │ │ ├── HttpRequest.java │ │ │ │ │ └── SimpleSubscriber.java │ │ │ │ └── utils/ │ │ │ │ ├── UpdateUtils.java │ │ │ │ └── UserInfoKeeper.java │ │ │ └── res/ │ │ │ ├── anim/ │ │ │ │ └── loading.xml │ │ │ ├── color/ │ │ │ │ └── txt_blue2gray_sel.xml │ │ │ ├── drawable/ │ │ │ │ ├── ic_fav_grey2black_sel.xml │ │ │ │ ├── ic_home_grey2black_sel.xml │ │ │ │ ├── ic_more_grey2black_sel.xml │ │ │ │ ├── ic_search_grey2black_sel.xml │ │ │ │ ├── ic_settings_grey2black_sel.xml │ │ │ │ └── oval_progress.xml │ │ │ ├── layout/ │ │ │ │ ├── activity_about.xml │ │ │ │ ├── activity_feed_back.xml │ │ │ │ ├── activity_input.xml │ │ │ │ ├── activity_login.xml │ │ │ │ ├── activity_main.xml │ │ │ │ ├── activity_regist.xml │ │ │ │ ├── activity_register_step1.xml │ │ │ │ ├── activity_register_step2.xml │ │ │ │ ├── activity_setting.xml │ │ │ │ ├── activity_user_info_edit.xml │ │ │ │ ├── frag_home.xml │ │ │ │ ├── frag_user.xml │ │ │ │ ├── include_bottom_tab.xml │ │ │ │ ├── include_more_header.xml │ │ │ │ ├── include_more_no_header.xml │ │ │ │ ├── item_design_res.xml │ │ │ │ └── item_more_header.xml │ │ │ ├── values/ │ │ │ │ ├── colors.xml │ │ │ │ ├── dimens.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ └── values-w820dp/ │ │ │ └── dimens.xml │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── boredream/ │ │ └── designrescollection/ │ │ └── ExampleUnitTest.java │ ├── bdcodehelper/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── boredream/ │ │ │ └── bdcodehelper/ │ │ │ └── ApplicationTest.java │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── assets/ │ │ │ └── city │ │ ├── java/ │ │ │ └── com/ │ │ │ └── boredream/ │ │ │ └── bdcodehelper/ │ │ │ ├── activity/ │ │ │ │ ├── ImageBrowserActivity.java │ │ │ │ └── WebViewActivity.java │ │ │ ├── adapter/ │ │ │ │ ├── BannerPagerAdapter.java │ │ │ │ ├── ImageBrowserAdapter.java │ │ │ │ ├── ListDropDownAdapter.java │ │ │ │ ├── LoadMoreAdapter.java │ │ │ │ └── SettingRecyclerAdapter.java │ │ │ ├── base/ │ │ │ │ ├── BoreBaseActivity.java │ │ │ │ └── BoreBaseEntity.java │ │ │ ├── db/ │ │ │ │ ├── AddressData.java │ │ │ │ └── AssetsDatabaseManager.java │ │ │ ├── entity/ │ │ │ │ ├── AppUpdateInfo.java │ │ │ │ ├── ErrorResponse.java │ │ │ │ ├── FileUploadResponse.java │ │ │ │ ├── FormItem.java │ │ │ │ ├── ImageUrlInterface.java │ │ │ │ ├── ListResponse.java │ │ │ │ ├── PageIndex.java │ │ │ │ ├── Pointer.java │ │ │ │ ├── Relation.java │ │ │ │ ├── RelationTo.java │ │ │ │ ├── SettingItem.java │ │ │ │ ├── UpdatePswRequest.java │ │ │ │ ├── Where.java │ │ │ │ └── city/ │ │ │ │ ├── BaseAddressModel.java │ │ │ │ └── CityModel.java │ │ │ ├── fragment/ │ │ │ │ └── FragmentController.java │ │ │ ├── net/ │ │ │ │ ├── ErrorConstants.java │ │ │ │ ├── GlideCircleTransform.java │ │ │ │ ├── MultiPageRequest.java │ │ │ │ ├── ObservableDecorator.java │ │ │ │ └── RoundedCornersTransformation.java │ │ │ ├── present/ │ │ │ │ ├── FormItemsPresent.java │ │ │ │ ├── GroupEtEmptyCheckPresent.java │ │ │ │ ├── ImageBannerPresent.java │ │ │ │ ├── ImageBrowserPresent.java │ │ │ │ └── MultiPageLoadPresent.java │ │ │ ├── utils/ │ │ │ │ ├── ActivityUtils.java │ │ │ │ ├── AppUtils.java │ │ │ │ ├── DateUtils.java │ │ │ │ ├── DialogUtils.java │ │ │ │ ├── DisplayUtils.java │ │ │ │ ├── ErrorInfoUtils.java │ │ │ │ ├── ImageUtils.java │ │ │ │ ├── LogUtils.java │ │ │ │ ├── NetUtils.java │ │ │ │ ├── StringUtils.java │ │ │ │ ├── TitleBuilder.java │ │ │ │ ├── ToastUtils.java │ │ │ │ └── ViewUtils.java │ │ │ └── view/ │ │ │ ├── AddressWheelDialog.java │ │ │ ├── BottomTabRadioButton.java │ │ │ ├── CheckableLinearLayout.java │ │ │ ├── DividerItemDecoration.java │ │ │ ├── DrawableRadioButton.java │ │ │ ├── DrawableTextView.java │ │ │ ├── DropDownMenu.java │ │ │ ├── EmptyItemDecoration.java │ │ │ ├── GridSpacingDecorator.java │ │ │ ├── PinnedSectionListView.java │ │ │ ├── PositionBar.java │ │ │ ├── WrapHeightGridView.java │ │ │ ├── WrapHeightLinearLayoutManager.java │ │ │ ├── WrapHeightListView.java │ │ │ └── wheel/ │ │ │ ├── ItemsRange.java │ │ │ ├── OnWheelChangedListener.java │ │ │ ├── OnWheelClickedListener.java │ │ │ ├── OnWheelScrollListener.java │ │ │ ├── WheelAdapter.java │ │ │ ├── WheelRecycle.java │ │ │ ├── WheelScroller.java │ │ │ ├── WheelView.java │ │ │ └── adapters/ │ │ │ ├── AbstractWheelAdapter.java │ │ │ ├── AbstractWheelTextAdapter.java │ │ │ ├── AdapterWheel.java │ │ │ ├── ArrayWheelAdapter.java │ │ │ ├── NumericWheelAdapter.java │ │ │ └── WheelViewAdapter.java │ │ ├── libs/ │ │ │ └── nineoldandroids-2.2.0.jar │ │ └── res/ │ │ ├── anim/ │ │ │ ├── dd_mask_in.xml │ │ │ ├── dd_mask_out.xml │ │ │ ├── dd_menu_in.xml │ │ │ └── dd_menu_out.xml │ │ ├── color/ │ │ │ ├── txt_blue2gray_sel.xml │ │ │ ├── txt_gray2primarydark_sel.xml │ │ │ ├── txt_lgray2white_sel.xml │ │ │ ├── txt_primary2white_sel.xml │ │ │ └── txt_white2gray_sel.xml │ │ ├── drawable/ │ │ │ ├── bg_gray2dark_sel.xml │ │ │ ├── bg_primary2dark_sel.xml │ │ │ ├── bg_primarydark_indicator_sel.xml │ │ │ ├── bg_tran2gray_sel.xml │ │ │ ├── bg_white2gray_sel.xml │ │ │ ├── cirrect_10a_primary_solid.xml │ │ │ ├── cirrect_5a_primary_solid.xml │ │ │ ├── cirrect_primary_stroke.xml │ │ │ ├── correct_gray_stroke.xml │ │ │ ├── correct_primary.xml │ │ │ ├── correct_primary2dark_sel.xml │ │ │ ├── correct_primary_dark.xml │ │ │ ├── correct_primary_light.xml │ │ │ ├── correct_primary_stroke.xml │ │ │ ├── correct_primary_stroke2solid_sel.xml │ │ │ ├── layerlist_primarydark_indicator.xml │ │ │ ├── oval_primary_light_solid.xml │ │ │ ├── oval_primary_solid.xml │ │ │ ├── shape_bottom_line.xml │ │ │ ├── shape_oval_primary2white_sel.xml │ │ │ ├── shape_oval_primary_stroke.xml │ │ │ ├── shape_oval_primary_stroke2solid_sel.xml │ │ │ ├── shape_oval_red_solid.xml │ │ │ ├── shape_oval_white_solid.xml │ │ │ ├── shape_top_line.xml │ │ │ ├── wheel_bg.xml │ │ │ └── wheel_val.xml │ │ ├── layout/ │ │ │ ├── activity_image_browser.xml │ │ │ ├── activity_web_view.xml │ │ │ ├── footer_progress.xml │ │ │ ├── formitem_input.xml │ │ │ ├── formitem_select.xml │ │ │ ├── include_banner_with_indicator.xml │ │ │ ├── include_ddm_listview.xml │ │ │ ├── include_group_divider.xml │ │ │ ├── include_refresh_list.xml │ │ │ ├── include_titlebar.xml │ │ │ ├── item_default_drop_down.xml │ │ │ ├── item_image_banner.xml │ │ │ ├── item_image_browser.xml │ │ │ ├── item_setting.xml │ │ │ ├── listview_dropdown_menu.xml │ │ │ └── wheel_dialog_address.xml │ │ └── values/ │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ ├── build.gradle │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradle.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── DesignResCollection_MVP/ │ ├── README.md │ ├── app/ │ │ ├── build.gradle │ │ ├── proguard.cfg │ │ └── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── boredream/ │ │ │ └── designrescollection/ │ │ │ ├── ApplicationTest.java │ │ │ ├── idlingres/ │ │ │ │ └── RxIdlingResource.java │ │ │ └── ui/ │ │ │ ├── login/ │ │ │ │ └── LoginActivityTest.java │ │ │ └── userinfoedit/ │ │ │ └── UserInfoEditActivityTest.java │ │ ├── main/ │ │ │ ├── AndroidManifest.xml │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── boredream/ │ │ │ │ └── designrescollection/ │ │ │ │ ├── adapter/ │ │ │ │ │ ├── DesignResAdapter.java │ │ │ │ │ └── MoreRecyclerAdapter.java │ │ │ │ ├── base/ │ │ │ │ │ ├── BaseActivity.java │ │ │ │ │ ├── BaseApplication.java │ │ │ │ │ ├── BaseEntity.java │ │ │ │ │ ├── BaseFragment.java │ │ │ │ │ ├── BasePresenter.java │ │ │ │ │ └── BaseView.java │ │ │ │ ├── constants/ │ │ │ │ │ └── CommonConstants.java │ │ │ │ ├── entity/ │ │ │ │ │ ├── Comment.java │ │ │ │ │ ├── DesignRes.java │ │ │ │ │ ├── FeedBack.java │ │ │ │ │ └── User.java │ │ │ │ ├── net/ │ │ │ │ │ ├── GlideHelper.java │ │ │ │ │ ├── HttpRequest.java │ │ │ │ │ └── SimpleSubscriber.java │ │ │ │ ├── ui/ │ │ │ │ │ ├── AboutActivity.java │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ ├── SettingActivity.java │ │ │ │ │ ├── UserFragment.java │ │ │ │ │ ├── feedback/ │ │ │ │ │ │ ├── FeedBackActivity.java │ │ │ │ │ │ ├── FeedBackContract.java │ │ │ │ │ │ └── FeedBackPresenter.java │ │ │ │ │ ├── home/ │ │ │ │ │ │ ├── HomeContract.java │ │ │ │ │ │ ├── HomeFragment.java │ │ │ │ │ │ └── HomePresenter.java │ │ │ │ │ ├── login/ │ │ │ │ │ │ ├── LoginActivity.java │ │ │ │ │ │ ├── LoginContract.java │ │ │ │ │ │ ├── LoginFragment.java │ │ │ │ │ │ └── LoginPresenter.java │ │ │ │ │ ├── modifytext/ │ │ │ │ │ │ ├── ModifyTextActivity.java │ │ │ │ │ │ ├── ModifyTextContract.java │ │ │ │ │ │ └── ModifyTextPresenter.java │ │ │ │ │ ├── register/ │ │ │ │ │ │ ├── RegisterContract.java │ │ │ │ │ │ ├── RegisterPresenter.java │ │ │ │ │ │ ├── RegisterStep1Activity.java │ │ │ │ │ │ └── RegisterStep2Activity.java │ │ │ │ │ └── userinfoedit/ │ │ │ │ │ ├── UserInfoEditActivity.java │ │ │ │ │ ├── UserInfoEditContract.java │ │ │ │ │ └── UserInfoEditPresenter.java │ │ │ │ └── utils/ │ │ │ │ ├── UpdateUtils.java │ │ │ │ └── UserInfoKeeper.java │ │ │ └── res/ │ │ │ ├── anim/ │ │ │ │ └── loading.xml │ │ │ ├── color/ │ │ │ │ └── txt_blue2gray_sel.xml │ │ │ ├── drawable/ │ │ │ │ ├── ic_fav_grey2black_sel.xml │ │ │ │ ├── ic_home_grey2black_sel.xml │ │ │ │ ├── ic_more_grey2black_sel.xml │ │ │ │ ├── ic_search_grey2black_sel.xml │ │ │ │ ├── ic_settings_grey2black_sel.xml │ │ │ │ └── oval_progress.xml │ │ │ ├── layout/ │ │ │ │ ├── activity_about.xml │ │ │ │ ├── activity_feed_back.xml │ │ │ │ ├── activity_input.xml │ │ │ │ ├── activity_login.xml │ │ │ │ ├── activity_main.xml │ │ │ │ ├── activity_regist.xml │ │ │ │ ├── activity_register_step1.xml │ │ │ │ ├── activity_register_step2.xml │ │ │ │ ├── activity_setting.xml │ │ │ │ ├── activity_user_info_edit.xml │ │ │ │ ├── frag_home.xml │ │ │ │ ├── frag_login.xml │ │ │ │ ├── frag_user.xml │ │ │ │ ├── include_bottom_tab.xml │ │ │ │ ├── include_more_header.xml │ │ │ │ ├── include_more_no_header.xml │ │ │ │ ├── item_design_res.xml │ │ │ │ └── item_more_header.xml │ │ │ ├── menu/ │ │ │ │ └── menu_main2.xml │ │ │ ├── values/ │ │ │ │ ├── colors.xml │ │ │ │ ├── dimens.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ └── values-w820dp/ │ │ │ └── dimens.xml │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── boredream/ │ │ └── designrescollection/ │ │ ├── net/ │ │ │ └── HttpRequestTest.java │ │ └── ui/ │ │ ├── feedback/ │ │ │ └── FeedBackPresenterTest.java │ │ ├── home/ │ │ │ └── HomePresenterTest.java │ │ ├── login/ │ │ │ └── LoginPresenterTest.java │ │ ├── modifytext/ │ │ │ └── ModifyTextPresenterTest.java │ │ ├── register/ │ │ │ └── RegisterPresenterTest.java │ │ └── userinfoedit/ │ │ └── UserInfoEditPresenterTest.java │ ├── bdcodehelper/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── assets/ │ │ │ └── city │ │ ├── java/ │ │ │ └── com/ │ │ │ └── boredream/ │ │ │ └── bdcodehelper/ │ │ │ ├── BoreConstants.java │ │ │ ├── activity/ │ │ │ │ ├── ImageBrowserActivity.java │ │ │ │ └── WebViewActivity.java │ │ │ ├── adapter/ │ │ │ │ ├── BannerPagerAdapter.java │ │ │ │ ├── ImageBrowserAdapter.java │ │ │ │ ├── ListDropDownAdapter.java │ │ │ │ ├── LoadMoreAdapter.java │ │ │ │ └── SettingRecyclerAdapter.java │ │ │ ├── base/ │ │ │ │ ├── BoreBaseActivity.java │ │ │ │ └── BoreBaseEntity.java │ │ │ ├── db/ │ │ │ │ ├── AddressData.java │ │ │ │ └── AssetsDatabaseManager.java │ │ │ ├── entity/ │ │ │ │ ├── AppUpdateInfo.java │ │ │ │ ├── ErrorResponse.java │ │ │ │ ├── FileInfo.java │ │ │ │ ├── FileUploadResponse.java │ │ │ │ ├── FormItem.java │ │ │ │ ├── ImageUrlInterface.java │ │ │ │ ├── ListResponse.java │ │ │ │ ├── PageIndex.java │ │ │ │ ├── Pointer.java │ │ │ │ ├── Relation.java │ │ │ │ ├── RelationTo.java │ │ │ │ ├── SettingItem.java │ │ │ │ ├── UpdatePswRequest.java │ │ │ │ ├── Where.java │ │ │ │ └── city/ │ │ │ │ ├── BaseAddressModel.java │ │ │ │ └── CityModel.java │ │ │ ├── fragment/ │ │ │ │ └── FragmentController.java │ │ │ ├── net/ │ │ │ │ ├── ErrorConstants.java │ │ │ │ ├── GlideCircleTransform.java │ │ │ │ ├── MultiPageRequest.java │ │ │ │ ├── ObservableDecorator.java │ │ │ │ └── RoundedCornersTransformation.java │ │ │ ├── present/ │ │ │ │ ├── FormItemsPresent.java │ │ │ │ ├── GroupEtEmptyCheckPresent.java │ │ │ │ ├── ImageBannerPresent.java │ │ │ │ ├── ImageBrowserPresent.java │ │ │ │ └── MultiPageLoadPresent.java │ │ │ ├── utils/ │ │ │ │ ├── ActivityUtils.java │ │ │ │ ├── AppUtils.java │ │ │ │ ├── DateUtils.java │ │ │ │ ├── DialogUtils.java │ │ │ │ ├── DisplayUtils.java │ │ │ │ ├── ErrorInfoUtils.java │ │ │ │ ├── ImageUtils.java │ │ │ │ ├── LogUtils.java │ │ │ │ ├── NetUtils.java │ │ │ │ ├── StringUtils.java │ │ │ │ ├── TitleBuilder.java │ │ │ │ ├── ToastUtils.java │ │ │ │ └── ViewUtils.java │ │ │ └── view/ │ │ │ ├── AddressWheelDialog.java │ │ │ ├── BottomTabRadioButton.java │ │ │ ├── CheckableLinearLayout.java │ │ │ ├── DividerItemDecoration.java │ │ │ ├── DrawableRadioButton.java │ │ │ ├── DrawableTextView.java │ │ │ ├── DropDownMenu.java │ │ │ ├── EmptyItemDecoration.java │ │ │ ├── GridSpacingDecorator.java │ │ │ ├── PinnedSectionListView.java │ │ │ ├── PositionBar.java │ │ │ ├── WrapHeightGridView.java │ │ │ ├── WrapHeightLinearLayoutManager.java │ │ │ ├── WrapHeightListView.java │ │ │ └── wheel/ │ │ │ ├── ItemsRange.java │ │ │ ├── OnWheelChangedListener.java │ │ │ ├── OnWheelClickedListener.java │ │ │ ├── OnWheelScrollListener.java │ │ │ ├── WheelAdapter.java │ │ │ ├── WheelRecycle.java │ │ │ ├── WheelScroller.java │ │ │ ├── WheelView.java │ │ │ └── adapters/ │ │ │ ├── AbstractWheelAdapter.java │ │ │ ├── AbstractWheelTextAdapter.java │ │ │ ├── AdapterWheel.java │ │ │ ├── ArrayWheelAdapter.java │ │ │ ├── NumericWheelAdapter.java │ │ │ └── WheelViewAdapter.java │ │ ├── libs/ │ │ │ └── nineoldandroids-2.2.0.jar │ │ └── res/ │ │ ├── anim/ │ │ │ ├── dd_mask_in.xml │ │ │ ├── dd_mask_out.xml │ │ │ ├── dd_menu_in.xml │ │ │ └── dd_menu_out.xml │ │ ├── color/ │ │ │ ├── txt_blue2gray_sel.xml │ │ │ ├── txt_gray2primarydark_sel.xml │ │ │ ├── txt_lgray2white_sel.xml │ │ │ ├── txt_primary2white_sel.xml │ │ │ └── txt_white2gray_sel.xml │ │ ├── drawable/ │ │ │ ├── bg_gray2dark_sel.xml │ │ │ ├── bg_primary2dark_sel.xml │ │ │ ├── bg_primarydark_indicator_sel.xml │ │ │ ├── bg_tran2gray_sel.xml │ │ │ ├── bg_white2gray_sel.xml │ │ │ ├── cirrect_10a_primary_solid.xml │ │ │ ├── cirrect_5a_primary_solid.xml │ │ │ ├── cirrect_primary_stroke.xml │ │ │ ├── correct_gray_stroke.xml │ │ │ ├── correct_primary.xml │ │ │ ├── correct_primary2dark_sel.xml │ │ │ ├── correct_primary_dark.xml │ │ │ ├── correct_primary_light.xml │ │ │ ├── correct_primary_stroke.xml │ │ │ ├── correct_primary_stroke2solid_sel.xml │ │ │ ├── layerlist_primarydark_indicator.xml │ │ │ ├── oval_primary_light_solid.xml │ │ │ ├── oval_primary_solid.xml │ │ │ ├── shape_bottom_line.xml │ │ │ ├── shape_oval_primary2white_sel.xml │ │ │ ├── shape_oval_primary_stroke.xml │ │ │ ├── shape_oval_primary_stroke2solid_sel.xml │ │ │ ├── shape_oval_red_solid.xml │ │ │ ├── shape_oval_white_solid.xml │ │ │ ├── shape_top_line.xml │ │ │ ├── wheel_bg.xml │ │ │ └── wheel_val.xml │ │ ├── layout/ │ │ │ ├── activity_image_browser.xml │ │ │ ├── activity_web_view.xml │ │ │ ├── footer_progress.xml │ │ │ ├── formitem_input.xml │ │ │ ├── formitem_select.xml │ │ │ ├── include_banner_with_indicator.xml │ │ │ ├── include_ddm_listview.xml │ │ │ ├── include_group_divider.xml │ │ │ ├── include_refresh_list.xml │ │ │ ├── include_titlebar.xml │ │ │ ├── item_default_drop_down.xml │ │ │ ├── item_image_banner.xml │ │ │ ├── item_image_browser.xml │ │ │ ├── item_setting.xml │ │ │ ├── listview_dropdown_menu.xml │ │ │ └── wheel_dialog_address.xml │ │ └── values/ │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ ├── build.gradle │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradle.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── DesignResCollection_MVP-Dagger2/ │ ├── README.md │ ├── app/ │ │ ├── build.gradle │ │ ├── proguard.cfg │ │ └── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── boredream/ │ │ │ └── designrescollection/ │ │ │ ├── ApplicationTest.java │ │ │ ├── idlingres/ │ │ │ │ └── RxIdlingResource.java │ │ │ └── ui/ │ │ │ ├── login/ │ │ │ │ └── LoginActivityTest.java │ │ │ └── userinfoedit/ │ │ │ └── UserInfoEditActivityTest.java │ │ ├── main/ │ │ │ ├── AndroidManifest.xml │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── boredream/ │ │ │ │ └── designrescollection/ │ │ │ │ ├── adapter/ │ │ │ │ │ ├── DesignResAdapter.java │ │ │ │ │ └── MoreRecyclerAdapter.java │ │ │ │ ├── base/ │ │ │ │ │ ├── BaseActivity.java │ │ │ │ │ ├── BaseApplication.java │ │ │ │ │ ├── BaseEntity.java │ │ │ │ │ ├── BaseFragment.java │ │ │ │ │ ├── BasePresenter.java │ │ │ │ │ └── BaseView.java │ │ │ │ ├── constants/ │ │ │ │ │ └── CommonConstants.java │ │ │ │ ├── entity/ │ │ │ │ │ ├── Comment.java │ │ │ │ │ ├── DesignRes.java │ │ │ │ │ ├── FeedBack.java │ │ │ │ │ └── User.java │ │ │ │ ├── net/ │ │ │ │ │ ├── ApiModule.java │ │ │ │ │ ├── ApiService.java │ │ │ │ │ ├── AppComponent.java │ │ │ │ │ ├── GlideHelper.java │ │ │ │ │ └── SimpleSubscriber.java │ │ │ │ ├── ui/ │ │ │ │ │ ├── AboutActivity.java │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ ├── SettingActivity.java │ │ │ │ │ ├── UserFragment.java │ │ │ │ │ ├── feedback/ │ │ │ │ │ │ ├── FeedBackActivity.java │ │ │ │ │ │ ├── FeedBackContract.java │ │ │ │ │ │ └── FeedBackPresenter.java │ │ │ │ │ ├── home/ │ │ │ │ │ │ ├── HomeContract.java │ │ │ │ │ │ ├── HomeFragment.java │ │ │ │ │ │ └── HomePresenter.java │ │ │ │ │ ├── login/ │ │ │ │ │ │ ├── LoginActivity.java │ │ │ │ │ │ ├── LoginComponent.java │ │ │ │ │ │ ├── LoginContract.java │ │ │ │ │ │ ├── LoginFragment.java │ │ │ │ │ │ ├── LoginPresenter.java │ │ │ │ │ │ └── LoginPresenterModule.java │ │ │ │ │ ├── modifytext/ │ │ │ │ │ │ ├── ModifyTextActivity.java │ │ │ │ │ │ ├── ModifyTextContract.java │ │ │ │ │ │ └── ModifyTextPresenter.java │ │ │ │ │ ├── register/ │ │ │ │ │ │ ├── RegisterContract.java │ │ │ │ │ │ ├── RegisterPresenter.java │ │ │ │ │ │ ├── RegisterStep1Activity.java │ │ │ │ │ │ └── RegisterStep2Activity.java │ │ │ │ │ └── userinfoedit/ │ │ │ │ │ ├── UserInfoEditActivity.java │ │ │ │ │ ├── UserInfoEditContract.java │ │ │ │ │ └── UserInfoEditPresenter.java │ │ │ │ └── utils/ │ │ │ │ ├── PerActivity.java │ │ │ │ ├── PerApplication.java │ │ │ │ ├── UpdateUtils.java │ │ │ │ └── UserInfoKeeper.java │ │ │ └── res/ │ │ │ ├── anim/ │ │ │ │ └── loading.xml │ │ │ ├── color/ │ │ │ │ └── txt_blue2gray_sel.xml │ │ │ ├── drawable/ │ │ │ │ ├── ic_fav_grey2black_sel.xml │ │ │ │ ├── ic_home_grey2black_sel.xml │ │ │ │ ├── ic_more_grey2black_sel.xml │ │ │ │ ├── ic_search_grey2black_sel.xml │ │ │ │ ├── ic_settings_grey2black_sel.xml │ │ │ │ └── oval_progress.xml │ │ │ ├── layout/ │ │ │ │ ├── activity_about.xml │ │ │ │ ├── activity_feed_back.xml │ │ │ │ ├── activity_input.xml │ │ │ │ ├── activity_login.xml │ │ │ │ ├── activity_main.xml │ │ │ │ ├── activity_regist.xml │ │ │ │ ├── activity_register_step1.xml │ │ │ │ ├── activity_register_step2.xml │ │ │ │ ├── activity_setting.xml │ │ │ │ ├── activity_user_info_edit.xml │ │ │ │ ├── frag_home.xml │ │ │ │ ├── frag_login.xml │ │ │ │ ├── frag_user.xml │ │ │ │ ├── include_bottom_tab.xml │ │ │ │ ├── include_more_header.xml │ │ │ │ ├── include_more_no_header.xml │ │ │ │ ├── item_design_res.xml │ │ │ │ └── item_more_header.xml │ │ │ ├── menu/ │ │ │ │ └── menu_main2.xml │ │ │ ├── values/ │ │ │ │ ├── colors.xml │ │ │ │ ├── dimens.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ └── values-w820dp/ │ │ │ └── dimens.xml │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── boredream/ │ │ └── designrescollection/ │ │ ├── net/ │ │ │ └── HttpRequestTest.java │ │ └── ui/ │ │ ├── feedback/ │ │ │ └── FeedBackPresenterTest.java │ │ ├── home/ │ │ │ └── HomePresenterTest.java │ │ ├── login/ │ │ │ └── LoginPresenterTest.java │ │ ├── modifytext/ │ │ │ └── ModifyTextPresenterTest.java │ │ ├── register/ │ │ │ └── RegisterPresenterTest.java │ │ └── userinfoedit/ │ │ └── UserInfoEditPresenterTest.java │ ├── bdcodehelper/ │ │ ├── README.md │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── assets/ │ │ │ └── city │ │ ├── java/ │ │ │ └── com/ │ │ │ └── boredream/ │ │ │ └── bdcodehelper/ │ │ │ ├── BoreConstants.java │ │ │ ├── activity/ │ │ │ │ ├── ImageBrowserActivity.java │ │ │ │ └── WebViewActivity.java │ │ │ ├── adapter/ │ │ │ │ ├── BannerPagerAdapter.java │ │ │ │ ├── ImageBrowserAdapter.java │ │ │ │ ├── ListDropDownAdapter.java │ │ │ │ ├── LoadMoreAdapter.java │ │ │ │ └── SettingRecyclerAdapter.java │ │ │ ├── base/ │ │ │ │ ├── BoreBaseActivity.java │ │ │ │ └── BoreBaseEntity.java │ │ │ ├── db/ │ │ │ │ ├── AddressData.java │ │ │ │ └── AssetsDatabaseManager.java │ │ │ ├── entity/ │ │ │ │ ├── AppUpdateInfo.java │ │ │ │ ├── ErrorResponse.java │ │ │ │ ├── FileInfo.java │ │ │ │ ├── FileUploadResponse.java │ │ │ │ ├── FormItem.java │ │ │ │ ├── ImageUrlInterface.java │ │ │ │ ├── ListResponse.java │ │ │ │ ├── PageIndex.java │ │ │ │ ├── Pointer.java │ │ │ │ ├── Relation.java │ │ │ │ ├── RelationTo.java │ │ │ │ ├── SettingItem.java │ │ │ │ ├── UpdatePswRequest.java │ │ │ │ ├── Where.java │ │ │ │ └── city/ │ │ │ │ ├── BaseAddressModel.java │ │ │ │ └── CityModel.java │ │ │ ├── fragment/ │ │ │ │ └── FragmentController.java │ │ │ ├── net/ │ │ │ │ ├── ErrorConstants.java │ │ │ │ ├── GlideCircleTransform.java │ │ │ │ ├── MultiPageRequest.java │ │ │ │ ├── ObservableDecorator.java │ │ │ │ └── RoundedCornersTransformation.java │ │ │ ├── present/ │ │ │ │ ├── FormItemsPresent.java │ │ │ │ ├── GroupEtEmptyCheckPresent.java │ │ │ │ ├── ImageBannerPresent.java │ │ │ │ ├── ImageBrowserPresent.java │ │ │ │ └── MultiPageLoadPresent.java │ │ │ ├── utils/ │ │ │ │ ├── ActivityUtils.java │ │ │ │ ├── AppUtils.java │ │ │ │ ├── DateUtils.java │ │ │ │ ├── DialogUtils.java │ │ │ │ ├── DisplayUtils.java │ │ │ │ ├── ErrorInfoUtils.java │ │ │ │ ├── ImageUtils.java │ │ │ │ ├── LogUtils.java │ │ │ │ ├── NetUtils.java │ │ │ │ ├── StringUtils.java │ │ │ │ ├── TitleBuilder.java │ │ │ │ ├── ToastUtils.java │ │ │ │ └── ViewUtils.java │ │ │ └── view/ │ │ │ ├── AddressWheelDialog.java │ │ │ ├── BottomTabRadioButton.java │ │ │ ├── CheckableLinearLayout.java │ │ │ ├── DividerItemDecoration.java │ │ │ ├── DrawableRadioButton.java │ │ │ ├── DrawableTextView.java │ │ │ ├── DropDownMenu.java │ │ │ ├── EmptyItemDecoration.java │ │ │ ├── GridSpacingDecorator.java │ │ │ ├── PinnedSectionListView.java │ │ │ ├── PositionBar.java │ │ │ ├── WrapHeightGridView.java │ │ │ ├── WrapHeightLinearLayoutManager.java │ │ │ ├── WrapHeightListView.java │ │ │ └── wheel/ │ │ │ ├── ItemsRange.java │ │ │ ├── OnWheelChangedListener.java │ │ │ ├── OnWheelClickedListener.java │ │ │ ├── OnWheelScrollListener.java │ │ │ ├── WheelAdapter.java │ │ │ ├── WheelRecycle.java │ │ │ ├── WheelScroller.java │ │ │ ├── WheelView.java │ │ │ └── adapters/ │ │ │ ├── AbstractWheelAdapter.java │ │ │ ├── AbstractWheelTextAdapter.java │ │ │ ├── AdapterWheel.java │ │ │ ├── ArrayWheelAdapter.java │ │ │ ├── NumericWheelAdapter.java │ │ │ └── WheelViewAdapter.java │ │ ├── libs/ │ │ │ └── nineoldandroids-2.2.0.jar │ │ └── res/ │ │ ├── anim/ │ │ │ ├── dd_mask_in.xml │ │ │ ├── dd_mask_out.xml │ │ │ ├── dd_menu_in.xml │ │ │ └── dd_menu_out.xml │ │ ├── color/ │ │ │ ├── txt_blue2gray_sel.xml │ │ │ ├── txt_gray2primarydark_sel.xml │ │ │ ├── txt_lgray2white_sel.xml │ │ │ ├── txt_primary2white_sel.xml │ │ │ └── txt_white2gray_sel.xml │ │ ├── drawable/ │ │ │ ├── bg_gray2dark_sel.xml │ │ │ ├── bg_primary2dark_sel.xml │ │ │ ├── bg_primarydark_indicator_sel.xml │ │ │ ├── bg_tran2gray_sel.xml │ │ │ ├── bg_white2gray_sel.xml │ │ │ ├── cirrect_10a_primary_solid.xml │ │ │ ├── cirrect_5a_primary_solid.xml │ │ │ ├── cirrect_primary_stroke.xml │ │ │ ├── correct_gray_stroke.xml │ │ │ ├── correct_primary.xml │ │ │ ├── correct_primary2dark_sel.xml │ │ │ ├── correct_primary_dark.xml │ │ │ ├── correct_primary_light.xml │ │ │ ├── correct_primary_stroke.xml │ │ │ ├── correct_primary_stroke2solid_sel.xml │ │ │ ├── layerlist_primarydark_indicator.xml │ │ │ ├── oval_primary_light_solid.xml │ │ │ ├── oval_primary_solid.xml │ │ │ ├── shape_bottom_line.xml │ │ │ ├── shape_oval_primary2white_sel.xml │ │ │ ├── shape_oval_primary_stroke.xml │ │ │ ├── shape_oval_primary_stroke2solid_sel.xml │ │ │ ├── shape_oval_red_solid.xml │ │ │ ├── shape_oval_white_solid.xml │ │ │ ├── shape_top_line.xml │ │ │ ├── wheel_bg.xml │ │ │ └── wheel_val.xml │ │ ├── layout/ │ │ │ ├── activity_image_browser.xml │ │ │ ├── activity_web_view.xml │ │ │ ├── footer_progress.xml │ │ │ ├── formitem_input.xml │ │ │ ├── formitem_select.xml │ │ │ ├── include_banner_with_indicator.xml │ │ │ ├── include_ddm_listview.xml │ │ │ ├── include_group_divider.xml │ │ │ ├── include_refresh_list.xml │ │ │ ├── include_titlebar.xml │ │ │ ├── item_default_drop_down.xml │ │ │ ├── item_image_banner.xml │ │ │ ├── item_image_browser.xml │ │ │ ├── item_setting.xml │ │ │ ├── listview_dropdown_menu.xml │ │ │ └── wheel_dialog_address.xml │ │ └── values/ │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ ├── build.gradle │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradle.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto # Custom for Visual Studio *.cs diff=csharp # Standard to msysgit *.doc diff=astextplain *.DOC diff=astextplain *.docx diff=astextplain *.DOCX diff=astextplain *.dot diff=astextplain *.DOT diff=astextplain *.pdf diff=astextplain *.PDF diff=astextplain *.rtf diff=astextplain *.RTF diff=astextplain ================================================ FILE: .gitignore ================================================ # Built application files *.apk *.ap_ # Files for the Dalvik VM *.dex # Java class files *.class # Generated files bin/ gen/ out/ # Gradle files .gradle/ build/ .idea/ # Local configuration file (sdk path, etc) local.properties # Proguard folder generated by Eclipse proguard/ # Log Files *.log # Android Studio Navigation editor temp files .navigation/ # Android Studio captures folder captures/ # Intellij *.iml # Keystore files *.jks # ========================= # Operating System Files # ========================= # OSX # ========================= .DS_Store .AppleDouble .LSOverride # Thumbnails ._* # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 .TemporaryItems .Trashes .VolumeIcon.icns # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk # Windows # ========================= # Windows image file caches Thumbs.db ehthumbs.db # Folder config file Desktop.ini # Recycle Bin used on file shares $RECYCLE.BIN/ # Windows Installer files *.cab *.msi *.msm *.msp # Windows shortcuts *.lnk ================================================ FILE: DesignResCollection_MVC/README.md ================================================ ## Model-View-Controller 结构 经典MVC模式。 LeanCloud作为后端,网络框架+图片框架,一起组成了一个普通App最基础的部分。可以参考本项目框架实现自己各种idea~ 最好自己去申请个LeanCloud或者Bmob的账号应用,两个平台的Restful-API由于是一毛一样的,所以可以随意切换~ ## 使用框架 * 使用LeanCloud的Restful-API接口作为后端服务。 * 网络框架部分使用Retrofit2.0 * 图片框架部分使用Glide。 * 响应式编程RxJava + RxBinding ================================================ FILE: DesignResCollection_MVC/app/build.gradle ================================================ apply plugin: 'com.android.application' android { compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { applicationId "com.boredream.designrescollection" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 70 versionName "0.7.0" } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg' } } packagingOptions { exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' } lintOptions { abortOnError false } android.applicationVariants.all { variant -> renameAPK(variant, defaultConfig, "release") } } def renameAPK(variant, defaultConfig, buildType) { variant.outputs.each { output -> def applicationName = 'DesignResCollection' def formattedDate = new Date().format('yyyyMMdd') def file = output.packageApplication.outputFile def fileName = applicationName + "_v" + defaultConfig.versionName + "_" + formattedDate + "_" + buildType + ".apk" output.packageApplication.outputFile = new File(file.parent, fileName) } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile project(path: ':bdcodehelper') } ================================================ FILE: DesignResCollection_MVC/app/proguard.cfg ================================================ ######################## 固定部分 ######################## #1.基本指令区 -optimizationpasses 5 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers -dontpreverify -verbose -ignorewarning -printmapping proguardMapping.txt -optimizations !code/simplification/cast,!field/*,!class/merging/* -keepattributes *Annotation*,InnerClasses -keepattributes Signature -keepattributes SourceFile,LineNumberTable #2.默认保留区 -keep public class * extends android.app.Activity -keep public class * extends android.app.Application -keep public class * extends android.app.Service -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.ContentProvider -keep public class * extends android.app.backup.BackupAgentHelper -keep public class * extends android.preference.Preference -keep public class * extends android.view.View -keep public class com.android.vending.licensing.ILicensingService -keep class android.support.** {*;} -keepclasseswithmembernames class * { native ; } -keepclassmembers class * extends android.app.Activity{ public void *(android.view.View); } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keep public class * extends android.view.View{ *** get*(); void set*(***); public (android.content.Context); public (android.content.Context, android.util.AttributeSet); public (android.content.Context, android.util.AttributeSet, int); } -keepclasseswithmembers class * { public (android.content.Context, android.util.AttributeSet); public (android.content.Context, android.util.AttributeSet, int); } -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } -keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve(); } -keep class **.R$* { *; } -keepclassmembers class * { void *(**On*Event); } #3.webview -keepclassmembers class fqcn.of.javascript.interface.for.webview { public *; } -keepclassmembers class * extends android.webkit.webViewClient { public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap); public boolean *(android.webkit.WebView, java.lang.String); } -keepclassmembers class * extends android.webkit.webViewClient { public void *(android.webkit.webView, jav.lang.String); } ######################## 非固定部分 ######################## ================================================ FILE: DesignResCollection_MVC/app/src/androidTest/java/com/boredream/designrescollection/ApplicationTest.java ================================================ package com.boredream.designrescollection; import android.app.Application; import android.test.ApplicationTestCase; /** * Testing Fundamentals */ public class ApplicationTest extends ApplicationTestCase { public ApplicationTest() { super(Application.class); } } ================================================ FILE: DesignResCollection_MVC/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/activity/AboutActivity.java ================================================ package com.boredream.designrescollection.activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.text.SpannableString; import android.text.Spanned; import android.text.method.LinkMovementMethod; import android.view.View; import android.widget.TextView; import com.boredream.bdcodehelper.utils.AppUtils; import com.boredream.bdcodehelper.utils.StringUtils; import com.boredream.designrescollection.R; import com.boredream.designrescollection.base.BaseActivity; public class AboutActivity extends BaseActivity { private TextView tv_version; private TextView tv_about; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_about); initView(); } private void initView() { initBackTitle("关于我"); tv_version = (TextView) findViewById(R.id.tv_version); tv_about = (TextView) findViewById(R.id.tv_about); tv_version.setText("Version " + AppUtils.getAppVersionName(this)); SpannableString ss = getAboutString(); tv_about.setMovementMethod(LinkMovementMethod.getInstance()); tv_about.setText(ss); } private SpannableString getAboutString() { final String githubLink = getString(R.string.github); String format = String.format(getString(R.string.about), githubLink); SpannableString ss = new SpannableString(format); // 网址部分可点击,跳转到网页 StringUtils.PrimaryClickableSpan span = new StringUtils.PrimaryClickableSpan(this) { @Override public void onClick(View widget) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(githubLink)); startActivity(intent); } }; int start = format.indexOf(githubLink); ss.setSpan(span, start, start + githubLink.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return ss; } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/activity/FeedBackActivity.java ================================================ package com.boredream.designrescollection.activity; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.EditText; import android.widget.Toast; import com.boredream.bdcodehelper.net.ObservableDecorator; import com.boredream.designrescollection.R; import com.boredream.designrescollection.base.BaseActivity; import com.boredream.designrescollection.base.BaseEntity; import com.boredream.designrescollection.entity.FeedBack; import com.boredream.designrescollection.net.HttpRequest; import com.boredream.designrescollection.net.SimpleSubscriber; import rx.Observable; public class FeedBackActivity extends BaseActivity { private EditText et_content; private EditText et_email; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_feed_back); initView(); } private void initView() { initBackTitle("意见反馈") .setRightText("提交") .setRightOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { submit(); } }); et_content = (EditText) findViewById(R.id.et_content); et_email = (EditText) findViewById(R.id.et_email); } private void submit() { // 开始验证输入内容 String content = et_content.getText().toString().trim(); if (TextUtils.isEmpty(content)) { Toast.makeText(this, "反馈内容不能为空", Toast.LENGTH_SHORT).show(); return; } String email = et_email.getText().toString().trim(); if (TextUtils.isEmpty(email)) { Toast.makeText(this, "请输入邮箱地址,方便我们对您的意见进行及时回复", Toast.LENGTH_SHORT).show(); return; } // 使用自定义对象存至云平台,作为简易版的反馈意见收集 FeedBack fb = new FeedBack(); fb.setContent(content); fb.setEmail(email); showProgressDialog(); Observable observable = HttpRequest.getApiService().addFeedBack(fb); ObservableDecorator.decorate(observable).subscribe( new SimpleSubscriber(this) { @Override public void onNext(BaseEntity entity) { dismissProgressDialog(); showToast("反馈成功"); finish(); } @Override public void onError(Throwable throwable) { super.onError(throwable); dismissProgressDialog(); } }); } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/activity/LoginActivity.java ================================================ package com.boredream.designrescollection.activity; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.Toast; import com.boredream.bdcodehelper.net.ObservableDecorator; import com.boredream.designrescollection.R; import com.boredream.designrescollection.base.BaseActivity; import com.boredream.designrescollection.entity.User; import com.boredream.designrescollection.net.HttpRequest; import com.boredream.designrescollection.net.SimpleSubscriber; import rx.Observable; public class LoginActivity extends BaseActivity implements View.OnClickListener { private EditText et_username; private EditText et_password; private Button btn_login; private LinearLayout ll_regist; /** * 是否为验证登录,true-登录成功后,直接finish返回到来源页 false-登录成功后跳转到主页 */ private boolean checkLogin; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); initExtras(); initView(); } private void initExtras() { checkLogin = getIntent().getBooleanExtra("checkLogin", false); } private void initView() { initBackTitle("登录"); et_username = (EditText) findViewById(R.id.et_username); et_password = (EditText) findViewById(R.id.et_password); btn_login = (Button) findViewById(R.id.btn_login); ll_regist = (LinearLayout) findViewById(R.id.ll_regist); btn_login.setOnClickListener(this); ll_regist.setOnClickListener(this); } private void login() { // validate String username = et_username.getText().toString().trim(); if (TextUtils.isEmpty(username)) { Toast.makeText(this, "请输入手机号", Toast.LENGTH_SHORT).show(); return; } String password = et_password.getText().toString().trim(); if (TextUtils.isEmpty(password)) { Toast.makeText(this, "请输入密码", Toast.LENGTH_SHORT).show(); return; } showProgressDialog(); Observable observable = HttpRequest.login(username, password); ObservableDecorator.decorate(observable) .subscribe(new SimpleSubscriber(this) { @Override public void onNext(User user) { dismissProgressDialog(); if (checkLogin) { // 是验证登录,登录成功后,直接finish返回到来源页 finish(); } else { // 不是验证登录,登录成功后跳转到主页 intent2Activity(MainActivity.class); } } @Override public void onError(Throwable throwable) { super.onError(throwable); dismissProgressDialog(); } }); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_login: login(); break; case R.id.ll_regist: intent2Activity(RegisterStep1Activity.class); break; } } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/activity/MainActivity.java ================================================ package com.boredream.designrescollection.activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.widget.RadioButton; import android.widget.RadioGroup; import com.boredream.bdcodehelper.fragment.FragmentController; import com.boredream.designrescollection.R; import com.boredream.designrescollection.base.BaseActivity; import com.boredream.designrescollection.fragment.HomeFragment; import com.boredream.designrescollection.fragment.UserFragment; import com.boredream.designrescollection.utils.UpdateUtils; import java.util.ArrayList; public class MainActivity extends BaseActivity implements RadioGroup.OnCheckedChangeListener { private RadioGroup rg_bottom_tab; private RadioButton rb1; private FragmentController controller; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); } private void initView() { setCouldDoubleBackExit(true); rg_bottom_tab = (RadioGroup) findViewById(R.id.rg_bottom_tab); rb1 = (RadioButton) findViewById(R.id.rb1); rg_bottom_tab.setOnCheckedChangeListener(this); } private void initData() { ArrayList fragments = new ArrayList<>(); fragments.add(new HomeFragment()); fragments.add(new UserFragment()); controller = new FragmentController(this, R.id.fl_content, fragments); // 默认Fragment rb1.setChecked(true); controller.showFragment(0); UpdateUtils.checkUpdate(this, false); } @Override public void onCheckedChanged(RadioGroup radioGroup, int checkedId) { switch (checkedId) { case R.id.rb1: controller.showFragment(0); break; case R.id.rb2: controller.showFragment(1); break; } } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/activity/RegisterStep1Activity.java ================================================ package com.boredream.designrescollection.activity; import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import com.boredream.designrescollection.R; import com.boredream.designrescollection.base.BaseActivity; /** * 注册页面步骤一 */ public class RegisterStep1Activity extends BaseActivity implements View.OnClickListener { private EditText et_username; private EditText et_password; private Button btn_next; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register_step1); initView(); } private void initView() { initBackTitle("注册"); et_username = (EditText) findViewById(R.id.et_username); et_password = (EditText) findViewById(R.id.et_password); btn_next = (Button) findViewById(R.id.btn_next); btn_next.setOnClickListener(this); } private void next() { // validate final String username = et_username.getText().toString().trim(); if (TextUtils.isEmpty(username)) { Toast.makeText(this, "请输入用户名", Toast.LENGTH_SHORT).show(); return; } final String password = et_password.getText().toString().trim(); if (TextUtils.isEmpty(password) || password.length() < 6) { Toast.makeText(this, "请设置登录密码,不少于6位", Toast.LENGTH_SHORT).show(); return; } // FIXME: 短信有限,所以直接模拟验证码发送成功,使用不验证的注册 // requestSmsCode(phone, password); toValidateStep2(username, password); } // 短信验证码发送成功后,跳转到短信验证页,同时传递所需数据 private void toValidateStep2(String phone, String password) { Intent intent = new Intent(RegisterStep1Activity.this, RegisterStep2Activity.class); intent.putExtra("phone", phone); intent.putExtra("password", password); startActivity(intent); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_next: next(); break; } } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/activity/RegisterStep2Activity.java ================================================ package com.boredream.designrescollection.activity; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.os.CountDownTimer; import android.support.v7.app.AlertDialog; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import com.boredream.bdcodehelper.net.ObservableDecorator; import com.boredream.bdcodehelper.utils.DateUtils; import com.boredream.designrescollection.R; import com.boredream.designrescollection.base.BaseActivity; import com.boredream.designrescollection.entity.User; import com.boredream.designrescollection.net.HttpRequest; import com.boredream.designrescollection.net.SimpleSubscriber; import com.boredream.designrescollection.utils.UserInfoKeeper; import rx.Observable; /** * 注册页面步骤二 */ public class RegisterStep2Activity extends BaseActivity implements View.OnClickListener { // 总倒计时60秒 private static final long TOTCAL_TIME = 60 * DateUtils.ONE_SECOND_MILLIONS; // 每次减少1秒 private static final long COUNT_DOWN_INTERVAL = DateUtils.ONE_SECOND_MILLIONS; private EditText et_verification_code; private Button btn_code_info; private Button btn_next; private String phone; private String password; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register_step2); initExtras(); initView(); initData(); } private void initExtras() { Intent intent = getIntent(); phone = intent.getStringExtra("phone"); password = intent.getStringExtra("password"); } private void initView() { initBackTitle("手机号验证"); et_verification_code = (EditText) findViewById(R.id.et_verification_code); btn_code_info = (Button) findViewById(R.id.btn_code_info); btn_next = (Button) findViewById(R.id.btn_next); btn_code_info.setOnClickListener(this); btn_next.setOnClickListener(this); } private void initData() { startCountDown(); } /** * 开始倒计时 */ private void startCountDown() { showToast("短信验证码发送成功"); btn_code_info.setText("60秒"); btn_code_info.setEnabled(false); // 倒计时开始,共60秒,每次减少1秒 CountDownTimer timer = new CountDownTimer(TOTCAL_TIME, COUNT_DOWN_INTERVAL) { @Override public void onTick(long l) { // 重新获取(60) String restTime = (int) (l / COUNT_DOWN_INTERVAL) + "秒"; btn_code_info.setText(restTime); } @Override public void onFinish() { // 倒计时结束,重置按钮 btn_code_info.setText("重新获取"); btn_code_info.setEnabled(true); } }; timer.start(); } /** * 根据类型提交注册或重置密码接口 */ private void submit() { // validate String code = et_verification_code.getText().toString().trim(); if (TextUtils.isEmpty(code)) { Toast.makeText(this, "请输入验证码", Toast.LENGTH_SHORT).show(); return; } register(code); } /** * 注册 */ private void register(String code) { User user = new User(); user.setMobilePhoneNumber(phone); user.setUsername(phone); user.setPassword(password); user.setSmsCode(code); Observable observable = HttpRequest.getApiService().register(user); showProgressDialog(); ObservableDecorator.decorate(observable) .subscribe(new SimpleSubscriber(this) { @Override public void onNext(User user) { // include token dismissProgressDialog(); UserInfoKeeper.setCurrentUser(user); // 注册成功,显示成功提示框 showRegistSuccessDialog(); } @Override public void onError(Throwable throwable) { super.onError(throwable); dismissProgressDialog(); } }); } /** * 注册成功提示框,提醒用户完善资料 */ private void showRegistSuccessDialog() { new AlertDialog.Builder(this) .setMessage("注册成功,你可以在个人详情中修改或完善用户信息。") .setPositiveButton("确定", null) .setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { // 确定或者返回键关闭对话框都走此 intent2Activity(MainActivity.class); } }) .setCancelable(false) // cancelable设为false,防止用户点击返回键关闭对话框停留在当前页面 .show(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_code_info: // FIXME: 短信有限,所以直接模拟验证码发送成功,使用不验证的注册 // resendSmsCode(); startCountDown(); break; case R.id.btn_next: submit(); break; } } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/activity/SettingActivity.java ================================================ package com.boredream.designrescollection.activity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.AdapterView; import android.widget.Button; import com.boredream.bdcodehelper.adapter.SettingRecyclerAdapter; import com.boredream.bdcodehelper.entity.SettingItem; import com.boredream.bdcodehelper.utils.AppUtils; import com.boredream.bdcodehelper.view.DividerItemDecoration; import com.boredream.designrescollection.R; import com.boredream.designrescollection.base.BaseActivity; import com.boredream.designrescollection.utils.UpdateUtils; import com.boredream.designrescollection.utils.UserInfoKeeper; import java.util.ArrayList; import java.util.List; public class SettingActivity extends BaseActivity implements View.OnClickListener, AdapterView.OnItemClickListener { private RecyclerView rv_setting; private Button btn_logout; private SettingRecyclerAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_setting); initView(); initData(); } private void initView() { initBackTitle("设置"); rv_setting = (RecyclerView) findViewById(R.id.rv_setting); btn_logout = (Button) findViewById(R.id.btn_logout); btn_logout.setOnClickListener(this); } private void initData() { // 使用列表显示多个选项条 List items = new ArrayList<>(); items.add(new SettingItem( R.mipmap.ic_cached_grey600_24dp, "检查更新", AppUtils.getAppVersionName(this), R.mipmap.ic_chevron_right_grey600_24dp )); items.add(new SettingItem( R.mipmap.ic_announcement_grey600_24dp, "反馈", null, R.mipmap.ic_chevron_right_grey600_24dp )); adapter = new SettingRecyclerAdapter(items, this); rv_setting.setAdapter(adapter); LinearLayoutManager linearLayoutManager = new LinearLayoutManager( this, LinearLayoutManager.VERTICAL, false); rv_setting.setLayoutManager(linearLayoutManager); // 每个item之间的分割线 rv_setting.addItemDecoration(new DividerItemDecoration(this)); } @Override public void onItemClick(AdapterView parent, View view, int position, long id) { switch (position) { case 0: showProgressDialog(); // 强制检查更新,并添加额外回调用于处理进度框 UpdateUtils.checkUpdate(this, true); break; case 1: if(UserInfoKeeper.checkLogin(this)) { // 一般意见反馈不需要登录,这里模拟下需登录场景的处理方法 intent2Activity(FeedBackActivity.class); } break; } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_logout: // 登出,清理用户数据同时跳转到主页 UserInfoKeeper.logout(); intent2Activity(MainActivity.class); break; } } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/activity/UserInfoEditActivity.java ================================================ package com.boredream.designrescollection.activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.boredream.bdcodehelper.entity.FileUploadResponse; import com.boredream.bdcodehelper.net.ObservableDecorator; import com.boredream.bdcodehelper.utils.ImageUtils; import com.boredream.designrescollection.R; import com.boredream.designrescollection.base.BaseActivity; import com.boredream.designrescollection.base.BaseEntity; import com.boredream.designrescollection.entity.User; import com.boredream.designrescollection.net.GlideHelper; import com.boredream.designrescollection.net.HttpRequest; import com.boredream.designrescollection.net.SimpleSubscriber; import com.boredream.designrescollection.utils.UserInfoKeeper; import java.util.HashMap; import java.util.Map; import rx.Observable; public class UserInfoEditActivity extends BaseActivity implements View.OnClickListener { private ImageView iv_avatar; private LinearLayout ll_avatar; private TextView tv_username; private LinearLayout ll_username; private User currentUser; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_info_edit); initView(); } @Override protected void onStart() { super.onStart(); // 如果跳转到二级页面修改了用户信息,则再次返回到该页面时显示最新的用户数据 initData(); } private void initData() { currentUser = UserInfoKeeper.getCurrentUser(); showUserAvatar(); tv_username.setText(currentUser.getUsername()); } private void showUserAvatar() { GlideHelper.showAvatar(this, currentUser.getAvatar(), iv_avatar); } private void initView() { initBackTitle("修改个人资料"); iv_avatar = (ImageView) findViewById(R.id.iv_avatar); ll_avatar = (LinearLayout) findViewById(R.id.ll_avatar); tv_username = (TextView) findViewById(R.id.tv_username); ll_username = (LinearLayout) findViewById(R.id.ll_username); ll_avatar.setOnClickListener(this); ll_username.setOnClickListener(this); } /** * 上传用户头像图片 * * @param uri 头像图片uri */ private void uploadUserAvatarImage(Uri uri) { showProgressDialog(); // 第一步,上传头像文件到服务器 HttpRequest.fileUpload(this, uri, iv_avatar.getWidth(), iv_avatar.getHeight(), new SimpleSubscriber(this) { @Override public void onNext(FileUploadResponse fileUploadResponse) { // 第二步,将上传图片返回的url地址更新至用户对象中 uploadUserAvatarImage(HttpRequest.FILE_HOST + fileUploadResponse.getUrl()); } @Override public void onError(Throwable throwable) { super.onError(throwable); dismissProgressDialog(); } }); } /** * 更新用户头像 * * @param avatarUrl 头像图片地址 */ private void uploadUserAvatarImage(final String avatarUrl) { Map updateMap = new HashMap<>(); updateMap.put("avatar", avatarUrl); Observable observable = HttpRequest.getApiService().updateUserById( currentUser.getObjectId(), updateMap); ObservableDecorator.decorate(observable) .subscribe(new SimpleSubscriber(this) { @Override public void onNext(BaseEntity entity) { dismissProgressDialog(); // 成功后更新当前用户的头像数据 currentUser.setAvatar(avatarUrl); UserInfoKeeper.setCurrentUser(currentUser); showUserAvatar(); showToast("头像修改成功"); } @Override public void onError(Throwable throwable) { super.onError(throwable); dismissProgressDialog(); } }); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.ll_avatar: ImageUtils.showImagePickDialog(this); break; case R.id.ll_username: intent2Activity(UsernameModifyActivity.class); break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != RESULT_OK) { return; } Uri uri; switch (requestCode) { case ImageUtils.REQUEST_CODE_FROM_ALBUM: // 从相册选择 uri = data.getData(); // 选择后裁剪 ImageUtils.cropImage(this, uri); break; case ImageUtils.REQUEST_CODE_FROM_CAMERA: // 相机拍照 uri = ImageUtils.imageUriFromCamera; // 拍照后裁剪 ImageUtils.cropImage(this, uri); break; case ImageUtils.REQUEST_CODE_CROP_IMAGE: // 裁剪完成后上传图片 uploadUserAvatarImage(ImageUtils.cropImageUri); break; } } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/activity/UsernameModifyActivity.java ================================================ package com.boredream.designrescollection.activity; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.EditText; import android.widget.Toast; import com.boredream.bdcodehelper.net.ObservableDecorator; import com.boredream.designrescollection.R; import com.boredream.designrescollection.base.BaseActivity; import com.boredream.designrescollection.base.BaseEntity; import com.boredream.designrescollection.entity.User; import com.boredream.designrescollection.net.HttpRequest; import com.boredream.designrescollection.net.SimpleSubscriber; import com.boredream.designrescollection.utils.UserInfoKeeper; import java.util.HashMap; import java.util.Map; import rx.Observable; /** * 修改用户名输入框页面 */ public class UsernameModifyActivity extends BaseActivity { private EditText et; private User currentUser; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_input); initView(); initData(); } private void initView() { initBackTitle("昵称修改") .setRightText("保存") .setRightOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { submit(); } }); et = (EditText) findViewById(R.id.et); } private void initData() { currentUser = UserInfoKeeper.getCurrentUser(); et.setText(currentUser.getUsername()); } private void submit() { // validate final String username = et.getText().toString().trim(); if (TextUtils.isEmpty(username)) { Toast.makeText(this, "昵称不能为空", Toast.LENGTH_SHORT).show(); return; } // 修改用户的username Map updateMap = new HashMap<>(); updateMap.put("username", username); showProgressDialog(); Observable observable = HttpRequest.getApiService() .updateUserById(currentUser.getObjectId(), updateMap); ObservableDecorator.decorate(observable) .subscribe(new SimpleSubscriber(this) { @Override public void onNext(BaseEntity entity) { dismissProgressDialog(); // 修改成功后更新当前用户的昵称 currentUser.setUsername(username); UserInfoKeeper.setCurrentUser(currentUser); showToast("昵称修改成功"); finish(); } @Override public void onError(Throwable throwable) { super.onError(throwable); dismissProgressDialog(); } }); } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/adapter/DesignResAdapter.java ================================================ package com.boredream.designrescollection.adapter; import android.content.Context; import android.content.Intent; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.boredream.bdcodehelper.activity.WebViewActivity; import com.boredream.designrescollection.R; import com.boredream.designrescollection.entity.DesignRes; import com.boredream.designrescollection.net.GlideHelper; import java.util.ArrayList; public class DesignResAdapter extends RecyclerView.Adapter { private Context context; private ArrayList datas; public DesignResAdapter(Context context, ArrayList datas) { this.context = context; this.datas = datas; } @Override public int getItemCount() { return datas.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { public ImageView iv_image; public TextView tv_name; public ViewHolder(View rootView) { super(rootView); this.iv_image = (ImageView) rootView.findViewById(R.id.iv_image); this.tv_name = (TextView) rootView.findViewById(R.id.tv_name); } } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(context).inflate(R.layout.item_design_res, parent, false); return new ViewHolder(v); } @Override public void onBindViewHolder(ViewHolder holder, int position) { final DesignRes data = datas.get(position); GlideHelper.showImage(context, data.getImgUrl(), holder.iv_image); String str = String.format("[%s] %s", data.getSrcTag(), data.getName()); holder.tv_name.setText(str); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(context, WebViewActivity.class); intent.putExtra(WebViewActivity.EXTRA_TITLE, data.getName()); intent.putExtra(WebViewActivity.EXTRA_URL, data.getSrcLink()); context.startActivity(intent); } }); } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/adapter/MoreRecyclerAdapter.java ================================================ package com.boredream.designrescollection.adapter; import android.content.Intent; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView.OnItemClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import com.boredream.bdcodehelper.adapter.SettingRecyclerAdapter; import com.boredream.bdcodehelper.entity.SettingItem; import com.boredream.designrescollection.R; import com.boredream.designrescollection.activity.LoginActivity; import com.boredream.designrescollection.entity.User; import com.boredream.designrescollection.net.GlideHelper; import java.util.List; /** * 更多选项列表适配器 *

* 第一个位置为HEADER类型,对应用户信息
* 其他位置为LIST类型,对应选项item */ public class MoreRecyclerAdapter extends SettingRecyclerAdapter { private static final int ITEM_VIEW_TYPE_HEADER = 0; private User user; public MoreRecyclerAdapter(List datas, OnItemClickListener listener) { super(datas, listener); } @Override public int getItemCount() { // header + 1 return datas.size() + 1; } @Override public int getItemViewType(int position) { return position == 0 ? ITEM_VIEW_TYPE_HEADER : super.getItemViewType(position); } public void setUser(User user) { this.user = user; } public static class ViewHolderUserHeader extends RecyclerView.ViewHolder { public View include_more_header; public ImageView iv_avatar; public TextView tv_name; // not login public View include_more_no_header; public Button btn_login; public ViewHolderUserHeader(final View itemView) { super(itemView); include_more_header = itemView.findViewById(R.id.include_more_header); iv_avatar = (ImageView) itemView.findViewById(R.id.iv_avatar); tv_name = (TextView) itemView.findViewById(R.id.tv_name); include_more_no_header = itemView.findViewById(R.id.include_more_no_header); btn_login = (Button) itemView.findViewById(R.id.btn_login); } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == ITEM_VIEW_TYPE_HEADER) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_more_header, parent, false); return new ViewHolderUserHeader(v); } else { return super.onCreateViewHolder(parent, viewType); } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { int itemViewType = getItemViewType(position); if (itemViewType == ITEM_VIEW_TYPE_HEADER) { // header ViewHolderUserHeader viewHolderHeader = (ViewHolderUserHeader) holder; if (user != null) { // 如果已登录,用户数据非空,则显示用户信息 viewHolderHeader.include_more_header.setVisibility(View.VISIBLE); viewHolderHeader.include_more_no_header.setVisibility(View.GONE); GlideHelper.showAvatar(holder.itemView.getContext(), user.getAvatar(), viewHolderHeader.iv_avatar); viewHolderHeader.tv_name.setText(user.getUsername()); viewHolderHeader.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mOnItemClickListener != null) { // header使用特殊的position -1 mOnItemClickListener.onItemClick(null, view, -1, -1); } } }); } else { // 未登录,提供登录按钮,点击进入登录页 viewHolderHeader.include_more_header.setVisibility(View.GONE); viewHolderHeader.include_more_no_header.setVisibility(View.VISIBLE); viewHolderHeader.btn_login.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(view.getContext(), LoginActivity.class); view.getContext().startActivity(intent); } }); } } else { // setting item // 第一个位置多了个HEADER,所以position差1 super.onBindViewHolder(holder, position - 1); } } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/base/BaseActivity.java ================================================ package com.boredream.designrescollection.base; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import com.boredream.bdcodehelper.base.BoreBaseActivity; import com.boredream.designrescollection.activity.MainActivity; import com.boredream.designrescollection.constants.CommonConstants; import java.util.concurrent.TimeUnit; import rx.Observable; import rx.functions.Action1; public class BaseActivity extends BoreBaseActivity { public BaseApplication application; public SharedPreferences sp; private boolean couldDoubleBackExit; private boolean doubleBackExitPressedOnce; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 如果是退出应用flag,则直接关闭当前页面,不加载UI boolean exit = getIntent().getBooleanExtra("exit", false); if (exit) { finish(); return; } application = (BaseApplication) getApplication(); sp = getSharedPreferences(CommonConstants.SP_NAME, MODE_PRIVATE); } /** * 设置是否可以双击返回退出,需要有该功能的页面set true即可 * * @param couldDoubleBackExit true-开启双击退出 */ public void setCouldDoubleBackExit(boolean couldDoubleBackExit) { this.couldDoubleBackExit = couldDoubleBackExit; } @Override public void onBackPressed() { if (!couldDoubleBackExit) { // 非双击退出状态,使用原back逻辑 super.onBackPressed(); return; } // 双击返回键关闭程序 // 如果两秒重置时间内再次点击返回,则退出程序 if (doubleBackExitPressedOnce) { exit(); return; } doubleBackExitPressedOnce = true; showToast("再按一次返回键关闭程序"); Observable.just(null) .delay(2, TimeUnit.SECONDS) .subscribe(new Action1() { @Override public void call(Object o) { // 延迟两秒后重置标志位为false doubleBackExitPressedOnce = false; } }); } /** * 退出程序 */ protected void exit() { // 退出程序方法有多种 // 这里使用clear + new task的方式清空整个任务栈,只保留新打开的Main页面 // 然后Main页面接收到退出的标志位exit=true,finish自己,这样就关闭了全部页面 Intent intent = new Intent(this, MainActivity.class); intent.putExtra("exit", true); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/base/BaseApplication.java ================================================ package com.boredream.designrescollection.base; import android.app.Application; import com.boredream.designrescollection.net.HttpRequest; import com.bumptech.glide.Glide; import com.bumptech.glide.integration.okhttp.OkHttpUrlLoader; import com.bumptech.glide.load.model.GlideUrl; import com.squareup.okhttp.OkHttpClient; import java.io.InputStream; public class BaseApplication extends Application { private static BaseApplication instance; public static BaseApplication getInstance() { return instance; } @Override public void onCreate() { super.onCreate(); instance = this; initGlide(); } /** * 图片加载框架Glide,使用OkHttp处理网络请求 */ private void initGlide() { OkHttpClient okHttpClient = HttpRequest.getHttpClient(); Glide.get(this).register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(okHttpClient)); } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/base/BaseEntity.java ================================================ package com.boredream.designrescollection.base; import com.boredream.bdcodehelper.base.BoreBaseEntity; public class BaseEntity extends BoreBaseEntity { @Override public boolean equals(Object o) { if (o instanceof BaseEntity) { BaseEntity oEntity = (BaseEntity) o; return this.objectId.equals(oEntity.objectId); } return super.equals(o); } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/base/BaseFragment.java ================================================ package com.boredream.designrescollection.base; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; import android.util.Log; import android.widget.Toast; import com.boredream.bdcodehelper.utils.ToastUtils; public abstract class BaseFragment extends Fragment { protected String TAG; protected BaseActivity activity; // progressDialog/sp/application 等使用activity.xx 调用 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TAG = getClass().getSimpleName(); activity = (BaseActivity) getActivity(); } protected void intent2Activity(Class tarActivity) { Intent intent = new Intent(activity, tarActivity); startActivity(intent); } protected void showToast(String msg) { ToastUtils.showToast(activity, msg, Toast.LENGTH_SHORT); } protected void showLog(String msg) { Log.i(TAG, msg); } protected void showProgressDialog() { activity.showProgressDialog(); } protected void dismissProgressDialog() { activity.dismissProgressDialog(); } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/constants/CommonConstants.java ================================================ package com.boredream.designrescollection.constants; /** * 通用常量 */ public class CommonConstants { private CommonConstants() { } /** * SharedPreferences 名称 */ public static final String SP_NAME = "config"; /** * 每页加载的数量 */ public static final int COUNT_OF_PAGE = 20; } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/entity/Comment.java ================================================ package com.boredream.designrescollection.entity; import com.boredream.designrescollection.base.BaseEntity; public class Comment extends BaseEntity { /** * 所属资源 */ private DesignRes designRes; /** * 发送用户, Pointer or User */ private User user; /** * 评论内容 */ private String content; public DesignRes getDesignRes() { return designRes; } public void setDesignRes(DesignRes designRes) { this.designRes = designRes; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/entity/DesignRes.java ================================================ package com.boredream.designrescollection.entity; import com.boredream.designrescollection.base.BaseEntity; /** * 设计资源 */ public class DesignRes extends BaseEntity { private String desc; private String srcTag; private String name; private String imgUrl; private String srcLink; public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public String getSrcTag() { return srcTag; } public void setSrcTag(String srcTag) { this.srcTag = srcTag; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getImgUrl() { return imgUrl; } public void setImgUrl(String imgUrl) { this.imgUrl = imgUrl; } public String getSrcLink() { return srcLink; } public void setSrcLink(String srcLink) { this.srcLink = srcLink; } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/entity/FeedBack.java ================================================ package com.boredream.designrescollection.entity; import com.boredream.designrescollection.base.BaseEntity; public class FeedBack extends BaseEntity { private String content; private String email; public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/entity/User.java ================================================ package com.boredream.designrescollection.entity; import com.boredream.designrescollection.base.BaseEntity; public class User extends BaseEntity { private String sessionToken; private String nickname; private String username; /** * 验证手机号 */ private String mobilePhoneNumber; /** * 密码 */ private String password; /** * 手机号验证码,发送短信验证时请求使用 */ private String smsCode; /** * 头像图片地址 */ private String avatar; private String company; public String getSessionToken() { return sessionToken; } public void setSessionToken(String sessionToken) { this.sessionToken = sessionToken; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } public String getAvatar() { return avatar; } public void setAvatar(String avatar) { this.avatar = avatar; } public String getSmsCode() { return smsCode; } public void setSmsCode(String smsCode) { this.smsCode = smsCode; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getMobilePhoneNumber() { return mobilePhoneNumber; } public void setMobilePhoneNumber(String mobilePhoneNumber) { this.mobilePhoneNumber = mobilePhoneNumber; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/fragment/HomeFragment.java ================================================ package com.boredream.designrescollection.fragment; import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.boredream.bdcodehelper.adapter.LoadMoreAdapter; import com.boredream.bdcodehelper.entity.ListResponse; import com.boredream.bdcodehelper.net.ObservableDecorator; import com.boredream.bdcodehelper.utils.DisplayUtils; import com.boredream.bdcodehelper.utils.TitleBuilder; import com.boredream.bdcodehelper.view.GridSpacingDecorator; import com.boredream.designrescollection.R; import com.boredream.designrescollection.adapter.DesignResAdapter; import com.boredream.designrescollection.base.BaseFragment; import com.boredream.designrescollection.constants.CommonConstants; import com.boredream.designrescollection.entity.DesignRes; import com.boredream.designrescollection.net.HttpRequest; import com.boredream.designrescollection.net.SimpleSubscriber; import java.util.ArrayList; import rx.Observable; public class HomeFragment extends BaseFragment { private View view; private SwipeRefreshLayout srl; private RecyclerView rv; private int curPage = 1; private ArrayList datas = new ArrayList<>(); private LoadMoreAdapter adapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = View.inflate(activity, R.layout.frag_home, null); initView(); initData(); return view; } private void initView() { new TitleBuilder(view).setTitleText(getString(R.string.tab1)); srl = (SwipeRefreshLayout) view.findViewById(R.id.srl); srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { loadData(1); } }); rv = (RecyclerView) view.findViewById(R.id.rv); rv.addItemDecoration(new GridSpacingDecorator(DisplayUtils.dp2px(activity, 8))); GridLayoutManager gridLayoutManager = new GridLayoutManager(activity, 2); rv.setLayoutManager(gridLayoutManager); adapter = new LoadMoreAdapter(rv, new DesignResAdapter(activity, datas), new LoadMoreAdapter.OnLoadMoreListener() { @Override public void onLoadMore() { loadData(curPage + 1); } }); rv.setAdapter(adapter); } private void initData() { showProgressDialog(); loadData(1); } private void loadData(final int page) { Observable> observable = HttpRequest.getDesignRes(page); ObservableDecorator.decorate(observable).subscribe( new SimpleSubscriber>(activity) { @Override public void onNext(ListResponse response) { curPage = page; srl.setRefreshing(false); dismissProgressDialog(); if (page == 1) { datas.clear(); } setResponse(response); } @Override public void onError(Throwable throwable) { super.onError(throwable); srl.setRefreshing(false); dismissProgressDialog(); } }); } private void setResponse(ListResponse response) { datas.addAll(response.getResults()); // 设置是否已加载完全部数据状态 adapter.setStatus(response.getResults().size() == CommonConstants.COUNT_OF_PAGE ? LoadMoreAdapter.STATUS_HAVE_MORE : LoadMoreAdapter.STATUS_LOADED_ALL); adapter.notifyDataSetChanged(); } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/fragment/UserFragment.java ================================================ package com.boredream.designrescollection.fragment; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import com.boredream.bdcodehelper.entity.SettingItem; import com.boredream.bdcodehelper.utils.DisplayUtils; import com.boredream.bdcodehelper.utils.TitleBuilder; import com.boredream.bdcodehelper.view.DividerItemDecoration; import com.boredream.bdcodehelper.view.EmptyItemDecoration; import com.boredream.designrescollection.R; import com.boredream.designrescollection.activity.AboutActivity; import com.boredream.designrescollection.activity.SettingActivity; import com.boredream.designrescollection.activity.UserInfoEditActivity; import com.boredream.designrescollection.adapter.MoreRecyclerAdapter; import com.boredream.designrescollection.base.BaseFragment; import com.boredream.designrescollection.utils.UserInfoKeeper; import java.util.ArrayList; import java.util.List; public class UserFragment extends BaseFragment implements AdapterView.OnItemClickListener { private RecyclerView rv_user; private MoreRecyclerAdapter adapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = View.inflate(activity, R.layout.frag_user, null); initView(view); initData(); return view; } @Override public void onStart() { super.onStart(); // 如果未登录进入本页面,然后跳转登录页面成功后返回,此时应该再次更新用户信息 adapter.setUser(UserInfoKeeper.getCurrentUser()); adapter.notifyDataSetChanged(); } private void initView(View view) { new TitleBuilder(view).setTitleText("更多"); rv_user = (RecyclerView) view.findViewById(R.id.rv_user); } private void initData() { // more items List items = new ArrayList<>(); items.add(new SettingItem( R.mipmap.ic_info_grey600_24dp, "关于", null, R.mipmap.ic_chevron_right_grey600_24dp )); items.add(new SettingItem( R.mipmap.ic_settings_grey600_24dp, "设置", null, R.mipmap.ic_chevron_right_grey600_24dp )); adapter = new MoreRecyclerAdapter(items, this); rv_user.setAdapter(adapter); LinearLayoutManager linearLayoutManager = new LinearLayoutManager( activity, LinearLayoutManager.VERTICAL, false); rv_user.setLayoutManager(linearLayoutManager); // 每个item之间的分割线 rv_user.addItemDecoration(new DividerItemDecoration(activity)); // 每组item之间的分割间隔 rv_user.addItemDecoration(new EmptyItemDecoration( new Integer[]{0, 1}, DisplayUtils.dp2px(activity, 16))); } @Override public void onItemClick(AdapterView parent, View view, int position, long id) { switch (position) { case -1: // 给特殊的用户信息header位置设为了position=-1的item click事件 intent2Activity(UserInfoEditActivity.class); break; case 0: intent2Activity(AboutActivity.class); break; case 1: intent2Activity(SettingActivity.class); break; } } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/net/GlideHelper.java ================================================ package com.boredream.designrescollection.net; import android.content.Context; import android.widget.ImageView; import com.boredream.bdcodehelper.net.GlideCircleTransform; import com.boredream.designrescollection.R; import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; /** * Glide */ public class GlideHelper { public static void showAvatar(Context context, String avatar, ImageView iv) { Glide.with(context) .load(avatar) .diskCacheStrategy(DiskCacheStrategy.ALL) .placeholder(R.mipmap.ic_account_circle_grey600_24dp) .error(R.mipmap.ic_account_circle_grey600_24dp) .transform(new GlideCircleTransform(context)) .crossFade() .into(iv); } public static void showImage(Context context, String imageUrl, ImageView iv) { Glide.with(context) .load(imageUrl) .asBitmap() .animate(android.R.anim.fade_in) .diskCacheStrategy(DiskCacheStrategy.ALL) .into(iv); } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/net/HttpRequest.java ================================================ package com.boredream.designrescollection.net; import android.content.Context; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; import android.text.TextUtils; import com.boredream.bdcodehelper.entity.AppUpdateInfo; import com.boredream.bdcodehelper.entity.FileUploadResponse; import com.boredream.bdcodehelper.entity.ListResponse; import com.boredream.bdcodehelper.net.ObservableDecorator; import com.boredream.designrescollection.base.BaseEntity; import com.boredream.designrescollection.constants.CommonConstants; import com.boredream.designrescollection.entity.DesignRes; import com.boredream.designrescollection.entity.FeedBack; import com.boredream.designrescollection.entity.User; import com.boredream.designrescollection.utils.UserInfoKeeper; import com.bumptech.glide.Glide; import com.bumptech.glide.request.animation.GlideAnimation; import com.bumptech.glide.request.target.SimpleTarget; import com.squareup.okhttp.Interceptor; import com.squareup.okhttp.MediaType; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.RequestBody; import com.squareup.okhttp.Response; import com.squareup.okhttp.logging.HttpLoggingInterceptor; import java.io.IOException; import java.util.Map; import retrofit.GsonConverterFactory; import retrofit.Retrofit; import retrofit.RxJavaCallAdapterFactory; import retrofit.http.Body; import retrofit.http.GET; import retrofit.http.POST; import retrofit.http.PUT; import retrofit.http.Path; import retrofit.http.Query; import rx.Observable; import rx.Subscriber; import rx.functions.Action1; public class HttpRequest { // LeanCloud public static final String HOST = "https://api.leancloud.cn"; public static final String FILE_HOST = ""; private static final String APP_ID_NAME = "X-LC-Id"; private static final String API_KEY_NAME = "X-LC-Key"; public static final String SESSION_TOKEN_KEY = "X-LC-Session"; private static final String APP_ID_VALUE = "iaEH7ObIA4sPY8RSs3VCVXBg-gzGzoHsz"; private static final String API_KEY_VALUE = "dXfhXIVyeWMN2czJkd4ehwzs"; private static Retrofit retrofit; private static OkHttpClient httpClient; public static OkHttpClient getHttpClient() { return httpClient; } static { // OkHttpClient httpClient = new OkHttpClient(); // 统一添加的Header httpClient.networkInterceptors().add(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request().newBuilder() .addHeader("Content-Type", "application/json") .addHeader(APP_ID_NAME, APP_ID_VALUE) .addHeader(API_KEY_NAME, API_KEY_VALUE) .addHeader(SESSION_TOKEN_KEY, UserInfoKeeper.getToken()) .build(); return chain.proceed(request); } }); // log HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); httpClient.interceptors().add(interceptor); // Retrofit retrofit = new Retrofit.Builder() .baseUrl(HOST) .addConverterFactory(GsonConverterFactory.create()) // gson .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // rxjava .client(httpClient) .callbackExecutor(AsyncTask.THREAD_POOL_EXECUTOR) .build(); } public interface AppService { ////////////////////////////// 通用接口 ////////////////////////////// // 登录用户 @GET("/1/login") Observable login( @Query("username") String username, @Query("password") String password); // 注册用户 @POST("/1/users") Observable register( @Body User user); // 修改用户详情(注意, 提交什么参数修改什么参数) @PUT("/1/users/{objectId}") Observable updateUserById( @Path("objectId") String userId, @Body Map updateInfo); // 上传图片接口 @POST("/1/files/{fileName}") Observable fileUpload( @Path("fileName") String fileName, @Body RequestBody image); // 查询app更新信息 @GET("/1/classes/AppUpdateInfo") Observable> getAppUpdateInfo(); // 提交意见反馈 @POST("/1/classes/FeedBack") Observable addFeedBack( @Body FeedBack feedBack); ////////////////////////////// 业务接口 ////////////////////////////// // 查询设计资源 @GET("/1/classes/DesignRes") Observable> getDesignRes( @Query("limit") int perPageCount, @Query("skip") int page, @Query("where") String where, @Query("include") String include); } public static AppService getApiService() { return retrofit.create(AppService.class); } ////////////////////////////// 业务接口方法 ////////////////////////////// /** * 查询设计资源 */ public static Observable> getDesignRes(int page) { AppService service = getApiService(); String where = "{}"; return service.getDesignRes(CommonConstants.COUNT_OF_PAGE, (page - 1) * CommonConstants.COUNT_OF_PAGE, where, null); } /** * 查询设计资源 * * @param page * @param name 搜索名称 */ public static Observable> getDesignRes(int page, String name) { AppService service = getApiService(); String whereName = "{}"; if (!TextUtils.isEmpty(name)) { whereName = "{\"name\":{\"$regex\":\".*" + name + ".*\"}}"; } String where = whereName; return service.getDesignRes(CommonConstants.COUNT_OF_PAGE, (page - 1) * CommonConstants.COUNT_OF_PAGE, where, null); } ////////////////////////////// 通用接口方法 ////////////////////////////// /** * 登录用户 * * @param username 用户名 * @param password 密码 */ public static Observable login(String username, String password) { AppService service = getApiService(); return service.login(username, password) .doOnNext(new Action1() { @Override public void call(User user) { // 保存登录用户数据以及token信息 UserInfoKeeper.setCurrentUser(user); } }); } /** * 上传图片 * * @param call 上传成功回调 * @param context * @param uri 图片uri * @param reqW 上传图片需要压缩的宽度 * @param reqH 上传图片需要压缩的高度 * @param call */ public static void fileUpload(final Context context, Uri uri, int reqW, int reqH, final Subscriber call) { final AppService service = getApiService(); final String filename = "avatar_" + System.currentTimeMillis() + ".jpg"; // 先从本地获取图片,利用Glide压缩图片后获取byte[] Glide.with(context).load(uri).asBitmap().toBytes().into( new SimpleTarget(reqW, reqH) { @Override public void onResourceReady(final byte[] resource, GlideAnimation glideAnimation) { // 上传图片 RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpeg"), resource); Observable observable = service.fileUpload(filename, requestBody); ObservableDecorator.decorate(observable) .subscribe(call); } @Override public void onLoadFailed(Exception e, Drawable errorDrawable) { super.onLoadFailed(e, errorDrawable); call.onError(new Throwable("图片解析失败")); } }); } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/net/SimpleSubscriber.java ================================================ package com.boredream.designrescollection.net; import android.content.Context; import com.boredream.bdcodehelper.utils.ErrorInfoUtils; import com.boredream.bdcodehelper.utils.ToastUtils; import rx.Subscriber; /** * 通用订阅者,用于统一处理回调 */ public class SimpleSubscriber extends Subscriber { private Context context; public SimpleSubscriber(Context context) { this.context = context; } @Override public void onCompleted() { // sub } @Override public void onError(Throwable throwable) { // 统一处理错误回调,显示Toast String errorInfo = ErrorInfoUtils.parseHttpErrorInfo(throwable); ToastUtils.showToast(context, errorInfo); } @Override public void onNext(T t) { // sub } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/utils/UpdateUtils.java ================================================ package com.boredream.designrescollection.utils; import android.app.Activity; import android.app.DownloadManager; import android.content.Context; import android.content.DialogInterface; import android.database.Cursor; import android.net.Uri; import android.os.Environment; import android.support.annotation.NonNull; import android.support.v7.app.AlertDialog; import com.boredream.bdcodehelper.entity.AppUpdateInfo; import com.boredream.bdcodehelper.entity.ListResponse; import com.boredream.bdcodehelper.net.ObservableDecorator; import com.boredream.bdcodehelper.utils.AppUtils; import com.boredream.bdcodehelper.utils.DialogUtils; import com.boredream.bdcodehelper.utils.NetUtils; import com.boredream.bdcodehelper.utils.ToastUtils; import com.boredream.designrescollection.R; import com.boredream.designrescollection.base.BaseActivity; import com.boredream.designrescollection.net.HttpRequest; import com.boredream.designrescollection.net.SimpleSubscriber; import java.util.ArrayList; import java.util.Locale; import rx.Observable; /** * 检查更新工具类 */ public class UpdateUtils { public static final int DOWNLOAD_STATUS_NEED_LOAD = 1; public static final int DOWNLOAD_STATUS_RUNNING = 2; public static final int DOWNLOAD_STATUS_LOADED = 3; /** * 检测版本更新 * * @param context * @param isForceCheck 是否强制检测更新 * true强制 - 无论什么网络环境都会提示更新 * false非强制 - WiFi情况下才提示更新 */ public static void checkUpdate(final BaseActivity context, final boolean isForceCheck) { if (!NetUtils.isConnected(context)) { // 无网络时 if (isForceCheck) { // 手动强制检测更新时,提示文字 ToastUtils.showToast(context, "请检查网络连接"); } else { // 非强制不做操作 } return; } // 开始检测更新 if (isForceCheck) { // 强制更新时,才提示进度框 context.showProgressDialog(); } Observable> observable = HttpRequest.getApiService().getAppUpdateInfo(); ObservableDecorator.decorate(observable).subscribe( new SimpleSubscriber>(context) { @Override public void onError(Throwable throwable) { if (isForceCheck) { // 强制更新时,才提示错误 super.onError(throwable); } context.dismissProgressDialog(); } @Override public void onNext(ListResponse response) { context.dismissProgressDialog(); ArrayList results = response.getResults(); if (results.size() == 0) { if (isForceCheck) { ToastUtils.showToast(context, "当前已经是最新版本"); } } AppUpdateInfo newestUpdateInfo = results.get(0); for (AppUpdateInfo updateInfo : results) { if (updateInfo.getVersion() > newestUpdateInfo.getVersion()) { // 取最大版本号的作为最新版本 newestUpdateInfo = updateInfo; } } if (newestUpdateInfo.getVersion() <= AppUtils.getAppVersionCode(context)) { if (isForceCheck) { ToastUtils.showToast(context, "当前已经是最新版本"); } } else { showUpdateConfirmDialog(context, newestUpdateInfo); } } } ); } /** * 无Wifi状态确认更新对话框 */ private static void showNoWifiConfirmDialog(final BaseActivity context, final AppUpdateInfo updateInfo) { DialogUtils.showCommonDialog(context, "没有wifi连接,是否继续选择更新?", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { startDownload(context, updateInfo); } }); } /** * 显示更新对话框,包含版本相关信息 */ private static void showUpdateConfirmDialog(final BaseActivity context, final AppUpdateInfo updateInfo) { String content = String.format(Locale.CHINESE, context.getResources().getString(R.string.update_info), updateInfo.getVersionName(), updateInfo.getUpdateInfo() == null ? "无" : updateInfo.getUpdateInfo()); new AlertDialog.Builder(context) .setTitle("发现新版本") .setMessage(content) .setPositiveButton("立即更新", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (NetUtils.isWifi(context)) { startDownload(context, updateInfo); } else { showNoWifiConfirmDialog(context, updateInfo); } } }) .setNegativeButton("以后再说", null) .show(); } /** * 开始下载 * * @param context * @param updateInfo */ private static void startDownload(BaseActivity context, AppUpdateInfo updateInfo) { int status = getDownloadStatus(context, updateInfo); if (status != DOWNLOAD_STATUS_NEED_LOAD) { // 不用下载则无需下列操作 return; } ToastUtils.showToast(context, "开始下载安装包..."); // parse url Uri mUri = Uri.parse(updateInfo.getFileUrl()); // create request DownloadManager.Request r = new DownloadManager.Request(mUri); // set request property String apkName = getDownloadApkName(context, updateInfo); r.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkName); r.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // create manager DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); // key code, set mine type r.setMimeType("application/vnd.android.package-archive"); // add to queue dm.enqueue(r); } @NonNull private static String getDownloadApkName(BaseActivity context, AppUpdateInfo updateInfo) { return context.getString(R.string.app_name) + "_" + updateInfo.getVersionName() + ".apk"; } /** * 判断当前版本文件下载状态 * * @param context * @param updateInfo * @return */ private static int getDownloadStatus(BaseActivity context, AppUpdateInfo updateInfo) { DownloadManager.Query query = new DownloadManager.Query(); DownloadManager dm = (DownloadManager) context.getSystemService(Activity.DOWNLOAD_SERVICE); Cursor c = dm.query(query); if (!c.moveToFirst()) { // 无下载内容 return DOWNLOAD_STATUS_NEED_LOAD; } do { int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)); String title = c.getString(c.getColumnIndex(DownloadManager.COLUMN_TITLE)); String apkName = getDownloadApkName(context, updateInfo); if (title.equals(apkName)) { // 如果下载列表中文件是当前版本应用,则继续判断下载状态 if (status == DownloadManager.STATUS_SUCCESSFUL) { // 如果已经下载,返回状态,同时直接提示安装 String uri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); AppUtils.promptInstall(context, Uri.parse(uri)); return DOWNLOAD_STATUS_LOADED; } else if (status == DownloadManager.STATUS_RUNNING || status == DownloadManager.STATUS_PAUSED || status == DownloadManager.STATUS_PENDING) { return DOWNLOAD_STATUS_RUNNING; } else { // 失败也视为可以再次下载 return DOWNLOAD_STATUS_NEED_LOAD; } } } while (c.moveToNext()); return DOWNLOAD_STATUS_NEED_LOAD; } /** * 根据下载队列id获取下载Uri * * @param enqueueId * @return null-获取不到 */ public static Uri getDownloadUriById(Context context, long enqueueId) { DownloadManager.Query query = new DownloadManager.Query(); query.setFilterById(enqueueId); DownloadManager dm = (DownloadManager) context.getSystemService(Activity.DOWNLOAD_SERVICE); Cursor c = dm.query(query); if (c.moveToFirst()) { int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS); if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) { String uri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); return Uri.parse(uri); } } return null; } } ================================================ FILE: DesignResCollection_MVC/app/src/main/java/com/boredream/designrescollection/utils/UserInfoKeeper.java ================================================ package com.boredream.designrescollection.utils; import android.content.Context; import android.content.Intent; import com.boredream.designrescollection.activity.LoginActivity; import com.boredream.designrescollection.entity.User; /** * 用户信息保存工具 */ public class UserInfoKeeper { private static User currentUser; /** * 获取当前登录用户 */ public static User getCurrentUser() { return currentUser; } /** * 保存设置当前登录用户 */ public static void setCurrentUser(User user) { currentUser = user; } /** * 清空当前登录用户 */ public static void clearCurrentUser() { currentUser = null; } public static String getToken() { // 统一Header配置时用的token,没有的话要用空字符串,不能为null String token = ""; if (currentUser != null && currentUser.getSessionToken() != null) { token = currentUser.getSessionToken(); } return token; } /** * 登出 */ public static void logout() { clearCurrentUser(); } /** * 检测登录状态 * * @return true-已登录 false-未登录,会自动跳转至登录页 */ public static boolean checkLogin(Context context) { if (currentUser == null) { Intent intent = new Intent(context, LoginActivity.class); intent.putExtra("checkLogin", true); context.startActivity(intent); return false; } return true; } } ================================================ FILE: DesignResCollection_MVC/app/src/main/res/anim/loading.xml ================================================ ================================================ FILE: DesignResCollection_MVC/app/src/main/res/color/txt_blue2gray_sel.xml ================================================ ================================================ FILE: DesignResCollection_MVC/app/src/main/res/drawable/ic_fav_grey2black_sel.xml ================================================ ================================================ FILE: DesignResCollection_MVC/app/src/main/res/drawable/ic_home_grey2black_sel.xml ================================================ ================================================ FILE: DesignResCollection_MVC/app/src/main/res/drawable/ic_more_grey2black_sel.xml ================================================ ================================================ FILE: DesignResCollection_MVC/app/src/main/res/drawable/ic_search_grey2black_sel.xml ================================================ ================================================ FILE: DesignResCollection_MVC/app/src/main/res/drawable/ic_settings_grey2black_sel.xml ================================================ ================================================ FILE: DesignResCollection_MVC/app/src/main/res/drawable/oval_progress.xml ================================================ ================================================ FILE: DesignResCollection_MVC/app/src/main/res/layout/activity_about.xml ================================================ ================================================ FILE: DesignResCollection_MVC/app/src/main/res/layout/activity_feed_back.xml ================================================ ================================================ FILE: DesignResCollection_MVC/app/src/main/res/layout/activity_input.xml ================================================ ================================================ FILE: DesignResCollection_MVC/app/src/main/res/layout/activity_login.xml ================================================