├── app ├── .gitignore ├── FreeCsdn.jks ├── libs │ ├── xutils.jar │ └── jsoup-1.8.2.jar ├── src │ ├── main │ │ ├── assets │ │ │ ├── about │ │ │ │ ├── contact.md │ │ │ │ └── about.md │ │ │ ├── shThemeDefault.scss │ │ │ ├── code.html │ │ │ ├── shBrushJScript.js │ │ │ ├── shBrushXml.js │ │ │ ├── shBrushJava.js │ │ │ └── shBrushPython.js │ │ ├── res │ │ │ ├── drawable-hdpi │ │ │ │ ├── csdn.png │ │ │ │ ├── mat2.jpg │ │ │ │ ├── blog_img.jpg │ │ │ │ ├── comment.png │ │ │ │ ├── ic_add.png │ │ │ │ ├── ic_menu.png │ │ │ │ ├── ic_yes.png │ │ │ │ ├── up_white.png │ │ │ │ ├── back_white.png │ │ │ │ ├── fb_msg_tip.png │ │ │ │ ├── ic_default.png │ │ │ │ ├── ic_delete.png │ │ │ │ ├── ic_drawer.png │ │ │ │ ├── ic_repost.png │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_original.png │ │ │ │ ├── ic_translate.png │ │ │ │ ├── base_empty_view.png │ │ │ │ ├── drawer_shadow.9.png │ │ │ │ ├── ic_user_default.png │ │ │ │ ├── base_send_normal.png │ │ │ │ ├── base_send_pressed.png │ │ │ │ ├── dialog_progressbar.png │ │ │ │ ├── base_loading_large_icon.png │ │ │ │ ├── biz_pics_ic_download_tp.png │ │ │ │ ├── fb_default_dev_portrait.png │ │ │ │ ├── list_activated_holo.9.png │ │ │ │ ├── logo_pro_logo_sina_dis.png │ │ │ │ ├── biz_pics_ic_back_pressed.png │ │ │ │ ├── fb_default_user_portrait.png │ │ │ │ ├── umeng_update_close_bg_tap.png │ │ │ │ ├── umeng_update_wifi_disable.png │ │ │ │ ├── base_action_bar_back_divider.png │ │ │ │ ├── base_list_divider_drawable.png │ │ │ │ ├── biz_news_detail_back_normal.png │ │ │ │ ├── umeng_update_close_bg_normal.png │ │ │ │ ├── biz_news_detaila_action_bar_bg.png │ │ │ │ ├── biz_topic_vote_submit_default.png │ │ │ │ ├── biz_news_detailpage_comment_normal.9.png │ │ │ │ ├── umeng_update_btn_check_off_holo_light.png │ │ │ │ ├── umeng_update_btn_check_on_holo_light.png │ │ │ │ ├── umeng_update_btn_check_off_focused_holo_light.png │ │ │ │ ├── umeng_update_btn_check_off_pressed_holo_light.png │ │ │ │ ├── umeng_update_btn_check_on_focused_holo_light.png │ │ │ │ └── umeng_update_btn_check_on_pressed_holo_light.png │ │ │ ├── drawable-xhdpi │ │ │ │ ├── back.png │ │ │ │ ├── find_01.png │ │ │ │ ├── find_02.png │ │ │ │ ├── find_03.png │ │ │ │ ├── find_04.png │ │ │ │ ├── find_05.png │ │ │ │ ├── me_01.png │ │ │ │ ├── me_02.png │ │ │ │ ├── me_03.png │ │ │ │ ├── me_04.png │ │ │ │ ├── me_05.png │ │ │ │ ├── me_06.png │ │ │ │ ├── me_more.png │ │ │ │ ├── me_share.png │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── logo_dropbox.png │ │ │ │ ├── logo_twitter.png │ │ │ │ ├── logo_yixin.png │ │ │ │ ├── me_comment.png │ │ │ │ ├── me_scan_code.png │ │ │ │ ├── fb_input_bg.9.png │ │ │ │ ├── find_red_point.png │ │ │ │ ├── ic_user_avater.jpg │ │ │ │ ├── logo_evernote.png │ │ │ │ ├── logo_pinterest.png │ │ │ │ ├── logo_vkontakte.png │ │ │ │ ├── fb_dev_reply_bg.9.png │ │ │ │ ├── find_user_point.png │ │ │ │ ├── logo_googleplus.png │ │ │ │ ├── logo_yixinmoments.png │ │ │ │ ├── fb_send_btn_pressed.png │ │ │ │ ├── fb_user_reply_bg.9.png │ │ │ │ ├── logo_sohumicroblog.png │ │ │ │ ├── material_go_normal.png │ │ │ │ ├── me_collect_checked.png │ │ │ │ ├── me_collect_uncheck.png │ │ │ │ ├── fb_send_btn_unpressed.png │ │ │ │ └── logo_neteasemicroblog.png │ │ │ ├── drawable-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── drawable-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── splashscreen.png │ │ │ │ ├── tab_find_checked.png │ │ │ │ ├── tab_find_uncheck.png │ │ │ │ ├── tab_me_checked.png │ │ │ │ ├── tab_me_uncheck.png │ │ │ │ ├── tab_blogger_checked.png │ │ │ │ ├── tab_blogger_uncheck.png │ │ │ │ ├── tab_channel_checked.png │ │ │ │ └── tab_channel_uncheck.png │ │ │ ├── drawable-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── drawable │ │ │ │ ├── umeng_update_wifi_disable.png │ │ │ │ ├── animated_progressbar.xml │ │ │ │ ├── umeng_update_button_cancel_bg_tap.xml │ │ │ │ ├── umeng_update_button_ok_bg_tap.xml │ │ │ │ ├── umeng_update_dialog_bg.xml │ │ │ │ ├── umeng_update_button_ok_bg_focused.xml │ │ │ │ ├── umeng_update_button_cancel_bg_focused.xml │ │ │ │ ├── progressbar_large.xml │ │ │ │ ├── umeng_update_button_cancel_bg_normal.xml │ │ │ │ ├── umeng_update_button_ok_bg_normal.xml │ │ │ │ ├── selector_share_bg.xml │ │ │ │ ├── shap_rect_bg_gray.xml │ │ │ │ ├── selector_btn_header.xml │ │ │ │ ├── selector_tab_textcolor.xml │ │ │ │ ├── shap_rect_bg_blue.xml │ │ │ │ ├── shap_rect_bg_blue_deep.xml │ │ │ │ ├── shap_rect_bg_toast.xml │ │ │ │ ├── shap_rect_bg_white_no_stroke.xml │ │ │ │ ├── shap_rect_bg_transparent.xml │ │ │ │ ├── selector_btn_cancle.xml │ │ │ │ ├── selector_btn_confirm.xml │ │ │ │ ├── shadow_gradient.xml │ │ │ │ ├── umeng_common_gradient_red.xml │ │ │ │ ├── umeng_common_gradient_green.xml │ │ │ │ ├── umeng_common_gradient_orange.xml │ │ │ │ ├── umeng_fb_send_btn_bg.xml │ │ │ │ ├── back_btn.xml │ │ │ │ ├── selector_text_bg_white.xml │ │ │ │ ├── selector_drawer_bg_white.xml │ │ │ │ ├── comment_btn.xml │ │ │ │ ├── download_btn.xml │ │ │ │ ├── umeng_update_title_bg.xml │ │ │ │ ├── shap_rect_bg_white.xml │ │ │ │ ├── selector_find_me.xml │ │ │ │ ├── selector_btn_collect.xml │ │ │ │ ├── selector_tab_find.xml │ │ │ │ ├── umeng_update_button_close_bg_selector.xml │ │ │ │ ├── selector_tab_blogger.xml │ │ │ │ ├── selector_tab_channel.xml │ │ │ │ ├── umeng_update_button_ok_bg_selector.xml │ │ │ │ ├── umeng_update_button_cancel_bg_selector.xml │ │ │ │ └── umeng_update_button_check_selector.xml │ │ │ ├── anim │ │ │ │ ├── push_no.xml │ │ │ │ ├── push_left_in.xml │ │ │ │ └── push_right_out.xml │ │ │ ├── values-w820dp │ │ │ │ └── dimens.xml │ │ │ ├── values │ │ │ │ ├── umeng_fb_style.xml │ │ │ │ ├── attrs.xml │ │ │ │ ├── umeng_fb_dimens.xml │ │ │ │ ├── umeng_fb_color.xml │ │ │ │ ├── umeng_update_string.xml │ │ │ │ ├── umeng_common_strings.xml │ │ │ │ ├── dimens.xml │ │ │ │ └── colors.xml │ │ │ ├── values-v21 │ │ │ │ └── styles.xml │ │ │ ├── xml │ │ │ │ └── provider_paths.xml │ │ │ ├── menu │ │ │ │ └── main.xml │ │ │ ├── layout │ │ │ │ ├── activity_about.xml │ │ │ │ ├── activity_update_log.xml │ │ │ │ ├── loading_refresh_header.xml │ │ │ │ ├── empty_view_list.xml │ │ │ │ ├── popwindow_bloglist.xml │ │ │ │ ├── toast_bg.xml │ │ │ │ ├── activity_base_web.xml │ │ │ │ ├── listitem_blogtype.xml │ │ │ │ ├── dialog_loading.xml │ │ │ │ ├── listitem_column.xml │ │ │ │ ├── listitem_drawer.xml │ │ │ │ ├── common_base_refresh.xml │ │ │ │ ├── include_head_unback_layout.xml │ │ │ │ ├── dialog_blogger_operation.xml │ │ │ │ ├── activity_splash.xml │ │ │ │ ├── listitem_blogger.xml │ │ │ │ ├── include_head_layout.xml │ │ │ │ ├── dialog_blogger_add.xml │ │ │ │ └── listitem_comment.xml │ │ │ └── values-zh │ │ │ │ ├── umeng_update_string.xml │ │ │ │ └── umeng_common_strings.xml │ │ └── java │ │ │ └── com │ │ │ └── free │ │ │ └── blog │ │ │ ├── ui │ │ │ ├── search │ │ │ │ └── SearchActivity.java │ │ │ ├── base │ │ │ │ ├── vp │ │ │ │ │ ├── IBaseView.java │ │ │ │ │ ├── IBasePresenter.java │ │ │ │ │ ├── single │ │ │ │ │ │ ├── ISinglePresenter.java │ │ │ │ │ │ ├── ISingleView.java │ │ │ │ │ │ └── SinglePresenter.java │ │ │ │ │ ├── menu │ │ │ │ │ │ ├── IMenuRefreshView.java │ │ │ │ │ │ ├── IMenuRefreshPresenter.java │ │ │ │ │ │ └── MenuRefreshPresenter.java │ │ │ │ │ ├── refresh │ │ │ │ │ │ ├── IRefreshPresenter.java │ │ │ │ │ │ └── IRefreshView.java │ │ │ │ │ └── BasePresenter.java │ │ │ │ ├── activity │ │ │ │ │ ├── IBaseRefresh.java │ │ │ │ │ ├── BaseActivity.java │ │ │ │ │ ├── BaseSingleActivity.java │ │ │ │ │ └── BaseBlogListActivity.java │ │ │ │ ├── fragment │ │ │ │ │ ├── IBaseRefreshFragment.java │ │ │ │ │ └── BaseFragment.java │ │ │ │ └── adapter │ │ │ │ │ └── BaseViewAdapter.java │ │ │ ├── home │ │ │ │ ├── find │ │ │ │ │ ├── pk │ │ │ │ │ │ └── PkActivity.java │ │ │ │ │ ├── expert │ │ │ │ │ │ └── DailyActivity.java │ │ │ │ │ ├── hot │ │ │ │ │ │ ├── HotBlogActivity.java │ │ │ │ │ │ └── HotBlogPresenter.java │ │ │ │ │ ├── rank │ │ │ │ │ │ ├── RankContract.java │ │ │ │ │ │ ├── RankAdapter.java │ │ │ │ │ │ └── RankPresenter.java │ │ │ │ │ └── last │ │ │ │ │ │ ├── NewBlogContract.java │ │ │ │ │ │ ├── NewBlogPresenter.java │ │ │ │ │ │ └── NewBlogActivity.java │ │ │ │ ├── mine │ │ │ │ │ ├── BlogCollectActivity.java │ │ │ │ │ ├── BlogHistoryActivity.java │ │ │ │ │ ├── AboutActivity.java │ │ │ │ │ ├── ContactUsActivity.java │ │ │ │ │ ├── UpdateLogActivity.java │ │ │ │ │ ├── BlogCollectPresenter.java │ │ │ │ │ └── BlogHistoryPresenter.java │ │ │ │ ├── column │ │ │ │ │ ├── ColumnContract.java │ │ │ │ │ ├── ColumnAdapter.java │ │ │ │ │ └── detail │ │ │ │ │ │ ├── ColumnDetailActivity.java │ │ │ │ │ │ └── ColumnDetailPresenter.java │ │ │ │ └── blogger │ │ │ │ │ ├── BloggerContract.java │ │ │ │ │ └── BloggerAdapter.java │ │ │ ├── list │ │ │ │ ├── BlogListContract.java │ │ │ │ ├── BlogListAdapter.java │ │ │ │ └── BlogCategoryAdapter.java │ │ │ └── content │ │ │ │ ├── comment │ │ │ │ ├── CommentComparator.java │ │ │ │ └── CommentActivity.java │ │ │ │ └── BlogContentContract.java │ │ │ ├── model │ │ │ ├── local │ │ │ │ └── dao │ │ │ │ │ ├── BlogHistoryDao.java │ │ │ │ │ ├── BlogContentDao.java │ │ │ │ │ ├── BlogCommentDao.java │ │ │ │ │ ├── impl │ │ │ │ │ ├── BlogHistoryDaoImpl.java │ │ │ │ │ ├── BlogContentDaoImpl.java │ │ │ │ │ └── BlogCommentDaoImpl.java │ │ │ │ │ ├── BlogCollectDao.java │ │ │ │ │ ├── BlogItemDao.java │ │ │ │ │ ├── ChannelBloggerDao.java │ │ │ │ │ ├── BloggerDao.java │ │ │ │ │ └── DaoFactory.java │ │ │ ├── entity │ │ │ │ ├── BaseEntity.java │ │ │ │ ├── BlogRank.java │ │ │ │ ├── DrawerInfo.java │ │ │ │ ├── BlogHtml.java │ │ │ │ ├── RankItem.java │ │ │ │ ├── BlogCategory.java │ │ │ │ ├── BlogColumn.java │ │ │ │ └── Comment.java │ │ │ └── remote │ │ │ │ ├── RetrofitClient.java │ │ │ │ ├── IBlogApi.java │ │ │ │ ├── OkHttpFactory.java │ │ │ │ └── NetEngine.java │ │ │ └── library │ │ │ ├── rx │ │ │ ├── RxSubscriber.java │ │ │ ├── BlogSubscriber.java │ │ │ └── RxHelper.java │ │ │ ├── util │ │ │ ├── DateUtils.java │ │ │ ├── StringUtils.java │ │ │ ├── DisplayUtils.java │ │ │ ├── Md5Utils.java │ │ │ ├── KeyBoardUtils.java │ │ │ ├── ToastUtil.java │ │ │ └── LogUtils.java │ │ │ ├── view │ │ │ ├── refresh │ │ │ │ ├── PullRefreshHandler.java │ │ │ │ ├── PullRefreshLayout.java │ │ │ │ └── CustomRefreshHeader.java │ │ │ └── dialog │ │ │ │ ├── BaseDialog.java │ │ │ │ ├── LoadingDialog.java │ │ │ │ ├── BloggerAddDialog.java │ │ │ │ └── BloggerOperationDialog.java │ │ │ └── config │ │ │ ├── KeyConfig.java │ │ │ ├── NewBlogManager.java │ │ │ ├── ColumnManager.java │ │ │ ├── HotBlogManager.java │ │ │ ├── Config.java │ │ │ └── CacheManager.java │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── free │ │ │ └── blog │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── free │ │ └── blog │ │ └── ApplicationTest.java ├── Todo.md ├── google-services.json └── Release.md ├── settings.gradle ├── screenshots ├── 1.png ├── 2.png ├── 3.png ├── 4.png └── 5.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── .travis.yml └── README.md /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | *.iml 3 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /app/FreeCsdn.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/FreeCsdn.jks -------------------------------------------------------------------------------- /screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/screenshots/1.png -------------------------------------------------------------------------------- /screenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/screenshots/2.png -------------------------------------------------------------------------------- /screenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/screenshots/3.png -------------------------------------------------------------------------------- /screenshots/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/screenshots/4.png -------------------------------------------------------------------------------- /screenshots/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/screenshots/5.png -------------------------------------------------------------------------------- /app/libs/xutils.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/libs/xutils.jar -------------------------------------------------------------------------------- /app/libs/jsoup-1.8.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/libs/jsoup-1.8.2.jar -------------------------------------------------------------------------------- /app/src/main/assets/about/contact.md: -------------------------------------------------------------------------------- 1 | ###通信方式 2 | - 邮箱:[tangqi374@163.com](mailto:tangqi374@163.com) 3 | - QQ群:65644347 -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/csdn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/csdn.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/mat2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/mat2.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/blog_img.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/blog_img.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/comment.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/ic_add.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/ic_menu.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_yes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/ic_yes.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/up_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/up_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/find_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/find_01.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/find_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/find_02.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/find_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/find_03.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/find_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/find_04.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/find_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/find_05.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/me_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/me_01.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/me_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/me_02.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/me_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/me_03.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/me_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/me_04.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/me_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/me_05.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/me_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/me_06.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/me_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/me_more.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/back_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/back_white.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/fb_msg_tip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/fb_msg_tip.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/ic_default.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/ic_delete.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_drawer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/ic_drawer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_repost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/ic_repost.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/me_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/me_share.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/ic_original.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_translate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/ic_translate.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_dropbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/logo_dropbox.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/logo_twitter.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_yixin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/logo_yixin.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/me_comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/me_comment.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/me_scan_code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/me_scan_code.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/base_empty_view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/base_empty_view.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/drawer_shadow.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/drawer_shadow.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_user_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/ic_user_default.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/fb_input_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/fb_input_bg.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/find_red_point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/find_red_point.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_user_avater.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/ic_user_avater.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_evernote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/logo_evernote.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_pinterest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/logo_pinterest.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_vkontakte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/logo_vkontakte.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/splashscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xxhdpi/splashscreen.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/base_send_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/base_send_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/base_send_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/base_send_pressed.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/dialog_progressbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/dialog_progressbar.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/fb_dev_reply_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/fb_dev_reply_bg.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/find_user_point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/find_user_point.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_googleplus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/logo_googleplus.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_yixinmoments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/logo_yixinmoments.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_find_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xxhdpi/tab_find_checked.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_find_uncheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xxhdpi/tab_find_uncheck.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_me_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xxhdpi/tab_me_checked.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_me_uncheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xxhdpi/tab_me_uncheck.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | bin/ 3 | build/ 4 | .idea/ 5 | gen/ 6 | captures/ 7 | .gradle/ 8 | .project 9 | .classpath 10 | *.iml 11 | local.properties 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/fb_send_btn_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/fb_send_btn_pressed.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/fb_user_reply_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/fb_user_reply_bg.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_sohumicroblog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/logo_sohumicroblog.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/material_go_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/material_go_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/me_collect_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/me_collect_checked.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/me_collect_uncheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/me_collect_uncheck.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_wifi_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable/umeng_update_wifi_disable.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/base_loading_large_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/base_loading_large_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/biz_pics_ic_download_tp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/biz_pics_ic_download_tp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/fb_default_dev_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/fb_default_dev_portrait.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/list_activated_holo.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/list_activated_holo.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/logo_pro_logo_sina_dis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/logo_pro_logo_sina_dis.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/fb_send_btn_unpressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/fb_send_btn_unpressed.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_neteasemicroblog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xhdpi/logo_neteasemicroblog.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_blogger_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xxhdpi/tab_blogger_checked.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_blogger_uncheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xxhdpi/tab_blogger_uncheck.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_channel_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xxhdpi/tab_channel_checked.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/tab_channel_uncheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-xxhdpi/tab_channel_uncheck.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/biz_pics_ic_back_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/biz_pics_ic_back_pressed.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/fb_default_user_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/fb_default_user_portrait.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_close_bg_tap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/umeng_update_close_bg_tap.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_wifi_disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/umeng_update_wifi_disable.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/base_action_bar_back_divider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/base_action_bar_back_divider.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/base_list_divider_drawable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/base_list_divider_drawable.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/biz_news_detail_back_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/biz_news_detail_back_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_close_bg_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/umeng_update_close_bg_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/biz_news_detaila_action_bar_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/biz_news_detaila_action_bar_bg.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/biz_topic_vote_submit_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/biz_topic_vote_submit_default.png -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/search/SearchActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.search; 2 | 3 | /** 4 | * @author studiotang on 17/3/25 5 | */ 6 | public class SearchActivity { 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/biz_news_detailpage_comment_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/biz_news_detailpage_comment_normal.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_btn_check_off_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/umeng_update_btn_check_off_holo_light.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_btn_check_on_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/umeng_update_btn_check_on_holo_light.png -------------------------------------------------------------------------------- /app/Todo.md: -------------------------------------------------------------------------------- 1 | ## TODO 2 | - 更新最新博主列表 3 | 4 | ## Deprecated 5 | - 增加文章是否已读标识 6 | - 界面改版 7 | - 博客列表排序 8 | - 刷新和加载更多的冲突 9 | - 热更新 10 | - 权限判断 11 | - 增加收藏标签 12 | - 刷新动画 13 | - 网页加载动画 14 | - 增加搜索 15 | -------------------------------------------------------------------------------- /app/src/main/assets/shThemeDefault.scss: -------------------------------------------------------------------------------- 1 | // Default Syntax Highlighter theme. 2 | 3 | @import "_theme_template.scss"; 4 | 5 | .syntaxhighlighter { 6 | .keyword { font-weight: bold !important; } 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_btn_check_off_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/umeng_update_btn_check_off_focused_holo_light.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_btn_check_off_pressed_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/umeng_update_btn_check_off_pressed_holo_light.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_btn_check_on_focused_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/umeng_update_btn_check_on_focused_holo_light.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/umeng_update_btn_check_on_pressed_holo_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kylingo/CsdnBlog/HEAD/app/src/main/res/drawable-hdpi/umeng_update_btn_check_on_pressed_holo_light.png -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/local/dao/BlogHistoryDao.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.local.dao; 2 | 3 | /** 4 | * @author tangqi on 17-3-23. 5 | */ 6 | public interface BlogHistoryDao extends BlogCollectDao { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/res/anim/push_no.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/vp/IBaseView.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.vp; 2 | 3 | /** 4 | * @author tangqi on 17-3-20. 5 | */ 6 | public interface IBaseView { 7 | 8 | void setPresenter(T t); 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/animated_progressbar.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_cancel_bg_tap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_ok_bg_tap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_dialog_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_ok_bg_focused.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_cancel_bg_focused.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/find/pk/PkActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.find.pk; 2 | 3 | import com.free.blog.ui.base.activity.WebActivity; 4 | 5 | /** 6 | * @author studiotang on 17/3/25 7 | */ 8 | public class PkActivity extends WebActivity { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Nov 12 17:02:20 CST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progressbar_large.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_cancel_bg_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_ok_bg_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_share_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/activity/IBaseRefresh.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.activity; 2 | 3 | /** 4 | * @author tangqi on 17-3-20. 5 | */ 6 | public interface IBaseRefresh { 7 | 8 | void doRefresh(); 9 | 10 | void loadInitData(); 11 | 12 | void loadMoreData(); 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/vp/IBasePresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.vp; 2 | 3 | /** 4 | * @author tangqi on 17-3-20. 5 | */ 6 | public interface IBasePresenter { 7 | 8 | boolean isNetWorkAvailable(); 9 | 10 | void subscribe(); 11 | 12 | void unSubscribe(); 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/find/expert/DailyActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.find.expert; 2 | 3 | import com.free.blog.ui.home.column.detail.ColumnDetailActivity; 4 | 5 | /** 6 | * @author studiotang on 17/3/25 7 | */ 8 | public class DailyActivity extends ColumnDetailActivity { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shap_rect_bg_gray.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/vp/single/ISinglePresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.vp.single; 2 | 3 | import com.free.blog.ui.base.vp.IBasePresenter; 4 | 5 | /** 6 | * @author studiotang on 17/3/21 7 | */ 8 | public interface ISinglePresenter extends IBasePresenter { 9 | void loadData(); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_btn_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_tab_textcolor.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shap_rect_bg_blue.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shap_rect_bg_blue_deep.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shap_rect_bg_toast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shap_rect_bg_white_no_stroke.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/rx/RxSubscriber.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.rx; 2 | 3 | import rx.Subscriber; 4 | 5 | /** 6 | * @author studiotang on 17/3/19 7 | */ 8 | public abstract class RxSubscriber extends Subscriber { 9 | 10 | @Override 11 | public void onCompleted() { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shap_rect_bg_transparent.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_btn_cancle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/vp/menu/IMenuRefreshView.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.vp.menu; 2 | 3 | import com.free.blog.ui.base.vp.refresh.IRefreshView; 4 | 5 | /** 6 | * @author studiotang on 17/3/26 7 | */ 8 | public interface IMenuRefreshView extends IRefreshView { 9 | void updateTitle(String title); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_btn_confirm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shadow_gradient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_common_gradient_red.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_common_gradient_green.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_common_gradient_orange.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_fb_send_btn_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/vp/single/ISingleView.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.vp.single; 2 | 3 | import com.free.blog.ui.base.vp.IBaseView; 4 | 5 | /** 6 | * @author studiotang on 17/3/21 7 | */ 8 | public interface ISingleView extends IBaseView

