├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── commonlibrary ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── txl │ │ └── commonlibrary │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── txl │ │ │ └── commonlibrary │ │ │ └── utils │ │ │ ├── AndroidKeyBoardUtils.kt │ │ │ ├── AndroidLogWrapperUtil.java │ │ │ ├── CloseableUtils.java │ │ │ ├── ColorsUtils.java │ │ │ ├── DeviceIdUtil.java │ │ │ ├── DeviceMacUtils.java │ │ │ ├── DrawableUtils.kt │ │ │ ├── Md5Utils.java │ │ │ ├── ReflectUtils.java │ │ │ ├── StringUtils.kt │ │ │ ├── TimeUtils.java │ │ │ ├── UpdateUtils.kt │ │ │ ├── exector │ │ │ ├── AppExecutors.java │ │ │ ├── CancelRunnable.java │ │ │ └── DiskIOThreadExecutor.java │ │ │ ├── file │ │ │ ├── DownLoadUtils.java │ │ │ └── FileUtil.java │ │ │ └── qr │ │ │ └── QrCodeUtil.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── txl │ └── commonlibrary │ ├── ExampleUnitTest.java │ └── ReflectTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── libversion.gradle ├── netModel ├── .gitignore ├── README.md ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── txl │ └── netmodel │ └── okhttp │ └── okhttp │ ├── OkHttpUtils.java │ ├── SSL.java │ ├── SSLSocketFactoryCompat.java │ ├── TLSSocketFactory.java │ ├── TestHttpsInAndroidApi19.java │ └── Tls12SocketFactory.java ├── router ├── .gitignore ├── ReadMe.md ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── txl │ │ └── basic │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── txl │ │ └── router │ │ └── web │ │ └── IWebRouter.kt │ └── test │ └── java │ └── com │ └── txl │ └── basic │ └── ExampleUnitTest.kt ├── settings.gradle ├── skin ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── txl │ │ └── skin │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── txl │ └── skin │ └── ExampleUnitTest.kt ├── testmoudle ├── .gitignore ├── testtvlib │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── txl │ │ │ └── testtvlib │ │ │ └── ExampleInstrumentedTest.kt │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── txl │ │ │ │ └── testtvlib │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── NavTestActivity.kt │ │ │ │ ├── TestGridLayoutManagerActivity.java │ │ │ │ ├── TestTvLibApplication.kt │ │ │ │ ├── basic │ │ │ │ └── adapter │ │ │ │ │ └── BaseVLayoutAdapter.java │ │ │ │ ├── cardframe │ │ │ │ └── draworder │ │ │ │ │ └── CardFrameDrawOrderActivity.kt │ │ │ │ ├── testborder │ │ │ │ ├── TestBorderActivity.kt │ │ │ │ ├── TestBorderViewActivity.kt │ │ │ │ └── TestFlyBorderActivity.kt │ │ │ │ └── testrecyclerview │ │ │ │ └── item │ │ │ │ └── center │ │ │ │ ├── TestRecyclerViewFocusCenterActivity.kt │ │ │ │ └── viewholder │ │ │ │ ├── ContentSureWidthViewHolder.kt │ │ │ │ ├── ContentViewHolder.kt │ │ │ │ ├── RecyclerViewHorizontalViewHolder.kt │ │ │ │ ├── RecyclerViewViewHolder.kt │ │ │ │ └── TitleViewHolder.kt │ │ └── res │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable-xxhdpi │ │ │ ├── kakaxi.png │ │ │ ├── vip_checked.png │ │ │ └── vip_normal.png │ │ │ ├── drawable │ │ │ ├── ic_launcher_background.xml │ │ │ ├── item_test_focus_bg.xml │ │ │ ├── item_test_recycler_center_title_text_color.xml │ │ │ ├── item_test_recycler_focus_bg.xml │ │ │ └── vip.xml │ │ │ ├── layout │ │ │ ├── activity_card_frame_draw_order.xml │ │ │ ├── activity_main.xml │ │ │ ├── activity_nav_test.xml │ │ │ ├── activity_test_border.xml │ │ │ ├── activity_test_border_view.xml │ │ │ ├── activity_test_fly_border.xml │ │ │ ├── activity_test_grid_layout_manager.xml │ │ │ ├── activity_test_recycler_view_focus_center.xml │ │ │ ├── item_decoration_text.xml │ │ │ ├── item_focuscenter.xml │ │ │ ├── item_grid_recycler_view.xml │ │ │ ├── item_image2_librecycler_radiogroup.xml │ │ │ ├── item_image_and_text.xml │ │ │ ├── item_image_librecycler_radiogroup.xml │ │ │ ├── item_sure_width_image_and_text.xml │ │ │ ├── item_test_librecycler_radiogroup.xml │ │ │ └── test_recycler_item_center_title.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── txl │ │ └── testtvlib │ │ └── ExampleUnitTest.kt └── testweblinkparse │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── txl │ │ └── testweblinkparse │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── txl │ │ │ └── testweblinkparse │ │ │ └── TestParseLinkActivity.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_test_parse_link.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── txl │ └── testweblinkparse │ └── ExampleUnitTest.kt ├── tvlib ├── .gitignore ├── ReadMe.md ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── txl │ │ │ └── tvlib │ │ │ ├── border │ │ │ ├── BorderPainter.java │ │ │ ├── BorderPainterOrigin.java │ │ │ ├── BorderViewPainter.java │ │ │ ├── DrawBorderFrameLayout.java │ │ │ ├── DrawBorderGridLayout.java │ │ │ ├── ICustomBorderView.java │ │ │ ├── ViewBoundHolder.java │ │ │ └── config │ │ │ │ └── BorderConfig.java │ │ │ ├── card │ │ │ ├── mode │ │ │ │ ├── BannerCard.kt │ │ │ │ ├── BaseCard.kt │ │ │ │ ├── ImageTextCard.kt │ │ │ │ └── TextCard.kt │ │ │ ├── presenter │ │ │ │ └── SupperPresenter.kt │ │ │ └── viewholder │ │ │ │ ├── BaseViewHolder.kt │ │ │ │ ├── IBaseViewHolder.java │ │ │ │ ├── ImageTextCardViewHolder.kt │ │ │ │ ├── TextCardViewHolder.kt │ │ │ │ └── ViewHolderFactory.kt │ │ │ ├── config │ │ │ └── TvLibConfig.kt │ │ │ ├── focushandler │ │ │ ├── FocusAnimator.java │ │ │ ├── IFocusHandler.java │ │ │ ├── IFocusSearchHelper.java │ │ │ ├── ViewFocusChangeListener.java │ │ │ └── ViewFocusHandler.java │ │ │ ├── utils │ │ │ ├── ViewExt.kt │ │ │ └── ViewFocusHelper.kt │ │ │ └── widget │ │ │ ├── BaseCustomCardView.java │ │ │ ├── BorderView.java │ │ │ ├── CardFrameLayout.java │ │ │ ├── FocusBorderView.java │ │ │ ├── FocusFixVerticalGridView.java │ │ │ ├── ICheckView.java │ │ │ ├── ITvView.java │ │ │ ├── ITvViewGroup.java │ │ │ ├── ModuleLayoutManager.java │ │ │ ├── RadioGroupHorizontalGridView.java │ │ │ ├── RadioGroupVerticalGridView.java │ │ │ ├── TvAttr.java │ │ │ ├── TvRecyclerView.java │ │ │ ├── ViewExt.kt │ │ │ ├── dynamic │ │ │ └── focus │ │ │ │ ├── DynamicLinearLayout.java │ │ │ │ ├── IDynamicFocusViewGroup.java │ │ │ │ ├── LibTvRecyclerView.java │ │ │ │ ├── LibTvRecyclerView2.java │ │ │ │ └── utils │ │ │ │ ├── DynamicFocusHelper.java │ │ │ │ └── IDynamicFocusHelper.java │ │ │ └── focus │ │ │ └── shake │ │ │ ├── IFocusShake.java │ │ │ └── ViewShakeAnimation.java │ └── res │ │ ├── drawable │ │ ├── b_menu_settled.xml │ │ ├── border.xml │ │ ├── color_text_checked.xml │ │ ├── select_border.9.png │ │ └── select_border_origin.9.png │ │ ├── layout │ │ ├── lib_image_text_card.xml │ │ └── lib_text_card.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── dimens.xml │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── txl │ └── tvlib │ └── ExampleUnitTest.java ├── txllog ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── txl │ │ └── txllog │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── txl │ │ │ └── txllog │ │ │ └── AndroidLogWrapper.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── txl │ └── txllog │ └── ExampleUnitTest.java ├── ui_basic ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── txl │ │ └── ui_basic │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── txl │ │ │ └── ui_basic │ │ │ ├── BaseActivity.java │ │ │ ├── adapter │ │ │ ├── BaseRecyclerAdapter.java │ │ │ ├── BaseRecyclerFactoryAdapter.java │ │ │ └── NavTypeSpec.java │ │ │ ├── fragment │ │ │ └── BaseFragment.kt │ │ │ ├── recyclerView │ │ │ └── RecycleViewDivider.java │ │ │ ├── utils │ │ │ ├── LoadingViewUtils.kt │ │ │ └── PopWindowUtils.kt │ │ │ ├── viewholder │ │ │ ├── BaseViewHolder.java │ │ │ └── IViewHolderFactory.java │ │ │ └── widget │ │ │ └── WebBrowse.java │ └── res │ │ ├── drawable-xxhdpi │ │ └── ui_basic_loading.png │ │ ├── drawable │ │ ├── ui_basic_anim.xml │ │ └── ui_basic_shape_dialog_bg.xml │ │ ├── layout │ │ ├── ui_basic_lib_loading.xml │ │ ├── ui_basic_lib_root_frame_layout.xml │ │ ├── ui_basic_pop_bgs.xml │ │ ├── ui_basic_pop_choice_bgs.xml │ │ ├── ui_basic_pop_loading_l.xml │ │ └── ui_basic_pop_wait_notice.xml │ │ └── values │ │ └── dimens.xml │ └── test │ └── java │ └── com │ └── txl │ └── ui_basic │ └── ExampleUnitTest.kt ├── wan_android_data_provider ├── .gitignore ├── README.md ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── txl │ │ └── wan_android_data_provider │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── txl │ │ └── wan_android_data_provider │ │ ├── bean │ │ ├── NavItemData.kt │ │ ├── com │ │ │ └── besjon │ │ │ │ └── pojo │ │ │ │ ├── Data.java │ │ │ │ ├── HomeArticleListData.java │ │ │ │ ├── NavigateArticleListData.java │ │ │ │ ├── NavigateCategoryData.java │ │ │ │ ├── ProjectClassifyItem.java │ │ │ │ └── setup │ │ │ │ ├── Children.java │ │ │ │ ├── JsonRootBean.java │ │ │ │ └── SetUpData.java │ │ ├── home │ │ │ ├── Article.java │ │ │ ├── BannerItemData.kt │ │ │ └── TopDataWrapper.kt │ │ └── user │ │ │ └── UserInfo.kt │ │ ├── data │ │ ├── DataDriven.kt │ │ ├── Error.kt │ │ ├── ErrorCode.kt │ │ └── Response.kt │ │ ├── utils │ │ └── WanAndroidNetInvokerUtils.kt │ │ └── viewModel │ │ ├── AbsNavItemListViewModel.kt │ │ ├── HomeNavItemListViewModel.java │ │ ├── IPageViewModel.kt │ │ ├── NavigateNavItemListViewModel.kt │ │ ├── ProjectNavItemListViewModel.kt │ │ ├── QANavItemListViewModel.kt │ │ ├── ResourceBoundary.kt │ │ ├── SetUpNavItemListViewModel.kt │ │ ├── SquareNavItemListViewModel.kt │ │ ├── ViewModelContainer.kt │ │ └── user │ │ └── UserViewModel.kt │ └── test │ └── java │ └── com │ └── txl │ └── wan_android_data_provider │ └── ExampleUnitTest.kt ├── wanandroid ├── .gitignore ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ └── com │ │ └── txl │ │ └── wanandroidtv │ │ ├── MainActivity.java │ │ ├── SplashActivity.kt │ │ ├── WanAndroidBaseActivity.java │ │ ├── WanAndroidTvApplication.java │ │ ├── ui │ │ ├── NavItemWidthUtils.kt │ │ ├── adpater │ │ │ ├── BaseVLayoutAdapter.java │ │ │ ├── ListAdapterFactory.kt │ │ │ ├── MainNavPageAdapter.java │ │ │ ├── NavRecyclerAdapter.java │ │ │ └── WanAndroidListItemType.java │ │ ├── fragment │ │ │ ├── BaseNavFragment.kt │ │ │ ├── HomeNavFragment.kt │ │ │ ├── NavFragmentCreateFactory.kt │ │ │ ├── NavigateNavFragment.kt │ │ │ ├── ProjectNavFragment.kt │ │ │ ├── SetUpNavFragment.kt │ │ │ └── SquareNavFragment.kt │ │ ├── user │ │ │ ├── LoginFragment.kt │ │ │ └── UserCenterActivity.kt │ │ ├── utils │ │ │ ├── PageJumpUtils.kt │ │ │ └── ThemeUtils.kt │ │ ├── viewholder │ │ │ ├── NavigateFlexBoxItemViewHolderFactory.kt │ │ │ ├── NvaItem.kt │ │ │ ├── WanAndroidBannerItemViewHolder.kt │ │ │ ├── WanAndroidCommonItemViewHolder.kt │ │ │ ├── WanAndroidListTitleViewHolder.kt │ │ │ ├── WanAndroidTopScrollerItemViewHolder.kt │ │ │ └── WanAndroidTopScrollerViewHolder.kt │ │ └── widget │ │ │ ├── DynamicFlexboxLayout.java │ │ │ ├── HomeGridDividerItemDecoration.kt │ │ │ ├── NavViewPager.java │ │ │ └── RatioImageView.java │ │ └── utils │ │ ├── RecyclerViewConfigUtils.kt │ │ └── Utils.java │ └── res │ ├── drawable-xhdpi │ └── user_icon.png │ ├── drawable │ ├── b_menu_settled.xml │ ├── bg_radius10.xml │ ├── color_text_checked.xml │ ├── ic_action_member.xml │ ├── ic_action_mine.xml │ ├── ic_action_search.xml │ ├── ic_launcher_background.xml │ ├── image_place_holder.xml │ ├── list_title_bg.xml │ ├── nav_item_bg.xml │ └── wan_android.9.png │ ├── layout │ ├── activity_main.xml │ ├── activity_splash.xml │ ├── activity_user_center.xml │ ├── card_nav_title_bg.xml │ ├── fragment_lib_nav_base.xml │ ├── fragment_login.xml │ ├── fragment_navigate_nav.xml │ ├── fragment_project_nav.xml │ ├── fragment_setup_nav.xml │ ├── item_home_banner.xml │ ├── item_home_common.xml │ ├── item_home_top.xml │ ├── item_navigate_left_nav.xml │ ├── item_navigate_right_flex_box_content.xml │ ├── item_navigate_right_flex_box_content_child_item.xml │ ├── item_title.xml │ ├── recycler_item_nav.xml │ ├── top_bar.xml │ └── top_bar1.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── navigation │ └── user_nav_graph.xml │ ├── raw │ ├── main_nav.json │ └── main_nav_all_save.json │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── web ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── txl │ │ └── web │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── txl │ │ │ └── web │ │ │ ├── WebApplication.kt │ │ │ ├── router │ │ │ └── WebRouterImpl.kt │ │ │ ├── ui │ │ │ └── WebActivity.kt │ │ │ ├── utils │ │ │ └── WebViewThirdAppJumpUtils.java │ │ │ └── widget │ │ │ └── WebBrowse.java │ └── res │ │ ├── layout │ │ └── web_activity_web.xml │ │ └── values │ │ ├── dimens.xml │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── txl │ └── web │ └── ExampleUnitTest.java └── webLinkParse ├── .gitignore ├── README.md ├── build.gradle ├── consumer-rules.pro ├── libs └── jsoup-1.11.3.jar ├── proguard-rules.pro └── src ├── androidTest └── java │ └── com │ └── txl │ └── weblinkparse │ └── ExampleInstrumentedTest.kt ├── main ├── AndroidManifest.xml └── java │ └── com │ └── txl │ └── weblinkparse │ └── WebLinkParse.java └── test └── java └── com └── txl └── weblinkparse └── ExampleUnitTest.kt /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | /.idea 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WanAndroidTv 2 | Tv 版WanAndroid客户端 3 | 4 | 使用的技术框架 5 | 6 | jetpack 7 | 8 | 组件化 9 | 10 | GSON 11 | 12 | 自定义Tv开发焦点处理框架 13 | 14 | 阿里 VLayout 15 | 16 | AutoSize 17 | 18 | LeakCanary 19 | 20 | BlockCanary 21 | 22 | 23 | 24 | 25 | 26 | 计划实现功能 27 | 28 | 1. 首页导航 29 | 2. 动态换肤 30 | 3. 个人中心 31 | 4. 特殊效果的banner 32 | 33 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | apply from: 'libversion.gradle' 3 | buildscript { 4 | ext.kotlin_version = '1.3.61' 5 | repositories { 6 | google() 7 | jcenter() 8 | 9 | } 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:3.5.2' 12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50" 13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 14 | classpath "io.github.prototypez:app-joint:1.7" 15 | // NOTE: Do not place your application dependencies here; they belong 16 | // in the individual module build.gradle files 17 | } 18 | } 19 | 20 | allprojects { 21 | repositories { 22 | google() 23 | jcenter() 24 | 25 | } 26 | } 27 | 28 | task clean(type: Delete) { 29 | delete rootProject.buildDir 30 | } 31 | -------------------------------------------------------------------------------- /commonlibrary/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /commonlibrary/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /commonlibrary/src/androidTest/java/com/txl/commonlibrary/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.txl.commonlibrary; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.runner.AndroidJUnit4; 7 | 8 | 9 | import org.junit.Test; 10 | import org.junit.runner.RunWith; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | /** 15 | * Instrumented test, which will execute on an Android device. 16 | * 17 | * @see Testing documentation 18 | */ 19 | @RunWith(AndroidJUnit4.class) 20 | public class ExampleInstrumentedTest { 21 | 22 | @Test 23 | public void useAppContext() { 24 | // Context of the app under test. 25 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 26 | 27 | assertEquals("com.example.commonlibrary", appContext.getPackageName()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /commonlibrary/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /commonlibrary/src/main/java/com/txl/commonlibrary/utils/AndroidKeyBoardUtils.kt: -------------------------------------------------------------------------------- 1 | package com.txl.commonlibrary.utils 2 | 3 | import android.content.Context 4 | import android.view.View 5 | import android.view.inputmethod.InputMethodManager 6 | 7 | object AndroidKeyBoardUtils { 8 | fun hideKeyBoard(currentFocus: View){ 9 | val imm: InputMethodManager = currentFocus.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager 10 | if(imm.isActive ){ 11 | //拿到view的token 不为空 12 | if (currentFocus.windowToken !=null) { 13 | //表示软键盘窗口总是隐藏,除非开始时以SHOW_FORCED显示。 14 | imm.hideSoftInputFromWindow(currentFocus.windowToken, 0) 15 | } 16 | } 17 | } 18 | 19 | fun showKeyBoard(currentFocus: View){ 20 | val imm: InputMethodManager = currentFocus.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager 21 | if(imm.isActive ){ 22 | imm.showSoftInput(currentFocus, 0) 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /commonlibrary/src/main/java/com/txl/commonlibrary/utils/AndroidLogWrapperUtil.java: -------------------------------------------------------------------------------- 1 | package com.txl.commonlibrary.utils; 2 | 3 | import android.util.Log; 4 | 5 | /** 6 | * 对需要调试的打印 进行全局的配置 7 | * */ 8 | public class AndroidLogWrapperUtil { 9 | /** 10 | * 开启调试打印 11 | * */ 12 | public static boolean DEBUG = true; 13 | 14 | public static void i(String tag,String message){ 15 | if(DEBUG){ 16 | Log.i(tag,message); 17 | } 18 | } 19 | 20 | public static void d(String tag,String message){ 21 | if(DEBUG){ 22 | Log.d(tag,message); 23 | } 24 | } 25 | 26 | /** 27 | * 错误信息直接打印 28 | * */ 29 | public static void e(String tag,String message){ 30 | Log.e(tag,message); 31 | } 32 | 33 | /** 34 | * 警告信息直接打印 35 | * */ 36 | public static void w(String tag,String message){ 37 | Log.w(tag,message); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /commonlibrary/src/main/java/com/txl/commonlibrary/utils/CloseableUtils.java: -------------------------------------------------------------------------------- 1 | package com.txl.commonlibrary.utils; 2 | 3 | import java.io.Closeable; 4 | import java.io.IOException; 5 | 6 | public class CloseableUtils { 7 | public static void close(Closeable closeable){ 8 | if(closeable != null){ 9 | try { 10 | closeable.close(); 11 | } catch (IOException e) { 12 | e.printStackTrace(); 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /commonlibrary/src/main/java/com/txl/commonlibrary/utils/ColorsUtils.java: -------------------------------------------------------------------------------- 1 | package com.txl.commonlibrary.utils; 2 | 3 | import android.content.res.ColorStateList; 4 | 5 | public class ColorsUtils { 6 | public static ColorStateList createColorStateList(int normalColor, int checkedColor, int focusedColor) { 7 | int[] colors = new int[] { focusedColor,checkedColor,normalColor}; 8 | int[][] states = new int[3][]; 9 | states[0] = new int[] { android.R.attr.state_focused }; 10 | states[1] = new int[] { android.R.attr.state_checked}; 11 | states[2] = new int[] { }; 12 | return new ColorStateList(states, colors); 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /commonlibrary/src/main/java/com/txl/commonlibrary/utils/Md5Utils.java: -------------------------------------------------------------------------------- 1 | package com.txl.commonlibrary.utils; 2 | 3 | import java.security.MessageDigest; 4 | 5 | public class Md5Utils { 6 | public static String MD5(String str) { 7 | MessageDigest md5 = null; 8 | try { 9 | md5 = MessageDigest.getInstance("MD5"); 10 | } catch (Exception e) { 11 | e.printStackTrace(); 12 | return ""; 13 | } 14 | 15 | char[] charArray = str.toCharArray(); 16 | byte[] byteArray = new byte[charArray.length]; 17 | 18 | for (int i = 0; i < charArray.length; i++) { 19 | byteArray[i] = (byte) charArray[i]; 20 | } 21 | byte[] md5Bytes = md5.digest(byteArray); 22 | 23 | StringBuilder hexValue = new StringBuilder(); 24 | for (int i = 0; i < md5Bytes.length; i++) { 25 | int val = ((int) md5Bytes[i]) & 0xff; 26 | if (val < 16) { 27 | hexValue.append("0"); 28 | } 29 | hexValue.append(Integer.toHexString(val)); 30 | } 31 | return hexValue.toString(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /commonlibrary/src/main/java/com/txl/commonlibrary/utils/StringUtils.kt: -------------------------------------------------------------------------------- 1 | package com.txl.commonlibrary.utils 2 | 3 | import android.text.TextUtils 4 | import java.util.regex.Matcher 5 | import java.util.regex.Pattern 6 | 7 | /** 8 | * Copyright (c) 2020 唐小陆 All rights reserved. 9 | * author:txl 10 | * date:2020/9/18 11 | * description: 12 | */ 13 | object StringUtils { 14 | fun isNetUrl(url:String?):Boolean{ 15 | if(TextUtils.isEmpty(url)){ 16 | return false; 17 | } 18 | val regUrl = "^([hH][tT]{2}[pP]://|[hH][tT]{2}[pP][sS]://)(([A-Za-z0-9-~]+).)+([A-Za-z0-9-~\\\\/])+$" 19 | val p: Pattern = Pattern.compile(regUrl) 20 | val m: Matcher = p.matcher(url) 21 | if (!m.matches()) { 22 | return false 23 | } 24 | return true; 25 | } 26 | } -------------------------------------------------------------------------------- /commonlibrary/src/main/java/com/txl/commonlibrary/utils/TimeUtils.java: -------------------------------------------------------------------------------- 1 | package com.txl.commonlibrary.utils; 2 | 3 | import java.util.Locale; 4 | 5 | /** 6 | * 时间转换工具 7 | * */ 8 | public class TimeUtils { 9 | /** 10 | * @param seconds 时间 单位为秒 11 | * @param needShowHour 返回格式是否包含小时 true 返回格式 00:00:00 ; false 返回格式 00:00 12 | * */ 13 | public static String convertTimeFormat(int seconds,boolean needShowHour) { 14 | if(seconds<0) 15 | seconds=0; 16 | // seconds = seconds/1000; 17 | int hh = seconds / 3600; 18 | int mm = seconds % 3600 / 60; 19 | int ss = seconds % 60; 20 | String strTemp = null; 21 | if (0 != hh||needShowHour) { 22 | strTemp = String.format(Locale.getDefault(),"%02d:%02d:%02d", hh, mm, ss); 23 | } 24 | else { 25 | strTemp = String.format(Locale.getDefault(),"%02d:%02d", mm, ss); 26 | } 27 | return strTemp; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /commonlibrary/src/main/java/com/txl/commonlibrary/utils/UpdateUtils.kt: -------------------------------------------------------------------------------- 1 | package com.txl.commonlibrary.utils 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.net.Uri 6 | import android.os.Build 7 | import androidx.core.content.FileProvider 8 | import java.io.File 9 | 10 | object UpdateUtils { 11 | fun installApk(context: Context, path: String) { 12 | val apkFile = File(path) 13 | val intent = Intent(Intent.ACTION_VIEW) 14 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 15 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 16 | intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) 17 | val contentUri = FileProvider.getUriForFile(context, "${context.packageName}.provider", apkFile) //中间参数为 provider 中的 authorities 18 | intent.setDataAndType(contentUri, "application/vnd.android.package-archive") 19 | } else { 20 | intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive") 21 | } 22 | context.startActivity(intent) 23 | } 24 | } -------------------------------------------------------------------------------- /commonlibrary/src/main/java/com/txl/commonlibrary/utils/exector/CancelRunnable.java: -------------------------------------------------------------------------------- 1 | package com.txl.commonlibrary.utils.exector; 2 | 3 | public abstract class CancelRunnable implements Runnable { 4 | 5 | 6 | public static CancelRunnable createCancelRunnable(CancelRunnable cancelRunnable){ 7 | CancelRunnable temp = cancelRunnable; 8 | if(cancelRunnable != null){ 9 | temp.setCancel(true); 10 | temp = null; 11 | } 12 | try { 13 | temp = cancelRunnable.getClass().newInstance(); 14 | } catch (IllegalAccessException e) { 15 | e.printStackTrace(); 16 | } catch (InstantiationException e) { 17 | e.printStackTrace(); 18 | } 19 | return temp; 20 | } 21 | 22 | private boolean cancel = false; 23 | 24 | public void setCancel(boolean cancel) { 25 | this.cancel = cancel; 26 | } 27 | 28 | @Override 29 | public void run() { 30 | if(cancel){ 31 | return; 32 | } 33 | realRun(); 34 | } 35 | 36 | protected abstract void realRun(); 37 | } 38 | -------------------------------------------------------------------------------- /commonlibrary/src/main/java/com/txl/commonlibrary/utils/exector/DiskIOThreadExecutor.java: -------------------------------------------------------------------------------- 1 | package com.txl.commonlibrary.utils.exector; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import java.util.concurrent.Executor; 6 | import java.util.concurrent.Executors; 7 | 8 | public class DiskIOThreadExecutor implements Executor{ 9 | private final Executor mDiskIO; 10 | 11 | public DiskIOThreadExecutor() { 12 | mDiskIO = Executors.newSingleThreadExecutor(); 13 | } 14 | 15 | @Override 16 | public void execute(@NonNull Runnable command) { 17 | mDiskIO.execute(command); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /commonlibrary/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /commonlibrary/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /commonlibrary/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/commonlibrary/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /commonlibrary/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/commonlibrary/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /commonlibrary/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/commonlibrary/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /commonlibrary/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/commonlibrary/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /commonlibrary/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/commonlibrary/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /commonlibrary/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/commonlibrary/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /commonlibrary/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/commonlibrary/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /commonlibrary/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/commonlibrary/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /commonlibrary/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/commonlibrary/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /commonlibrary/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/commonlibrary/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /commonlibrary/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /commonlibrary/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | commonLibrary 3 | 4 | -------------------------------------------------------------------------------- /commonlibrary/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /commonlibrary/src/test/java/com/txl/commonlibrary/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.txl.commonlibrary; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | 21 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Nov 12 08:19:30 CST 2019 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-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /libversion.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | minVersion = 19 //APP最小支持版本 3 | compileVersion = 28 //编译时版本 4 | targetVersion = 28 //目标版本 5 | buildVersion = "29.0.0" //构建版本 6 | appcompat = '1.0.0' 7 | google_material = "1.0.0" 8 | 9 | support_v4 = '1.0.0-alpha1' 10 | junit = "4.12" 11 | test_runner = "1.0.2" 12 | espresso_core = "3.0.2" 13 | 14 | okhttp = "3.12.0" 15 | kotlinx_coroutines_android = "1.3.0-M1" 16 | 17 | gson = "2.8.5" 18 | glide = "4.9.0" 19 | 20 | work_version = "2.0.1" 21 | anko_version = '0.10.8' 22 | 23 | paging_version = "2.1.0" 24 | constraintlayout = "1.1.3" 25 | 26 | nav_version_ktx = "2.0.0" 27 | kotlinx_coroutines = "1.0.1" 28 | lifecycle_version = "2.0.0" 29 | constraintlayout = "1.1.3" 30 | anko_version = '0.10.8' 31 | 32 | hdodenhof_circleimageview="2.2.0"//圆形图片 33 | app_joint = "1.7" 34 | mmkv = "1.0.22" 35 | 36 | } -------------------------------------------------------------------------------- /netModel/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /netModel/README.md: -------------------------------------------------------------------------------- 1 | 将网络请求封装成一个独立的组件,供其它的模块使用。 2 | 同时为组件化做准备 3 | 4 | -------------------------------------------------------------------------------- /netModel/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | apply plugin: 'kotlin-kapt' 5 | 6 | android { 7 | compileSdkVersion compileVersion 8 | buildToolsVersion buildVersion 9 | 10 | 11 | defaultConfig { 12 | minSdkVersion minVersion 13 | targetSdkVersion targetVersion 14 | versionCode 1 15 | versionName "1.0" 16 | 17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 18 | } 19 | 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | compileOptions { 27 | sourceCompatibility = 1.8 28 | targetCompatibility = 1.8 29 | } 30 | 31 | } 32 | 33 | dependencies { 34 | implementation fileTree(dir: 'libs', include: ['*.jar']) 35 | api "com.squareup.okhttp3:okhttp:4.4.0" 36 | } 37 | 38 | sourceCompatibility = "7" 39 | targetCompatibility = "7" 40 | -------------------------------------------------------------------------------- /netModel/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /router/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /router/ReadMe.md: -------------------------------------------------------------------------------- 1 | 其余组件依赖的基础模块 -------------------------------------------------------------------------------- /router/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 29 7 | buildToolsVersion "29.0.3" 8 | 9 | defaultConfig { 10 | minSdkVersion 16 11 | targetSdkVersion 29 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | consumerProguardFiles 'consumer-rules.pro' 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(dir: 'libs', include: ['*.jar']) 30 | implementation 'androidx.appcompat:appcompat:1.1.0' 31 | implementation 'androidx.core:core-ktx:1.2.0' 32 | testImplementation 'junit:junit:4.12' 33 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 34 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 35 | api 'androidx.lifecycle:lifecycle-extensions:2.2.0' 36 | api project(path: ':txllog') 37 | api project(path: ':netModel') 38 | api project(path: ':ui_basic') 39 | } 40 | -------------------------------------------------------------------------------- /router/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/router/consumer-rules.pro -------------------------------------------------------------------------------- /router/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /router/src/androidTest/java/com/txl/basic/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.basic 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.txl.basic.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /router/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /router/src/main/java/com/txl/router/web/IWebRouter.kt: -------------------------------------------------------------------------------- 1 | package com.txl.router.web 2 | 3 | import android.content.Context 4 | 5 | /** 6 | * Copyright (c) 2020 唐小陆 All rights reserved. 7 | * author:txl 8 | * date:2020/3/25 9 | * description:web模块对外提供的接口 10 | */ 11 | interface IWebRouter { 12 | /** 13 | * @param title 网页标题 14 | * @param url 网页链接 15 | * */ 16 | fun openWebPage(context: Context,title:String,url: String) 17 | } -------------------------------------------------------------------------------- /router/src/test/java/com/txl/basic/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.basic 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':testmoudle:testweblinkparse' 2 | include ':wan_android_data_provider' 3 | include ':webLinkParse' 4 | include ':testmoudle:testtvlib' 5 | include ':testmoudle' 6 | include ':wanandroid', ':tvlib', ':commonlibrary', ':skin', ':netModel', ':txllog' 7 | rootProject.name='WanAndroidTv' 8 | include ':router' 9 | include ':web' 10 | include ':ui_basic' 11 | -------------------------------------------------------------------------------- /skin/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /skin/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | 4 | apply plugin: 'kotlin-android-extensions' 5 | 6 | apply plugin: 'kotlin-kapt' 7 | android { 8 | compileSdkVersion compileVersion 9 | buildToolsVersion buildVersion 10 | 11 | 12 | defaultConfig { 13 | minSdkVersion minVersion 14 | targetSdkVersion targetVersion 15 | versionCode 1 16 | versionName "1.0" 17 | 18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 25 | } 26 | } 27 | 28 | } 29 | 30 | dependencies { 31 | implementation fileTree(dir: 'libs', include: ['*.jar']) 32 | implementation 'androidx.appcompat:appcompat:1.1.0' 33 | implementation 'androidx.core:core-ktx:1.2.0' 34 | testImplementation 'junit:junit:4.12' 35 | androidTestImplementation 'androidx.test:runner:1.2.0' 36 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 37 | api 'skin.support:skin-support:4.0.4' 38 | } 39 | -------------------------------------------------------------------------------- /skin/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /skin/src/androidTest/java/com/txl/skin/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.skin 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.txl.skin", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /skin/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /skin/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /skin/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /skin/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/skin/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /skin/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/skin/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /skin/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/skin/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /skin/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/skin/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /skin/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/skin/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /skin/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/skin/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /skin/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/skin/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /skin/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/skin/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /skin/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/skin/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /skin/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/skin/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /skin/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /skin/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | skin 3 | 4 | -------------------------------------------------------------------------------- /skin/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /skin/src/test/java/com/txl/skin/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.skin 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /testmoudle/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /testmoudle/testtvlib/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /testmoudle/testtvlib/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 28 7 | buildToolsVersion "30.0.0" 8 | 9 | defaultConfig { 10 | applicationId "com.txl.testtvlib" 11 | minSdkVersion 19 12 | targetSdkVersion 28 13 | versionCode 1 14 | versionName "1.0" 15 | multiDexEnabled true 16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | compileOptions { 26 | sourceCompatibility 1.8 27 | targetCompatibility 1.8 28 | } 29 | } 30 | 31 | dependencies { 32 | implementation fileTree(dir: "libs", include: ["*.jar"]) 33 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 34 | implementation 'androidx.core:core-ktx:1.3.1' 35 | implementation 'androidx.appcompat:appcompat:1.2.0' 36 | implementation 'androidx.constraintlayout:constraintlayout:2.0.1' 37 | testImplementation 'junit:junit:4.12' 38 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 39 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' 40 | implementation project(path: ':tvlib') 41 | implementation project(path: ':router') 42 | implementation 'com.android.support:multidex:1.0.3' 43 | } 44 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/androidTest/java/com/txl/testtvlib/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testtvlib 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.txl.testtvlib", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/java/com/txl/testtvlib/TestTvLibApplication.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testtvlib 2 | 3 | import android.graphics.Color 4 | import androidx.multidex.MultiDexApplication 5 | import com.txl.tvlib.config.TvLibConfig 6 | 7 | /** 8 | * Copyright (c) 2020 唐小陆 All rights reserved. 9 | * author:txl 10 | * date:2020/9/2 11 | * description: 12 | */ 13 | class TestTvLibApplication: MultiDexApplication() { 14 | override fun onCreate() { 15 | super.onCreate() 16 | TvLibConfig.defaultConfig = TvLibConfig.Builder() 17 | .setHasSelectBorder(true) 18 | .setBorderWidth(resources.getDimensionPixelSize(R.dimen.dp_5)) 19 | .setBorderColor(Color.RED) 20 | .build() 21 | } 22 | } -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/java/com/txl/testtvlib/cardframe/draworder/CardFrameDrawOrderActivity.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testtvlib.cardframe.draworder 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import android.os.Bundle 5 | import com.txl.testtvlib.R 6 | 7 | class CardFrameDrawOrderActivity : AppCompatActivity() { 8 | override fun onCreate(savedInstanceState: Bundle?) { 9 | super.onCreate(savedInstanceState) 10 | setContentView(R.layout.activity_card_frame_draw_order) 11 | } 12 | } -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/java/com/txl/testtvlib/testborder/TestBorderActivity.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testtvlib.testborder 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import android.os.Bundle 5 | import com.txl.testtvlib.R 6 | 7 | class TestBorderActivity : AppCompatActivity() { 8 | override fun onCreate(savedInstanceState: Bundle?) { 9 | super.onCreate(savedInstanceState) 10 | setContentView(R.layout.activity_test_border) 11 | } 12 | } -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/java/com/txl/testtvlib/testborder/TestBorderViewActivity.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testtvlib.testborder 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import android.os.Bundle 5 | import android.util.Log 6 | import androidx.core.content.ContextCompat 7 | import com.txl.testtvlib.R 8 | import kotlinx.android.synthetic.main.activity_test_border_view.* 9 | 10 | class TestBorderViewActivity : AppCompatActivity() { 11 | override fun onCreate(savedInstanceState: Bundle?) { 12 | super.onCreate(savedInstanceState) 13 | setContentView(R.layout.activity_test_border_view) 14 | border_02.setBorderDrawable(ContextCompat.getDrawable(this,R.drawable.border)) 15 | border_02.setOutBound(30) 16 | border_03.postDelayed({ 17 | Log.d("BorderView","请求焦点"+ border_03.requestFocus() +" 焦点变化 "+border_03.isFocused) 18 | },500) 19 | } 20 | } -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/java/com/txl/testtvlib/testborder/TestFlyBorderActivity.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testtvlib.testborder 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import android.os.Bundle 5 | import com.txl.testtvlib.R 6 | 7 | /** 8 | * 飞框 9 | * */ 10 | class TestFlyBorderActivity : AppCompatActivity() { 11 | override fun onCreate(savedInstanceState: Bundle?) { 12 | super.onCreate(savedInstanceState) 13 | setContentView(R.layout.activity_test_fly_border) 14 | } 15 | } -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/java/com/txl/testtvlib/testrecyclerview/item/center/viewholder/ContentSureWidthViewHolder.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testtvlib.testrecyclerview.item.center.viewholder 2 | 3 | import android.view.LayoutInflater 4 | import android.view.View 5 | import android.view.ViewGroup 6 | import android.widget.TextView 7 | import com.txl.testtvlib.R 8 | import com.txl.ui_basic.viewholder.BaseViewHolder 9 | 10 | /** 11 | * Copyright (c) 2020 唐小陆 All rights reserved. 12 | * author:txl 13 | * date:2020/9/4 14 | * description: 15 | */ 16 | class ContentSureWidthViewHolder(itemView:View):BaseViewHolder(itemView) { 17 | companion object{ 18 | fun onCreateViewHolder(parent: ViewGroup): ContentSureWidthViewHolder{ 19 | return ContentSureWidthViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_sure_width_image_and_text,parent,false)) 20 | } 21 | } 22 | 23 | 24 | override fun onBindViewHolder(position: Int, data: T) { 25 | super.onBindViewHolder(position, data) 26 | itemView.findViewById(R.id.tv_text_item).text = "第${position}个元素" 27 | } 28 | } -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/java/com/txl/testtvlib/testrecyclerview/item/center/viewholder/ContentViewHolder.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testtvlib.testrecyclerview.item.center.viewholder 2 | 3 | import android.view.LayoutInflater 4 | import android.view.View 5 | import android.view.ViewGroup 6 | import android.widget.TextView 7 | import com.txl.testtvlib.R 8 | import com.txl.ui_basic.viewholder.BaseViewHolder 9 | 10 | /** 11 | * Copyright (c) 2020 唐小陆 All rights reserved. 12 | * author:txl 13 | * date:2020/9/4 14 | * description: 15 | */ 16 | class ContentViewHolder(itemView:View):BaseViewHolder(itemView) { 17 | companion object{ 18 | fun onCreateViewHolder(parent: ViewGroup): ContentViewHolder{ 19 | return ContentViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_image_and_text,parent,false)) 20 | } 21 | } 22 | 23 | 24 | override fun onBindViewHolder(position: Int, data: T) { 25 | super.onBindViewHolder(position, data) 26 | itemView.findViewById(R.id.tv_text_item).text = "第${position}个" 27 | } 28 | } -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/java/com/txl/testtvlib/testrecyclerview/item/center/viewholder/TitleViewHolder.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testtvlib.testrecyclerview.item.center.viewholder 2 | 3 | import android.view.LayoutInflater 4 | import android.view.View 5 | import android.view.ViewGroup 6 | import android.widget.RadioButton 7 | import com.txl.testtvlib.R 8 | import com.txl.ui_basic.viewholder.BaseViewHolder 9 | 10 | /** 11 | * Copyright (c) 2020 唐小陆 All rights reserved. 12 | * author:txl 13 | * date:2020/9/3 14 | * description: 15 | */ 16 | class TitleViewHolder(itemView:View):BaseViewHolder(itemView) { 17 | companion object{ 18 | fun onCreateViewHolder(parent: ViewGroup): TitleViewHolder{ 19 | return TitleViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.test_recycler_item_center_title,parent,false)) 20 | } 21 | } 22 | 23 | override fun onBindViewHolder(position: Int, data: T) { 24 | super.onBindViewHolder(position, data) 25 | if(data is String){ 26 | itemView.findViewById(R.id.rb_title).text = data 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/drawable-xxhdpi/kakaxi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/drawable-xxhdpi/kakaxi.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/drawable-xxhdpi/vip_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/drawable-xxhdpi/vip_checked.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/drawable-xxhdpi/vip_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/drawable-xxhdpi/vip_normal.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/drawable/item_test_focus_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/drawable/item_test_recycler_center_title_text_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/drawable/item_test_recycler_focus_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/drawable/vip.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/activity_card_frame_draw_order.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/activity_test_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 | 25 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/activity_test_fly_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 23 | 24 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/activity_test_grid_layout_manager.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/activity_test_recycler_view_focus_center.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 18 | 29 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/item_decoration_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/item_focuscenter.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 14 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/item_grid_recycler_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 14 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/item_image2_librecycler_radiogroup.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 19 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/item_image_and_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 12 | 18 | 22 | 23 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/item_image_librecycler_radiogroup.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 22 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/item_sure_width_image_and_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 12 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/item_test_librecycler_radiogroup.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 19 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/layout/test_recycler_item_center_title.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 20 | 21 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testtvlib/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | #3303DAC5 7 | #ffffff 8 | #ff0000 9 | #ff000000 10 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 30dp 4 | 20dp 5 | 15dp 6 | 15sp 7 | 100dp 8 | 12sp 9 | 80dp 10 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | testTvlib 3 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /testmoudle/testtvlib/src/test/java/com/txl/testtvlib/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testtvlib 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 30 7 | buildToolsVersion "30.0.0" 8 | 9 | defaultConfig { 10 | applicationId "com.txl.testweblinkparse" 11 | minSdkVersion 19 12 | targetSdkVersion 30 13 | versionCode 1 14 | versionName "1.0" 15 | 16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | } 26 | 27 | dependencies { 28 | implementation fileTree(dir: "libs", include: ["*.jar"]) 29 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 30 | implementation 'androidx.core:core-ktx:1.3.1' 31 | implementation 'androidx.appcompat:appcompat:1.2.0' 32 | implementation 'androidx.constraintlayout:constraintlayout:2.0.1' 33 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0" 34 | testImplementation 'junit:junit:4.12' 35 | androidTestImplementation 'androidx.test.ext:junit:1.1.2' 36 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' 37 | implementation project(path: ':webLinkParse') 38 | } 39 | -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/androidTest/java/com/txl/testweblinkparse/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testweblinkparse 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.txl.testweblinkparse", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/java/com/txl/testweblinkparse/TestParseLinkActivity.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testweblinkparse 2 | 3 | import android.app.Activity 4 | import android.os.Bundle 5 | import android.util.Log 6 | import com.txl.weblinkparse.WebLinkParse 7 | import kotlinx.android.synthetic.main.activity_test_parse_link.* 8 | import kotlinx.coroutines.GlobalScope 9 | import kotlinx.coroutines.launch 10 | 11 | class TestParseLinkActivity : Activity() { 12 | 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | setContentView(R.layout.activity_test_parse_link) 16 | tv_test.setOnClickListener { 17 | Log.d("TestParseLinkActivity","WebLinkParse click test") 18 | GlobalScope.launch { 19 | Log.d("TestParseLinkActivity","WebLinkParse suit url start") 20 | WebLinkParse.isSuitImagePath("https://blog.csdn.net/summerrse/article/details/108491905", 21 | "https://img-blog.csdnimg.cn/20200909161743229.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N1bW1lcnJzZQ==,size_16,color_FFFFFF,t_70#pic_center") 22 | Log.d("TestParseLinkActivity","WebLinkParse suit url finish") 23 | WebLinkParse.getMaxImgAddress("https://blog.csdn.net/summerrse/article/details/108491905") 24 | } 25 | 26 | } 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/layout/activity_test_parse_link.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testweblinkparse/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testweblinkparse/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testweblinkparse/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testweblinkparse/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testweblinkparse/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testweblinkparse/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testweblinkparse/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testweblinkparse/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testweblinkparse/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/testmoudle/testweblinkparse/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | testWebLinkParse 3 | -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /testmoudle/testweblinkparse/src/test/java/com/txl/testweblinkparse/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.testweblinkparse 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /tvlib/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /tvlib/ReadMe.md: -------------------------------------------------------------------------------- 1 | #模块说明 2 | 3 | 定义tv开发中一些常见通用逻辑 -------------------------------------------------------------------------------- /tvlib/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | 4 | apply plugin: 'kotlin-android-extensions' 5 | 6 | apply plugin: 'kotlin-kapt' 7 | 8 | android { 9 | compileSdkVersion compileVersion 10 | buildToolsVersion buildVersion 11 | 12 | 13 | defaultConfig { 14 | minSdkVersion minVersion 15 | targetSdkVersion targetVersion 16 | versionCode 1 17 | versionName "1.0" 18 | 19 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 20 | consumerProguardFiles 'consumer-rules.pro' 21 | } 22 | 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | 30 | } 31 | 32 | dependencies { 33 | implementation fileTree(dir: 'libs', include: ['*.jar']) 34 | 35 | implementation 'androidx.appcompat:appcompat:1.1.0' 36 | testImplementation 'junit:junit:4.12' 37 | androidTestImplementation 'androidx.test:runner:1.2.0' 38 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 39 | api "androidx.leanback:leanback:$appcompat" 40 | implementation project(path: ':commonlibrary') 41 | api ('com.alibaba.android:vlayout:1.2.8@aar') { 42 | transitive = true 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tvlib/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/tvlib/consumer-rules.pro -------------------------------------------------------------------------------- /tvlib/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /tvlib/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/border/DrawBorderGridLayout.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.border; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.util.AttributeSet; 6 | import android.view.View; 7 | import android.widget.GridLayout; 8 | 9 | import com.txl.tvlib.R; 10 | 11 | /** 12 | * Created by liutao on 12/16/15. 13 | */ 14 | public class DrawBorderGridLayout extends GridLayout implements View.OnFocusChangeListener { 15 | 16 | private BorderPainter mBorderPainter; 17 | 18 | public DrawBorderGridLayout(Context context) { 19 | super(context); 20 | } 21 | 22 | public DrawBorderGridLayout(Context context, AttributeSet attrs) { 23 | super(context, attrs); 24 | mBorderPainter = new BorderPainter(this, R.drawable.select_border); 25 | } 26 | 27 | @Override 28 | protected void onMeasure(int widthSpec, int heightSpec) { 29 | super.onMeasure(widthSpec, heightSpec); 30 | for (int i = 0; i < getChildCount(); i++) { 31 | getChildAt(i).setOnFocusChangeListener(this); 32 | } 33 | } 34 | 35 | @Override 36 | protected void dispatchDraw(Canvas canvas) { 37 | super.dispatchDraw(canvas); 38 | mBorderPainter.draw(canvas); 39 | } 40 | 41 | @Override 42 | public void onFocusChange(View v, boolean hasFocus) { 43 | if (hasFocus) { 44 | mBorderPainter.setView(v); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/border/ICustomBorderView.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.border; 2 | 3 | /** 4 | * Copyright (c) 2020 唐小陆 All rights reserved. 5 | * author:txl 6 | * date:2020/9/13 7 | * description: 8 | */ 9 | public interface ICustomBorderView { 10 | /** 11 | * 是否自己绘制焦点,返回true 全局的焦点border不会被绘制 12 | * */ 13 | boolean drawBorderBySelf(); 14 | 15 | /** 16 | * 是否需要飞框的移动效果,如果 {@link #drawBorderBySelf} 返回true,并且 drawFlyBorder 返回true 17 | * 会额外的绘制边框的移动效果 18 | * */ 19 | boolean drawFlyBorder(); 20 | 21 | /** 22 | * 返回小于0的的值表示不自己进行独立设置,返回大于0的值才可以 23 | * 格式 1.1 表示 x,y方向都进行1.1倍缩放 24 | * 格式 1.1,1.2 表示x方向进行1.1倍缩放;y 方向上进行1.2倍缩放 25 | * */ 26 | String focusScale(); 27 | 28 | /** 29 | * 是否拥有焦点变化的缩放 animation 30 | * */ 31 | boolean hasFocusAnimation(); 32 | } 33 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/border/ViewBoundHolder.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.border; 2 | 3 | /** 4 | * Created by liutao on 12/16/15. 5 | */ 6 | public class ViewBoundHolder { 7 | private int mLeft; 8 | private int mTop; 9 | private int mWidth; 10 | private int mHeight; 11 | 12 | public int getLeft() { 13 | return mLeft; 14 | } 15 | 16 | public void setLeft(int left) { 17 | mLeft = left; 18 | } 19 | 20 | public int getTop() { 21 | return mTop; 22 | } 23 | 24 | public void setTop(int top) { 25 | mTop = top; 26 | } 27 | 28 | public int getWidth() { 29 | return mWidth; 30 | } 31 | 32 | public void setWidth(int width) { 33 | mWidth = width; 34 | } 35 | 36 | public int getHeight() { 37 | return mHeight; 38 | } 39 | 40 | public void setHeight(int height) { 41 | mHeight = height; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/border/config/BorderConfig.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.border.config; 2 | 3 | import android.graphics.drawable.Drawable; 4 | 5 | /** 6 | * Copyright (c) 2020 唐小陆 All rights reserved. 7 | * author:txl 8 | * date:2020/9/13 9 | * description: 10 | */ 11 | public class BorderConfig { 12 | private Drawable drawable; 13 | 14 | public class BorderConfigBuilder{ 15 | private Drawable borderDrawable; 16 | 17 | public BorderConfigBuilder setViewDefaultDrawable(Drawable defaultDrawable){ 18 | borderDrawable = defaultDrawable; 19 | return this; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/card/mode/BannerCard.kt: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.card.mode 2 | 3 | /** 4 | * 轮播图 5 | * */ 6 | const val TYPE_BANNER = 2 7 | class BannerCard(var titles:ArrayList,var images:ArrayList,date: Any) : BaseCard(TYPE_BANNER, date) { 8 | override fun getCardType(): Int { 9 | return TYPE_BANNER 10 | } 11 | 12 | override fun getCardName(): String { 13 | return BannerCard::class.java.simpleName 14 | } 15 | } -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/card/mode/BaseCard.kt: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.card.mode 2 | 3 | import android.text.TextUtils 4 | import android.util.SparseArray 5 | import java.lang.RuntimeException 6 | 7 | /** 8 | * 文字 9 | * */ 10 | const val TYPE_TEXT = 0 11 | /** 12 | * 图片文字 13 | * */ 14 | const val TYPE_IMAGE_TEXT = 1 15 | 16 | private val arrayTypes = SparseArray() 17 | 18 | /** 19 | * 为了防止type冲突,每次试下card就自己添加注册一次,需要保证每一个card的name是不同的 20 | * */ 21 | fun registerType(key:Int, name:String){ 22 | if(TextUtils.isEmpty(name)){ 23 | throw RuntimeException("not support empty name") 24 | } 25 | if(arrayTypes.get(key) != null && name != arrayTypes.get(key)){ 26 | throw RuntimeException("has register the type key :: $key last type name is ${arrayTypes.get(key)}") 27 | } 28 | arrayTypes.put(key,name) 29 | } 30 | 31 | abstract class BaseCard(val type:Int= TYPE_TEXT, 32 | var date:Any?) { 33 | init { 34 | registerType(getCardType(),getCardName()) 35 | } 36 | 37 | abstract fun getCardType():Int 38 | abstract fun getCardName():String 39 | } -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/card/mode/ImageTextCard.kt: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.card.mode 2 | 3 | class ImageTextCard(var imageUrl:String?,var title:String?, date: Any?) : BaseCard(TYPE_IMAGE_TEXT, date) { 4 | override fun getCardName(): String { 5 | return ImageTextCard::class.java.simpleName 6 | } 7 | 8 | override fun getCardType(): Int { 9 | return TYPE_IMAGE_TEXT 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/card/mode/TextCard.kt: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.card.mode 2 | 3 | /** 4 | * 纯文本 5 | * */ 6 | class TextCard(var title:String?, date: Any?) : BaseCard(TYPE_TEXT, date) { 7 | override fun getCardType(): Int { 8 | return TYPE_TEXT 9 | } 10 | 11 | override fun getCardName(): String { 12 | return TextCard::class.java.simpleName 13 | } 14 | } -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/card/viewholder/BaseViewHolder.kt: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.card.viewholder 2 | 3 | import android.view.View 4 | import androidx.leanback.widget.Presenter 5 | 6 | abstract class BaseViewHolder(view: View) : Presenter.ViewHolder(view), 7 | IBaseViewHolder { 8 | } -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/card/viewholder/IBaseViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.card.viewholder; 2 | 3 | import androidx.leanback.widget.Presenter; 4 | 5 | public interface IBaseViewHolder { 6 | void onBindViewHolder(Presenter.ViewHolder viewHolder, Object data); 7 | void onUnbindViewHolder(Presenter.ViewHolder viewHolder); 8 | } 9 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/card/viewholder/ImageTextCardViewHolder.kt: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.card.viewholder 2 | 3 | import android.view.LayoutInflater 4 | import android.view.View 5 | import android.view.ViewGroup 6 | import android.widget.ImageView 7 | import android.widget.TextView 8 | import androidx.leanback.widget.Presenter 9 | import com.bumptech.glide.Glide 10 | import com.txl.tvlib.R 11 | import com.txl.tvlib.card.mode.ImageTextCard 12 | import com.txl.tvlib.widget.BaseCustomCardView 13 | 14 | open class ImageTextCardViewHolder(view: View) : BaseViewHolder(view) { 15 | companion object{ 16 | fun createViewHolder(parent: ViewGroup):ImageTextCardViewHolder{ 17 | val root = LayoutInflater.from(parent.context).inflate(R.layout.lib_image_text_card,parent,false) 18 | return ImageTextCardViewHolder(root) 19 | } 20 | } 21 | 22 | val tvTitle: TextView = view.findViewById(R.id.tv_image_text_card_title) 23 | val image:ImageView = view.findViewById(R.id.image_image_text_card_logo) 24 | val customCardView: BaseCustomCardView = view.findViewById(R.id.image_text_card_root) 25 | 26 | override fun onBindViewHolder(viewHolder: Presenter.ViewHolder?, data: Any?) { 27 | if(data is ImageTextCard){ 28 | tvTitle.text = data.title 29 | Glide.with(customCardView).load(data.imageUrl).into(image) 30 | } 31 | } 32 | 33 | override fun onUnbindViewHolder(viewHolder: Presenter.ViewHolder?) { 34 | 35 | } 36 | } -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/card/viewholder/TextCardViewHolder.kt: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.card.viewholder 2 | 3 | import android.view.LayoutInflater 4 | import android.view.View 5 | import android.view.ViewGroup 6 | import android.widget.TextView 7 | import androidx.leanback.widget.Presenter 8 | import com.txl.tvlib.R 9 | import com.txl.tvlib.card.mode.TextCard 10 | import com.txl.tvlib.widget.BaseCustomCardView 11 | 12 | open class TextCardViewHolder(view: View) : BaseViewHolder(view) { 13 | val tvTitle: TextView = view.findViewById(R.id.tv_text_card_title) 14 | val customCardView: BaseCustomCardView = view.findViewById(R.id.root_text_card) 15 | 16 | companion object{ 17 | fun createViewHolder(parent: ViewGroup):TextCardViewHolder{ 18 | val root = LayoutInflater.from(parent.context).inflate(R.layout.lib_text_card,parent,false) 19 | return TextCardViewHolder(root) 20 | } 21 | } 22 | override fun onBindViewHolder(viewHolder: Presenter.ViewHolder?, data: Any?) { 23 | //RecyclerView重用 ViewHolder的时候会将选中状态一起重用 下面的代码简单处理ViewHolder的重用问题,可能还会有bug 。 24 | // 考虑能不能通过RecyclerView的重用池相关的来处理 25 | customCardView.isSelected = false 26 | customCardView.isChecked = false 27 | 28 | if(data is TextCard){ 29 | tvTitle.text = data.title 30 | } 31 | } 32 | 33 | override fun onUnbindViewHolder(viewHolder: Presenter.ViewHolder?) { 34 | 35 | } 36 | } -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/card/viewholder/ViewHolderFactory.kt: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.card.viewholder 2 | 3 | import android.view.ViewGroup 4 | 5 | interface ViewHolderFactory { 6 | fun createViewHolder(parent: ViewGroup):BaseViewHolder 7 | } -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/focushandler/IFocusHandler.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.focushandler; 2 | 3 | import android.view.View; 4 | 5 | public interface IFocusHandler { 6 | /** 7 | * Called when an item gains or loses focus. 8 | * 9 | * @param view The view whose focus is changing. 10 | * @param hasFocus True if focus is gained; false otherwise. 11 | */ 12 | void onItemFocused(View view, boolean hasFocus); 13 | 14 | /** 15 | * Called when the view is being created. 16 | */ 17 | void onInitializeView(View view); 18 | } 19 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/focushandler/IFocusSearchHelper.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.focushandler; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * 辅助LibTvRecyclerView的焦点查找 7 | * */ 8 | public interface IFocusSearchHelper { 9 | View findFirstFocusAbleView(); 10 | View findLastFocusAbleView(); 11 | } 12 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/focushandler/ViewFocusChangeListener.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.focushandler; 2 | 3 | import android.view.View; 4 | 5 | public class ViewFocusChangeListener implements View.OnFocusChangeListener { 6 | /** 7 | * 默认获取焦点的时候缩放1.1倍 8 | * */ 9 | private float focusScale; 10 | 11 | private View.OnFocusChangeListener _chainedListener; 12 | private IFocusHandler _focusHandler; 13 | 14 | public ViewFocusChangeListener(View targetView) { 15 | this(targetView,1.1f); 16 | } 17 | 18 | public ViewFocusChangeListener(View targetView,float focusScale) { 19 | this.focusScale = focusScale; 20 | _chainedListener = targetView.getOnFocusChangeListener(); 21 | _focusHandler = new ViewFocusHandler(focusScale,false); 22 | _focusHandler.onInitializeView(targetView); 23 | targetView.setOnFocusChangeListener(this); 24 | } 25 | 26 | @Override 27 | public void onFocusChange(View v, boolean hasFocus) { 28 | if (_focusHandler != null) { 29 | _focusHandler.onItemFocused(v, hasFocus); 30 | } 31 | if (_chainedListener != null) { 32 | _chainedListener.onFocusChange(v, hasFocus); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/focushandler/ViewFocusHandler.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.focushandler; 2 | 3 | import android.view.View; 4 | 5 | import com.txl.tvlib.R; 6 | 7 | /** 8 | * 参考 leanback 对元素焦点进行处理 9 | * */ 10 | public class ViewFocusHandler implements IFocusHandler { 11 | private final float _focusScale; 12 | private static final int DURATION_MS = 150; 13 | private final boolean _useDimmer; 14 | 15 | public ViewFocusHandler(float focusScale,boolean useDimmer) { 16 | _focusScale = focusScale; 17 | _useDimmer = useDimmer; 18 | } 19 | 20 | 21 | public float getFocusScale() { 22 | return _focusScale; 23 | } 24 | 25 | @Override 26 | public void onItemFocused(View view, boolean hasFocus) { 27 | // view.setSelected(hasFocus); 28 | getOrCreateAnimator(view).animateFocus(hasFocus, false); 29 | } 30 | 31 | 32 | 33 | @Override 34 | public void onInitializeView(View view) { 35 | getOrCreateAnimator(view).animateFocus(false, true); 36 | } 37 | 38 | private FocusAnimator getOrCreateAnimator(View view) { 39 | FocusAnimator animator = (FocusAnimator) view.getTag(R.id.lb_focus_animator); 40 | if (animator == null) { 41 | animator = new FocusAnimator( 42 | view, getFocusScale(), _useDimmer, DURATION_MS); 43 | view.setTag(R.id.lb_focus_animator, animator); 44 | } 45 | return animator; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/utils/ViewExt.kt: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.utils 2 | 3 | import android.view.View 4 | 5 | /** 6 | * Copyright (c) 2020 唐小陆 All rights reserved. 7 | * author:txl 8 | * date:2020/4/1 9 | * description: 10 | */ 11 | 12 | fun View.viewCanFocus():Boolean{ 13 | return isFocusable && visibility == View.VISIBLE 14 | } -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/widget/ICheckView.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.widget; 2 | 3 | import android.widget.Checkable; 4 | 5 | public interface ICheckView extends Checkable { 6 | /** 7 | * 设置选中监听 8 | * */ 9 | void setOnCheckedChangeListener(OnCheckedChangeListener onCheckedChangeListener); 10 | 11 | /** 12 | * 被包含的是父容器添加的时候调用 13 | * */ 14 | void setOnCheckedChangeWidgetListener(OnCheckedChangeListener onCheckedChangeWidgetListener); 15 | 16 | interface OnCheckedChangeListener { 17 | /** 18 | * Called when the checked state of a compound button has changed. 19 | * 20 | * @param checkable The compound button view whose state has changed. 21 | * @param isChecked The new checked state of buttonView. 22 | */ 23 | void onCheckedChanged(Checkable checkable, boolean isChecked); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/widget/ITvView.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.widget; 2 | 3 | public interface ITvView { 4 | /** 5 | * 设置获取到焦点的放大比例 6 | * */ 7 | void setFocusScale(float scale); 8 | 9 | /** 10 | * 获取焦点的颜色 11 | * */ 12 | void setFocusColor(int focusColor); 13 | 14 | /** 15 | * 正常状态下的颜色 16 | * */ 17 | void setNormalColor(int normalColor); 18 | 19 | /** 20 | * 设置选中的颜色 21 | * */ 22 | void setSelectColor(int selectColor); 23 | 24 | /** 25 | * 设置元素上焦点的时候是否设置选中 26 | * */ 27 | void setFocusSelect(boolean focusSelect); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/widget/ITvViewGroup.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.widget; 2 | 3 | public interface ITvViewGroup extends ITvView { 4 | /** 5 | * 设置焦点的查找方式 6 | * default,priority,dynamic 7 | * default 按照系统的焦点处理方式进行查找 8 | * priority 按优先级进行查找 9 | * dynamic 动态记忆焦点 10 | * */ 11 | void setFocusSearchMode(String searchMode); 12 | } 13 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/widget/TvAttr.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.widget; 2 | 3 | import android.graphics.drawable.Drawable; 4 | 5 | /** 6 | * tv开发的相关属性封装 7 | * */ 8 | public class TvAttr { 9 | /** 10 | * 上焦点的时候的缩放规则 11 | * */ 12 | private float focusScale = 1.0f; 13 | private Drawable normalBgDrawable; 14 | private Drawable focusBsDrawable; 15 | private Drawable selectBgDrawable; 16 | private boolean focusSelect; 17 | } 18 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/widget/ViewExt.kt: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.widget 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/widget/dynamic/focus/IDynamicFocusViewGroup.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.widget.dynamic.focus; 2 | 3 | import android.view.View; 4 | 5 | import java.util.ArrayList; 6 | 7 | public interface IDynamicFocusViewGroup { 8 | boolean dispatchAddFocusables(ArrayList views, int direction, int focusableMode); 9 | void openFocusDynamic(boolean open); 10 | } 11 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/widget/dynamic/focus/utils/IDynamicFocusHelper.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.widget.dynamic.focus.utils; 2 | 3 | import android.graphics.Rect; 4 | import android.view.View; 5 | 6 | import java.util.ArrayList; 7 | 8 | /** 9 | * 定义焦点记忆的ViewGroup需要重写的方法, 10 | * 可以直接使用{@link DynamicFocusHelper}里面对应的方法来进行处理,或者自己实现 11 | * */ 12 | public interface IDynamicFocusHelper { 13 | 14 | boolean hasDynamicFocusView(); 15 | 16 | /** 17 | * ViewGroup默认有实现, 18 | * 要实现自己的焦点记忆参考leanback的RecyclerView 19 | * @return true 自己处理可获取焦点元素的添加 20 | * */ 21 | boolean addFocusables(ArrayList views, int direction, int focusableMode); 22 | 23 | /** 24 | * ViewGroup有默认的实现 25 | * 在这个位置需要记忆当前获取焦点的子元素 26 | * */ 27 | void requestChildFocus(View child, View focused); 28 | 29 | /** 30 | * 清除对应的记录 31 | * */ 32 | void clearFocus(); 33 | 34 | void clearChildFocus(); 35 | 36 | /** 37 | * 自身获取焦点的时候需要清除对应的焦点记忆 38 | * */ 39 | boolean requestFocus(int direction, Rect previouslyFocusedRect); 40 | 41 | /** 42 | * 在添加可以获取焦点的元素的时候,通过ViewGroup的addFocusables开始调用这个方法 43 | * 如果记忆的焦点是一个记忆焦点的容器那么向下再次寻找焦点 44 | * 否则调用addFocusables对可获取焦点的View进行添加 45 | * 这个方法是层层向下调用的。 46 | * */ 47 | boolean dispatchAddFocusables(ArrayList views, int direction, int focusableMode); 48 | } 49 | -------------------------------------------------------------------------------- /tvlib/src/main/java/com/txl/tvlib/widget/focus/shake/IFocusShake.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib.widget.focus.shake; 2 | 3 | /** 4 | * 无法查找到对应焦点元素的抖动动画抽取 5 | * */ 6 | public interface IFocusShake { 7 | void startHorizontalShakeAnimator(); 8 | 9 | void startVerticalShakeAnimator(); 10 | 11 | void startAnimation(int direction); 12 | } 13 | -------------------------------------------------------------------------------- /tvlib/src/main/res/drawable/b_menu_settled.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /tvlib/src/main/res/drawable/border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tvlib/src/main/res/drawable/color_text_checked.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /tvlib/src/main/res/drawable/select_border.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/tvlib/src/main/res/drawable/select_border.9.png -------------------------------------------------------------------------------- /tvlib/src/main/res/drawable/select_border_origin.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/tvlib/src/main/res/drawable/select_border_origin.9.png -------------------------------------------------------------------------------- /tvlib/src/main/res/layout/lib_image_text_card.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 15 | 22 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /tvlib/src/main/res/layout/lib_text_card.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 24 | 25 | -------------------------------------------------------------------------------- /tvlib/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2dp 4 | 28sp 5 | 50dp 6 | 10dp 7 | 45dp 8 | 30sp 9 | 150dp 10 | 60dp 11 | 70dp 12 | 24sp 13 | 232dp 14 | 135dp 15 | 5dp 16 | -------------------------------------------------------------------------------- /tvlib/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | tvlib 3 | 4 | -------------------------------------------------------------------------------- /tvlib/src/test/java/com/txl/tvlib/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.txl.tvlib; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /txllog/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /txllog/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 29 5 | buildToolsVersion "29.0.2" 6 | 7 | 8 | defaultConfig { 9 | minSdkVersion 15 10 | targetSdkVersion 29 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 15 | consumerProguardFiles 'consumer-rules.pro' 16 | } 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | 25 | } 26 | 27 | dependencies { 28 | implementation fileTree(dir: 'libs', include: ['*.jar']) 29 | 30 | implementation 'androidx.appcompat:appcompat:1.1.0' 31 | testImplementation 'junit:junit:4.12' 32 | androidTestImplementation 'androidx.test:runner:1.2.0' 33 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 34 | } 35 | -------------------------------------------------------------------------------- /txllog/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/txllog/consumer-rules.pro -------------------------------------------------------------------------------- /txllog/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /txllog/src/androidTest/java/com/txl/txllog/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.txl.txllog; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.runner.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | 25 | assertEquals( "com.txl.txllog.test", appContext.getPackageName() ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /txllog/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /txllog/src/main/java/com/txl/txllog/AndroidLogWrapper.java: -------------------------------------------------------------------------------- 1 | package com.txl.txllog; 2 | 3 | import android.util.Log; 4 | 5 | /** 6 | * Copyright (c) 2020, 唐小陆 All rights reserved. 7 | * author:txl 8 | * date:2020/3/12 9 | * description: 对Android的Log进行装饰添加仿便自己通用处理 10 | * */ 11 | public class AndroidLogWrapper { 12 | public static void e(String tag, String msg){ 13 | Log.e( tag, msg ); 14 | } 15 | public static void v(String tag, String msg){ 16 | Log.v( tag, msg ); 17 | } 18 | public static void i(String tag, String msg){ 19 | Log.i( tag, msg ); 20 | } 21 | public static void w(String tag, String msg){ 22 | Log.w( tag, msg ); 23 | } 24 | public static void d(String tag, String msg){ 25 | Log.d( tag, msg ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /txllog/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | txlLog 3 | 4 | -------------------------------------------------------------------------------- /txllog/src/test/java/com/txl/txllog/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.txl.txllog; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals( 4, 2 + 2 ); 16 | } 17 | } -------------------------------------------------------------------------------- /ui_basic/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /ui_basic/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 29 7 | buildToolsVersion "29.0.3" 8 | 9 | defaultConfig { 10 | minSdkVersion 16 11 | targetSdkVersion 29 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | consumerProguardFiles 'consumer-rules.pro' 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | compileOptions { 26 | sourceCompatibility 1.8 27 | targetCompatibility 1.8 28 | } 29 | resourcePrefix "ui_basic_" 30 | } 31 | 32 | dependencies { 33 | implementation fileTree(dir: 'libs', include: ['*.jar']) 34 | implementation 'androidx.appcompat:appcompat:1.1.0' 35 | implementation 'androidx.core:core-ktx:1.2.0' 36 | implementation 'androidx.recyclerview:recyclerview:1.1.0' 37 | implementation 'androidx.cardview:cardview:1.0.0' 38 | implementation 'androidx.constraintlayout:constraintlayout:2.0.2' 39 | testImplementation 'junit:junit:4.12' 40 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 41 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 42 | } 43 | -------------------------------------------------------------------------------- /ui_basic/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/ui_basic/consumer-rules.pro -------------------------------------------------------------------------------- /ui_basic/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /ui_basic/src/androidTest/java/com/txl/ui_basic/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.ui_basic 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.txl.ui_basic.test", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ui_basic/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /ui_basic/src/main/java/com/txl/ui_basic/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.txl.ui_basic; 2 | 3 | import androidx.fragment.app.FragmentActivity; 4 | 5 | /** 6 | * 抽取和业务无关的 ui基础样式 7 | * */ 8 | public abstract class BaseActivity extends FragmentActivity { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /ui_basic/src/main/java/com/txl/ui_basic/viewholder/BaseViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.txl.ui_basic.viewholder; 2 | 3 | import android.view.View; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.recyclerview.widget.RecyclerView; 7 | 8 | public abstract class BaseViewHolder extends RecyclerView.ViewHolder { 9 | protected String TAG = getClass().getSimpleName(); 10 | protected int currentPosition; 11 | private OnViewHolderItemClickListener mOnViewHolderItemClickListener; 12 | 13 | public void setOnViewHolderItemClickListener(OnViewHolderItemClickListener onViewHolderItemClickListener) { 14 | this.mOnViewHolderItemClickListener = onViewHolderItemClickListener; 15 | } 16 | 17 | public BaseViewHolder(@NonNull View itemView) { 18 | super(itemView); 19 | itemView.setOnClickListener(v -> { 20 | if(mOnViewHolderItemClickListener != null){ 21 | mOnViewHolderItemClickListener.onViewHolderItemClick(v,currentPosition); 22 | } 23 | }); 24 | } 25 | 26 | /** 27 | * 用于更新数据 28 | * @param data 更新ui所需要的数据 29 | * */ 30 | public void onBindViewHolder(int position,T data) { 31 | currentPosition = position; 32 | } 33 | 34 | public void resetCurrentPosition(int position ){ 35 | currentPosition = position; 36 | } 37 | 38 | public interface OnViewHolderItemClickListener{ 39 | void onViewHolderItemClick(View view, int position); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ui_basic/src/main/java/com/txl/ui_basic/viewholder/IViewHolderFactory.java: -------------------------------------------------------------------------------- 1 | package com.txl.ui_basic.viewholder; 2 | 3 | import android.view.ViewGroup; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | public interface IViewHolderFactory { 8 | VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType); 9 | int getItemViewType(int position, T data); 10 | } 11 | -------------------------------------------------------------------------------- /ui_basic/src/main/java/com/txl/ui_basic/widget/WebBrowse.java: -------------------------------------------------------------------------------- 1 | package com.txl.ui_basic.widget; 2 | 3 | import android.content.Context; 4 | import android.os.Build; 5 | import android.util.AttributeSet; 6 | import android.webkit.WebSettings; 7 | import android.webkit.WebView; 8 | 9 | import androidx.annotation.RequiresApi; 10 | 11 | public class WebBrowse extends WebView { 12 | public WebBrowse(Context context) { 13 | super(context); 14 | init(); 15 | } 16 | 17 | public WebBrowse(Context context, AttributeSet attrs) { 18 | super(context, attrs); 19 | init(); 20 | } 21 | 22 | public WebBrowse(Context context, AttributeSet attrs, int defStyleAttr) { 23 | super(context, attrs, defStyleAttr); 24 | init(); 25 | } 26 | 27 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 28 | public WebBrowse(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 29 | super(context, attrs, defStyleAttr, defStyleRes); 30 | init(); 31 | } 32 | 33 | protected void init(){ 34 | WebSettings settings = getSettings(); 35 | settings.setJavaScriptEnabled(true); 36 | settings.setTextZoom(100); 37 | settings.setUseWideViewPort(true);//将图片调整到适合webview的大小 38 | settings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小 39 | setBackgroundColor(0); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ui_basic/src/main/res/drawable-xxhdpi/ui_basic_loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/ui_basic/src/main/res/drawable-xxhdpi/ui_basic_loading.png -------------------------------------------------------------------------------- /ui_basic/src/main/res/drawable/ui_basic_anim.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ui_basic/src/main/res/drawable/ui_basic_shape_dialog_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ui_basic/src/main/res/layout/ui_basic_lib_root_frame_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /ui_basic/src/main/res/layout/ui_basic_pop_loading_l.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14 | 15 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /ui_basic/src/main/res/layout/ui_basic_pop_wait_notice.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 16 | 17 | 26 | 27 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /ui_basic/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20dp 4 | 14dp 5 | 30dp 6 | 15dp 7 | 15sp 8 | 29dp 9 | 12dp 10 | 25dp 11 | 12sp 12 | 10dp 13 | -------------------------------------------------------------------------------- /ui_basic/src/test/java/com/txl/ui_basic/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.ui_basic 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /wan_android_data_provider/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /wan_android_data_provider/README.md: -------------------------------------------------------------------------------- 1 | WanAndroid 数据提供模块 -------------------------------------------------------------------------------- /wan_android_data_provider/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 30 7 | buildToolsVersion "30.0.0" 8 | 9 | defaultConfig { 10 | minSdkVersion 19 11 | targetSdkVersion 30 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | consumerProguardFiles "consumer-rules.pro" 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | } 26 | 27 | dependencies { 28 | implementation fileTree(dir: "libs", include: ["*.jar"]) 29 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 30 | implementation 'androidx.core:core-ktx:1.3.1' 31 | implementation 'androidx.appcompat:appcompat:1.2.0' 32 | testImplementation 'junit:junit:4.12' 33 | androidTestImplementation 'androidx.test.ext:junit:1.1.2' 34 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' 35 | implementation "com.google.code.gson:gson:$gson" 36 | implementation "com.tencent:mmkv:$mmkv" 37 | implementation project(path: ':netModel') 38 | implementation project(path: ':commonlibrary') 39 | implementation project(path: ':webLinkParse') 40 | } -------------------------------------------------------------------------------- /wan_android_data_provider/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wan_android_data_provider/consumer-rules.pro -------------------------------------------------------------------------------- /wan_android_data_provider/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /wan_android_data_provider/src/androidTest/java/com/txl/wan_android_data_provider/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.txl.wan_android_data_provider.test", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | / 5 | -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/bean/com/besjon/pojo/HomeArticleListData.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020 bejson.com 3 | */ 4 | package com.txl.wan_android_data_provider.bean.com.besjon.pojo; 5 | 6 | /** 7 | * Auto-generated: 2020-03-12 21:56:12 8 | * 9 | * @author bejson.com (i@bejson.com) 10 | * @website http://www.bejson.com/java2pojo/ 11 | */ 12 | public class HomeArticleListData { 13 | 14 | private Data data; 15 | private int errorCode; 16 | private String errorMsg; 17 | public void setData(Data data) { 18 | this.data = data; 19 | } 20 | public Data getData() { 21 | return data; 22 | } 23 | 24 | public void setErrorCode(int errorCode) { 25 | this.errorCode = errorCode; 26 | } 27 | public int getErrorCode() { 28 | return errorCode; 29 | } 30 | 31 | public void setErrorMsg(String errorMsg) { 32 | this.errorMsg = errorMsg; 33 | } 34 | public String getErrorMsg() { 35 | return errorMsg; 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/bean/com/besjon/pojo/NavigateArticleListData.java: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider.bean.com.besjon.pojo; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Copyright (c) 2020 唐小陆 All rights reserved. 7 | * author:txl 8 | * date:2020/3/30 9 | * description:导航数据 10 | * */ 11 | public class NavigateArticleListData { 12 | private List data; 13 | private int errorCode; 14 | private String errorMsg; 15 | 16 | public List getData() { 17 | return data; 18 | } 19 | 20 | public void setData(List data) { 21 | this.data = data; 22 | } 23 | 24 | public void setErrorCode(int errorCode) { 25 | this.errorCode = errorCode; 26 | } 27 | public int getErrorCode() { 28 | return errorCode; 29 | } 30 | 31 | public void setErrorMsg(String errorMsg) { 32 | this.errorMsg = errorMsg; 33 | } 34 | public String getErrorMsg() { 35 | return errorMsg; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/bean/com/besjon/pojo/NavigateCategoryData.java: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider.bean.com.besjon.pojo; 2 | 3 | import com.txl.wan_android_data_provider.bean.home.Article; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Copyright (c) 2020 唐小陆 All rights reserved. 9 | * author:txl 10 | * date:2020/3/30 11 | * description: 12 | */ 13 | public class NavigateCategoryData { 14 | private String cid; 15 | private List
articles; 16 | private String name; 17 | 18 | 19 | public String getCid() { 20 | return cid; 21 | } 22 | 23 | public void setCid(String cid) { 24 | this.cid = cid; 25 | } 26 | 27 | public List
getArticles() { 28 | return articles; 29 | } 30 | 31 | public void setArticles(List
articles) { 32 | this.articles = articles; 33 | } 34 | 35 | public String getName() { 36 | return name; 37 | } 38 | 39 | public void setName(String name) { 40 | this.name = name; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/bean/com/besjon/pojo/setup/JsonRootBean.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2020 bejson.com 3 | */ 4 | package com.txl.wan_android_data_provider.bean.com.besjon.pojo.setup; 5 | import com.txl.wan_android_data_provider.bean.com.besjon.pojo.Data; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Auto-generated: 2020-04-01 18:22:19 11 | * 12 | * @author bejson.com (i@bejson.com) 13 | * @website http://www.bejson.com/java2pojo/ 14 | */ 15 | public class JsonRootBean { 16 | 17 | private List data; 18 | private int errorCode; 19 | private String errorMsg; 20 | public void setData(List data) { 21 | this.data = data; 22 | } 23 | public List getData() { 24 | return data; 25 | } 26 | 27 | public void setErrorCode(int errorCode) { 28 | this.errorCode = errorCode; 29 | } 30 | public int getErrorCode() { 31 | return errorCode; 32 | } 33 | 34 | public void setErrorMsg(String errorMsg) { 35 | this.errorMsg = errorMsg; 36 | } 37 | public String getErrorMsg() { 38 | return errorMsg; 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/bean/home/BannerItemData.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider.bean.home 2 | 3 | /** 4 | * Copyright (c) 2020 唐小陆 All rights reserved. 5 | * author:txl 6 | * date:2020/9/14 7 | * description: 8 | */ 9 | data class BannerItemData(var desc:String?,var id:Int?,var imagePath:String?,var isVisible:Int?, 10 | var order:Int?,var title:String?,var type:Int?,var url:String?) { 11 | } -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/bean/home/TopDataWrapper.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider.bean.home 2 | 3 | /** 4 | * Copyright (c) 2020 唐小陆 All rights reserved. 5 | * author:txl 6 | * date:2020/9/17 7 | * description: 8 | */ 9 | data class TopDataWrapper(val data: List
) { 10 | } -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/bean/user/UserInfo.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider.bean.user 2 | 3 | /** 4 | * Copyright (c) 2020 唐小陆 All rights reserved. 5 | * author:txl 6 | * date:2020/10/31 7 | * description: 8 | */ 9 | data class UserInfo (var admin:Boolean?=false,var coinCount:Int?,var email:String?,var icon:String?, 10 | val id:Int,var nickname:String?,var password:String?,var publishName:String?, 11 | var token:String?,var type:Int?,var username:String,var collectIds:List?):Cloneable{ 12 | 13 | 14 | 15 | override fun clone(): UserInfo { 16 | return UserInfo(this.admin,this.coinCount,this.email,this.icon,this.id,this.nickname,this.password, this.publishName,this.token,this.type,this.username,ArrayList(collectIds)) 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/data/Error.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider.data 2 | 3 | import androidx.annotation.Keep 4 | 5 | /** 6 | * 7 | * 服务器返回的错误信息 8 | * 9 | */ 10 | @Keep 11 | data class Error( 12 | /** 13 | * 错误代码 14 | */ 15 | val code:String, 16 | /** 17 | * 系统外部的错误码 18 | */ 19 | val hd_code:Int, 20 | /** 21 | * 错误信息的描述 22 | */ 23 | val description:String){ 24 | companion object{ 25 | fun newNetError(code: String):Error{ 26 | return Error(code,ErrorCode.ERROR_NETWORK_EXCEPTION,"Network exception") 27 | } 28 | } 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/data/ErrorCode.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider.data 2 | 3 | /** 4 | * citsin 5 | * 2018/12/29 6 | */ 7 | object ErrorCode{ 8 | /** 9 | * 10 | * 网络连接异常 11 | */ 12 | const val ERROR_NETWORK_EXCEPTION = -1 13 | /** 14 | * 网络不可用 15 | */ 16 | const val ERROR_NETWORK_INVALIED = -2 17 | } 18 | -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/data/Response.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider.data 2 | 3 | import androidx.annotation.Keep 4 | 5 | @Keep 6 | data class Response( 7 | /** 8 | * 接口调用返回数据 9 | */ 10 | val data: T? = null, 11 | var originString:String? = "", 12 | /** 13 | * 错误码,为0正常 14 | * */ 15 | var errorCode:Int?=0, 16 | var errorMsg:String?="" 17 | ){ 18 | fun netSuccess():Boolean{ 19 | return errorCode == 0 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/viewModel/AbsNavItemListViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider.viewModel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import androidx.lifecycle.ViewModel 5 | 6 | /** 7 | * 列表抽象的ViewModel,对列表接口数据进行缓存和提前进行处理。 8 | * 因为列表导航的接口和返回数据都有可能不同因此这里不限制数据的类型。建议使用 实现 数据类型实现 Parcelable 接口 9 | * 这样可以使用默认实现好了的本地缓存和读取 10 | * */ 11 | abstract class AbsNavItemListViewModel:ViewModel(),IPageViewModel { 12 | val data = MutableLiveData>() 13 | 14 | @Volatile 15 | protected var resetData = false 16 | @Volatile 17 | protected var loadData = false 18 | 19 | /** 20 | * 当前加载的第几页数据 21 | * */ 22 | var currentPage = 0 23 | protected set 24 | 25 | init { 26 | this.resetData() 27 | } 28 | 29 | override fun resetData() { 30 | currentPage = 0 31 | getPageData() 32 | } 33 | 34 | override fun nextPage() { 35 | if (loadData || resetData) { //重置或者 正在加载数据的时候不能进行获取下一页的数据 36 | return 37 | } 38 | loadData = true 39 | currentPage++ 40 | getPageData() 41 | } 42 | 43 | override fun getViewModelData(): MutableLiveData> { 44 | return data 45 | } 46 | 47 | protected abstract fun getPageData() 48 | } -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/viewModel/IPageViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider.viewModel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | 5 | /** 6 | * Copyright (c) 2020, 唐小陆 All rights reserved. 7 | * author:txl 8 | * date:2020/3/12 9 | * description:列表页的数据ViewModel接口定义 10 | * eg.进行列表页网络请求 11 | * 第一次获取或重置 这个数据使用 resetData() 12 | * 余下的使用nextPage() 13 | */ 14 | interface IPageViewModel { 15 | /** 16 | * 初始化数据 17 | * */ 18 | fun resetData() 19 | /** 20 | * 获取下一页的数据 21 | * */ 22 | fun nextPage() 23 | 24 | fun getViewModelData(): MutableLiveData> 25 | } -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/viewModel/ResourceBoundary.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider.viewModel 2 | 3 | import androidx.annotation.Keep 4 | 5 | /** 6 | * txl 7 | * 封装接口返回数据 8 | */ 9 | 10 | /** 11 | * 加载完成 12 | */ 13 | const val STATE_LOADED = 0 14 | /** 15 | * 加载状态 16 | */ 17 | const val STATE_LOADING = 1 18 | /** 19 | * 错误状态 20 | */ 21 | const val STATE_ERROR = 2 22 | 23 | @Keep 24 | data class ResourceBoundary( 25 | /** 26 | * 响应状态: STATE_LOADED; STATE_LOADING; STATE_ERROR 27 | * */ 28 | val state: Int, 29 | val extraCode: Int, 30 | val message:String = "", 31 | val data: T? = null, 32 | var currentPage:Int=0 33 | ) 34 | -------------------------------------------------------------------------------- /wan_android_data_provider/src/main/java/com/txl/wan_android_data_provider/viewModel/user/UserViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider.viewModel.user 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import androidx.lifecycle.ViewModel 5 | import androidx.lifecycle.ViewModelProvider 6 | import com.txl.wan_android_data_provider.bean.user.UserInfo 7 | import com.txl.wan_android_data_provider.data.DataDriven 8 | import kotlinx.coroutines.GlobalScope 9 | import kotlinx.coroutines.launch 10 | 11 | /** 12 | * Copyright (c) 2020, 唐小陆 All rights reserved. 13 | * author:txl 14 | * date:2020/10/16 15 | * description:可以借助ViewModel管理用户信息,如何共享viewModel 16 | */ 17 | class UserViewModel :ViewModel(){ 18 | 19 | val userInfo: MutableLiveData = MutableLiveData() 20 | 21 | fun login(userName:String, password:String){ 22 | GlobalScope.launch { 23 | val response = DataDriven.login(userName,password) 24 | if(response.netSuccess()){ 25 | userInfo.postValue(response.data) 26 | }else{ 27 | userInfo.postValue(null) 28 | } 29 | } 30 | } 31 | } 32 | 33 | class UserViewModelFactory() : ViewModelProvider.NewInstanceFactory() { 34 | companion object{ 35 | var userViewModel:UserViewModel? = null 36 | private set 37 | } 38 | 39 | override fun create(modelClass: Class): T { 40 | if(userViewModel == null){ 41 | userViewModel = UserViewModel() 42 | } 43 | return userViewModel as T 44 | } 45 | } -------------------------------------------------------------------------------- /wan_android_data_provider/src/test/java/com/txl/wan_android_data_provider/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wan_android_data_provider 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /wanandroid/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /wanandroid/README.md: -------------------------------------------------------------------------------- 1 | # 主项目 app说明 2 | 分包说明: 3 | 4 | - bean: 主要用于存放javaBean对象 5 | - data: 数据的获取 从网络或者本地 (MVP的Model层) 6 | - ui: 项目界面的展示相关 7 | - viewModel (MVP的Presenter层,为什么叫ViewModel。主要使用jetpack的ViewModel充当p层) -------------------------------------------------------------------------------- /wanandroid/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /wanandroid/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/SplashActivity.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv 2 | 3 | import android.content.Intent 4 | import androidx.appcompat.app.AppCompatActivity 5 | import android.os.Bundle 6 | import com.txl.ui_basic.BaseActivity 7 | 8 | class SplashActivity : WanAndroidBaseActivity() { 9 | 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContentView(R.layout.activity_splash) 13 | jumpToMainPage() 14 | finish() 15 | } 16 | 17 | private fun jumpToMainPage(){ 18 | val intent = Intent(this,MainActivity::class.java) 19 | startActivity(intent) 20 | } 21 | } -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/WanAndroidBaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv; 2 | 3 | import android.content.res.Resources; 4 | import android.os.Bundle; 5 | import android.view.WindowManager; 6 | 7 | import androidx.annotation.Nullable; 8 | 9 | import com.txl.ui_basic.BaseActivity; 10 | 11 | import me.jessyan.autosize.AutoSizeCompat; 12 | 13 | /** 14 | * Copyright (c) 2020 唐小陆 All rights reserved. 15 | * author:txl 16 | * date:2020/9/18 17 | * description: 18 | */ 19 | public class WanAndroidBaseActivity extends BaseActivity { 20 | 21 | @Override 22 | protected void onCreate(@Nullable Bundle savedInstanceState) { 23 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 24 | super.onCreate(savedInstanceState); 25 | } 26 | 27 | @Override 28 | public Resources getResources() { 29 | //需要升级到 v1.1.2 及以上版本才能使用 AutoSizeCompat 30 | AutoSizeCompat.autoConvertDensityOfGlobal((super.getResources()));//如果没有自定义需求用这个方法 31 | return super.getResources(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/WanAndroidTvApplication.java: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv; 2 | 3 | import androidx.multidex.MultiDexApplication; 4 | 5 | import com.txl.netmodel.okhttp.okhttp.OkHttpUtils; 6 | 7 | import io.github.prototypez.appjoint.core.AppSpec; 8 | import me.jessyan.autosize.AutoSize; 9 | import skin.support.SkinCompatManager; 10 | 11 | @AppSpec 12 | public class WanAndroidTvApplication extends MultiDexApplication { 13 | 14 | @Override 15 | public void onCreate() { 16 | super.onCreate(); 17 | SkinCompatManager.withoutActivity(this) 18 | .setSkinStatusBarColorEnable(false) // 关闭状态栏换肤,默认打开[可选] 19 | .setSkinWindowBackgroundEnable(false) // 关闭windowBackground换肤,默认打开[可选] 20 | .loadSkin(); 21 | AutoSize.initCompatMultiProcess(this); 22 | OkHttpUtils.initCache(getExternalCacheDir().toString(),( 20 * 1024 * 1024)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/ui/NavItemWidthUtils.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv.ui 2 | 3 | import android.content.Context 4 | import com.txl.wanandroidtv.R 5 | import org.jetbrains.anko.displayMetrics 6 | 7 | /** 8 | * Copyright (c) 2020 唐小陆 All rights reserved. 9 | * author:txl 10 | * date:2020/3/18 11 | * description:通过比例计算元素宽度 12 | */ 13 | object NavItemWidthUtils { 14 | /** 15 | * @param col 有多少行 16 | * @param itemPadding 元素之间间距 17 | * */ 18 | fun getItemWidth(context: Context,col:Int,itemPadding:Int):Float{ 19 | //主界面左右各有90dp的间距 20 | val canUseWidth = context.displayMetrics.widthPixels - context.resources.getDimensionPixelSize(R.dimen.dp_90) * 2 21 | val totalPadding = itemPadding * (col -1f) 22 | return (canUseWidth - totalPadding) /col 23 | } 24 | } -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/ui/adpater/NavRecyclerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv.ui.adpater; 2 | 3 | import android.view.ViewGroup; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.txl.ui_basic.adapter.BaseRecyclerAdapter; 8 | import com.txl.ui_basic.viewholder.BaseViewHolder; 9 | import com.txl.wan_android_data_provider.bean.NavItemData; 10 | import com.txl.wanandroidtv.ui.viewholder.NavItemViewHolder; 11 | import com.txl.wanandroidtv.ui.viewholder.NvaItemViewHolderFactory; 12 | 13 | import java.util.Collection; 14 | 15 | /** 16 | * Copyright (c) 2020, 唐小陆 All rights reserved. 17 | * author:txl 18 | * date:2020/1/1 19 | * description: 20 | */ 21 | public class NavRecyclerAdapter extends BaseRecyclerAdapter { 22 | private NvaItemViewHolderFactory nvaItemViewHolderFactory; 23 | public NavRecyclerAdapter() { 24 | 25 | } 26 | 27 | public NavRecyclerAdapter(Collection data) { 28 | super( data ); 29 | } 30 | 31 | @NonNull 32 | @Override 33 | public NavItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 34 | if(nvaItemViewHolderFactory == null){ 35 | nvaItemViewHolderFactory = new NvaItemViewHolderFactory(); 36 | } 37 | return nvaItemViewHolderFactory.onCreateViewHolder( parent, viewType ); 38 | } 39 | 40 | @Override 41 | public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) { 42 | holder.onBindViewHolder( position,getData().get( position ) ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/ui/adpater/WanAndroidListItemType.java: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv.ui.adpater; 2 | 3 | import com.txl.ui_basic.adapter.NavTypeSpec; 4 | 5 | /** 6 | * Copyright (c) 2020 唐小陆 All rights reserved. 7 | * author:txl 8 | * date:2020/9/16 9 | * description:wanAndroid 列表元素显示集合 10 | */ 11 | public class WanAndroidListItemType { 12 | /** 13 | * 文本标题 14 | * */ 15 | public static final int TYPE_TEXT_TITLE = NavTypeSpec.makeMeasureSpec(0,NavTypeSpec.MODE_COMMON_ELEMENT); 16 | /** 17 | * 轮播图 18 | * */ 19 | public static final int TYPE_BANNER = NavTypeSpec.makeMeasureSpec(1,NavTypeSpec.MODE_COMMON_ELEMENT); 20 | /** 21 | * 普通列表元素 22 | * */ 23 | public static final int TYPE_COMMON = NavTypeSpec.makeMeasureSpec(2,NavTypeSpec.MODE_COMMON_ELEMENT); 24 | /** 25 | * 置顶数据 26 | * */ 27 | public static final int TYPE_TOP = NavTypeSpec.makeMeasureSpec(3,NavTypeSpec.MODE_COMMON_ELEMENT); 28 | 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/ui/fragment/NavFragmentCreateFactory.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv.ui.fragment 2 | 3 | import android.util.Log 4 | import com.txl.ui_basic.fragment.BaseFragment 5 | 6 | /** 7 | * Copyright (c) 2020 唐小陆 All rights reserved. 8 | * author:txl 9 | * date:2020/3/16 10 | * description:创建导航Fragment 11 | */ 12 | /** 13 | * 首页 14 | * */ 15 | const val CATEGORY_HOME = "1" 16 | /** 17 | * 广场 18 | * */ 19 | const val CATEGORY_SQUARE = "2" 20 | /** 21 | * 导航 22 | * */ 23 | const val CATEGORY_NAVIGATE = "3" 24 | /** 25 | * 问答 26 | * */ 27 | const val CATEGORY_PROJECT = "4" 28 | 29 | class NavFragmentCreateFactory { 30 | companion object { 31 | @JvmStatic 32 | fun createFragmentByCategory(category: String, vararg args: Any): BaseFragment { 33 | Log.d("Nav","NavFragmentCreateFactory category $category ") 34 | when (category) { 35 | CATEGORY_HOME-> { 36 | return HomeNavFragment.newInstance(category) 37 | } 38 | CATEGORY_SQUARE->{ 39 | return SquareNavFragment.newInstance(category) 40 | } 41 | CATEGORY_NAVIGATE->{ 42 | return NavigateNavFragment.newInstance(category) 43 | } 44 | CATEGORY_PROJECT->{ 45 | return ProjectNavFragment.newInstance(category) 46 | } 47 | else -> { 48 | return HomeNavFragment.newInstance(category) 49 | } 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/ui/fragment/SetUpNavFragment.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv.ui.fragment 2 | 3 | import com.txl.wanandroidtv.R 4 | import com.txl.wan_android_data_provider.bean.com.besjon.pojo.HomeArticleListData 5 | import kotlinx.android.synthetic.main.fragment_setup_nav.* 6 | 7 | /** 8 | * Copyright (c) 2020 唐小陆 All rights reserved. 9 | * author:txl 10 | * date:2020/4/1 11 | * description:体系导航 12 | */ 13 | class SetUpNavFragment:BaseNavFragment() { 14 | override fun showLoading(currentPage: Int) { 15 | if(currentPage == 0){ 16 | loadingViewUtils?.showLoadingView(true) 17 | }else{ 18 | smart_refresh_layout?.autoLoadMore() 19 | } 20 | } 21 | 22 | override fun onDataReady(currentPage: Int, data: Any?) { 23 | loadingViewUtils?.showLoadingView(false) 24 | smart_refresh_layout?.finishLoadMore() 25 | if (data is HomeArticleListData){ 26 | // mAdapter?.appendData(data.data.datas) 27 | } 28 | } 29 | 30 | override fun getLayoutRes(): Int { 31 | return R.layout.fragment_setup_nav 32 | } 33 | 34 | override fun initView() { 35 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates. 36 | } 37 | } -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/ui/user/UserCenterActivity.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv.ui.user 2 | 3 | import android.os.Bundle 4 | import com.txl.wanandroidtv.R 5 | import com.txl.wanandroidtv.WanAndroidBaseActivity 6 | 7 | class UserCenterActivity : WanAndroidBaseActivity() { 8 | override fun onCreate(savedInstanceState: Bundle?) { 9 | super.onCreate(savedInstanceState) 10 | setContentView(R.layout.activity_user_center) 11 | 12 | } 13 | } -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/ui/utils/PageJumpUtils.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv.ui.utils 2 | 3 | import android.content.Context 4 | import com.txl.router.web.IWebRouter 5 | import com.txl.wan_android_data_provider.bean.home.Article 6 | import io.github.prototypez.appjoint.AppJoint 7 | 8 | /** 9 | * Copyright (c) 2020 唐小陆 All rights reserved. 10 | * author:txl 11 | * date:2020/3/25 12 | * description: 13 | */ 14 | object PageJumpUtils { 15 | fun openPage(context: Context,data:Any?,vararg args:Any?){ 16 | if(data is Article){ 17 | val webRouter = AppJoint.service(IWebRouter::class.java) 18 | webRouter?.openWebPage(context,data.title,data.link) 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/ui/utils/ThemeUtils.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv.ui.utils 2 | 3 | import android.content.Context 4 | import androidx.core.content.ContextCompat 5 | import com.txl.wanandroidtv.R 6 | 7 | object ThemeUtils { 8 | fun getThemeColor(context: Context):Int{ 9 | return ContextCompat.getColor(context, R.color.theme) 10 | } 11 | } -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/ui/widget/NavViewPager.java: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv.ui.widget; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.KeyEvent; 6 | import android.view.View; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.annotation.Nullable; 10 | import androidx.viewpager.widget.ViewPager; 11 | 12 | /** 13 | * Copyright (c) 2020 唐小陆 All rights reserved. 14 | * author:txl 15 | * date:2020/4/2 16 | * description: 17 | */ 18 | public class NavViewPager extends ViewPager { 19 | public NavViewPager(@NonNull Context context) { 20 | super(context); 21 | } 22 | 23 | public NavViewPager(@NonNull Context context, @Nullable AttributeSet attrs) { 24 | super(context, attrs); 25 | } 26 | 27 | @Override 28 | public View focusSearch(View focused, int direction) { 29 | if(arrowScroll(direction)){ 30 | return null; 31 | } 32 | return super.focusSearch(focused, direction); 33 | } 34 | 35 | @Override 36 | public boolean dispatchKeyEvent(KeyEvent event) { 37 | if(hasFocus()){ 38 | return super.dispatchKeyEvent(event); 39 | } 40 | 41 | View focused = findFocus(); 42 | if(focused != null){ 43 | return focused.dispatchKeyEvent(event); 44 | } 45 | return false; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/ui/widget/RatioImageView.java: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv.ui.widget; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.ImageView; 6 | 7 | import androidx.annotation.Nullable; 8 | 9 | /** 10 | * Copyright (c) 2020 唐小陆 All rights reserved. 11 | * author:txl 12 | * date:2020/9/16 13 | * description:具有比例的ImageView 14 | */ 15 | public class RatioImageView extends ImageView { 16 | private float ratio = 16f/9f; 17 | 18 | public RatioImageView(Context context) { 19 | super(context); 20 | } 21 | 22 | public RatioImageView(Context context, @Nullable AttributeSet attrs) { 23 | super(context, attrs); 24 | } 25 | 26 | public RatioImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 27 | super(context, attrs, defStyleAttr); 28 | } 29 | 30 | @Override 31 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 32 | int hms = heightMeasureSpec; 33 | if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY){ 34 | int height = (int) (MeasureSpec.getSize(widthMeasureSpec)/ratio); 35 | hms = MeasureSpec.makeMeasureSpec(height,MeasureSpec.EXACTLY); 36 | } 37 | super.onMeasure(widthMeasureSpec, hms); 38 | } 39 | 40 | public void setRatio(float ratio){ 41 | this.ratio = ratio; 42 | requestLayout(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /wanandroid/src/main/java/com/txl/wanandroidtv/utils/RecyclerViewConfigUtils.kt: -------------------------------------------------------------------------------- 1 | package com.txl.wanandroidtv.utils 2 | 3 | import androidx.recyclerview.widget.RecyclerView.RecycledViewPool 4 | 5 | 6 | /** 7 | * Copyright (c) 2020 唐小陆 All rights reserved. 8 | * author:txl 9 | * date:2020/9/15 10 | * description: 11 | */ 12 | object RecyclerViewConfigUtils { 13 | 14 | /** 15 | * 全局重用池 16 | * */ 17 | val viewPool =RecycledViewPool() 18 | 19 | init { 20 | viewPool.setMaxRecycledViews(0, 10) 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /wanandroid/src/main/res/drawable-xhdpi/user_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/drawable-xhdpi/user_icon.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/drawable/b_menu_settled.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/drawable/bg_radius10.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/drawable/color_text_checked.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/drawable/ic_action_member.xml: -------------------------------------------------------------------------------- 1 | 7 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/drawable/ic_action_mine.xml: -------------------------------------------------------------------------------- 1 | 7 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/drawable/ic_action_search.xml: -------------------------------------------------------------------------------- 1 | 7 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/drawable/image_place_holder.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/drawable/list_title_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/drawable/nav_item_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/drawable/wan_android.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/drawable/wan_android.9.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 16 | 17 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/layout/activity_user_center.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 20 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/layout/card_nav_title_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 24 | 25 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/layout/fragment_lib_nav_base.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 20 | 25 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/layout/fragment_navigate_nav.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/layout/fragment_project_nav.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/layout/item_navigate_left_nav.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 20 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/layout/item_navigate_right_flex_box_content.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/layout/item_navigate_right_flex_box_content_child_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 21 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/layout/item_title.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/layout/recycler_item_nav.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 24 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/wanandroid/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /wanandroid/src/main/res/navigation/user_nav_graph.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/raw/main_nav.json: -------------------------------------------------------------------------------- 1 | [ 2 | 3 | { 4 | "type": "text", 5 | "title": "首页", 6 | "isHome": true, 7 | "category": "1" 8 | }, 9 | { 10 | "type": "text", 11 | "title": "广场", 12 | "category": "2" 13 | }, 14 | { 15 | "type": "text", 16 | "title": "导航", 17 | "category": "3" 18 | } 19 | ] -------------------------------------------------------------------------------- /wanandroid/src/main/res/raw/main_nav_all_save.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "text", 4 | "title": "我的", 5 | "category": "0" 6 | }, 7 | { 8 | "type": "text", 9 | "title": "首页", 10 | "isHome": true, 11 | "category": "1" 12 | }, 13 | { 14 | "type": "text", 15 | "title": "广场", 16 | "category": "2" 17 | }, 18 | { 19 | "type": "text", 20 | "title": "导航", 21 | "category": "3" 22 | }, 23 | { 24 | "type": "text", 25 | "title": "问答", 26 | "category": "4" 27 | }, 28 | { 29 | "type": "text", 30 | "title": "体系", 31 | "category": "5" 32 | }, 33 | { 34 | "type": "text", 35 | "title": "项目", 36 | "category": "6" 37 | }, 38 | { 39 | "type": "text", 40 | "title": "公众号", 41 | "category": "7" 42 | }, 43 | { 44 | "type": "text", 45 | "title": "项目分类", 46 | "category": "8" 47 | }, 48 | { 49 | "type": "text", 50 | "title": "工具", 51 | "category": "9" 52 | }, 53 | { 54 | "type": "text", 55 | "title": "收藏", 56 | "category": "10" 57 | } 58 | ] -------------------------------------------------------------------------------- /wanandroid/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #060 4 | #fff 5 | #fff 6 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 45dp 4 | 10dp 5 | 30dp 6 | 16dp 7 | 28sp 8 | 50dp 9 | 20dp 10 | 120dp 11 | 100dp 12 | 60dp 13 | 200dp 14 | 32sp 15 | 15dp 16 | 8dp 17 | 90dp 18 | 200dp 19 | 18sp 20 | 400dp 21 | 600dp 22 | 48sp 23 | 3dp 24 | 25 | 16dp 26 | 16dp 27 | 80dp 28 | 300dp 29 | 96dp 30 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | WanAndroidTv 3 | 搜索 4 | 我的 5 | 会员 6 | 我的 7 | 8 | Email 9 | Account 10 | Password 11 | Sign in or register 12 | Sign in 13 | "Welcome!" 14 | Not a valid username 15 | Password must be >5 characters 16 | "Login failed" 17 | 18 | -------------------------------------------------------------------------------- /wanandroid/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /web/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | apply plugin: 'kotlin-kapt' 5 | 6 | android { 7 | compileSdkVersion compileVersion 8 | buildToolsVersion buildVersion 9 | 10 | defaultConfig { 11 | minSdkVersion minVersion 12 | targetSdkVersion targetVersion 13 | versionCode 1 14 | versionName "1.0" 15 | 16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 17 | consumerProguardFiles 'consumer-rules.pro' 18 | } 19 | 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | resourcePrefix "web_" 27 | 28 | } 29 | 30 | dependencies { 31 | implementation fileTree(dir: 'libs', include: ['*.jar']) 32 | 33 | implementation 'androidx.appcompat:appcompat:1.1.0' 34 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 35 | testImplementation 'junit:junit:4.12' 36 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 37 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 38 | api project(path: ':router') 39 | implementation "io.github.prototypez:app-joint-core:$app_joint" 40 | } 41 | -------------------------------------------------------------------------------- /web/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/web/consumer-rules.pro -------------------------------------------------------------------------------- /web/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /web/src/androidTest/java/com/txl/web/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.txl.web; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | 25 | assertEquals("com.txl.web.test", appContext.getPackageName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /web/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /web/src/main/java/com/txl/web/WebApplication.kt: -------------------------------------------------------------------------------- 1 | package com.txl.web 2 | 3 | import android.app.Application 4 | import io.github.prototypez.appjoint.core.ModuleSpec 5 | 6 | /** 7 | * Copyright (c) 2020 唐小陆 All rights reserved. 8 | * author:txl 9 | * date:2020/3/25 10 | * description: 11 | */ 12 | @ModuleSpec 13 | class WebApplication: Application() { 14 | } -------------------------------------------------------------------------------- /web/src/main/java/com/txl/web/router/WebRouterImpl.kt: -------------------------------------------------------------------------------- 1 | package com.txl.web.router 2 | 3 | import android.content.Context 4 | import com.txl.router.web.IWebRouter 5 | import com.txl.web.ui.WebActivity 6 | import io.github.prototypez.appjoint.core.ServiceProvider 7 | 8 | /** 9 | * Copyright (c) 2020 唐小陆 All rights reserved. 10 | * author:txl 11 | * date:2020/3/25 12 | * description: 13 | */ 14 | @ServiceProvider 15 | class WebRouterImpl :IWebRouter { 16 | override fun openWebPage(context: Context, title: String, url: String) { 17 | WebActivity.openWebPage(context,title,url) 18 | } 19 | } -------------------------------------------------------------------------------- /web/src/main/java/com/txl/web/ui/WebActivity.kt: -------------------------------------------------------------------------------- 1 | package com.txl.web.ui 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.os.Bundle 6 | import com.txl.ui_basic.BaseActivity 7 | import com.txl.web.R 8 | import kotlinx.android.synthetic.main.web_activity_web.* 9 | 10 | class WebActivity : BaseActivity() { 11 | 12 | companion object{ 13 | private const val TITLE = "title" 14 | private const val LINK = "link" 15 | 16 | /** 17 | * @param title 网页标题 18 | * @param url 网页链接 19 | * */ 20 | fun openWebPage(context: Context,title:String, url:String){ 21 | val intent = Intent(context,WebActivity::class.java) 22 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 23 | intent.putExtra(TITLE,title) 24 | intent.putExtra(LINK,url) 25 | context.startActivity(intent) 26 | } 27 | } 28 | 29 | override fun onCreate(savedInstanceState: Bundle?) { 30 | super.onCreate(savedInstanceState) 31 | setContentView(R.layout.web_activity_web) 32 | initViewAndData() 33 | } 34 | 35 | private fun initViewAndData(){ 36 | val title = intent.getStringExtra(TITLE) 37 | val url = intent.getStringExtra(LINK) 38 | tv_title.text = title 39 | web_browse.loadUrl(url) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /web/src/main/res/layout/web_activity_web.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 19 | 24 | 25 | -------------------------------------------------------------------------------- /web/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 30dp 4 | 28sp 5 | 90dp 6 | -------------------------------------------------------------------------------- /web/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | %1$s正在请求打开%2$s 3 | 取消 4 | 确认 5 | 6 | -------------------------------------------------------------------------------- /web/src/test/java/com/txl/web/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.txl.web; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /webLinkParse/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /webLinkParse/README.md: -------------------------------------------------------------------------------- 1 | # 网页内容解析模块 -------------------------------------------------------------------------------- /webLinkParse/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 30 7 | buildToolsVersion "30.0.0" 8 | 9 | defaultConfig { 10 | minSdkVersion 19 11 | targetSdkVersion 30 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | consumerProguardFiles "consumer-rules.pro" 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | } 26 | 27 | dependencies { 28 | implementation fileTree(dir: "libs", include: ["*.jar"]) 29 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 30 | implementation 'androidx.core:core-ktx:1.3.1' 31 | implementation 'androidx.appcompat:appcompat:1.2.0' 32 | implementation files('libs/jsoup-1.11.3.jar') 33 | testImplementation 'junit:junit:4.12' 34 | androidTestImplementation 'androidx.test.ext:junit:1.1.2' 35 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' 36 | 37 | } -------------------------------------------------------------------------------- /webLinkParse/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/webLinkParse/consumer-rules.pro -------------------------------------------------------------------------------- /webLinkParse/libs/jsoup-1.11.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaolutang/WanAndroidTv/33d5fa6b4b6c11228fa761111668b2359570a9b9/webLinkParse/libs/jsoup-1.11.3.jar -------------------------------------------------------------------------------- /webLinkParse/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /webLinkParse/src/androidTest/java/com/txl/weblinkparse/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.weblinkparse 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.txl.weblinkparse.test", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /webLinkParse/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /webLinkParse/src/test/java/com/txl/weblinkparse/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.txl.weblinkparse 2 | 3 | import android.graphics.BitmapFactory 4 | import android.util.Log 5 | import org.jsoup.Jsoup 6 | import org.junit.Assert.assertEquals 7 | import org.junit.Test 8 | import java.io.IOException 9 | import java.net.URL 10 | 11 | /** 12 | * Example local unit test, which will execute on the development machine (host). 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | class ExampleUnitTest { 17 | @Test 18 | fun addition_isCorrect() { 19 | assertEquals(4, 2 + 2) 20 | } 21 | 22 | private val TAG = "ParseBzTest" 23 | 24 | @Test 25 | fun parseBzImg() { 26 | // val linkUrl = "https://www.bilibili.com/video/BV1b54y1U71P/" 27 | val s = WebLinkParse.getMaxImgAddress("https://juejin.im/post/6873466220885049351") 28 | System.out.println("$TAG img :: $s") 29 | } 30 | } --------------------------------------------------------------------------------