{ 9 | void onUpdateUI(T t); 10 | 11 | void onUpdateFailure(int errNo); 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/rx/BlogSubscriber.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.rx; 2 | 3 | /** 4 | * @author studiotang on 17/3/21 5 | */ 6 | public class BlogSubscriber extends RxSubscriber { 7 | @Override 8 | public void onError(Throwable e) { 9 | 10 | } 11 | 12 | @Override 13 | public void onNext(T t) { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/fragment/IBaseRefreshFragment.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.fragment; 2 | 3 | import com.free.blog.ui.base.activity.IBaseRefresh; 4 | 5 | /** 6 | * @author tangqi on 17-3-23. 7 | */ 8 | public interface IBaseRefreshFragment extends IBaseRefresh { 9 | boolean enableRefresh(); 10 | 11 | boolean enableLoadMore(); 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/back_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/util/DateUtils.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.util; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Locale; 5 | 6 | public class DateUtils { 7 | 8 | public static String getDate() { 9 | SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日 HH:mm", 10 | Locale.CHINA); 11 | return sdf.format(new java.util.Date()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_text_bg_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_drawer_bg_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/comment_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/find/hot/HotBlogActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.find.hot; 2 | 3 | import com.free.blog.ui.home.find.last.NewBlogActivity; 4 | 5 | /** 6 | * @author studiotang on 17/3/25 7 | */ 8 | public class HotBlogActivity extends NewBlogActivity { 9 | 10 | @Override 11 | protected void beforeInitView() { 12 | new HotBlogPresenter(this); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/res/values/umeng_fb_style.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/test/java/com/free/blog/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.free.blog; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/download_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | > 2 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_title_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/xml/provider_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/vp/refresh/IRefreshPresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.vp.refresh; 2 | 3 | import com.free.blog.ui.base.vp.IBasePresenter; 4 | 5 | /** 6 | * @author tangqi on 17-3-20. 7 | */ 8 | public interface IRefreshPresenter extends IBasePresenter { 9 | 10 | void loadRefreshData(); 11 | 12 | void loadMoreData(); 13 | 14 | int getPageSize(); 15 | 16 | boolean hasMore(int size); 17 | } 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/free/blog/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.free.blog; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/shap_rect_bg_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 |

4 | 5 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/util/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.util; 2 | 3 | import android.text.TextUtils; 4 | 5 | /** 6 | * @author studiotang on 17/3/19 7 | */ 8 | public class StringUtils { 9 | 10 | public static String trimLastChar(String string) { 11 | if (!TextUtils.isEmpty(string)) { 12 | string = string.substring(0, string.length()); 13 | } 14 | 15 | return string; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/local/dao/BlogContentDao.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.local.dao; 2 | 3 | import com.free.blog.model.entity.BlogHtml; 4 | 5 | /** 6 | * 博客内容-数据库 7 | * 8 | * @author tangqi 9 | * @since 2015年8月7日下午11:47:16 10 | */ 11 | 12 | public interface BlogContentDao { 13 | 14 | /** 15 | * 保存博客内容 16 | */ 17 | void insert(BlogHtml blogHtml); 18 | 19 | /** 20 | * 获取博客内容 21 | */ 22 | BlogHtml query(String url); 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/adapter/BaseViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.adapter; 2 | 3 | import com.chad.library.adapter.base.BaseQuickAdapter; 4 | import com.chad.library.adapter.base.BaseViewHolder; 5 | 6 | 7 | /** 8 | * @author studiotang on 17/3/19 9 | */ 10 | public abstract class BaseViewAdapter extends BaseQuickAdapter { 11 | 12 | public BaseViewAdapter() { 13 | super(0); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/find/rank/RankContract.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.find.rank; 2 | 3 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 4 | import com.free.blog.ui.base.vp.refresh.IRefreshView; 5 | 6 | /** 7 | * @author studiotang on 17/3/25 8 | */ 9 | interface RankContract { 10 | interface View extends IRefreshView { 11 | 12 | } 13 | 14 | interface Presenter extends IRefreshPresenter { 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/vp/refresh/IRefreshView.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.vp.refresh; 2 | 3 | import com.free.blog.ui.base.vp.IBaseView; 4 | 5 | /** 6 | * @author tangqi on 17-3-20. 7 | */ 8 | public interface IRefreshView extends IBaseView

{ 9 | 10 | P getPresenter(); 11 | 12 | void onRefreshUI(T data); 13 | 14 | void onRefreshFailure(int errNo); 15 | 16 | void onMoreUI(T data); 17 | 18 | void onMoreFailure(int errNo); 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/res/values/umeng_fb_dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 48dp 3 | 14sp 4 | 12sp 5 | 0.8dp 6 | 12dp 7 | 20sp 8 | 13dp 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/find/last/NewBlogContract.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.find.last; 2 | 3 | import com.free.blog.ui.base.vp.menu.IMenuRefreshPresenter; 4 | import com.free.blog.ui.base.vp.menu.IMenuRefreshView; 5 | 6 | /** 7 | * @author studiotang on 17/3/26 8 | */ 9 | public class NewBlogContract { 10 | 11 | public interface View extends IMenuRefreshView { 12 | 13 | } 14 | 15 | public interface Presenter extends IMenuRefreshPresenter { 16 | 17 | } 18 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | language: android 3 | android: 4 | components: 5 | - tools 6 | - tools #Running this twice get's the latest build tools (https://github.com/codepath/android_guides/wiki/Setting-up-Travis-CI) 7 | - platform-tools 8 | - android-27 9 | - build-tools-27.0.3 10 | - extra 11 | 12 | jdk: oraclejdk8 13 | 14 | notifications: 15 | email: true 16 | 17 | sudo: required #The build runs out of memory and is killed if we use the container system 18 | 19 | script: 20 | - ./gradlew clean build 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_find_me.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/mine/BlogCollectActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.mine; 2 | 3 | import com.free.blog.ui.base.activity.BaseBlogListActivity; 4 | 5 | /** 6 | * @author studiotang on 17/3/22 7 | */ 8 | public class BlogCollectActivity extends BaseBlogListActivity { 9 | @Override 10 | protected String getActionBarTitle() { 11 | return "博客收藏"; 12 | } 13 | 14 | @Override 15 | protected void beforeInitView() { 16 | new BlogCollectPresenter(this); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/mine/BlogHistoryActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.mine; 2 | 3 | import com.free.blog.ui.base.activity.BaseBlogListActivity; 4 | 5 | /** 6 | * @author tangqi on 17-3-23. 7 | */ 8 | public class BlogHistoryActivity extends BaseBlogListActivity { 9 | 10 | @Override 11 | protected String getActionBarTitle() { 12 | return "博客历史"; 13 | } 14 | 15 | @Override 16 | protected void beforeInitView() { 17 | new BlogHistoryPresenter(this); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/vp/menu/IMenuRefreshPresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.vp.menu; 2 | 3 | import com.free.blog.model.entity.BlogCategory; 4 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author studiotang on 17/3/26 10 | */ 11 | public interface IMenuRefreshPresenter extends IRefreshPresenter { 12 | String getTitle(); 13 | 14 | List getCategoryList(); 15 | 16 | void setType(BlogCategory blogCategory); 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_btn_collect.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/view/refresh/PullRefreshHandler.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.view.refresh; 2 | 3 | import in.srain.cube.views.ptr.PtrDefaultHandler; 4 | import in.srain.cube.views.ptr.PtrFrameLayout; 5 | 6 | /** 7 | * @author kylingo on 18/2/27 8 | */ 9 | public abstract class PullRefreshHandler extends PtrDefaultHandler { 10 | 11 | protected abstract void onRefresh(); 12 | 13 | @Override 14 | public final void onRefreshBegin(PtrFrameLayout ptrFrameLayout) { 15 | onRefresh(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/local/dao/BlogCommentDao.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.local.dao; 2 | 3 | 4 | import com.free.blog.model.entity.Comment; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 博客评论数据库 10 | * 11 | * @author tangqi 12 | * @since 2015年8月7日下午11:58:31 13 | */ 14 | 15 | public interface BlogCommentDao { 16 | 17 | /** 18 | * 保存博客评论列表 19 | */ 20 | void insert(List list); 21 | 22 | /** 23 | * 获取博客评论列表 24 | */ 25 | List query(int page, int pageSize); 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/assets/code.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | code demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

13 |     {{code}}
14 |     
15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/local/dao/impl/BlogHistoryDaoImpl.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.local.dao.impl; 2 | 3 | import android.content.Context; 4 | 5 | import com.free.blog.model.local.dao.BlogHistoryDao; 6 | 7 | /** 8 | * @author tangqi on 17-3-23. 9 | */ 10 | public class BlogHistoryDaoImpl extends BlogCollectDaoImpl implements BlogHistoryDao { 11 | 12 | private static final String DB_NAME = "blog_history"; 13 | 14 | public BlogHistoryDaoImpl(Context context) { 15 | super(context, DB_NAME); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_tab_find.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_close_bg_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_tab_blogger.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_tab_channel.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/umeng_fb_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FF0FB0A8 4 | #FFD8D8D8 5 | #DCDCDC 6 | #8A000000 7 | #FFFFFF 8 | #F4F0745F 9 | #6633B5E5 10 | #F6F6F6 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/list/BlogListContract.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.list; 2 | 3 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 4 | import com.free.blog.ui.base.vp.refresh.IRefreshView; 5 | 6 | /** 7 | * @author tangqi on 17-3-20. 8 | */ 9 | class BlogListContract { 10 | 11 | interface View extends IRefreshView { 12 | 13 | } 14 | 15 | interface Presenter extends IRefreshPresenter { 16 | 17 | void setCategoryName(String category); 18 | 19 | void setCategoryLink(String categoryLink); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_ok_bg_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_cancel_bg_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/entity/BaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.entity; 2 | 3 | import com.lidroid.xutils.db.annotation.Column; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 实体类--基类 9 | * 10 | * @author tangqi 11 | * @since 2015年8月01日下午10:42:07 12 | */ 13 | public abstract class BaseEntity implements Serializable { 14 | 15 | private static final long serialVersionUID = 4995176180527325406L; 16 | 17 | @Column(column = "id") 18 | private int id; 19 | 20 | public int getId() { 21 | return id; 22 | } 23 | 24 | public void setId(int id) { 25 | this.id = id; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_about.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_update_log.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/activity/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.activity; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | 6 | /** 7 | * Activity-基类 8 | * @author tangqi 9 | * @since 2015年7月8日下午9:20:10 10 | */ 11 | 12 | public abstract class BaseActivity extends Activity { 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | } 18 | 19 | @Override 20 | protected void onPause() { 21 | super.onPause(); 22 | } 23 | 24 | @Override 25 | protected void onResume() { 26 | super.onResume(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/loading_refresh_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/content/comment/CommentComparator.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.content.comment; 2 | 3 | import com.free.blog.model.entity.Comment; 4 | 5 | import java.util.Comparator; 6 | 7 | /** 8 | * 评论列表-排序 9 | * 10 | * @author tangqi 11 | * @since 2015年8月4日下午4:09:58 12 | */ 13 | 14 | class CommentComparator implements Comparator { 15 | 16 | @Override 17 | public int compare(Comment arg0, Comment arg1) { 18 | if (arg0.getParentId().equals(arg1.getCommentId())) { 19 | return -1; 20 | } else if (arg0.getCommentId().equals(arg1.getParentId())) { 21 | return 1; 22 | } 23 | return 0; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/entity/BlogRank.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.entity; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author studiotang on 17/3/25 7 | */ 8 | public class BlogRank extends BaseEntity { 9 | 10 | private String name; 11 | 12 | private List data; 13 | 14 | public String getName() { 15 | return name; 16 | } 17 | 18 | public void setName(String name) { 19 | this.name = name; 20 | } 21 | 22 | public List getData() { 23 | return data; 24 | } 25 | 26 | public void setData(List data) { 27 | this.data = data; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/activity/BaseSingleActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.activity; 2 | 3 | import android.os.Bundle; 4 | 5 | /** 6 | * @author studiotang on 17/3/25 7 | */ 8 | public abstract class BaseSingleActivity extends BaseActivity { 9 | 10 | protected abstract int getContentView(); 11 | protected abstract void beforeInitView(); 12 | protected abstract void initView(); 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(getContentView()); 18 | 19 | beforeInitView(); 20 | initView(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/util/DisplayUtils.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.util; 2 | 3 | import android.content.Context; 4 | 5 | /** 6 | * 显示数据相关计算 7 | * @author Administrator 8 | * 9 | */ 10 | 11 | public class DisplayUtils { 12 | 13 | public static int dp2px(Context context, float dp) { 14 | final float scale = context.getResources().getDisplayMetrics().density; 15 | return (int) (dp * scale + 0.5f); 16 | } 17 | 18 | @SuppressWarnings("unused") 19 | public static int px2dp(Context context, float px) { 20 | final float scale = context.getResources().getDisplayMetrics().density; 21 | return (int) (px / scale + 0.5f); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/column/ColumnContract.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.column; 2 | 3 | import com.free.blog.model.entity.BlogCategory; 4 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 5 | import com.free.blog.ui.base.vp.refresh.IRefreshView; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author studiotang on 17/3/25 11 | */ 12 | class ColumnContract { 13 | 14 | interface View extends IRefreshView { 15 | void updateTitle(String title); 16 | } 17 | 18 | interface Presenter extends IRefreshPresenter { 19 | String getTitle(); 20 | 21 | List getCategoryList(); 22 | 23 | void setType(BlogCategory blogCategory); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/empty_view_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values-zh/umeng_update_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 未联网 4 | 发现新版本 5 | 最新版本: 6 | 更新内容 7 | 仅需要下载: 8 | 新版本大小: 9 | (提示:非WIFI环境) 10 | 立即更新 11 | 应用更新 12 | 以后再说 13 | 忽略该版 14 | 正在更新中.... 15 | 最新版本已下载,是否安装? 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/fragment/BaseFragment.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.fragment; 2 | 3 | import android.app.Fragment; 4 | import android.os.Bundle; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | /** 10 | * Fragment-基类 11 | * 12 | * @author tangqi 13 | * @since 2015年8月9日上午10:28:46 14 | */ 15 | 16 | public class BaseFragment extends Fragment { 17 | 18 | @Override 19 | public void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | } 22 | 23 | @Override 24 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 25 | return super.onCreateView(inflater, container, savedInstanceState); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/assets/about/about.md: -------------------------------------------------------------------------------- 1 | ###关于软件 2 | 这是一款可以随时查看CSDN博客的软件。
3 | 目前只支持Android分类的博客,内置了五十余名Android博客专家。
4 | 功能列表: 5 | 6 | - 查看博客专家列表【默认添加50名CSDN博客专家】 7 | - 自定义添加、删除博主,置顶博主 8 | - 查看博客列表,博客分类,以及博客详情,博客评论 9 | - 支持收藏博客 10 | - 支持离线阅读,包括博主、博客列表、博客详情,博客评论 11 | - 支持最新、最新的博客,技术点,以及博客专栏 12 | - 支持分享到本地软件,或者社交软件 13 | - 支持软件自动更新,升级 14 | - 无广告,无特殊权限,绿色安全环保 15 | - 软件最新版本1.0.7 16 | 17 | ###联系我们 18 | 19 | - 邮箱:[tangqi374@163.com](mailto:tangqi374@163.com) 20 | - QQ群:65644347 21 | 22 | ###免责声明 23 | 本应用所收集的部分公开资料来源于CSDN网站[http://www.csdn.net/](http://www.csdn.net/),转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现本应用有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。 24 | 25 | ###最后的话 26 | 本人上班比较忙,软件仍然会持续更新。
27 | 考虑后续功能点比较多,有任何需求或想法都可以通过以上方式联系我。
28 | 期待您的意见,或者加入! 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/popwindow_bloglist.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/toast_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 项目简介 2 | 这是一款可以随时查看CSDN博客的开源软件,欢迎Star或Fork。 3 | 默认支持Android分类的博客,内置了五十余名Android博客专家。 4 | 5 | 最新版本v2.1.5 6 | - [点我下载](http://www.pgyer.com/csdn) 7 | - [更新历史](./app/Release.md) 8 | 9 | ## 功能列表 10 | - 查看博客专家列表 11 | - 查看博客列表、分类、专栏、详情、评论 12 | - 支持自定义添加、删除、置顶博主 13 | - 支持博客收藏、历史、分享 14 | - 支持离线阅读 15 | - 支持最新、最热的博客 16 | - 支持软件自动更新,升级 17 | 18 | ## 免责声明 19 | 本应用所收集的部分公开资料来源于[CSDN网站](http://www.csdn.net/),转载的目的在于传递更多信息及用于网络分享, 20 | 并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现本应用有侵犯您的知识产权的作品, 21 | 请与我们取得联系,我们会及时修改或删除。 22 | 23 | ## 应用截图 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/local/dao/BlogCollectDao.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.local.dao; 2 | 3 | 4 | import com.free.blog.model.entity.BlogItem; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 博客收藏-数据库定义 10 | * 11 | * @author tangqi 12 | * @since 2015年8月7日下午11:19:46 13 | */ 14 | 15 | public interface BlogCollectDao { 16 | 17 | /** 18 | * 保存博客列表 19 | */ 20 | void insert(List list); 21 | 22 | /** 23 | * 保存博客 24 | */ 25 | void insert(BlogItem blogItem); 26 | 27 | /** 28 | * 删除博客 29 | */ 30 | void delete(BlogItem blogItem); 31 | 32 | /** 33 | * 查找博客 34 | */ 35 | BlogItem query(String link); 36 | 37 | /** 38 | * 查找博客列表 39 | */ 40 | List query(int page, int pageSize); 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/config/KeyConfig.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.config; 2 | 3 | /** 4 | * Extra字段定义 5 | * 6 | * @author Frank 7 | * @since 2015年9月18日下午5:31:46 8 | */ 9 | 10 | public class KeyConfig { 11 | /** 12 | * 首次登录 13 | */ 14 | final static String IS_FIRST_INIT = "isFirst"; 15 | 16 | /** 17 | * 博客类型 18 | */ 19 | public final static String BLOG_TYPE = "blog_type"; 20 | 21 | /** 22 | * 刷新时间 23 | */ 24 | public final static String UPDATE_TIME = "update_time"; 25 | 26 | /** 27 | * 专栏类型 28 | */ 29 | public final static String COLUMN_TYPE = "column_type"; 30 | 31 | public final static String HOT_BLOG_TYPE = "hot_blog_type"; 32 | 33 | public final static String NEW_BLOG_TYPE = "new_blog_type"; 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/util/Md5Utils.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.util; 2 | 3 | import java.security.MessageDigest; 4 | 5 | /** 6 | * 对外提供getMD5(String)方法 7 | * 8 | * @author randyjia 9 | * 10 | */ 11 | public class Md5Utils { 12 | 13 | public static String getMD5(String source) throws Exception { 14 | MessageDigest md5 = MessageDigest.getInstance("Md5Utils"); 15 | byte[] result; 16 | md5.reset(); 17 | md5.update(source.getBytes("UTF-8")); 18 | result = md5.digest(); 19 | 20 | StringBuilder buf = new StringBuilder(result.length * 2); 21 | for (byte aResult : result) { 22 | int intVal = aResult & 0xff; 23 | if (intVal < 0x10) { 24 | buf.append("0"); 25 | } 26 | buf.append(Integer.toHexString(intVal)); 27 | } 28 | 29 | return buf.toString(); 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_base_web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 17 | 18 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/find/hot/HotBlogPresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.find.hot; 2 | 3 | import com.free.blog.library.config.HotBlogManager; 4 | import com.free.blog.library.config.UrlManager; 5 | import com.free.blog.model.entity.BlogItem; 6 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 7 | import com.free.blog.ui.home.find.last.NewBlogContract; 8 | import com.free.blog.ui.home.find.last.NewBlogPresenter; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @author studiotang on 17/3/26 14 | */ 15 | public class HotBlogPresenter extends NewBlogPresenter { 16 | 17 | HotBlogPresenter(NewBlogContract.View, IRefreshPresenter> viewDelegate) { 18 | super(viewDelegate); 19 | } 20 | 21 | @Override 22 | protected UrlManager getUrlManager() { 23 | return new HotBlogManager(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/listitem_blogtype.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/entity/DrawerInfo.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.entity; 2 | 3 | /** 4 | * 主页侧滑-ListItem 5 | * 6 | * @author tangqi 7 | * @since 2015年8月13日下午11:46:39 8 | */ 9 | @SuppressWarnings("unused") 10 | public class DrawerInfo extends BaseEntity { 11 | 12 | private static final long serialVersionUID = -887156398580286575L; 13 | 14 | private String name; 15 | private int resId; 16 | private String reserve; 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void setName(String name) { 23 | this.name = name; 24 | } 25 | 26 | public int getResId() { 27 | return resId; 28 | } 29 | 30 | public void setResId(int resId) { 31 | this.resId = resId; 32 | } 33 | 34 | public String getReserve() { 35 | return reserve; 36 | } 37 | 38 | public void setReserve(String reserve) { 39 | this.reserve = reserve; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/content/BlogContentContract.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.content; 2 | 3 | import android.app.Activity; 4 | 5 | import com.free.blog.ui.base.vp.single.ISinglePresenter; 6 | import com.free.blog.ui.base.vp.single.ISingleView; 7 | 8 | /** 9 | * @author studiotang on 17/3/21 10 | */ 11 | interface BlogContentContract { 12 | interface View extends ISingleView { 13 | void onUpdateCollectUI(boolean isCollect); 14 | void onCollectSuccess(boolean isCollect); 15 | void onCollectFailure(boolean isCollect); 16 | } 17 | 18 | interface Presenter extends ISinglePresenter { 19 | 20 | void setUrl(String url); 21 | 22 | void comment(Activity activity, String blogId); 23 | 24 | void share(Activity activity, String title, String url); 25 | 26 | void queryCollect(); 27 | 28 | void saveHistory(); 29 | 30 | void collect(boolean isCollect); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/local/dao/BlogItemDao.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.local.dao; 2 | 3 | import com.free.blog.model.entity.BlogCategory; 4 | import com.free.blog.model.entity.BlogItem; 5 | 6 | import java.util.List; 7 | 8 | 9 | /** 10 | * 博客列表-数据库定义 11 | * 12 | * @author tangqi 13 | * @since 2015年8月7日下午11:19:46 14 | */ 15 | 16 | public interface BlogItemDao { 17 | 18 | /** 19 | * 保存博客列表 20 | */ 21 | void insert(String category, List blogItemList); 22 | 23 | /** 24 | * 查找博客列表 25 | */ 26 | List query(String category, int page, int pageSize); 27 | 28 | /** 29 | * 查询所有 30 | */ 31 | List queryAll(); 32 | 33 | /** 34 | * 插入博客分类 35 | */ 36 | void insertCategory(List blogCategoryList); 37 | 38 | /** 39 | * 查询博客分类 40 | */ 41 | List queryCategory(); 42 | 43 | /** 44 | * 删除所有 45 | */ 46 | void deleteAll(); 47 | } 48 | -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "866966575431", 4 | "project_id": "firebase-freecsdn" 5 | }, 6 | "client": [ 7 | { 8 | "client_info": { 9 | "mobilesdk_app_id": "1:866966575431:android:3ca59a7234d77282", 10 | "android_client_info": { 11 | "package_name": "com.free.blog" 12 | } 13 | }, 14 | "oauth_client": [], 15 | "api_key": [ 16 | { 17 | "current_key": "AIzaSyATmFCNKUdHyDUUeqL9wOfFUzewIvzzbRg" 18 | } 19 | ], 20 | "services": { 21 | "analytics_service": { 22 | "status": 2, 23 | "analytics_property": { 24 | "tracking_id": "UA-99039176-1" 25 | } 26 | }, 27 | "appinvite_service": { 28 | "status": 1, 29 | "other_platform_oauth_client": [] 30 | }, 31 | "ads_service": { 32 | "status": 1 33 | } 34 | } 35 | } 36 | ], 37 | "configuration_version": "1" 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/content/comment/CommentActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.content.comment; 2 | 3 | import com.free.blog.R; 4 | import com.free.blog.model.entity.Comment; 5 | import com.free.blog.ui.base.activity.BaseRefreshActivity; 6 | import com.free.blog.ui.base.adapter.BaseViewAdapter; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author tangqi on 17-3-22. 12 | */ 13 | public class CommentActivity extends BaseRefreshActivity> { 14 | 15 | public static final String EXTRA_BLOG_ID = "blog_id"; 16 | 17 | @Override 18 | protected String getActionBarTitle() { 19 | return getString(R.string.comment_list); 20 | } 21 | 22 | @Override 23 | protected void beforeInitView() { 24 | String blogId = getIntent().getExtras().getString(EXTRA_BLOG_ID); 25 | new CommentPresenter(this, blogId); 26 | } 27 | 28 | @Override 29 | protected BaseViewAdapter onCreateAdapter() { 30 | return new CommentAdapter(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/res/anim/push_left_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/anim/push_right_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/values/umeng_update_string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Please make sure you are connected to internet,update failed 5 | New version found 6 | Latest version: 7 | Update Content 8 | Update size: 9 | Target size: 10 | (Warning: Not WIFI Condition) 11 | Update now 12 | App updating 13 | Not now 14 | Ingore this 15 | Updating.... 16 | The lastest version has been downloaded, install now ? 17 | 2.6.0.1.20150312 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/blogger/BloggerContract.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.blogger; 2 | 3 | import com.free.blog.model.entity.Blogger; 4 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 5 | import com.free.blog.ui.base.vp.refresh.IRefreshView; 6 | 7 | /** 8 | * @author tangqi on 17-3-23. 9 | */ 10 | class BloggerContract { 11 | interface View extends IRefreshView { 12 | void addBloggerStart(); 13 | 14 | void addBloggerSuccess(Blogger blogger); 15 | 16 | void addBloggerRepeat(); 17 | 18 | void addBloggerFailure(); 19 | 20 | void deleteBloggerSuccess(); 21 | 22 | void deleteBloggerFailure(); 23 | 24 | void stickBloggerSuccess(Blogger blogger); 25 | 26 | void stickBloggerFailure(); 27 | } 28 | 29 | interface Presenter extends IRefreshPresenter { 30 | void addBlogger(String userId); 31 | 32 | void deleteBlogger(Blogger blogger); 33 | 34 | void stickBlogger(Blogger blogger); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/view/dialog/BaseDialog.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.view.dialog; 2 | 3 | import android.app.Dialog; 4 | import android.content.Context; 5 | 6 | /** 7 | * 8 | * @author tangqi 9 | * @since 2015年8月8日下午4:26:32 10 | */ 11 | 12 | public class BaseDialog extends Dialog { 13 | 14 | @SuppressWarnings("unused") 15 | public BaseDialog(Context context) { 16 | super(context); 17 | } 18 | 19 | public BaseDialog(Context context, int theme) { 20 | super(context, theme); 21 | } 22 | 23 | /** 24 | * 监听确定 25 | */ 26 | public interface OnConfirmListener { 27 | 28 | void onConfirm(String result); 29 | } 30 | 31 | /** 32 | * 监听取消 33 | */ 34 | public interface OnCancelListener { 35 | 36 | void onCancel(String result); 37 | } 38 | 39 | /** 40 | * 监听删除 41 | */ 42 | public interface OnDeleteListener { 43 | 44 | void onDelete(String result); 45 | } 46 | 47 | /** 48 | * 监听置顶 49 | */ 50 | public interface OnStickListener { 51 | 52 | void onStick(String result); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/find/rank/RankAdapter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.find.rank; 2 | 3 | import android.view.ViewGroup; 4 | import android.widget.ImageView; 5 | 6 | import com.chad.library.adapter.base.BaseViewHolder; 7 | import com.free.blog.R; 8 | import com.free.blog.library.util.ImageLoaderUtils; 9 | import com.free.blog.model.entity.RankItem; 10 | import com.free.blog.ui.base.adapter.BaseViewAdapter; 11 | 12 | /** 13 | * @author studiotang on 17/3/25 14 | */ 15 | class RankAdapter extends BaseViewAdapter { 16 | 17 | @Override 18 | protected BaseViewHolder onCreateDefViewHolder(ViewGroup parent, int viewType) { 19 | return new BaseViewHolder(getItemView(R.layout.listitem_column, null)); 20 | } 21 | 22 | @Override 23 | protected void convert(BaseViewHolder helper, RankItem item) { 24 | helper.setText(R.id.tvChannel, item.getName()); 25 | ImageView imageView = helper.getView(R.id.imvChannel); 26 | ImageLoaderUtils.displayRoundImage(item.getIcon(), imageView); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/local/dao/ChannelBloggerDao.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.local.dao; 2 | 3 | import com.free.blog.model.entity.Blogger; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 博主数据库 9 | * 10 | * @author tangqi 11 | * @since 2015年8月8日下午12:59:26 12 | */ 13 | 14 | public interface ChannelBloggerDao { 15 | 16 | /** 17 | * 插入博主 18 | */ 19 | void insert(Blogger blogger); 20 | 21 | /** 22 | * 插入博主列表 23 | */ 24 | void insert(List list); 25 | 26 | /** 27 | * 查询某个博主是否存在 28 | */ 29 | Blogger query(String userId); 30 | 31 | /** 32 | * 查询所有博主 33 | */ 34 | @SuppressWarnings("unused") 35 | List queryAll(); 36 | 37 | /** 38 | * 查询博主(分页) 39 | */ 40 | List query(int pageIndex, int pageSize); 41 | 42 | /** 43 | * 删除博主 44 | */ 45 | void delete(Blogger blogger); 46 | 47 | /** 48 | * 删除博主列表 49 | */ 50 | @SuppressWarnings("unused") 51 | void deleteAll(List list); 52 | 53 | /** 54 | * 删除所有博主 55 | */ 56 | @SuppressWarnings("unused") 57 | void deleteAll(); 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/column/ColumnAdapter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.column; 2 | 3 | import android.view.ViewGroup; 4 | import android.widget.ImageView; 5 | 6 | import com.chad.library.adapter.base.BaseViewHolder; 7 | import com.free.blog.R; 8 | import com.free.blog.library.util.ImageLoaderUtils; 9 | import com.free.blog.model.entity.BlogColumn; 10 | import com.free.blog.ui.base.adapter.BaseViewAdapter; 11 | 12 | /** 13 | * @author studiotang on 17/3/23 14 | */ 15 | class ColumnAdapter extends BaseViewAdapter { 16 | 17 | @Override 18 | protected BaseViewHolder onCreateDefViewHolder(ViewGroup parent, int viewType) { 19 | return new BaseViewHolder(getItemView(R.layout.listitem_column, null)); 20 | } 21 | 22 | @Override 23 | protected void convert(BaseViewHolder helper, BlogColumn item) { 24 | helper.setText(R.id.tvChannel, item.getName()); 25 | ImageView imageView = helper.getView(R.id.imvChannel); 26 | ImageLoaderUtils.displayRoundImage(item.getIcon(), imageView); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/local/dao/BloggerDao.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.local.dao; 2 | 3 | import com.free.blog.model.entity.Blogger; 4 | 5 | import java.util.List; 6 | 7 | 8 | /** 9 | * 博主数据库 10 | * 11 | * @author tangqi 12 | * @since 2015年8月8日下午12:59:26 13 | */ 14 | 15 | public interface BloggerDao { 16 | 17 | /** 18 | * 插入博主 19 | */ 20 | void insert(Blogger blogger); 21 | 22 | /** 23 | * 插入博主列表 24 | */ 25 | void insert(List list); 26 | 27 | /** 28 | * 查询某个博主是否存在 29 | */ 30 | Blogger query(String userId); 31 | 32 | /** 33 | * 查询所有博主 34 | */ 35 | List queryAll(); 36 | 37 | /** 38 | * 查询博主(分页) 39 | */ 40 | List query(int pageIndex, int pageSize); 41 | 42 | /** 43 | * 删除博主 44 | */ 45 | void delete(Blogger blogger); 46 | 47 | /** 48 | * 删除博主列表 49 | */ 50 | @SuppressWarnings("unused") 51 | void deleteAll(List list); 52 | 53 | /*** 54 | * 删除所有博主 55 | */ 56 | void deleteAll(); 57 | 58 | /** 59 | * 初始化博客数据库 60 | */ 61 | void init(String type); 62 | 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 17 | 18 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/view/dialog/LoadingDialog.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.view.dialog; 2 | 3 | import android.app.ProgressDialog; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.widget.TextView; 7 | 8 | import com.free.blog.R; 9 | 10 | /** 11 | * 加载对话框 12 | * 13 | * @author tangqi 14 | * @since 2015年8月8日下午5:16:41 15 | */ 16 | 17 | public class LoadingDialog extends ProgressDialog { 18 | 19 | private String mMessage; 20 | 21 | // private Context mContext; 22 | 23 | public LoadingDialog(Context context, String message) { 24 | // TODO Auto-generated constructor stub 25 | super(context, R.style.Theme_Light_LoadingDialog); 26 | 27 | // this.mContext = context; 28 | this.mMessage = message; 29 | } 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | 35 | setContentView(R.layout.dialog_loading); 36 | TextView messageView = (TextView) findViewById(R.id.tv_loading_dialog); 37 | messageView.setText(mMessage); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/res/values-zh/umeng_common_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 正在下载中. 4 | 下载出错啦,请检查网络后继续。 5 | 暂停 6 | 继续 7 | 取消 8 | 正在下载: 9 | 暂停: 10 | 正在下载应用 11 | 正在更新安装包 12 | 请连接网络后再尝试! 13 | 下载失败 14 | 下载完成,请点击安装 15 | 更新完成,请点击安装 16 | 新版本已经准备好,请点击安装 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/config/NewBlogManager.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.config; 2 | 3 | /** 4 | * @author studiotang on 17/3/26 5 | */ 6 | public class NewBlogManager extends UrlManager { 7 | 8 | @Override 9 | protected int getFirstIndex() { 10 | return 1; 11 | } 12 | 13 | @Override 14 | protected String getSpfKey() { 15 | return KeyConfig.NEW_BLOG_TYPE; 16 | } 17 | 18 | @Override 19 | protected String[] getUrls() { 20 | return mUrls; 21 | } 22 | 23 | private static String[] mUrls = { 24 | UrlFactory.NewBlogUrl.ANDROID, 25 | UrlFactory.NewBlogUrl.MOBILE, 26 | UrlFactory.NewBlogUrl.WEB, 27 | UrlFactory.NewBlogUrl.ENTERPRISE, 28 | UrlFactory.NewBlogUrl.CODE, 29 | UrlFactory.NewBlogUrl.WWW, 30 | UrlFactory.NewBlogUrl.DATABASE, 31 | UrlFactory.NewBlogUrl.SYSTEM, 32 | UrlFactory.NewBlogUrl.CLOUD, 33 | UrlFactory.NewBlogUrl.SOFTWARE, 34 | UrlFactory.NewBlogUrl.OTHER 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/config/ColumnManager.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.config; 2 | 3 | /** 4 | * @author studiotang on 17/3/25 5 | */ 6 | public class ColumnManager extends UrlManager { 7 | 8 | public ColumnManager() { 9 | super(); 10 | } 11 | 12 | @Override 13 | protected int getFirstIndex() { 14 | return 0; 15 | } 16 | 17 | @Override 18 | protected String getSpfKey() { 19 | return KeyConfig.COLUMN_TYPE; 20 | } 21 | 22 | @Override 23 | protected String[] getUrls() { 24 | return mUrls; 25 | } 26 | 27 | private static String[] mUrls = { 28 | UrlFactory.ColumnUrl.ANDROID, 29 | UrlFactory.ColumnUrl.MOBILE, 30 | UrlFactory.ColumnUrl.WEB, 31 | UrlFactory.ColumnUrl.ENTERPRISE, 32 | UrlFactory.ColumnUrl.CODE, 33 | UrlFactory.ColumnUrl.WWW, 34 | UrlFactory.ColumnUrl.DATABASE, 35 | UrlFactory.ColumnUrl.SYSTEM, 36 | UrlFactory.ColumnUrl.CLOUD, 37 | UrlFactory.ColumnUrl.SOFTWARE, 38 | UrlFactory.ColumnUrl.OTHER 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/res/layout/listitem_column.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 | 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/config/HotBlogManager.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.config; 2 | 3 | /** 4 | * @author studiotang on 17/3/26 5 | */ 6 | public class HotBlogManager extends UrlManager { 7 | 8 | public HotBlogManager() { 9 | super(); 10 | } 11 | 12 | @Override 13 | protected int getFirstIndex() { 14 | return 1; 15 | } 16 | 17 | @Override 18 | protected String getSpfKey() { 19 | return KeyConfig.HOT_BLOG_TYPE; 20 | } 21 | 22 | @Override 23 | protected String[] getUrls() { 24 | return mUrls; 25 | } 26 | 27 | private static String[] mUrls = { 28 | UrlFactory.HotBlogUrl.ANDROID, 29 | UrlFactory.HotBlogUrl.MOBILE, 30 | UrlFactory.HotBlogUrl.WEB, 31 | UrlFactory.HotBlogUrl.ENTERPRISE, 32 | UrlFactory.HotBlogUrl.CODE, 33 | UrlFactory.HotBlogUrl.WWW, 34 | UrlFactory.HotBlogUrl.DATABASE, 35 | UrlFactory.HotBlogUrl.SYSTEM, 36 | UrlFactory.HotBlogUrl.CLOUD, 37 | UrlFactory.HotBlogUrl.SOFTWARE, 38 | UrlFactory.HotBlogUrl.OTHER 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/rx/RxHelper.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.rx; 2 | 3 | import rx.Observable; 4 | import rx.android.schedulers.AndroidSchedulers; 5 | import rx.functions.Func1; 6 | import rx.schedulers.Schedulers; 7 | 8 | /** 9 | * @author studiotang on 17/3/19 10 | */ 11 | public class RxHelper { 12 | 13 | public static Observable.Transformer getErrAndIOSchedulerTransformer() { 14 | return new Observable.Transformer() { 15 | @Override 16 | public Observable call(Observable observable) { 17 | return observable.onErrorResumeNext(RxHelper.getErrReturnFunc()) 18 | .subscribeOn(Schedulers.io()) 19 | .unsubscribeOn(Schedulers.io()) 20 | .observeOn(AndroidSchedulers.mainThread()); 21 | } 22 | }; 23 | } 24 | 25 | private static Func1> getErrReturnFunc() { 26 | return new Func1>() { 27 | @Override 28 | public Observable call(Throwable throwable) { 29 | return Observable.error(throwable); 30 | } 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/view/refresh/PullRefreshLayout.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.view.refresh; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import in.srain.cube.views.ptr.PtrFrameLayout; 7 | 8 | /** 9 | * 下拉刷新控件-封装 10 | * 11 | * @author kylingo on 18/2/27 12 | */ 13 | public class PullRefreshLayout extends PtrFrameLayout { 14 | 15 | public PullRefreshLayout(Context context) { 16 | this(context, null); 17 | } 18 | 19 | public PullRefreshLayout(Context context, AttributeSet attrs) { 20 | this(context, attrs, 0); 21 | } 22 | 23 | public PullRefreshLayout(Context context, AttributeSet attrs, int defStyle) { 24 | super(context, attrs, defStyle); 25 | init(); 26 | } 27 | 28 | protected void init() { 29 | addHeaderView(); 30 | } 31 | 32 | protected void addHeaderView() { 33 | // PtrClassicDefaultHeader header = new PtrClassicDefaultHeader(getActivity()); 34 | // header.setLastUpdateTimeKey(KeyConfig.UPDATE_TIME); 35 | CustomRefreshHeader header = new CustomRefreshHeader(getContext()); 36 | addPtrUIHandler(header); 37 | setHeaderView(header); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/listitem_drawer.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 20 | 21 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/column/detail/ColumnDetailActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.column.detail; 2 | 3 | import com.free.blog.model.entity.BlogColumn; 4 | import com.free.blog.model.entity.BlogItem; 5 | import com.free.blog.ui.base.activity.BaseBlogListActivity; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author tangqi on 17-3-13. 11 | */ 12 | public class ColumnDetailActivity extends BaseBlogListActivity { 13 | public static final String EXTRA_BLOG_COLUMN = "blog_column"; 14 | 15 | private BlogColumn mBlogColumn; 16 | 17 | @Override 18 | protected String getActionBarTitle() { 19 | return mBlogColumn.getName(); 20 | } 21 | 22 | @Override 23 | protected void beforeInitView() { 24 | mBlogColumn = (BlogColumn) getIntent().getSerializableExtra(EXTRA_BLOG_COLUMN); 25 | new ColumnDetailPresenter(this, mBlogColumn); 26 | } 27 | 28 | @Override 29 | protected boolean hasMore(List blogItems) { 30 | if (blogItems != null && blogItems.size() > 0) { 31 | BlogItem blogItem = blogItems.get(blogItems.size() - 1); 32 | return mPresenter.hasMore(blogItem.getTotalPage()); 33 | } 34 | return false; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/activity/BaseBlogListActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.activity; 2 | 3 | import android.content.Intent; 4 | import android.view.View; 5 | 6 | import com.chad.library.adapter.base.BaseQuickAdapter; 7 | import com.free.blog.R; 8 | import com.free.blog.model.entity.BlogItem; 9 | import com.free.blog.ui.base.adapter.BaseViewAdapter; 10 | import com.free.blog.ui.content.BlogContentActivity; 11 | import com.free.blog.ui.list.BlogListAdapter; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * @author tangqi on 17-3-23. 17 | */ 18 | public abstract class BaseBlogListActivity extends BaseRefreshActivity> { 19 | 20 | @Override 21 | protected BaseViewAdapter onCreateAdapter() { 22 | return new BlogListAdapter(); 23 | } 24 | 25 | @Override 26 | public void onItemClick(BaseQuickAdapter adapter, View view, int position) { 27 | BlogItem item = (BlogItem) mAdapter.getItem(position); 28 | Intent intent = new Intent(); 29 | intent.setClass(this, BlogContentActivity.class); 30 | intent.putExtra(BlogContentActivity.EXTRA_BLOG_ITEM, item); 31 | startActivity(intent); 32 | overridePendingTransition(R.anim.push_left_in, R.anim.push_no); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/remote/RetrofitClient.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.remote; 2 | 3 | import com.free.blog.library.config.Config; 4 | 5 | import retrofit2.Retrofit; 6 | import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; 7 | import retrofit2.converter.gson.GsonConverterFactory; 8 | import retrofit2.converter.scalars.ScalarsConverterFactory; 9 | 10 | /** 11 | * @author tangqi on 17-3-14. 12 | */ 13 | public class RetrofitClient { 14 | private static final RetrofitClient sInstance = new RetrofitClient(); 15 | private IBlogApi mNetAPi; 16 | 17 | public static RetrofitClient getInstance() { 18 | return sInstance; 19 | } 20 | 21 | public RetrofitClient() { 22 | Retrofit retrofit = new Retrofit.Builder() 23 | .baseUrl(Config.BLOG_HOST) 24 | .client(OkHttpFactory.getsInstance().getOkHttpClient()) 25 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 26 | .addConverterFactory(ScalarsConverterFactory.create()) 27 | .addConverterFactory(GsonConverterFactory.create()) 28 | .build(); 29 | 30 | mNetAPi = retrofit.create(IBlogApi.class); 31 | } 32 | 33 | public IBlogApi getNetApi() { 34 | return mNetAPi; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/config/Config.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.config; 2 | 3 | /** 4 | * 全局常量 5 | * 6 | * @author tangqi 7 | * @since 2015年7月20日下午10:42:07 8 | */ 9 | public class Config { 10 | 11 | /** 12 | * CSDN博客基础地址 13 | */ 14 | public static final String BLOG_HOST = "https://blog.csdn.net/"; 15 | 16 | /** 17 | * 博客分类--全部 18 | */ 19 | public static final String BLOG_CATEGORY_ALL = "全部"; 20 | 21 | /** 22 | * 博客类型 23 | */ 24 | public class BLOG_TYPE { 25 | public static final String BLOG_TYPE_REPOST = "article-type type-2"; 26 | public static final String BLOG_TYPE_ORIGINAL = "article-type type-1"; 27 | public static final String BLOG_TYPE_TRANSLATED = "article-type type-3"; 28 | } 29 | 30 | /** 31 | * 博客每一项的类型 32 | */ 33 | public class DEF_BLOG_ITEM_TYPE { 34 | public static final int TITLE = 1; // 标题 35 | @SuppressWarnings("unused") 36 | public static final int SUMMARY = 2; // 摘要 37 | public static final int CONTENT = 3; // 内容 38 | public static final int IMG = 4; // 图片 39 | public static final int BOLD_TITLE = 5; // 加粗标题 40 | public static final int CODE = 6; // 代码 41 | } 42 | 43 | /** 44 | * 评论类型 45 | */ 46 | public class COMMENT_TYPE { 47 | public static final int PARENT = 1; 48 | public static final int CHILD = 2; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/mine/AboutActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.mine; 2 | 3 | import android.os.Bundle; 4 | import android.view.View; 5 | import android.view.View.OnClickListener; 6 | import android.webkit.WebView; 7 | import android.widget.ImageView; 8 | import android.widget.TextView; 9 | 10 | import com.free.blog.R; 11 | import com.free.blog.ui.base.activity.BaseActivity; 12 | 13 | /** 14 | * 关于 15 | * 16 | * @author tangqi 17 | * @since 2015年8月9日下午11:09:57 18 | */ 19 | 20 | public class AboutActivity extends BaseActivity { 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_about); 26 | 27 | initView(); 28 | } 29 | 30 | private void initView() { 31 | TextView mTitleView = (TextView) findViewById(R.id.tv_title); 32 | mTitleView.setText("关于"); 33 | 34 | ImageView mBackBtn = (ImageView) findViewById(R.id.btn_back); 35 | mBackBtn.setVisibility(View.VISIBLE); 36 | mBackBtn.setOnClickListener(new OnClickListener() { 37 | 38 | @Override 39 | public void onClick(View v) { 40 | finish(); 41 | } 42 | }); 43 | 44 | WebView mWebView = (WebView) findViewById(R.id.webview_about); 45 | mWebView.loadUrl("file:///android_asset/about/about.html"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/res/layout/common_base_refresh.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 23 | 24 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/remote/IBlogApi.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.remote; 2 | 3 | import java.util.HashMap; 4 | 5 | import retrofit2.http.GET; 6 | import retrofit2.http.Path; 7 | import retrofit2.http.Query; 8 | import retrofit2.http.QueryMap; 9 | import retrofit2.http.Url; 10 | import rx.Observable; 11 | 12 | /** 13 | * @author tangqi on 17-3-14. 14 | */ 15 | interface IBlogApi { 16 | 17 | @GET("{userId}") 18 | Observable getBloggerInfo(@Path("userId") String userId); 19 | 20 | @GET("{userId}/article/list/{page}") 21 | Observable getBlogList(@Path("userId") String userId, @Path("page") int page); 22 | 23 | @GET("{category}/{page}") 24 | Observable getCategoryBlogList(@Path("category") String category, @Path("page") int page); 25 | 26 | @GET 27 | Observable getHtml(@Url String url); 28 | 29 | @GET("me/comment/list/{blogId}") 30 | Observable getBlogComment(@Path("blogId") String blogId, @Query("page") int page); 31 | 32 | @GET 33 | Observable getHtmlByPage(@Url String url, @Query("page") int page); 34 | 35 | @GET("ranking.html") 36 | Observable getBlogRank(); 37 | 38 | @GET("http://so.csdn.net/so/search/s.do") 39 | Observable getSearchBlog(@QueryMap HashMap queryMap); 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/mine/ContactUsActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.mine; 2 | 3 | import android.os.Bundle; 4 | import android.view.View; 5 | import android.view.View.OnClickListener; 6 | import android.webkit.WebView; 7 | import android.widget.ImageView; 8 | import android.widget.TextView; 9 | 10 | import com.free.blog.R; 11 | import com.free.blog.ui.base.activity.BaseActivity; 12 | 13 | /** 14 | * 联系我们 15 | * 16 | * @author tangqi 17 | * @since 2015年8月9日下午11:09:57 18 | */ 19 | 20 | public class ContactUsActivity extends BaseActivity { 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_about); 26 | 27 | initView(); 28 | } 29 | 30 | private void initView() { 31 | TextView mTitleView = (TextView) findViewById(R.id.tv_title); 32 | mTitleView.setText("联系我们"); 33 | 34 | ImageView mBackBtn = (ImageView) findViewById(R.id.btn_back); 35 | mBackBtn.setVisibility(View.VISIBLE); 36 | mBackBtn.setOnClickListener(new OnClickListener() { 37 | 38 | @Override 39 | public void onClick(View v) { 40 | finish(); 41 | } 42 | }); 43 | 44 | WebView mWebView = (WebView) findViewById(R.id.webview_about); 45 | mWebView.loadUrl("file:///android_asset/about/contact.html"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/remote/OkHttpFactory.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.remote; 2 | 3 | import com.free.blog.library.util.LogUtils; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | import okhttp3.OkHttpClient; 8 | import okhttp3.logging.HttpLoggingInterceptor; 9 | 10 | /** 11 | * @author tangqi on 17-3-14. 12 | */ 13 | public class OkHttpFactory { 14 | 15 | private static final String TAG = "OkHttpFactory"; 16 | private static final int TIMEOUT_CONNECT = 15; 17 | private static OkHttpClient.Builder sBuilder; 18 | private static final OkHttpFactory sInstance = new OkHttpFactory(); 19 | 20 | public static OkHttpFactory getsInstance() { 21 | return sInstance; 22 | } 23 | 24 | private OkHttpFactory() { 25 | sBuilder = new OkHttpClient.Builder(); 26 | sBuilder.connectTimeout(TIMEOUT_CONNECT, TimeUnit.SECONDS) 27 | .addInterceptor(new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { 28 | @Override 29 | public void log(String message) { 30 | LogUtils.log(TAG, message); 31 | } 32 | }).setLevel(HttpLoggingInterceptor.Level.BODY)); 33 | } 34 | 35 | public OkHttpClient getOkHttpClient() { 36 | return sBuilder.build(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/mine/UpdateLogActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.mine; 2 | 3 | import android.os.Bundle; 4 | import android.view.View; 5 | import android.view.View.OnClickListener; 6 | import android.webkit.WebView; 7 | import android.widget.ImageView; 8 | import android.widget.TextView; 9 | 10 | import com.free.blog.R; 11 | import com.free.blog.ui.base.activity.BaseActivity; 12 | 13 | 14 | /** 15 | * 更新日志 16 | * 17 | * @author tangqi 18 | * @since 2015年8月15日下午10:05:51 19 | */ 20 | public class UpdateLogActivity extends BaseActivity { 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_update_log); 26 | 27 | initView(); 28 | } 29 | 30 | private void initView() { 31 | TextView mTitleView = (TextView) findViewById(R.id.tv_title); 32 | mTitleView.setText("更新日志"); 33 | 34 | ImageView mBackBtn = (ImageView) findViewById(R.id.btn_back); 35 | mBackBtn.setVisibility(View.VISIBLE); 36 | mBackBtn.setOnClickListener(new OnClickListener() { 37 | 38 | @Override 39 | public void onClick(View v) { 40 | finish(); 41 | } 42 | }); 43 | 44 | WebView mWebView = (WebView) findViewById(R.id.webview_update_log); 45 | mWebView.loadUrl("file:///android_asset/about/about.html"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/res/values/umeng_common_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | The app is already in downloading list. 4 | dowload interrupted. 5 | Pause 6 | Continue 7 | Cancel 8 | Downloading: 9 | Pause: 10 | Download start. 11 | Patch start. 12 | Please make sure you are connected to internet, download failed 13 | Download Failed! 14 | Download finished,click to install it. 15 | Patch finished,click to install it. 16 | New version is ready,click to install it. 17 | icon 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/include_head_unback_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 20 | 21 | 32 | 33 | -------------------------------------------------------------------------------- /app/Release.md: -------------------------------------------------------------------------------- 1 | # 发布日志 2 | 3 | ## 2.1.3 4 | - 修改博客解析问题 5 | 6 | ## 2.1.2 7 | - 增加博客https支持 8 | 9 | ## 2.1.0 10 | - 修复博客数据解析错误问题 11 | - 优化项目结构 12 | 13 | ## 2.0.1 14 | - 专栏分类查询 15 | - 去掉博客圈入口 16 | 17 | ## 2.0.0 18 | - 代码重构 19 | - 博客历史 20 | - 增加专栏 21 | - lint工具 22 | 23 | ## 功能点 24 | - 超链接不能点【完成】 25 | - 自动下载存储数据【暂不做】 26 | - 仅wifi状态,下载图片或数据【暂不做】 27 | - 博主列表,长按删除【完成】 28 | - 增加博主自定义功能,分页加载 29 | - 博客详情数据,不用区分太细【使用WebView加载】 30 | - 软件自动更新【已集成,待修改界面】 31 | - 社会化组件分享 32 | - 广告条、插屏广告 33 | - 用户登陆及管理【暂不做】 34 | - 用户反馈 35 | - 博客列表排序有问题【已解决】,添加报错【CSDN网页数据有变更】 36 | - WebView跳转页面返回的问题【修改了部分bug】 37 | - 博客图标类型:原创、转载、译文【完成】 38 | - 博客列表总页数 39 | - 详情页面刷新【WebView刷新 or 使用刷新按钮】 40 | - 博客列表,离线时数据库加载不全【完成】 41 | - ListView优化问题(重要,主要是图片加载),ScrollView嵌套ListView,滑动块好看一点【完成】 42 | - 搜索功能【暂不做】 43 | - 博主按分类进行存储 44 | - 有米广告【不做】 45 | - 缓存管理【完成】 46 | 47 | ## 2015-09-18 周五 48 | - 新增频道列表,频道详情【完成】 49 | - 热门博文 50 | - 清除缓存,保留收藏数据【暂不做】 51 | - 博客专栏 52 | - 切换频道【完成】 53 | 54 | ## 2015-08-16 周日 55 | - 如果首页不在博客页面,按返回跳到博客页面【未完成】 56 | 57 | ## 2015-08-15 周六 58 | - 反馈,使用友盟SDK【完成】 59 | - 设置,包括清除缓存、检查更新、反馈、更新日志、求认同感【应用市场下载】,分享好友【完成】 60 | 61 | ## 2015-08-10 周一 62 | - 修改应用图标【完成】 63 | 64 | ## 2015-08-09 周日 65 | - 收藏【界面完成】 66 | - 分享功能,第三方分享+本地分享【本地分享完成,第三方分享未做】 67 | - 反馈【第一版不做】 68 | - 友盟统计【完成】 69 | - 打包【完成】 70 | - 申请上线【完成,被拒】 71 | - 发现模块:博客专栏,博客专家,热门文章,排行榜,订阅【完成】 72 | - 个人中心:收藏,关于,反馈,设置【完成】 73 | 74 | ## 2015-08-08 周六 75 | - WebView离线缓存到SD卡上【完成】 76 | - 修改博主列表数据库,可删除,可置顶【完成】 77 | - 对话框样式,添加博客、数据加载、删除【完成】 78 | - 自定义Toast样式【完成】 -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/vp/BasePresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.vp; 2 | 3 | import com.free.blog.BlogApplication; 4 | import com.free.blog.library.util.NetUtils; 5 | 6 | import rx.Subscription; 7 | import rx.subscriptions.CompositeSubscription; 8 | 9 | /** 10 | * @author tangqi on 17-3-20. 11 | */ 12 | public abstract class BasePresenter implements IBasePresenter { 13 | 14 | private CompositeSubscription compositeSubscription; 15 | private boolean mIsSub = false; 16 | 17 | @Override 18 | public boolean isNetWorkAvailable() { 19 | return NetUtils.isNetAvailable(BlogApplication.getContext()); 20 | } 21 | 22 | @Override 23 | public void subscribe() { 24 | mIsSub = true; 25 | } 26 | 27 | @Override 28 | public void unSubscribe() { 29 | mIsSub = false; 30 | clearSubscribe(); 31 | } 32 | 33 | protected boolean isSubscribed() { 34 | return mIsSub; 35 | } 36 | 37 | protected void addSubscription(Subscription s) { 38 | if (s == null) { 39 | return; 40 | } 41 | if (compositeSubscription == null) { 42 | compositeSubscription = new CompositeSubscription(); 43 | } 44 | compositeSubscription.add(s); 45 | } 46 | 47 | private void clearSubscribe() { 48 | if (compositeSubscription != null && compositeSubscription.hasSubscriptions()) { 49 | compositeSubscription.clear(); 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/util/KeyBoardUtils.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.util; 2 | 3 | import android.content.Context; 4 | import android.view.inputmethod.InputMethodManager; 5 | import android.widget.EditText; 6 | 7 | /** 8 | * 9 | * @author tangqi 10 | * @since 2015年8月8日下午8:48:15 11 | */ 12 | 13 | public class KeyBoardUtils 14 | { 15 | /** 16 | * 打卡软键盘 17 | * 18 | * @param mEditText 19 | * 输入框 20 | * @param mContext 21 | * 上下文 22 | */ 23 | @SuppressWarnings("unused") 24 | public static void openKeyboard(EditText mEditText, Context mContext) 25 | { 26 | InputMethodManager imm = (InputMethodManager) mContext 27 | .getSystemService(Context.INPUT_METHOD_SERVICE); 28 | imm.showSoftInput(mEditText, InputMethodManager.RESULT_SHOWN); 29 | imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 30 | InputMethodManager.HIDE_IMPLICIT_ONLY); 31 | } 32 | 33 | /** 34 | * 关闭软键盘 35 | * 36 | * @param mEditText 37 | * 输入框 38 | * @param mContext 39 | * 上下文 40 | */ 41 | public static void closeKeyboard(EditText mEditText, Context mContext) 42 | { 43 | InputMethodManager imm = (InputMethodManager) mContext 44 | .getSystemService(Context.INPUT_METHOD_SERVICE); 45 | 46 | imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/entity/BlogHtml.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.entity; 2 | 3 | import com.lidroid.xutils.db.annotation.Column; 4 | 5 | /** 6 | * 博客详情页面 7 | * 8 | * @author tangqi 9 | * @since 2015年8月6日下午11:28:30 10 | */ 11 | @SuppressWarnings("unused") 12 | public class BlogHtml extends BaseEntity { 13 | 14 | private static final long serialVersionUID = -590113455366277508L; 15 | 16 | @Column(column = "url") 17 | private String url;// 地址 18 | 19 | @Column(column = "html") 20 | private String html; // 内容 21 | 22 | @Column(column = "title") 23 | private String title; // 标题 24 | 25 | @Column(column = "updateTime") 26 | private long updateTime; // 更新时间 27 | 28 | @Column(column = "reserve") 29 | private String reserve; // 保留 30 | 31 | public String getUrl() { 32 | return url; 33 | } 34 | 35 | public void setUrl(String url) { 36 | this.url = url; 37 | } 38 | 39 | public String getHtml() { 40 | return html; 41 | } 42 | 43 | public void setHtml(String html) { 44 | this.html = html; 45 | } 46 | 47 | public String getReserve() { 48 | return reserve; 49 | } 50 | 51 | public void setReserve(String reserve) { 52 | this.reserve = reserve; 53 | } 54 | 55 | public String getTitle() { 56 | return title; 57 | } 58 | 59 | public void setTitle(String title) { 60 | this.title = title; 61 | } 62 | 63 | public long getUpdateTime() { 64 | return updateTime; 65 | } 66 | 67 | public void setUpdateTime(long updateTime) { 68 | this.updateTime = updateTime; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_blogger_operation.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 19 | 20 | 26 | 27 | 31 | 32 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 8 | 50dip 9 | 17sp 10 | 20sp 11 | 12 | 13 | 16sp 14 | 15 | 16 | 15sp 17 | 18 | 19 | 50dip 20 | 13sp 21 | 22 | 23 | 40dip 24 | 25 | 26 | 220dip 27 | 28 | 29 | 240dip 30 | 50dp 31 | 18dp 32 | 11dp 33 | 2dp 34 | 3dp 35 | 16dp 36 | -16dp 37 | 38 | 39 | 35dip 40 | 12dip 41 | 42 | 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/vp/menu/MenuRefreshPresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.vp.menu; 2 | 3 | import com.free.blog.library.config.UrlManager; 4 | import com.free.blog.model.entity.BlogCategory; 5 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 6 | import com.free.blog.ui.base.vp.refresh.IRefreshView; 7 | import com.free.blog.ui.base.vp.refresh.RefreshPresenter; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author studiotang on 17/3/26 13 | */ 14 | public abstract class MenuRefreshPresenter extends RefreshPresenter implements IMenuRefreshPresenter{ 15 | 16 | protected UrlManager mNewBlogManager; 17 | protected BlogCategory mBlogCategory; 18 | 19 | protected abstract UrlManager getUrlManager(); 20 | protected abstract void updateTitle(String title); 21 | 22 | public MenuRefreshPresenter(IRefreshView viewDelegate) { 23 | super(viewDelegate); 24 | mNewBlogManager = getUrlManager(); 25 | mBlogCategory = mNewBlogManager.getType(); 26 | } 27 | 28 | @Override 29 | public String getTitle() { 30 | return mBlogCategory.getName(); 31 | } 32 | 33 | @Override 34 | public List getCategoryList() { 35 | return mNewBlogManager.getCategoryList(); 36 | } 37 | 38 | @Override 39 | public void setType(BlogCategory blogCategory) { 40 | mBlogCategory = blogCategory; 41 | mNewBlogManager.saveType(blogCategory); 42 | updateTitle(blogCategory.getName()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/base/vp/single/SinglePresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.base.vp.single; 2 | 3 | import com.free.blog.library.rx.RxHelper; 4 | import com.free.blog.library.rx.RxSubscriber; 5 | import com.free.blog.ui.base.vp.BasePresenter; 6 | 7 | import rx.Observable; 8 | import rx.Subscription; 9 | 10 | /** 11 | * @author studiotang on 17/3/21 12 | */ 13 | public abstract class SinglePresenter extends BasePresenter implements ISinglePresenter { 14 | 15 | protected ISingleView mViewDelegate; 16 | 17 | public SinglePresenter(ISingleView viewDelegate) { 18 | this.mViewDelegate = viewDelegate; 19 | mViewDelegate.setPresenter(this); 20 | } 21 | 22 | protected abstract Observable getObservable(); 23 | 24 | @Override 25 | public void loadData() { 26 | if (isSubscribed()) { 27 | addSubscription(loadSub()); 28 | } 29 | } 30 | 31 | private Subscription loadSub() { 32 | return getObservable() 33 | .compose(RxHelper.getErrAndIOSchedulerTransformer()) 34 | .subscribe(new RxSubscriber() { 35 | @Override 36 | public void onError(Throwable e) { 37 | mViewDelegate.onUpdateFailure(0); 38 | } 39 | 40 | @Override 41 | public void onNext(T t) { 42 | mViewDelegate.onUpdateUI(t); 43 | } 44 | }); 45 | } 46 | } -------------------------------------------------------------------------------- /app/src/main/assets/shBrushJScript.js: -------------------------------------------------------------------------------- 1 | ;(function() 2 | { 3 | // CommonJS 4 | SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null); 5 | 6 | function Brush() 7 | { 8 | var keywords = 'break case catch class continue ' + 9 | 'default delete do else enum export extends false ' + 10 | 'for function if implements import in instanceof ' + 11 | 'interface let new null package private protected ' + 12 | 'static return super switch ' + 13 | 'this throw true try typeof var while with yield'; 14 | 15 | var r = SyntaxHighlighter.regexLib; 16 | 17 | this.regexList = [ 18 | { regex: r.multiLineDoubleQuotedString, css: 'string' }, // double quoted strings 19 | { regex: r.multiLineSingleQuotedString, css: 'string' }, // single quoted strings 20 | { regex: r.singleLineCComments, css: 'comments' }, // one line comments 21 | { regex: r.multiLineCComments, css: 'comments' }, // multiline comments 22 | { regex: /\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion 23 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // keywords 24 | ]; 25 | 26 | this.forHtmlScript(r.scriptScriptTags); 27 | }; 28 | 29 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 30 | Brush.aliases = ['js', 'jscript', 'javascript', 'json']; 31 | 32 | SyntaxHighlighter.brushes.JScript = Brush; 33 | 34 | // CommonJS 35 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 36 | })(); 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/mine/BlogCollectPresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.mine; 2 | 3 | import com.free.blog.BlogApplication; 4 | import com.free.blog.model.entity.BlogItem; 5 | import com.free.blog.model.local.dao.BlogCollectDao; 6 | import com.free.blog.model.local.dao.DaoFactory; 7 | import com.free.blog.library.rx.RxHelper; 8 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 9 | import com.free.blog.ui.base.vp.refresh.IRefreshView; 10 | import com.free.blog.ui.base.vp.refresh.RefreshPresenter; 11 | 12 | import java.util.List; 13 | 14 | import rx.Observable; 15 | import rx.functions.Func1; 16 | 17 | /** 18 | * @author studiotang on 17/3/22 19 | */ 20 | class BlogCollectPresenter extends RefreshPresenter> { 21 | 22 | private BlogCollectDao mBlogCollectDao; 23 | 24 | BlogCollectPresenter(IRefreshView, IRefreshPresenter> viewDelegate) { 25 | super(viewDelegate); 26 | mBlogCollectDao = DaoFactory.create().getBlogCollectDao(BlogApplication.getContext()); 27 | } 28 | 29 | @Override 30 | protected Observable> getObservable(int page) { 31 | return Observable.just(page) 32 | .map(new Func1>() { 33 | @Override 34 | public List call(Integer page) { 35 | return mBlogCollectDao.query(page, getPageSize()); 36 | } 37 | }) 38 | .compose(RxHelper.>getErrAndIOSchedulerTransformer()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/mine/BlogHistoryPresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.mine; 2 | 3 | import com.free.blog.BlogApplication; 4 | import com.free.blog.model.entity.BlogItem; 5 | import com.free.blog.model.local.dao.BlogHistoryDao; 6 | import com.free.blog.model.local.dao.DaoFactory; 7 | import com.free.blog.library.rx.RxHelper; 8 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 9 | import com.free.blog.ui.base.vp.refresh.IRefreshView; 10 | import com.free.blog.ui.base.vp.refresh.RefreshPresenter; 11 | 12 | import java.util.List; 13 | 14 | import rx.Observable; 15 | import rx.functions.Func1; 16 | 17 | /** 18 | * @author tangqi on 17-3-23. 19 | */ 20 | class BlogHistoryPresenter extends RefreshPresenter> { 21 | 22 | private BlogHistoryDao mBlogHistoryDao; 23 | 24 | BlogHistoryPresenter(IRefreshView, IRefreshPresenter> viewDelegate) { 25 | super(viewDelegate); 26 | mBlogHistoryDao = DaoFactory.create().getBlogHistoryDao(BlogApplication.getContext()); 27 | } 28 | 29 | @Override 30 | protected Observable> getObservable(int page) { 31 | return Observable.just(page) 32 | .map(new Func1>() { 33 | @Override 34 | public List call(Integer page) { 35 | return mBlogHistoryDao.query(page, getPageSize()); 36 | } 37 | }) 38 | .compose(RxHelper.>getErrAndIOSchedulerTransformer()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/local/dao/impl/BlogContentDaoImpl.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.local.dao.impl; 2 | 3 | import android.content.Context; 4 | 5 | import com.free.blog.model.local.dao.BlogContentDao; 6 | import com.free.blog.model.entity.BlogHtml; 7 | import com.free.blog.library.config.CacheManager; 8 | import com.lidroid.xutils.DbUtils; 9 | import com.lidroid.xutils.db.sqlite.Selector; 10 | import com.lidroid.xutils.db.sqlite.WhereBuilder; 11 | import com.lidroid.xutils.exception.DbException; 12 | 13 | /** 14 | * 博客内容-数据库实现 15 | * 16 | * @author tangqi 17 | * @since 2015年8月7日下午11:24:06 18 | */ 19 | 20 | public class BlogContentDaoImpl implements BlogContentDao { 21 | 22 | private DbUtils db; 23 | 24 | public BlogContentDaoImpl(Context context) { 25 | db = DbUtils.create(context, CacheManager.getBlogContentDbPath(context), "blog_content"); 26 | } 27 | 28 | @Override 29 | public void insert(BlogHtml blogHtml) { 30 | BlogHtml findItem; 31 | try { 32 | findItem = db.findFirst(Selector.from(BlogHtml.class).where("url", 33 | "=", blogHtml.getUrl())); 34 | 35 | if (findItem != null) { 36 | db.update(blogHtml, 37 | WhereBuilder.b("url", "=", blogHtml.getUrl())); 38 | } else { 39 | db.save(blogHtml); 40 | } 41 | } catch (DbException e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | 46 | @Override 47 | public BlogHtml query(String url) { 48 | BlogHtml blogHtml = null; 49 | try { 50 | blogHtml = db.findFirst(Selector.from(BlogHtml.class).where("url", "=", url)); 51 | } catch (DbException e) { 52 | e.printStackTrace(); 53 | } 54 | return blogHtml; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/column/detail/ColumnDetailPresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.column.detail; 2 | 3 | import com.free.blog.library.rx.RxHelper; 4 | import com.free.blog.library.util.JsoupUtils; 5 | import com.free.blog.model.entity.BlogColumn; 6 | import com.free.blog.model.entity.BlogItem; 7 | import com.free.blog.model.remote.NetEngine; 8 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 9 | import com.free.blog.ui.base.vp.refresh.IRefreshView; 10 | import com.free.blog.ui.base.vp.refresh.RefreshPresenter; 11 | 12 | import java.util.List; 13 | 14 | import rx.Observable; 15 | import rx.functions.Func1; 16 | 17 | /** 18 | * @author studiotang on 17/3/24 19 | */ 20 | class ColumnDetailPresenter extends RefreshPresenter> { 21 | private BlogColumn mBlogColumn; 22 | 23 | ColumnDetailPresenter(IRefreshView, IRefreshPresenter> viewDelegate, 24 | BlogColumn blogColumn) { 25 | super(viewDelegate); 26 | mBlogColumn = blogColumn; 27 | } 28 | 29 | @Override 30 | protected Observable> getObservable(int page) { 31 | return NetEngine.getInstance().getHtmlByPage(mBlogColumn.getUrl(), page) 32 | .map(new Func1>() { 33 | @Override 34 | public List call(String s) { 35 | return JsoupUtils.getColumnDetail(s, mBlogColumn.getName()); 36 | } 37 | }) 38 | .compose(RxHelper.>getErrAndIOSchedulerTransformer()); 39 | } 40 | 41 | @Override 42 | public boolean hasMore(int size) { 43 | return mPage < size; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_update_button_check_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 10 | 13 | 16 | 17 | 20 | 23 | 24 | 27 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 22 | 23 | 33 | 34 | 35 | 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/list/BlogListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.list; 2 | 3 | import android.text.TextUtils; 4 | import android.view.ViewGroup; 5 | 6 | import com.chad.library.adapter.base.BaseViewHolder; 7 | import com.free.blog.R; 8 | import com.free.blog.library.config.Config; 9 | import com.free.blog.model.entity.BlogItem; 10 | import com.free.blog.ui.base.adapter.BaseViewAdapter; 11 | 12 | /** 13 | * @author studiotang on 17/3/19 14 | */ 15 | public class BlogListAdapter extends BaseViewAdapter { 16 | 17 | @Override 18 | protected BaseViewHolder onCreateDefViewHolder(ViewGroup parent, int viewType) { 19 | return new BaseViewHolder(getItemView(R.layout.listitem_blog, parent)); 20 | } 21 | 22 | @Override 23 | protected void convert(BaseViewHolder holder, BlogItem item) { 24 | holder.setText(R.id.title, item.getTitle()); 25 | 26 | if (TextUtils.isEmpty(item.getContent())) { 27 | item.setContent("暂无描述"); 28 | } 29 | holder.setText(R.id.content, String.format("\b\b\b\b\b\b\b%s", item.getContent())); 30 | 31 | if (!TextUtils.isEmpty(item.getDate())) { 32 | holder.setText(R.id.date, item.getDate()); 33 | } 34 | 35 | String icoType = item.getIcoType(); 36 | int imageResource = R.drawable.ic_original; 37 | if (Config.BLOG_TYPE.BLOG_TYPE_ORIGINAL.equals(icoType)) { 38 | imageResource = R.drawable.ic_original; 39 | } else if (Config.BLOG_TYPE.BLOG_TYPE_REPOST.equals(icoType)) { 40 | imageResource = R.drawable.ic_repost; 41 | } else if (Config.BLOG_TYPE.BLOG_TYPE_TRANSLATED.equals(icoType)) { 42 | imageResource = R.drawable.ic_translate; 43 | } 44 | holder.setImageResource(R.id.blogImg, imageResource); 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/util/ToastUtil.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.util; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | import android.view.Gravity; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.widget.TextView; 9 | import android.widget.Toast; 10 | 11 | import com.free.blog.R; 12 | 13 | 14 | @SuppressLint("InflateParams") 15 | public class ToastUtil { 16 | 17 | private static Toast mToast; 18 | 19 | /** 20 | * Toast显示消息(中间位置) 21 | */ 22 | 23 | public static void show(final Context context, final String message) { 24 | if (mToast != null) { 25 | mToast.cancel(); 26 | mToast = null; 27 | } 28 | 29 | mToast = Toast.makeText(context.getApplicationContext(), message, Toast.LENGTH_SHORT); 30 | View view = LayoutInflater.from(context.getApplicationContext()).inflate(R.layout.toast_bg, null); 31 | TextView messageView = (TextView) view.findViewById(R.id.tv_message); 32 | mToast.setView(view); 33 | 34 | messageView.setText(message); 35 | mToast.show(); 36 | } 37 | 38 | /** 39 | * Toast显示消息(底部) 40 | */ 41 | 42 | public static void showCenter(final Context context, final String message) { 43 | if (mToast != null) { 44 | mToast.cancel(); 45 | mToast = null; 46 | } 47 | 48 | mToast = Toast.makeText(context.getApplicationContext(), message, Toast.LENGTH_SHORT); 49 | View view = LayoutInflater.from(context).inflate(R.layout.toast_bg, null); 50 | TextView messageView = (TextView) view.findViewById(R.id.tv_message); 51 | mToast.setView(view); 52 | 53 | messageView.setText(message); 54 | mToast.setGravity(Gravity.CENTER, 0, 0); 55 | mToast.show(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/util/LogUtils.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.util; 2 | 3 | import android.util.Log; 4 | 5 | public class LogUtils { 6 | private static final boolean isLog = true; 7 | private static final String DEFAULT_TAG = "Debug"; 8 | 9 | private static void log(String tag, int level, String msg, Throwable tr) { 10 | if (isLog) { 11 | if (msg == null && tr == null) { 12 | return; 13 | } 14 | switch (level) { 15 | case Log.VERBOSE: 16 | if (tr == null) { 17 | Log.v(tag, msg); 18 | } else { 19 | Log.v(tag, msg, tr); 20 | } 21 | break; 22 | case Log.INFO: 23 | if (tr == null) { 24 | Log.i(tag, msg); 25 | } else { 26 | Log.i(tag, msg, tr); 27 | } 28 | break; 29 | case Log.DEBUG: 30 | if (tr == null) { 31 | Log.d(tag, msg); 32 | } else { 33 | Log.d(tag, msg, tr); 34 | } 35 | break; 36 | case Log.WARN: 37 | if (tr == null) { 38 | Log.w(tag, msg); 39 | } else { 40 | Log.w(tag, msg, tr); 41 | } 42 | break; 43 | case Log.ERROR: 44 | if (tr == null) { 45 | Log.e(tag, msg, null); 46 | } else { 47 | Log.e(tag, msg, tr); 48 | } 49 | 50 | break; 51 | } 52 | } 53 | 54 | } 55 | 56 | @SuppressWarnings("unused") 57 | static void log(String tag, int level, String msg) { 58 | if (isLog) { 59 | log(tag, Log.ERROR, msg, null); 60 | } 61 | } 62 | 63 | @SuppressWarnings("unused") 64 | public static void log(String tag, String msg) { 65 | if (isLog) { 66 | log(tag, Log.DEBUG, msg, null); 67 | } 68 | 69 | } 70 | 71 | public static void log(String msg) { 72 | if (isLog) { 73 | log(DEFAULT_TAG, Log.DEBUG, msg, null); 74 | } 75 | } 76 | 77 | @SuppressWarnings("unused") 78 | public static void log(Throwable msg) { 79 | if (isLog) { 80 | log(DEFAULT_TAG, Log.INFO, "", msg); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/blogger/BloggerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.blogger; 2 | 3 | import android.text.TextUtils; 4 | import android.view.ViewGroup; 5 | import android.widget.ImageView; 6 | 7 | import com.chad.library.adapter.base.BaseViewHolder; 8 | import com.free.blog.R; 9 | import com.free.blog.library.util.ImageLoaderUtils; 10 | import com.free.blog.model.entity.Blogger; 11 | import com.free.blog.ui.base.adapter.BaseViewAdapter; 12 | 13 | /** 14 | * @author tangqi on 17-3-23. 15 | */ 16 | public class BloggerAdapter extends BaseViewAdapter { 17 | @Override 18 | protected BaseViewHolder onCreateDefViewHolder(ViewGroup parent, int viewType) { 19 | return new BaseViewHolder(getItemView(R.layout.listitem_blogger, null)); 20 | } 21 | 22 | @Override 23 | protected void convert(BaseViewHolder helper, Blogger item) { 24 | if (!TextUtils.isEmpty(item.getImgUrl())) { 25 | ImageView imageView = helper.getView(R.id.imv_blogger); 26 | ImageLoaderUtils.displayRoundImage(item.getImgUrl(), imageView); 27 | } else { 28 | helper.setImageResource(R.id.imv_blogger, R.drawable.ic_default); 29 | } 30 | 31 | // if (item.getIsTop() == 1) { 32 | // helper.setText(R.id.tv_blog_title, String.format("%s\b[顶]", item.getTitle())); 33 | // helper.setTextColor(R.id.tv_blog_title, R.color.blue_text); 34 | // } else { 35 | helper.setText(R.id.tv_blog_title, item.getTitle()); 36 | // helper.setTextColor(R.id.tv_blog_title, R.color.black_text); 37 | // } 38 | 39 | if (!TextUtils.isEmpty(item.getDescription())) { 40 | helper.setText(R.id.tv_blog_desc, item.getDescription()); 41 | helper.setVisible(R.id.tv_blog_desc, true); 42 | } else { 43 | helper.setVisible(R.id.tv_blog_desc, false); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/assets/shBrushXml.js: -------------------------------------------------------------------------------- 1 | ;(function() 2 | { 3 | // CommonJS 4 | SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null); 5 | 6 | function Brush() 7 | { 8 | function process(match, regexInfo) 9 | { 10 | var constructor = SyntaxHighlighter.Match, 11 | code = match[0], 12 | tag = XRegExp.exec(code, XRegExp('(<|<)[\\s\\/\\?!]*(?[:\\w-\\.]+)', 'xg')), 13 | result = [] 14 | ; 15 | 16 | if (match.attributes != null) 17 | { 18 | var attributes, 19 | pos = 0, 20 | regex = XRegExp('(? [\\w:.-]+)' + 21 | '\\s*=\\s*' + 22 | '(? ".*?"|\'.*?\'|\\w+)', 23 | 'xg'); 24 | 25 | while ((attributes = XRegExp.exec(code, regex, pos)) != null) 26 | { 27 | result.push(new constructor(attributes.name, match.index + attributes.index, 'color1')); 28 | result.push(new constructor(attributes.value, match.index + attributes.index + attributes[0].indexOf(attributes.value), 'string')); 29 | pos = attributes.index + attributes[0].length; 30 | } 31 | } 32 | 33 | if (tag != null) 34 | result.push( 35 | new constructor(tag.name, match.index + tag[0].indexOf(tag.name), 'keyword') 36 | ); 37 | 38 | return result; 39 | } 40 | 41 | this.regexList = [ 42 | { regex: XRegExp('(\\<|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](\\>|>)', 'gm'), css: 'color2' }, // 43 | { regex: SyntaxHighlighter.regexLib.xmlComments, css: 'comments' }, // 44 | { regex: XRegExp('(<|<)[\\s\\/\\?!]*(\\w+)(?.*?)[\\s\\/\\?]*(>|>)', 'sg'), func: process } 45 | ]; 46 | }; 47 | 48 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 49 | Brush.aliases = ['xml', 'xhtml', 'xslt', 'html', 'plist']; 50 | 51 | SyntaxHighlighter.brushes.Xml = Brush; 52 | 53 | // CommonJS 54 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 55 | })(); 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/view/dialog/BloggerAddDialog.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.view.dialog; 2 | 3 | import android.content.Context; 4 | import android.view.Gravity; 5 | import android.view.View; 6 | import android.view.View.OnClickListener; 7 | import android.view.Window; 8 | import android.view.WindowManager; 9 | import android.widget.EditText; 10 | import android.widget.TextView; 11 | 12 | import com.free.blog.R; 13 | import com.free.blog.library.util.KeyBoardUtils; 14 | 15 | /** 16 | * 添加博主对话框 17 | */ 18 | 19 | public class BloggerAddDialog extends BaseDialog implements OnClickListener { 20 | 21 | private Context mContext; 22 | private EditText mUserIdView; 23 | private OnConfirmListener mOnConfirmListener; 24 | 25 | 26 | public BloggerAddDialog(Context context, OnConfirmListener onConfirmListener) { 27 | super(context, R.style.Theme_Light_FullScreenDialogAct); 28 | this.mContext = context; 29 | this.mOnConfirmListener = onConfirmListener; 30 | 31 | setContentView(R.layout.dialog_blogger_add); 32 | mUserIdView = (EditText) this.findViewById(R.id.et_userid); 33 | TextView mConfirmView = (TextView) this.findViewById(R.id.btn_confirm); 34 | mConfirmView.setOnClickListener(this); 35 | } 36 | 37 | @Override 38 | public void onClick(View v) { 39 | switch (v.getId()) { 40 | case R.id.btn_confirm: 41 | mOnConfirmListener.onConfirm(String.valueOf(mUserIdView.getText())); 42 | KeyBoardUtils.closeKeyboard(mUserIdView, mContext); 43 | dismiss(); 44 | break; 45 | 46 | default: 47 | break; 48 | } 49 | 50 | } 51 | 52 | /** 53 | * 显示在底部 54 | */ 55 | @SuppressWarnings("unused") 56 | public void showDialogBottom(float dimAmount) { 57 | Window window = this.getWindow(); 58 | if (window != null) { 59 | window.setGravity(Gravity.BOTTOM); 60 | WindowManager.LayoutParams lp = window.getAttributes(); 61 | lp.dimAmount = dimAmount; 62 | window.setAttributes(lp); 63 | } 64 | this.show(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/res/layout/listitem_blogger.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 17 | 25 | 26 | 34 | 35 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/entity/RankItem.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.entity; 2 | 3 | import com.lidroid.xutils.db.annotation.Column; 4 | 5 | /** 6 | * @author studiotang on 17/3/25 7 | */ 8 | public class RankItem extends BaseEntity { 9 | 10 | @Column(column = "name") 11 | private String name; 12 | 13 | @Column(column = "category") 14 | private String category; 15 | 16 | @Column(column = "icon") 17 | private String icon; 18 | 19 | @Column(column = "url") 20 | private String url; 21 | 22 | @Column(column = "size") 23 | private String size; 24 | 25 | @Column(column = "viewCount") 26 | private String viewCount; 27 | 28 | @Column(column = "reserve") 29 | private String reserve; 30 | 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | public void setName(String name) { 37 | this.name = name; 38 | } 39 | 40 | public String getCategory() { 41 | return category; 42 | } 43 | 44 | public void setCategory(String category) { 45 | this.category = category; 46 | } 47 | 48 | public String getIcon() { 49 | return icon; 50 | } 51 | 52 | public void setIcon(String icon) { 53 | this.icon = icon; 54 | } 55 | 56 | public String getUrl() { 57 | return url; 58 | } 59 | 60 | public void setUrl(String url) { 61 | this.url = url; 62 | } 63 | 64 | public String getSize() { 65 | return size; 66 | } 67 | 68 | public void setSize(String size) { 69 | this.size = size; 70 | } 71 | 72 | public String getViewCount() { 73 | return viewCount; 74 | } 75 | 76 | public void setViewCount(String viewCount) { 77 | this.viewCount = viewCount; 78 | } 79 | 80 | public String getReserve() { 81 | return reserve; 82 | } 83 | 84 | public void setReserve(String reserve) { 85 | this.reserve = reserve; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/find/last/NewBlogPresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.find.last; 2 | 3 | import com.free.blog.library.config.NewBlogManager; 4 | import com.free.blog.library.config.UrlManager; 5 | import com.free.blog.library.rx.RxHelper; 6 | import com.free.blog.library.util.JsoupUtils; 7 | import com.free.blog.model.entity.BlogItem; 8 | import com.free.blog.model.remote.NetEngine; 9 | import com.free.blog.ui.base.vp.menu.MenuRefreshPresenter; 10 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 11 | 12 | import java.util.List; 13 | 14 | import rx.Observable; 15 | import rx.functions.Func1; 16 | 17 | /** 18 | * @author studiotang on 17/3/26 19 | */ 20 | public class NewBlogPresenter extends MenuRefreshPresenter> implements 21 | NewBlogContract.Presenter { 22 | 23 | public NewBlogPresenter(NewBlogContract.View, IRefreshPresenter> viewDelegate) { 24 | super(viewDelegate); 25 | } 26 | 27 | @Override 28 | protected Observable> getObservable(int page) { 29 | return NetEngine.getInstance().getHtmlByPage(mBlogCategory.getLink(), page) 30 | .map(new Func1>() { 31 | @Override 32 | public List call(String s) { 33 | return JsoupUtils.getHotBlog(s, mBlogCategory.getName()); 34 | } 35 | }) 36 | .compose(RxHelper.>getErrAndIOSchedulerTransformer()); 37 | } 38 | 39 | @Override 40 | protected NewBlogContract.View, IRefreshPresenter> getViewDelegate() { 41 | return (NewBlogContract.View, IRefreshPresenter>) mViewDelegate; 42 | } 43 | 44 | @Override 45 | protected UrlManager getUrlManager() { 46 | return new NewBlogManager(); 47 | } 48 | 49 | @Override 50 | protected void updateTitle(String title) { 51 | getViewDelegate().updateTitle(title); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #00000000 5 | 6 | #21292C 7 | #09A284 8 | #019587 9 | #21292C 10 | #FFFFFF 11 | #000000 12 | #FF0000 13 | #5D5D5D 14 | #622f1b 15 | #f0f0f0 16 | #E0E0E0 17 | #5CACEE 18 | #80000000 19 | #00000000 20 | #88000000 21 | #A0000000 22 | #999999 23 | #D9D9D9 24 | #4A708B 25 | #01A7FF 26 | #FFFFFF 27 | 28 | 29 | 30 | 31 | 32 | #D9D9D9 33 | #353535 34 | #586B96 35 | #EBEBEB 36 | #FCFCFC 37 | #5AAE3E 38 | #D6D6D6 39 | #F2F2F2 40 | 41 | #FFD91C 42 | #FF4B4A 43 | #3D8EFF 44 | 45 | 46 | @color/ball1 47 | @color/ball2 48 | @color/ball3 49 | 50 | 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/entity/BlogCategory.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.entity; 2 | 3 | import com.lidroid.xutils.db.annotation.Column; 4 | 5 | /** 6 | * 博客分类(例如,移动开发、Web前端) 7 | * 8 | * @author tangqi 9 | * @since 2015年8月18日下午10:42:07 10 | */ 11 | @SuppressWarnings("unused") 12 | public class BlogCategory extends BaseEntity { 13 | private static final long serialVersionUID = -8366599113596257949L; 14 | 15 | /** 16 | * 分类名称 17 | */ 18 | @Column(column = "name") 19 | private String name; 20 | 21 | /** 22 | * 分类连接 23 | */ 24 | @Column(column = "link") 25 | private String link; 26 | 27 | /** 28 | * 分类图片 29 | */ 30 | @Column(column = "image") 31 | private String image; 32 | 33 | /** 34 | * 分类详情 35 | */ 36 | @Column(column = "content") 37 | private String content; 38 | 39 | /** 40 | * 分类更新时间 41 | */ 42 | @Column(column = "updateTime") 43 | private String updateTime; 44 | 45 | /** 46 | * 保留字段 47 | */ 48 | @Column(column = "reserve") 49 | private String reserve; 50 | 51 | public String getName() { 52 | return name; 53 | } 54 | 55 | public void setName(String name) { 56 | this.name = name; 57 | } 58 | 59 | public String getImage() { 60 | return image; 61 | } 62 | 63 | public void setImage(String image) { 64 | this.image = image; 65 | } 66 | 67 | public String getContent() { 68 | return content; 69 | } 70 | 71 | public void setContent(String content) { 72 | this.content = content; 73 | } 74 | 75 | public String getUpdateTime() { 76 | return updateTime; 77 | } 78 | 79 | public void setUpdateTime(String updateTime) { 80 | this.updateTime = updateTime; 81 | } 82 | 83 | public String getReserve() { 84 | return reserve; 85 | } 86 | 87 | public void setReserve(String reserve) { 88 | this.reserve = reserve; 89 | } 90 | 91 | public String getLink() { 92 | return link; 93 | } 94 | 95 | public void setLink(String link) { 96 | this.link = link; 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/find/rank/RankPresenter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.find.rank; 2 | 3 | import com.free.blog.library.rx.RxHelper; 4 | import com.free.blog.library.util.JsoupUtils; 5 | import com.free.blog.model.entity.BlogRank; 6 | import com.free.blog.model.entity.RankItem; 7 | import com.free.blog.model.remote.NetEngine; 8 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 9 | import com.free.blog.ui.base.vp.refresh.IRefreshView; 10 | import com.free.blog.ui.base.vp.refresh.RefreshPresenter; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | import rx.Observable; 16 | import rx.functions.Func1; 17 | 18 | /** 19 | * @author studiotang on 17/3/25 20 | */ 21 | class RankPresenter extends RefreshPresenter> implements RankContract.Presenter { 22 | 23 | RankPresenter(IRefreshView, IRefreshPresenter> viewDelegate) { 24 | super(viewDelegate); 25 | } 26 | 27 | @Override 28 | protected Observable> getObservable(int page) { 29 | return NetEngine.getInstance().getBlogRank() 30 | .map(new Func1>() { 31 | @Override 32 | public List call(String result) { 33 | List blogRanks = JsoupUtils.getBlogRank(result); 34 | if (blogRanks != null && blogRanks.size() > 0) { 35 | List list = new ArrayList<>(); 36 | for (BlogRank blogRank : blogRanks) { 37 | list.addAll(blogRank.getData()); 38 | } 39 | return list; 40 | } 41 | 42 | return null; 43 | } 44 | }) 45 | .compose(RxHelper.>getErrAndIOSchedulerTransformer()); 46 | } 47 | 48 | @Override 49 | public boolean hasMore(int size) { 50 | return false; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/entity/BlogColumn.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.entity; 2 | 3 | import com.lidroid.xutils.db.annotation.Column; 4 | 5 | /** 6 | * 频道分类 7 | * 8 | * @author tangqi 9 | * @since 2015年8月9日下午2:21:54 10 | */ 11 | public class BlogColumn extends BaseEntity { 12 | 13 | private static final long serialVersionUID = 3205931841537722040L; 14 | 15 | @Column(column = "name") 16 | private String name; 17 | 18 | @Column(column = "category") 19 | private String category; 20 | 21 | @Column(column = "icon") 22 | private String icon; 23 | 24 | @Column(column = "url") 25 | private String url; 26 | 27 | @Column(column = "size") 28 | private String size; 29 | 30 | @Column(column = "viewCount") 31 | private String viewCount; 32 | 33 | @Column(column = "reserve") 34 | private String reserve; 35 | 36 | public String getName() { 37 | return name; 38 | } 39 | 40 | public void setName(String name) { 41 | this.name = name; 42 | } 43 | 44 | public String getCategory() { 45 | return category; 46 | } 47 | 48 | public void setCategory(String category) { 49 | this.category = category; 50 | } 51 | 52 | public String getIcon() { 53 | return icon; 54 | } 55 | 56 | public void setIcon(String icon) { 57 | this.icon = icon; 58 | } 59 | 60 | public String getUrl() { 61 | return url; 62 | } 63 | 64 | public void setUrl(String url) { 65 | this.url = url; 66 | } 67 | 68 | public String getSize() { 69 | return size; 70 | } 71 | 72 | public void setSize(String size) { 73 | this.size = size; 74 | } 75 | 76 | public String getViewCount() { 77 | return viewCount; 78 | } 79 | 80 | public void setViewCount(String viewCount) { 81 | this.viewCount = viewCount; 82 | } 83 | 84 | public String getReserve() { 85 | return reserve; 86 | } 87 | 88 | public void setReserve(String reserve) { 89 | this.reserve = reserve; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/remote/NetEngine.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.remote; 2 | 3 | import com.free.blog.library.config.Config; 4 | 5 | import java.util.HashMap; 6 | 7 | import rx.Observable; 8 | 9 | /** 10 | * @author tangqi on 17-3-14. 11 | */ 12 | public class NetEngine { 13 | 14 | private final IBlogApi mBlogApi; 15 | private static final NetEngine sInstance = new NetEngine(); 16 | 17 | public static NetEngine getInstance() { 18 | return sInstance; 19 | } 20 | 21 | private NetEngine() { 22 | mBlogApi = RetrofitClient.getInstance().getNetApi(); 23 | } 24 | 25 | public Observable getBloggerInfo(String userId) { 26 | return mBlogApi.getBloggerInfo(userId); 27 | } 28 | 29 | public Observable getBlogList(String userId, int page) { 30 | return mBlogApi.getBlogList(userId, page); 31 | } 32 | 33 | public Observable getCategoryBlogList(String category, int page) { 34 | return mBlogApi.getCategoryBlogList(category, page); 35 | } 36 | 37 | public Observable getHtml(String url) { 38 | return mBlogApi.getHtml(url); 39 | } 40 | 41 | public Observable getHtmlByPage(String url, int page) { 42 | return mBlogApi.getHtmlByPage(url, page); 43 | } 44 | 45 | public Observable getBlogComment(String blogId, int page) { 46 | return mBlogApi.getBlogComment(blogId, page); 47 | } 48 | 49 | public Observable getBlogRank() { 50 | return mBlogApi.getBlogRank(); 51 | } 52 | 53 | public Observable getSearchBlog(String keywords) { 54 | HashMap queryMap = new HashMap<>(); 55 | queryMap.put("q", keywords); 56 | queryMap.put("t", "blog"); 57 | queryMap.put("l", ""); 58 | return mBlogApi.getSearchBlog(queryMap); 59 | } 60 | 61 | public String getBlogPkUrl() { 62 | return Config.BLOG_HOST + "PK.html"; 63 | } 64 | 65 | public String getBlogDaily() { 66 | return Config.BLOG_HOST + "column/details/14549.html"; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/local/dao/impl/BlogCommentDaoImpl.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.local.dao.impl; 2 | 3 | import android.content.Context; 4 | 5 | import com.free.blog.library.config.CacheManager; 6 | import com.free.blog.model.entity.Comment; 7 | import com.free.blog.model.local.dao.BlogCommentDao; 8 | import com.lidroid.xutils.DbUtils; 9 | import com.lidroid.xutils.db.sqlite.Selector; 10 | import com.lidroid.xutils.db.sqlite.WhereBuilder; 11 | import com.lidroid.xutils.exception.DbException; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * 博客评论-数据库实现 17 | * 18 | * @author tangqi 19 | * @since 2015年8月7日下午11:53:19 20 | */ 21 | 22 | public class BlogCommentDaoImpl implements BlogCommentDao { 23 | 24 | private DbUtils db; 25 | 26 | public BlogCommentDaoImpl(Context context, String blogId) { 27 | db = DbUtils.create(context, CacheManager.getBlogCommentDbPath(context), 28 | blogId + "_comment"); 29 | } 30 | 31 | @Override 32 | public void insert(List list) { 33 | try { 34 | for (int i = 0; i < list.size(); i++) { 35 | Comment commentItem = list.get(i); 36 | Comment findItem = db.findFirst(Selector.from(Comment.class) 37 | .where("commentId", "=", commentItem.getCommentId())); 38 | if (findItem != null) { 39 | db.update( 40 | commentItem, 41 | WhereBuilder.b("commentId", "=", 42 | commentItem.getCommentId())); 43 | } else { 44 | db.save(commentItem); 45 | } 46 | } 47 | } catch (DbException e) { 48 | e.printStackTrace(); 49 | } 50 | } 51 | 52 | @Override 53 | public List query(int page, int pageSize) { 54 | try { 55 | return db.findAll(Selector.from(Comment.class).limit( 56 | pageSize).offset((page - 1) * pageSize)); 57 | } catch (DbException e) { 58 | e.printStackTrace(); 59 | } 60 | 61 | return null; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/home/find/last/NewBlogActivity.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.home.find.last; 2 | 3 | import android.view.View; 4 | import android.widget.AdapterView; 5 | 6 | import com.free.blog.library.view.pop.CategoryPopupWindow; 7 | import com.free.blog.model.entity.BlogCategory; 8 | import com.free.blog.model.entity.BlogItem; 9 | import com.free.blog.ui.base.activity.BaseBlogListActivity; 10 | import com.free.blog.ui.base.vp.refresh.IRefreshPresenter; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * @author studiotang on 17/3/25 16 | */ 17 | public class NewBlogActivity extends BaseBlogListActivity implements 18 | NewBlogContract.View, IRefreshPresenter> { 19 | @Override 20 | protected String getActionBarTitle() { 21 | return getPresenter().getTitle(); 22 | } 23 | 24 | @Override 25 | protected void beforeInitView() { 26 | new NewBlogPresenter(this); 27 | } 28 | 29 | @Override 30 | public void updateTitle(String title) { 31 | setActionBarTitle(title); 32 | } 33 | 34 | @Override 35 | protected boolean isShowMenu() { 36 | return true; 37 | } 38 | 39 | @Override 40 | public NewBlogPresenter getPresenter() { 41 | return (NewBlogPresenter) mPresenter; 42 | } 43 | 44 | @Override 45 | protected void showMenu(View view) { 46 | List categoryList = getPresenter().getCategoryList(); 47 | CategoryPopupWindow popupWindow = new CategoryPopupWindow(this, categoryList); 48 | popupWindow.setOnItemClickListener(new OnCategoryItemClickListener()); 49 | popupWindow.showAsDropDown(view); 50 | } 51 | 52 | private class OnCategoryItemClickListener implements AdapterView.OnItemClickListener { 53 | 54 | @SuppressWarnings("unchecked") 55 | @Override 56 | public void onItemClick(AdapterView adapterView, View view, int position, long l) { 57 | 58 | BlogCategory item = (BlogCategory) adapterView.getAdapter().getItem(position); 59 | getPresenter().setType(item); 60 | mAdapter.setNewData(null); 61 | doRefresh(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/res/layout/include_head_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 17 | 18 | 26 | 27 | 40 | 41 | 52 | 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/view/dialog/BloggerOperationDialog.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.view.dialog; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.view.View; 6 | import android.widget.TextView; 7 | 8 | import com.free.blog.R; 9 | import com.free.blog.model.entity.Blogger; 10 | 11 | /** 12 | * 博主相关操作 13 | * 14 | * @author tangqi 15 | * @since 2015年8月8日下午9:54:05 16 | */ 17 | 18 | public class BloggerOperationDialog extends BaseDialog implements View.OnClickListener { 19 | 20 | private OnDeleteListener mOnDeleteListener; 21 | private OnStickListener mOnStickListener; 22 | private Blogger mBlogger; 23 | 24 | public BloggerOperationDialog(Context context, Blogger blogger) { 25 | super(context, R.style.Theme_Light_FullScreenDialogAct); 26 | 27 | this.mBlogger = blogger; 28 | setContentView(R.layout.dialog_blogger_operation); 29 | } 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | 35 | TextView deleteView = (TextView) findViewById(R.id.tv_delete_blogger); 36 | TextView stickView = (TextView) findViewById(R.id.tv_stick_blogger); 37 | TextView cancelView = (TextView) findViewById(R.id.tv_cancel_operate); 38 | 39 | if (mBlogger.getIsTop() == 0) { 40 | stickView.setText("置顶博主"); 41 | } else { 42 | stickView.setText("取消置顶"); 43 | } 44 | 45 | deleteView.setOnClickListener(this); 46 | stickView.setOnClickListener(this); 47 | cancelView.setOnClickListener(this); 48 | } 49 | 50 | @Override 51 | public void onClick(View v) { 52 | dismiss(); 53 | 54 | switch (v.getId()) { 55 | case R.id.tv_delete_blogger: 56 | mOnDeleteListener.onDelete(null); 57 | break; 58 | 59 | case R.id.tv_stick_blogger: 60 | mOnStickListener.onStick(null); 61 | break; 62 | 63 | case R.id.tv_cancel_operate: 64 | // TODO 65 | break; 66 | 67 | default: 68 | break; 69 | } 70 | } 71 | 72 | public void setOnDeleteListener(OnDeleteListener onDeleteListener) { 73 | this.mOnDeleteListener = onDeleteListener; 74 | } 75 | 76 | public void setOnStickListener(OnStickListener onStickListener) { 77 | this.mOnStickListener = onStickListener; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/assets/shBrushJava.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/ 4 | * 5 | * @version 6 | * 2.0.278 (February 03 2009) 7 | * 8 | * @author 9 | * Alex Gorbatchev 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2009 Alex Gorbatchev. 13 | * 14 | * Licensed under a GNU Lesser General Public License. 15 | * http://creativecommons.org/licenses/LGPL/2.1/ 16 | * 17 | * SyntaxHighlighter is donationware. You are allowed to download, modify and distribute 18 | * the source code in accordance with LGPL 2.1 license, however if you want to use 19 | * SyntaxHighlighter on your site or include it in your product, you must donate. 20 | * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate 21 | */ 22 | SyntaxHighlighter.brushes.Java = function() 23 | { 24 | var keywords = 'abstract assert boolean break byte case catch char class const ' + 25 | 'continue default do double else enum extends ' + 26 | 'false final finally float for goto if implements import ' + 27 | 'instanceof int interface long native new null ' + 28 | 'package private protected public return ' + 29 | 'short static strictfp super switch synchronized this throw throws true ' + 30 | 'transient try void volatile while'; 31 | 32 | this.regexList = [ 33 | { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments 34 | { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments 35 | { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings 36 | { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings 37 | { regex: /\b([\d]+(\.[\d]+)?|0x[a-f0-9]+)\b/gi, css: 'value' }, // numbers 38 | { regex: /(?!\@interface\b)\@[\$\w]+\b/g, css: 'color1' }, // annotation @anno 39 | { regex: /\@interface\b/g, css: 'color2' }, // @interface keyword 40 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // java keyword 41 | ]; 42 | 43 | this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); 44 | }; 45 | 46 | SyntaxHighlighter.brushes.Java.prototype = new SyntaxHighlighter.Highlighter(); 47 | SyntaxHighlighter.brushes.Java.aliases = ['java']; 48 | -------------------------------------------------------------------------------- /app/src/main/assets/shBrushPython.js: -------------------------------------------------------------------------------- 1 | ;(function() 2 | { 3 | // CommonJS 4 | SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null); 5 | 6 | function Brush() 7 | { 8 | // Contributed by Gheorghe Milas and Ahmad Sherif 9 | 10 | var keywords = 'and assert break class continue def del elif else ' + 11 | 'except exec finally for from global if import in is ' + 12 | 'lambda not or pass raise return try yield while'; 13 | 14 | var funcs = '__import__ abs all any apply basestring bin bool buffer callable ' + 15 | 'chr classmethod cmp coerce compile complex delattr dict dir ' + 16 | 'divmod enumerate eval execfile file filter float format frozenset ' + 17 | 'getattr globals hasattr hash help hex id input int intern ' + 18 | 'isinstance issubclass iter len list locals long map max min next ' + 19 | 'object oct open ord pow print property range raw_input reduce ' + 20 | 'reload repr reversed round set setattr slice sorted staticmethod ' + 21 | 'str sum super tuple type type unichr unicode vars xrange zip'; 22 | 23 | var special = 'None True False self cls class_'; 24 | 25 | this.regexList = [ 26 | { regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' }, 27 | { regex: /^\s*@\w+/gm, css: 'decorator' }, 28 | { regex: /(['\"]{3})([^\1])*?\1/gm, css: 'comments' }, 29 | { regex: /"(?!")(?:\.|\\\"|[^\""\n])*"/gm, css: 'string' }, 30 | { regex: /'(?!')(?:\.|(\\\')|[^\''\n])*'/gm, css: 'string' }, 31 | { regex: /\+|\-|\*|\/|\%|=|==/gm, css: 'keyword' }, 32 | { regex: /\b\d+\.?\w*/g, css: 'value' }, 33 | { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' }, 34 | { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, 35 | { regex: new RegExp(this.getKeywords(special), 'gm'), css: 'color1' } 36 | ]; 37 | 38 | this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags); 39 | }; 40 | 41 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 42 | Brush.aliases = ['py', 'python']; 43 | 44 | SyntaxHighlighter.brushes.Python = Brush; 45 | 46 | // CommonJS 47 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 48 | })(); 49 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_blogger_add.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 17 | 18 | 22 | 23 | 34 | 35 | 48 | 49 | 58 | 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/local/dao/DaoFactory.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.local.dao; 2 | 3 | import android.content.Context; 4 | 5 | import com.free.blog.model.local.dao.impl.BlogCollectDaoImpl; 6 | import com.free.blog.model.local.dao.impl.BlogCommentDaoImpl; 7 | import com.free.blog.model.local.dao.impl.BlogContentDaoImpl; 8 | import com.free.blog.model.local.dao.impl.BlogHistoryDaoImpl; 9 | import com.free.blog.model.local.dao.impl.BlogItemDaoImpl; 10 | import com.free.blog.model.local.dao.impl.BloggerDaoImpl; 11 | import com.free.blog.model.local.dao.impl.ChannelBloggerDaoImpl; 12 | 13 | 14 | /** 15 | * 数据库工厂类 16 | * 17 | * @author Frank 18 | * @since 2015年8月22日上午10:26:06 19 | */ 20 | 21 | public class DaoFactory { 22 | 23 | private static DaoFactory mInstance = null; 24 | 25 | /** 26 | * 获取DaoFactory的实例 27 | */ 28 | public static DaoFactory create() { 29 | if (mInstance == null) { 30 | synchronized (DaoFactory.class) { 31 | if (mInstance == null) { 32 | mInstance = new DaoFactory(); 33 | } 34 | } 35 | } 36 | return mInstance; 37 | } 38 | 39 | /** 40 | * 获取博主数据库 41 | */ 42 | public BloggerDao getBloggerDao(Context context, String type) { 43 | return new BloggerDaoImpl(context, type); 44 | } 45 | 46 | /** 47 | * 获取博客列表数据库 48 | */ 49 | public BlogItemDao getBlogItemDao(Context context, String userId) { 50 | return new BlogItemDaoImpl(context, userId); 51 | } 52 | 53 | /** 54 | * 获取博客内容数据库 55 | */ 56 | public BlogContentDao getBlogContentDao(Context context) { 57 | return new BlogContentDaoImpl(context); 58 | } 59 | 60 | /** 61 | * 获取博客收藏数据库 62 | */ 63 | public BlogCollectDao getBlogCollectDao(Context context) { 64 | return new BlogCollectDaoImpl(context); 65 | } 66 | 67 | /** 68 | * 获取博客收藏数据库 69 | */ 70 | public BlogHistoryDao getBlogHistoryDao(Context context) { 71 | return new BlogHistoryDaoImpl(context); 72 | } 73 | 74 | /** 75 | * 获取博客评论数据库 76 | */ 77 | public BlogCommentDao getBlogCommentDao(Context context, String blogId) { 78 | return new BlogCommentDaoImpl(context, blogId); 79 | } 80 | 81 | /** 82 | * 获取某频道-博客专家数据库 83 | */ 84 | @SuppressWarnings("unused") 85 | public ChannelBloggerDao getChannelBloggerDao(Context context, String channelName) { 86 | return new ChannelBloggerDaoImpl(context, channelName); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/res/layout/listitem_comment.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 19 | 20 | 25 | 26 | 35 | 36 | 45 | 46 | 47 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/config/CacheManager.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.config; 2 | 3 | import android.content.Context; 4 | 5 | import com.free.blog.library.util.FileUtils; 6 | 7 | import java.io.File; 8 | 9 | /** 10 | * App缓存管理 11 | * 12 | * @author tangqi 13 | * @since 2015年8月8日上午11:35:33 14 | */ 15 | 16 | public class CacheManager { 17 | 18 | /** 19 | * 获取外部缓存目录 20 | */ 21 | public static String getExternalCachePath(Context context) { 22 | return FileUtils.getExternalCacheDir(context); 23 | } 24 | 25 | /** 26 | * 获取博客收藏数据库目录 27 | */ 28 | public static String getBloggerCollectDbPath(Context context) { 29 | return getExternalCachePath(context) + File.separator + "BlogCollect"; 30 | } 31 | 32 | /** 33 | * 获取博主数据库目录 34 | */ 35 | @SuppressWarnings("unused") 36 | public static String getBloggerDbPath(Context context) { 37 | return getExternalCachePath(context) + File.separator + "Blogger"; 38 | } 39 | 40 | /** 41 | * 获取博客列表数据库目录 42 | */ 43 | public static String getBlogListDbPath(Context context) { 44 | return getExternalCachePath(context) + File.separator + "BlogList"; 45 | } 46 | 47 | /** 48 | * 获取博客内容数据库目录 49 | */ 50 | public static String getBlogContentDbPath(Context context) { 51 | return getExternalCachePath(context) + File.separator + "BlogContent"; 52 | } 53 | 54 | /** 55 | * 获取评论数据库目录 56 | */ 57 | public static String getBlogCommentDbPath(Context context) { 58 | return getExternalCachePath(context) + File.separator + "CommentList"; 59 | } 60 | 61 | /** 62 | * 获取某频道博主数据库目录 63 | */ 64 | public static String getChannelBloggerDbPath(Context context) { 65 | return getExternalCachePath(context) + File.separator + "ChannelBlogger"; 66 | } 67 | 68 | /** 69 | * 获取WebView缓存目录 70 | */ 71 | public static String getAppCachePath(Context context) { 72 | return getExternalCachePath(context) + File.separator + "App" + File.separator + "Cache"; 73 | } 74 | 75 | /** 76 | * 获取WebView数据库目录 77 | */ 78 | public static String getAppDatabasePath(Context context) { 79 | return getExternalCachePath(context) + File.separator + "App" + File.separator + "DataBase"; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/library/view/refresh/CustomRefreshHeader.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.library.view.refresh; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.widget.FrameLayout; 8 | 9 | import com.free.blog.R; 10 | import com.me.ui.widget.loading.MeLoadingView; 11 | 12 | import in.srain.cube.views.ptr.PtrFrameLayout; 13 | import in.srain.cube.views.ptr.PtrUIHandler; 14 | import in.srain.cube.views.ptr.indicator.PtrIndicator; 15 | 16 | 17 | /** 18 | * @author studiotang on 17/4/1 19 | */ 20 | public class CustomRefreshHeader extends FrameLayout implements PtrUIHandler { 21 | 22 | private MeLoadingView mCircleLoadingView; 23 | 24 | public CustomRefreshHeader(Context context) { 25 | this(context, null); 26 | } 27 | 28 | public CustomRefreshHeader(Context context, AttributeSet attr) { 29 | this(context, attr, 0); 30 | } 31 | 32 | public CustomRefreshHeader(Context context, AttributeSet attr, int defStyle) { 33 | super(context, attr, defStyle); 34 | initView(); 35 | } 36 | 37 | private void initView() { 38 | View header = LayoutInflater.from(getContext()).inflate(R.layout.loading_refresh_header, this); 39 | mCircleLoadingView = (MeLoadingView) header.findViewById(R.id.custom_refresh_loading_view); 40 | mCircleLoadingView.setAnimListener(new MeLoadingView.LeLoadingAnimListener() { 41 | @Override 42 | public void onLoadStart() { 43 | 44 | } 45 | 46 | @Override 47 | public void onLoadFinished() { 48 | 49 | } 50 | }); 51 | } 52 | 53 | @Override 54 | public void onUIReset(PtrFrameLayout frame) { 55 | 56 | } 57 | 58 | @Override 59 | public void onUIRefreshPrepare(PtrFrameLayout frame) { 60 | mCircleLoadingView.appearAnim(); 61 | } 62 | 63 | @Override 64 | public void onUIRefreshBegin(PtrFrameLayout frame) { 65 | 66 | } 67 | 68 | @Override 69 | public void onUIRefreshComplete(PtrFrameLayout frame) { 70 | mCircleLoadingView.disappearAnim(null); 71 | } 72 | 73 | @Override 74 | public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) { 75 | 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/ui/list/BlogCategoryAdapter.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.ui.list; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.BaseAdapter; 9 | import android.widget.TextView; 10 | 11 | import com.free.blog.R; 12 | import com.free.blog.model.entity.BlogCategory; 13 | 14 | import java.util.List; 15 | 16 | 17 | /** 18 | * 博客分类 19 | * 20 | * @author tangqi 21 | * @since 2015年8月9日下午2:01:25 22 | */ 23 | public class BlogCategoryAdapter extends BaseAdapter { 24 | 25 | private Context context; 26 | private List list; 27 | private int selection = -1; 28 | 29 | public BlogCategoryAdapter(Context context, List list) { 30 | super(); 31 | this.context = context; 32 | this.list = list; 33 | } 34 | 35 | public void setList(List list) { 36 | this.list = list; 37 | } 38 | 39 | public int getCount() { 40 | return list != null ? list.size() : 0; 41 | } 42 | 43 | @Override 44 | public BlogCategory getItem(int position) { 45 | return list.get(position); 46 | } 47 | 48 | public long getItemId(int position) { 49 | return position; 50 | } 51 | 52 | @SuppressLint("InflateParams") 53 | public View getView(int position, View convertView, ViewGroup parent) { 54 | ViewHolder holder; 55 | if (convertView == null) { 56 | convertView = LayoutInflater.from(context).inflate(R.layout.listitem_blogtype, null); 57 | holder = new ViewHolder(); 58 | holder.tvName = (TextView) convertView.findViewById(R.id.tv_name); 59 | 60 | convertView.setTag(holder); 61 | } else { 62 | holder = (ViewHolder) convertView.getTag(); 63 | } 64 | 65 | holder.tvName.setText(getItem(position).getName()); 66 | 67 | return convertView; 68 | } 69 | 70 | @SuppressWarnings("unused") 71 | public void setSelectionPosition(int selection) { 72 | this.selection = selection; 73 | notifyDataSetChanged(); 74 | } 75 | 76 | @SuppressWarnings("unused") 77 | public int getSelectionPosition() { 78 | return this.selection; 79 | } 80 | 81 | private static class ViewHolder { 82 | TextView tvName; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/com/free/blog/model/entity/Comment.java: -------------------------------------------------------------------------------- 1 | package com.free.blog.model.entity; 2 | 3 | /** 4 | * 评论实体类 5 | * 6 | * @author tangqi 7 | * @since 2015年8月6日下午09:28:30 8 | */ 9 | @SuppressWarnings("unused") 10 | public class Comment extends BaseEntity{ 11 | 12 | private static final long serialVersionUID = -5378134161928918526L; 13 | 14 | private String articleId; // 文章id 15 | private String blogId; // 博客id 16 | private String commentId; // 评论id 17 | private String content; // 评论内容 18 | private String parentId; // 父节点id 19 | private String postTime; // 发布时间 20 | private String replies; // 21 | private String username;// 用户名 22 | private String userface;// 用户头像 23 | private int type; // 评论类型,分topic和reply 24 | 25 | public String getArticleId() { 26 | return articleId; 27 | } 28 | 29 | public void setArticleId(String articleId) { 30 | this.articleId = articleId; 31 | } 32 | 33 | public String getBlogId() { 34 | return blogId; 35 | } 36 | 37 | public void setBlogId(String blogId) { 38 | this.blogId = blogId; 39 | } 40 | 41 | public String getCommentId() { 42 | return commentId; 43 | } 44 | 45 | public void setCommentId(String commentId) { 46 | this.commentId = commentId; 47 | } 48 | 49 | public String getContent() { 50 | return content; 51 | } 52 | 53 | public void setContent(String content) { 54 | this.content = content; 55 | } 56 | 57 | public String getParentId() { 58 | return parentId; 59 | } 60 | 61 | public void setParentId(String parentId) { 62 | this.parentId = parentId; 63 | } 64 | 65 | public String getPostTime() { 66 | return postTime; 67 | } 68 | 69 | public void setPostTime(String postTime) { 70 | this.postTime = postTime; 71 | } 72 | 73 | public String getReplies() { 74 | return replies; 75 | } 76 | 77 | public void setReplies(String replies) { 78 | this.replies = replies; 79 | } 80 | 81 | public String getUsername() { 82 | return username; 83 | } 84 | 85 | public void setUsername(String username) { 86 | this.username = username; 87 | } 88 | 89 | public String getUserface() { 90 | return userface; 91 | } 92 | 93 | public void setUserface(String userface) { 94 | this.userface = userface; 95 | } 96 | 97 | public int getType() { 98 | return type; 99 | } 100 | 101 | public void setType(int parent) { 102 | this.type = parent; 103 | } 104 | 105 | 106 | 107 | } 108 | --------------------------------------------------------------------------------