├── .gitignore ├── .travis.yml ├── LICENSE ├── README-zh.md ├── README.md ├── README_API-zh.md ├── README_API.md ├── README_SENCE-zh.md ├── README_SENCE.md ├── README_UPDATE-zh.md ├── README_UPDATE.md ├── android.keystore ├── app-androidx ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── example │ │ └── demo │ │ ├── App.java │ │ ├── Constants.java │ │ ├── MainActivity.java │ │ ├── TestSecondActivity.kt │ │ ├── anno │ │ ├── ApiContentType.java │ │ ├── ApiResetType.java │ │ └── ChatPageType.java │ │ ├── scene │ │ ├── chat │ │ │ ├── ChatActivity.java │ │ │ ├── ChatCusContentScrollActivity.java │ │ │ ├── ChatDialog.java │ │ │ ├── ChatDialogFragment.java │ │ │ ├── ChatFragment.java │ │ │ ├── ChatFragmentActivity.java │ │ │ ├── ChatPopupWindow.java │ │ │ ├── ChatSuperActivity.java │ │ │ ├── adapter │ │ │ │ ├── ChatAdapter.java │ │ │ │ ├── ChatBaseVH.java │ │ │ │ ├── ChatInfo.java │ │ │ │ ├── ChatLeftVH.java │ │ │ │ └── ChatRightVH.java │ │ │ ├── emotion │ │ │ │ ├── CenterImageSpan.java │ │ │ │ ├── EditTextSelector.java │ │ │ │ ├── EmojiSpanBuilder.java │ │ │ │ ├── Emotion.java │ │ │ │ ├── EmotionPagerView.java │ │ │ │ ├── EmotionView.java │ │ │ │ └── Emotions.java │ │ │ └── view │ │ │ │ └── AutoHidePanelRecyclerView.java │ │ ├── feed │ │ │ ├── FeedActivity.java │ │ │ ├── FeedCommentDialog.java │ │ │ └── FeedDialogActivity.java │ │ ├── live │ │ │ ├── douyin │ │ │ │ └── PhoneDouyinLiveActivity.java │ │ │ └── huya │ │ │ │ ├── PcHuyaCommentPopWindow.java │ │ │ │ └── PcHuyaLiveActivity.java │ │ ├── video │ │ │ ├── BiliBiliCommentPopWindow.java │ │ │ └── BiliBiliSampleActivity.java │ │ └── viewpager │ │ │ ├── ChatFragmentPagerAdapter.kt │ │ │ ├── ViewPager2Activity.kt │ │ │ └── ViewPagerActivity.kt │ │ ├── systemui │ │ ├── QMUIDeviceHelper.java │ │ ├── QMUIDisplayHelper.java │ │ ├── QMUIStatusBarHelper.java │ │ ├── StatusBarView.java │ │ ├── StatusbarHelper.java │ │ └── SystemBarTintManager.java │ │ └── util │ │ └── DisplayUtils.java │ ├── kotlin │ └── com │ │ └── example │ │ └── demo │ │ └── scene │ │ └── api │ │ ├── ContentActivity.kt │ │ ├── CusContentContainer.kt │ │ ├── CusPanelActivity.kt │ │ ├── CusPanelView.kt │ │ ├── DefaultHeightPanelActivity.kt │ │ ├── FixIssuesActivity.kt │ │ ├── FixIssuesActivity2.kt │ │ ├── FixIssuesActivity3.kt │ │ ├── FixIssuesActivity4.kt │ │ ├── FixIssuesForBackBerryActivity.kt │ │ ├── FloatContentView.kt │ │ ├── FloatWindowManager.kt │ │ ├── FloatWindowPermissionChecker.kt │ │ ├── MyRomUtil.kt │ │ ├── ResetActivity.kt │ │ └── SystemProperties.kt │ └── res │ ├── anim │ ├── anim_feed_pop_hide.xml │ └── anim_feed_pop_show.xml │ ├── color │ └── color_send_btn.xml │ ├── drawable-xxhdpi │ ├── avatar_android.png │ ├── avatar_cat.jpeg │ ├── bg_gradient.jpeg │ ├── chat_left_bg.9.png │ ├── chat_right_bg.9.png │ ├── expression_1.png │ ├── expression_10.png │ ├── expression_101.png │ ├── expression_102.png │ ├── expression_103.png │ ├── expression_104.png │ ├── expression_105.png │ ├── expression_106.png │ ├── expression_107.png │ ├── expression_108.png │ ├── expression_109.png │ ├── expression_11.png │ ├── expression_111.png │ ├── expression_113.png │ ├── expression_114.png │ ├── expression_115.png │ ├── expression_116.png │ ├── expression_117.png │ ├── expression_118.png │ ├── expression_119.png │ ├── expression_12.png │ ├── expression_13.png │ ├── expression_14.png │ ├── expression_15.png │ ├── expression_16.png │ ├── expression_18.png │ ├── expression_19.png │ ├── expression_2.png │ ├── expression_20.png │ ├── expression_21.png │ ├── expression_22.png │ ├── expression_23.png │ ├── expression_24.png │ ├── expression_26.png │ ├── expression_27.png │ ├── expression_28.png │ ├── expression_29.png │ ├── expression_3.png │ ├── expression_30.png │ ├── expression_31.png │ ├── expression_32.png │ ├── expression_33.png │ ├── expression_34.png │ ├── expression_35.png │ ├── expression_37.png │ ├── expression_38.png │ ├── expression_39.png │ ├── expression_4.png │ ├── expression_40.png │ ├── expression_41.png │ ├── expression_42.png │ ├── expression_43.png │ ├── expression_45.png │ ├── expression_46.png │ ├── expression_47.png │ ├── expression_48.png │ ├── expression_49.png │ ├── expression_5.png │ ├── expression_50.png │ ├── expression_51.png │ ├── expression_52.png │ ├── expression_53.png │ ├── expression_55.png │ ├── expression_56.png │ ├── expression_57.png │ ├── expression_58.png │ ├── expression_6.png │ ├── expression_61.png │ ├── expression_63.png │ ├── expression_64.png │ ├── expression_65.png │ ├── expression_66.png │ ├── expression_67.png │ ├── expression_68.png │ ├── expression_69.png │ ├── expression_7.png │ ├── expression_71.png │ ├── expression_75.png │ ├── expression_76.png │ ├── expression_77.png │ ├── expression_79.png │ ├── expression_8.png │ ├── expression_80.png │ ├── expression_81.png │ ├── expression_82.png │ ├── expression_83.png │ ├── expression_84.png │ ├── expression_85.png │ ├── expression_86.png │ ├── expression_9.png │ ├── expression_90.png │ ├── expression_93.png │ ├── expression_94.png │ ├── expression_95.png │ ├── expression_96.png │ ├── expression_97.png │ ├── expression_98.png │ ├── expression_99.png │ ├── ic_bilibili_input_send.png │ ├── ic_bilibili_input_send_select.png │ ├── ic_bilibili_input_tip.png │ ├── ic_bilibili_panel_key.png │ ├── ic_bilibili_panel_key_l.png │ ├── ic_bilibili_panel_key_select.png │ ├── ic_bilibili_video_back.png │ ├── ic_bilibili_video_checkout.png │ ├── ic_douyin_close.png │ ├── ic_douyin_gift.png │ ├── ic_douyin_live_user.jpg │ ├── ic_douyin_love.png │ ├── ic_douyin_more.png │ ├── ic_douyin_send.png │ ├── ic_feed_action_comment.png │ ├── ic_feed_action_like.png │ ├── ic_feed_avatar.jpg │ ├── ic_feed_cover.jpeg │ ├── ic_icon.png │ ├── ic_uzi_0.jpg │ ├── ic_uzi_1.jpg │ ├── ic_uzi_2.jpg │ ├── ic_uzi_3.jpg │ ├── ic_uzi_4.jpg │ ├── ic_uzi_5.jpg │ ├── ic_uzi_6.jpg │ ├── ic_uzi_7.jpg │ ├── ic_uzi_8.jpg │ └── ic_uzi_9.jpg │ ├── drawable │ ├── ic_launcher_background.xml │ ├── icon_account.xml │ ├── icon_add.xml │ ├── icon_camera.xml │ ├── icon_emotion.xml │ ├── icon_image.xml │ ├── icon_keyboard.xml │ ├── icon_location.xml │ ├── icon_video.xml │ ├── icon_voice.xml │ ├── se_bilibili_input_send.xml │ ├── se_bilibili_panel_key_l.xml │ ├── se_bilibili_panel_key_p.xml │ ├── se_douyin_action_btn.xml │ ├── se_huya_comment_send_p.xml │ ├── se_wechat_comment_send.xml │ ├── selector_edit_focus.xml │ ├── selector_emotion_btn.xml │ ├── selector_send_btn.xml │ ├── sh_activity_btn.xml │ ├── sh_bilibili_input_l.xml │ ├── sh_bilibili_input_l_but_white.xml │ ├── sh_bilibili_input_p.xml │ ├── sh_bilibili_panel_item_bg.xml │ ├── sh_bilibili_panel_item_select_bg.xml │ ├── sh_content_btn.xml │ ├── sh_douyin_follow_bg.xml │ ├── sh_douyin_time_bg.xml │ ├── sh_douyin_user_bg.xml │ ├── sh_feed_action.xml │ ├── sh_fragment_btn.xml │ ├── sh_huya_edit_cursor.xml │ ├── sh_panel_btn.xml │ ├── sh_pop_feed_action.xml │ ├── sh_reset_btn.xml │ ├── sh_special_page_btn.xml │ ├── sh_tip_btn.xml │ ├── sh_video_btn.xml │ ├── sh_wechat_comment_input.xml │ ├── shape_edit_cursor.xml │ ├── shape_edit_selected.xml │ ├── shape_edit_unselected.xml │ ├── shape_input_layout.xml │ └── shape_video_input_text.xml │ ├── layout │ ├── activity_api_auto_reset_disable_layout.xml │ ├── activity_api_auto_reset_enable_layout.xml │ ├── activity_api_auto_reset_enable_on_empty_view_layout.xml │ ├── activity_api_auto_reset_enable_on_recyclerview_layout.xml │ ├── activity_api_auto_reset_enbale_on_cus_recyclerview_layout.xml │ ├── activity_api_content_cus_layout.xml │ ├── activity_api_content_frame_layout.xml │ ├── activity_api_content_linear_layout.xml │ ├── activity_api_content_relative_layout.xml │ ├── activity_api_cus_panel_layout.xml │ ├── activity_api_default_panel_height_layout.xml │ ├── activity_bilibili_video_layout.xml │ ├── activity_chat_fragment_layout.xml │ ├── activity_douyin_live_layout.xml │ ├── activity_feed_dialog_layout.xml │ ├── activity_feed_layout.xml │ ├── activity_fix_issues_layout.xml │ ├── activity_fix_issues_layout2.xml │ ├── activity_fix_issues_layout3.xml │ ├── activity_fix_issues_layout4.xml │ ├── activity_huya_live_layout.xml │ ├── activity_main_layout.xml │ ├── activity_super_chat_layout.xml │ ├── activity_test_second_layout.xml │ ├── activity_view_pager_2_layout.xml │ ├── activity_view_pager_layout.xml │ ├── common_chat_layout.xml │ ├── common_chat_with_titlebar_layout.xml │ ├── dialog_feed_comment_layout.xml │ ├── holder_douyin_chat_item.xml │ ├── holder_feed_cover_layout.xml │ ├── holder_feed_item_layout.xml │ ├── holder_huya_chat_item.xml │ ├── list_parent_title_layout.xml │ ├── list_sub_title_layout.xml │ ├── panel_add_layout.xml │ ├── panel_bilibili_layout.xml │ ├── panel_emotion_layout.xml │ ├── panel_include_edit_layout.xml │ ├── pop_bilibili_video_comment_layout.xml │ ├── pop_feed_action_layout.xml │ ├── pop_huya_live_comment_layout.xml │ ├── vh_chat_left_layout.xml │ ├── vh_chat_right_layout.xml │ ├── vh_emotion_item_layout.xml │ ├── view_float_content_layout.xml │ └── view_status_bar_layout.xml │ ├── raw │ ├── uzi.mp4 │ └── yexiaoma.mp4 │ └── values │ ├── attr.xml │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── panel-androidx ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── effective │ │ └── android │ │ └── panel │ │ ├── Constants.kt │ │ ├── PanelSwitchHelper.kt │ │ ├── compat │ │ └── KeyboardHeightCompat.kt │ │ ├── device │ │ ├── DeviceInfo.kt │ │ └── DeviceRuntime.kt │ │ ├── interfaces │ │ ├── ContentScrollMeasurer.kt │ │ ├── PanelHeightMeasurer.kt │ │ ├── TriggerViewClickInterceptor.kt │ │ ├── ViewAssertion.kt │ │ └── listener │ │ │ ├── OnEditFocusChangeListener.kt │ │ │ ├── OnKeyboardStateListener.kt │ │ │ ├── OnPanelChangeListener.kt │ │ │ └── OnViewClickListener.kt │ │ ├── log │ │ ├── LogFormatter.kt │ │ └── LogTracker.kt │ │ ├── utils │ │ ├── DisplayUtil.kt │ │ ├── KeyboardExt.kt │ │ ├── PanelUtil.kt │ │ └── RomUtils.kt │ │ ├── view │ │ ├── PanelSwitchLayout.kt │ │ ├── content │ │ │ ├── ContentContainerImpl.kt │ │ │ ├── FrameContentContainer.kt │ │ │ ├── IContentContainer.kt │ │ │ ├── LinearContentContainer.kt │ │ │ └── RelativeContentContainer.kt │ │ └── panel │ │ │ ├── IPanelView.kt │ │ │ ├── PanelContainer.kt │ │ │ └── PanelView.kt │ │ └── window │ │ └── PanelDialog.kt │ └── res │ └── values │ ├── attr.xml │ └── ids.xml ├── settings.gradle ├── source ├── api │ ├── arch.jpg │ ├── cus_scroll_content.gif │ └── mode.jpg ├── demo.apk ├── demo.png ├── qr_code_apk.png ├── qr_code_wx.jpg └── scene │ ├── auto_adjust.gif │ ├── bilibili.gif │ ├── bilibili_demo.gif │ ├── chat.gif │ ├── compat_navigation.gif │ ├── douyin.gif │ ├── douyin_demo.gif │ ├── huya.gif │ ├── huya_demo.gif │ ├── wechat_feed.gif │ └── wechat_feed_demo.gif └── versions.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .DS_Store 5 | .idea 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | dist : trusty 3 | sudo: required 4 | jdk: oraclejdk8 5 | 6 | env: 7 | global: 8 | - ANDROID_API_LEVEL=29 9 | - ANDROID_BUILD_TOOLS_VERSION=29.0.1 10 | - ANDROID_ABI=armeabi-v7a 11 | 12 | android: 13 | components: 14 | - tools 15 | - platform-tools 16 | - tools 17 | - extra-android-m2repository 18 | licenses: 19 | - 'android-sdk-preview-license-52d11cd2' 20 | - 'android-sdk-license-.+' 21 | - 'google-gdk-license-.+' 22 | 23 | before_install: 24 | - touch $HOME/.android/repositories.cfg 25 | - yes | sdkmanager "platforms;android-29" 26 | - yes | sdkmanager "build-tools;29.0.1" 27 | 28 | before_cache: 29 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 30 | - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ 31 | 32 | cache: 33 | directories: 34 | - $HOME/.gradle/caches/ 35 | - $HOME/.gradle/wrapper/ 36 | - $HOME/.android/build-cache 37 | 38 | before_script: 39 | - chmod +x gradlew 40 | 41 | script: 42 | - ./gradlew clean build 43 | - ./gradlew test -------------------------------------------------------------------------------- /README_SENCE-zh.md: -------------------------------------------------------------------------------- 1 | 2 | ### 场景目录 3 | 1. 支持动态更改输入法高度/隐藏显示导航栏时适配功能面板 4 | 2. 聊天场景(类微信) 5 | 3. 视频播放场景(类BiliBili) 6 | 4. 电脑直播场景(类虎牙直播) 7 | 5. 手机直播场景(类抖音直播) 8 | 6. 信息流评论场景(类微信朋友圈) 9 | 10 | #### 支持动态更改输入法高度/隐藏显示导航栏时 11 | 市面上的很多IM场景,用户更改输入法高度时切换回功能面板,则发生高度不一致,微信也如此。同时还需要适配存在导航栏操作的设备,常见如华为,小米等。为了追求更平滑的切换效果,框架支持动态更改输入法高度时适配功能面板。 12 | 13 | 14 | 15 | #### 聊天场景 16 | 17 | 聊天场景适用于任何 IM 场景,Demo 分别使用了 Activity/Fragment/DialogFragment/PopupWindow/Dialog 来实现,满足你可所用的窗口技术。可参考 Demo 中的聊天场景。 18 | 19 | 20 | 21 | #### 视频播放场景 22 | 23 | 视频播放效果参考 BiliBili 实现,左图为 BiliBili 效果,右图为 Demo 效果,效果优于 BiliBili 实现。 24 | 25 | 26 | 27 | #### 电脑直播场景 28 | 29 | 电脑直播效果参考 虎牙直播间 实现,左图为 虎牙直播间 效果,右图为 Demo 效果,效果优于 虎牙 实现。 30 | 31 | 32 | 33 | 34 | #### 手机直播场景 35 | 36 | 手机直播效果参考 抖音直播 实现,左图为 抖音直播 效果,右图为 Demo 效果,效果优于 抖音直播 实现。 37 | 38 | 39 | 40 | 41 | #### 信息流评论场景 42 | 43 | 信息流评论效果参考 微信朋友圈 实现,左图为 微信朋友圈 效果,右图为 Demo 效果,效果与微信朋友圈相同。 44 | 45 | 46 | 47 | #### 复杂聊天场景 48 | 49 | * 自定义各个子View滑动 50 | * 支持模拟多个EditText拉起面板 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /README_SENCE.md: -------------------------------------------------------------------------------- 1 | ### Scene Directory 2 | 1. Support changing the height of the input method dynamically/hiding the function panel when the navigation bar is hidden 3 | 2. Chat scene (like WeChat) 4 | 3. Video playback scene (class BiliBili) 5 | 4. Computer live broadcast scene (like Huya live broadcast) 6 | 5. Mobile phone live broadcast scene (like TikTok live broadcast) 7 | 6. Information flow comment scene (like WeChat circle of friends) 8 | 9 | #### Support for dynamically changing the height of the input method/hiding the display of the navigation bar 10 | In many IM scenarios on the market, when users change the height of the input method and switch back to the function panel, the height inconsistency occurs, as does WeChat. At the same time, it also needs to adapt to the devices with navigation bar operations, such as Huawei and Xiaomi. In order to pursue a smoother switching effect, the framework supports adapting the function panel when dynamically changing the height of the input method. 11 | 12 | 13 | 14 | #### Chat scene 15 | 16 | The chat scene is applicable to any IM scene. Demo uses Activity/Fragment/DialogFragment/PopupWindow/Dialog respectively to realize the window technology you can use. You can refer to the chat scene in the Demo. 17 | 18 | 19 | 20 | #### Video playback scene 21 | 22 | Refer to the BiliBili implementation for video playback effects. The left picture shows the BiliBili effect, and the right picture shows the Demo effect. The effect is better than the BiliBili implementation. 23 | 24 | 25 | 26 | #### Computer live broadcast scene 27 | 28 | Refer to the Huya live broadcast room for the computer live broadcast effect. The left picture shows the Huya live broadcast room. The right picture shows the Demo effect, which is better than the Huya live broadcast. 29 | 30 | 31 | 32 | 33 | #### Mobile live broadcast scene 34 | 35 | For the mobile phone live broadcast effect, please refer to the realization of Douyin Live. The picture on the left shows the effect of Douyin Live, and the picture on the right shows the effect of Demo. 36 | 37 | 38 | 39 | 40 | #### Stream comment scene 41 | 42 | The effect of the comment on the information flow can be found on the WeChat Moments. The picture on the left shows the effect of the WeChat Moments, and the picture on the right shows the effect of the Demo. 43 | 44 | 45 | 46 | 47 | ####Complex chat scene 48 | 49 | * Customize the sliding of each subview 50 | * Support to simulate multiple EditText to pull up the panel -------------------------------------------------------------------------------- /README_UPDATE-zh.md: -------------------------------------------------------------------------------- 1 | ### 更新日志 2 | 3 | * 1.0.1 支持兼容AndroidQ+焦点冲突,支持视频模式 4 | * 1.0.2 支持微信式滑动列表收起面板同时列表响应滑动事件,提升用户体验 5 | * 1.0.3 修复 [issue](https://github.com/YummyLau/PanelSwitchHelper/issues/10) 场景问题 6 | * 1.0.4 新增支持 Dialog/Fragment/DialogFragment 7 | * 1.0.5 支持适配华为/小米等支持动态导航栏隐藏的特殊机型 8 | * 1.1.0 追求极致的切换体验 9 | * 支持切换流程中动画加持,效果同步“微信聊天”场景,但支持的场景远远不止这些(见Demo),同时支持自定义动画速度 10 | * 优化框架内部切换流程,摈弃旧逻辑实现,新实现通过自定义绘制切换界面,无需担心内存泄漏 11 | * Demo新增自定义标题栏场景,优化视频场景体验 12 | * 1.1.1 支持适配全面屏/刘海屏/水滴屏幕等特殊场景 13 | * 优化内部计算有效面积高度,兼容特殊场景 14 | * 免去 bindPanelSwitchLayout api 调用,框架内部自定完成逻辑 15 | * Demo新增复杂IM交互场景 16 | * 1.1.2 新增内容滑动模式/内容固定模式动态切换api 17 | * 优化隐藏面板逻辑,提升动画流畅性 18 | * 新增内容滑动模式,内容区域可动态滑动到界面外部,类 adjustPan,默认开启 19 | * 新增内容固定模式,内容区域动态调整绘制区域,类 adjustResize 20 | * 解决 IM 场景下可能因为内容过少而被滑动外部的问题,支持动态切换模式,优化体验 21 | * 1.1.3 兼容谷歌渠道非公开SDK-API的使用要求,优化固定模式的绘制实现 22 | * 1.2.0 kotlin版本/新增支持多种布局类型的内容区域容器 23 | * panel 调整为 kotlin 语言实现,完全兼容现有功能及 Java,支持 DSL 24 | * 新增内容区域容器,默认提供线性/相对/帧布局,支持实现自定义内容区域容器 25 | * Demo 新增 kotlin 使用约束布局实现自定义容器,新增 4 种不同布局的容器场景 26 | * 1.2.2 修复已知缺陷及优化 27 | * 合并 pr 修复 emptyView 引用错误问题 28 | * 优化固定模式下切换的流畅性 29 | * 1.2.3 兼容 android pad 机型 30 | * 1.3.0 支持自动隐藏面板,开放自定义面板,优化性调整 31 | * 新增 auto_reset_enable 及 auto_reset_area api 用于开放自动隐藏面板,摒弃 EmptyView 32 | * 新增 IPanelView 接口,外部可自主实现 PanelView,更灵活 33 | * 优化滑动模式下的动画实 34 | 35 | `1.3.0` 为重要版本,建议升级,同时注意以下 Api 更改 36 | * EmptyView 移除,可参考 Demo 如何更优雅实现隐藏面板 37 | * 面板类规范命名,已原生 Linear/Relative/Frame 为前缀,更容易区分 38 | * PanelView 迁移到 panel 包 39 | * 1.3.1 支持适配采用底部系统布局来捕获用户手势的机型,这部分机型在界面底部多出的系统view可能导致输入法计算有偏差。比如 Findx,红米等机型。 40 | * 1.3.2 支持xml布局预览,优化动画,解决Demo存在背景时切换面板背景可见的问题 41 | * 1.3.2.1 兼容使用autoSize库的项目,解决可能因为状态栏高度被修改导致输入法高度计算错误的问题 42 | * 1.3.3 优化体验,修复已知问题 43 | * 修复多fragment场景下 window 可能引起 fragment 内存泄漏问题 44 | * 新增 `toPanelState`api 用于外部拉起面板 45 | * 新增 `addDistanceMeasurer` 用于外部自主控制内容区域滑动,兼容 IM 场景下未满一屏数据被滑走的问题 46 | * 1.3.4 修复已知问题,增强功能 47 | * 更改 api `contentCanScrollOutside` -> `contentScrollOutsideEnable`,用于切换固定/滑动模式 48 | * 更改 api `addDistanceMeasurer` -> `addContentScrollMeasurer`, 当处于滑动模式时,可自主控制内容滑动距离 49 | * 新增 api `addPanelHeightMeasurer` 用于设置默认面板高度,兼容未获取输入法场景 50 | * 优化动画及内部逻辑 51 | * 1.3.5 兼容 AndroidQ 全屏虚拟导航栏手势模式,如 MiUI12 设备等 52 | * 1.3.6 扩展 api 53 | * 扩展 `animationSpeed`,支持设置动画速度, `standard` 标准速,`slow` 慢速,`slowest` 最慢速,`fast` 快速,`fastest`最快速 54 | * PanelSwitchHelper 新增判断当前面板状态,如 `isPanelState()` 等 55 | * 优化全面屏软键盘高度计算逻辑,修复已知问题 56 | * 1.3.7 兼容OneUI 2版本前 s8/note8 等三星设备 57 | * 1.3.8 扩展 api 58 | * 扩展 `PanelHeightMeasurer` 接口新增 `synchronizeKeyboardHeight` 方法控制面板高度是否同步软键盘高度 59 | * Container 容器支持控制内部多层嵌套布局自由滑动 60 | * 1.3.10 支持全屏模式,支持额外设置EditText唤起面板,修复已知问题 61 | * 1.3.11 修复部分 MiUI 手机横屏状态栏拉起输入法异常问题,优化 Log 显示,统一所有自定义面板容器属性命名的前缀 62 | * 1.3.12 兼容悬浮键盘场景 63 | * 1.3.13 兼容部分手机锁屏收起输入法问题;兼容华为定制平板问题;优化全屏显示速度; 64 | * 1.4.0 该版本起仅支持 Androidx,非 Androidx 不再维护 65 | * 修复三星部分设备的兼容问题 66 | * 新增 `setTriggerViewClickInterceptor` 支持动态控制 TriggerView 是否自动响应"点击触发切换面板"行为,默认相应 67 | * 新增 `DisUtils#setCompatSizeProxy` 支持动态设置像素转化逻辑 68 | * 1.5.0 支持Android 11键盘过渡动画特性 69 | * 添加了悬浮弹窗场景的用例。 70 | * `PanelSwitchLayout` 控件添加了 `enableKeyboardAnimator` 属性,用来控制是否启用Android 11 的键盘动画效果,默认开启。 71 | * Android 11 键盘过渡动画需要在 SOFT_INPUT_ADJUST_NOTHING 模式下才能生效。 72 | * 暂时不支持DialogFragment、PopupWindow、悬浮弹窗等场景下Android 11键盘过渡动画效果。 73 | * 修复已知Bug [issue](https://github.com/DSAppTeam/PanelSwitchHelper/issues) 74 | * 1.5.1 修复已知Bug。 75 | * 修复ContentScrollMeasurer计算子View高度不准确问题。 76 | * IContentContainer#layoutContainer()添加了changed参数,用来判断是否需要重新布局。 77 | * 1.5.2 修复已知Bug。 78 | * 修复Android 11 以上布局偏移量变化后,布局位置没有同步的问题。 79 | * 1.5.3 修复已知Bug。 80 | * 修复快速滑动列表时,偏移量计算异常的问题。 81 | * 优化viewPosition位置变化的监听。 82 | * 1.5.4 修复已知Bug,提供兼容方案。 83 | * 更改 api `enableKeyboardAnimator` -> `android11KeyboardFeature`,用来控制是否启用Android 11 的键盘动画效果,默认开启。 84 | * 新增 `PanelSwitchLayout`提供两个兼容方法(`softInputHeightCalculatorOnStart`,`softInputHeightCalculatorOnProgress`),针对Android 11以上开启键盘动画特性,高度获取失败时,对外提供兼容方案。 85 | * 1.5.5 修复已知Bug,支持ViewPager、ViewPager2场景。 86 | * 添加 PanelSwitchLayout.recycle() 方法,用于释放键盘高度变化监听器。 87 | -------------------------------------------------------------------------------- /android.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/android.keystore -------------------------------------------------------------------------------- /app-androidx/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app-androidx/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion config.compile_sdk_version 7 | // buildToolsVersion config.build_tool_version 8 | 9 | dataBinding { 10 | enabled = true 11 | } 12 | 13 | defaultConfig { 14 | applicationId "com.example.demo" 15 | minSdkVersion config.min_sdk_version 16 | targetSdkVersion config.target_sdk_version 17 | versionCode config.version_code 18 | versionName config.version_name 19 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 20 | buildConfigField "String", "VERSION", "\"${versions.panelSwitchHelper}\"" 21 | } 22 | 23 | signingConfigs { 24 | release { 25 | keyAlias 'keystore' 26 | keyPassword 'mm123456' 27 | storeFile file('../android.keystore') 28 | storePassword '123456' 29 | } 30 | } 31 | 32 | buildTypes { 33 | release { 34 | minifyEnabled true 35 | signingConfig signingConfigs.release 36 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 37 | } 38 | } 39 | 40 | compileOptions { 41 | sourceCompatibility JavaVersion.VERSION_1_8 42 | targetCompatibility JavaVersion.VERSION_1_8 43 | } 44 | 45 | lintOptions { 46 | abortOnError false 47 | } 48 | 49 | // 配置一个路径专门存放kotlin文件 50 | sourceSets { 51 | main.java.srcDirs += 'src/main/kotlin' 52 | } 53 | } 54 | 55 | dependencies { 56 | implementation fileTree(include: ['*.jar'], dir: 'libs') 57 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 58 | implementation deps.androidx.appcompat 59 | implementation deps.androidx.recyclerview 60 | implementation deps.androidx.constraint 61 | implementation deps.pageindicator 62 | implementation deps.circleimageview 63 | // implementation deps.panelSwitchHelper_androidx 64 | implementation project(":panel-androidx") 65 | // implementation 'com.github.DSAppTeam:PanelSwitchHelper:v1.5.12' 66 | // implementation 'com.squareup.leakcanary:leakcanary-android:2.4' 67 | implementation "androidx.viewpager2:viewpager2:1.0.0" 68 | 69 | } -------------------------------------------------------------------------------- /app-androidx/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 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/App.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import android.app.Application; 4 | 5 | 6 | public class App extends Application { 7 | 8 | @Override 9 | public void onCreate() { 10 | super.onCreate(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/Constants.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | public class Constants { 4 | public static final String KEY_PAGE_TYPE = "pageType"; 5 | public static final String KEY_CONTENT_TYPE = "contentType"; 6 | public static final String RELEASE_WITH_PAGER = "release_with_pager"; 7 | } 8 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/TestSecondActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import android.os.Bundle 5 | import com.effective.R 6 | 7 | /** 8 | * 测试用的二级页面 9 | */ 10 | class TestSecondActivity : AppCompatActivity() { 11 | override fun onCreate(savedInstanceState: Bundle?) { 12 | super.onCreate(savedInstanceState) 13 | setContentView(R.layout.activity_test_second_layout) 14 | } 15 | } -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/anno/ApiContentType.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.anno; 2 | import androidx.annotation.IntDef; 3 | 4 | import static com.example.demo.anno.ApiContentType.Linear; 5 | import static com.example.demo.anno.ApiContentType.Relative; 6 | import static com.example.demo.anno.ApiContentType.Frame; 7 | import static com.example.demo.anno.ApiContentType.CUS; 8 | 9 | @IntDef({Linear, Relative, Frame, CUS}) 10 | public @interface ApiContentType { 11 | int Linear = 0; 12 | int Relative = 1; 13 | int Frame = 2; 14 | int CUS = 3; 15 | } 16 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/anno/ApiResetType.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.anno; 2 | 3 | 4 | import androidx.annotation.IntDef; 5 | import static com.example.demo.anno.ApiResetType.ENABLE_EmptyView; 6 | import static com.example.demo.anno.ApiResetType.ENABLE_RecyclerView; 7 | import static com.example.demo.anno.ApiResetType.ENABLE_HookActionUpRecyclerview; 8 | import static com.example.demo.anno.ApiResetType.DISABLE; 9 | import static com.example.demo.anno.ApiResetType.ENABLE; 10 | 11 | @IntDef({DISABLE,ENABLE,ENABLE_EmptyView, ENABLE_RecyclerView, ENABLE_HookActionUpRecyclerview}) 12 | public @interface ApiResetType { 13 | int DISABLE = 0; 14 | int ENABLE = 1; 15 | int ENABLE_EmptyView = 11; 16 | int ENABLE_RecyclerView = 12; 17 | int ENABLE_HookActionUpRecyclerview = 13; 18 | } 19 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/anno/ChatPageType.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.anno; 2 | 3 | 4 | import androidx.annotation.IntDef; 5 | 6 | import static com.example.demo.anno.ChatPageType.DEFAULT; 7 | import static com.example.demo.anno.ChatPageType.COLOR_STATUS_BAR; 8 | import static com.example.demo.anno.ChatPageType.TITLE_BAR; 9 | import static com.example.demo.anno.ChatPageType.TRANSPARENT_STATUS_BAR; 10 | import static com.example.demo.anno.ChatPageType.TRANSPARENT_STATUS_BAR_DRAW_UNDER; 11 | import static com.example.demo.anno.ChatPageType.CUS_TITLE_BAR; 12 | 13 | @IntDef({DEFAULT, TITLE_BAR, COLOR_STATUS_BAR, CUS_TITLE_BAR, TRANSPARENT_STATUS_BAR, TRANSPARENT_STATUS_BAR_DRAW_UNDER}) 14 | public @interface ChatPageType { 15 | int DEFAULT = 0; 16 | int TITLE_BAR = 1; 17 | int CUS_TITLE_BAR = 2; 18 | int COLOR_STATUS_BAR = 3; 19 | int TRANSPARENT_STATUS_BAR = 4; 20 | int TRANSPARENT_STATUS_BAR_DRAW_UNDER = 5; 21 | } 22 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/chat/ChatFragmentActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.chat; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.graphics.Color; 6 | import android.os.Build; 7 | import android.os.Bundle; 8 | import android.util.Log; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.view.Window; 12 | import android.view.WindowManager; 13 | 14 | import androidx.annotation.NonNull; 15 | import androidx.annotation.Nullable; 16 | import androidx.appcompat.view.WindowCallbackWrapper; 17 | import androidx.core.content.ContextCompat; 18 | import androidx.databinding.DataBindingUtil; 19 | import androidx.fragment.app.Fragment; 20 | import androidx.fragment.app.FragmentActivity; 21 | import androidx.fragment.app.FragmentPagerAdapter; 22 | 23 | import com.effective.R; 24 | import com.effective.databinding.ActivityChatFragmentLayoutBinding; 25 | import com.example.demo.Constants; 26 | import com.example.demo.anno.ChatPageType; 27 | import com.example.demo.systemui.StatusbarHelper; 28 | 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | 32 | import static androidx.fragment.app.FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT; 33 | 34 | public class ChatFragmentActivity extends FragmentActivity { 35 | 36 | public static void startFragment(Context context, @ChatPageType int pageType) { 37 | Intent intent = new Intent(context, ChatFragmentActivity.class); 38 | intent.putExtra(Constants.KEY_PAGE_TYPE, pageType); 39 | context.startActivity(intent); 40 | } 41 | 42 | private ActivityChatFragmentLayoutBinding mBinding; 43 | private ChatFragment fragment; 44 | 45 | @Override 46 | protected void onCreate(@Nullable Bundle savedInstanceState) { 47 | super.onCreate(savedInstanceState); 48 | //涉及fragment页面沉浸的,建议统一都在fragment里面,这样做是为了多fragment的时候灵活控制 49 | mBinding = DataBindingUtil.setContentView(this, R.layout.activity_chat_fragment_layout); 50 | StatusbarHelper.setStatusBarColor(this, Color.TRANSPARENT); 51 | fragment = new ChatFragment(); 52 | fragment.setArguments(getIntent().getExtras()); 53 | getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, fragment).commit(); 54 | /* if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 55 | Window window = getWindow(); 56 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); 57 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 58 | window.setStatusBarColor(Color.TRANSPARENT); 59 | window.setNavigationBarColor(Color.TRANSPARENT); 60 | window.getDecorView().setSystemUiVisibility( 61 | window.getDecorView().getSystemUiVisibility() | 62 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | 63 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | 64 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); 65 | }*/ 66 | } 67 | 68 | @Override 69 | public void onBackPressed() { 70 | if (fragment != null && fragment.hookOnBackPressed()) { 71 | return; 72 | } 73 | super.onBackPressed(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/chat/adapter/ChatAdapter.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.chat.adapter; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.databinding.DataBindingUtil; 10 | import androidx.recyclerview.widget.RecyclerView; 11 | 12 | import com.effective.R; 13 | import com.effective.databinding.VhChatLeftLayoutBinding; 14 | import com.effective.databinding.VhChatRightLayoutBinding; 15 | import com.example.demo.scene.api.FixIssuesActivity4; 16 | 17 | import org.jetbrains.annotations.NotNull; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | /** 23 | * chatting pager adapter 24 | * Created by yummyLau on 18-7-11 25 | * Email: yummyl.lau@gmail.com 26 | * blog: yummylau.com 27 | */ 28 | public class ChatAdapter extends RecyclerView.Adapter { 29 | 30 | private List mData; 31 | private Context mContext; 32 | private ItemLongClickListener mItemLongClickListener; 33 | 34 | public ChatAdapter(Context context) { 35 | mData = new ArrayList<>(); 36 | mContext = context; 37 | } 38 | 39 | public ChatAdapter(Context context, List data) { 40 | if (data != null) { 41 | mData = data; 42 | } else { 43 | mData = new ArrayList<>(); 44 | } 45 | mContext = context; 46 | } 47 | 48 | public ChatAdapter(Context context, int count) { 49 | mData = new ArrayList<>(); 50 | for (int i = 0; i < count; i++) { 51 | mData.add(ChatInfo.CREATE("模拟数据第" + (i + 1) + "条")); 52 | } 53 | mContext = context; 54 | } 55 | 56 | public void insertInfo(ChatInfo chatInfo) { 57 | if (chatInfo != null) { 58 | mData.add(chatInfo); 59 | notifyItemInserted(mData.size() - 1); 60 | } 61 | } 62 | 63 | @Override 64 | public int getItemViewType(int position) { 65 | if (mData.get(position).owner) { 66 | return 0; 67 | } else { 68 | return 1; 69 | } 70 | } 71 | 72 | @NonNull 73 | @Override 74 | public ChatBaseVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 75 | if (viewType == 0) { 76 | VhChatRightLayoutBinding binding = 77 | DataBindingUtil.inflate(LayoutInflater.from(mContext), 78 | R.layout.vh_chat_right_layout, parent, false); 79 | return new ChatRightVH(binding); 80 | } else { 81 | VhChatLeftLayoutBinding binding = 82 | DataBindingUtil.inflate(LayoutInflater.from(mContext), 83 | R.layout.vh_chat_left_layout, parent, false); 84 | return new ChatLeftVH(binding); 85 | } 86 | } 87 | 88 | @Override 89 | @SuppressWarnings("unchecked") 90 | public void onBindViewHolder(ChatBaseVH holder, int position) { 91 | holder.bindData((mData.get(position)), position); 92 | holder.itemView.findViewById(R.id.text).setOnLongClickListener(new View.OnLongClickListener() { 93 | @Override 94 | public boolean onLongClick(View v) { 95 | if (mItemLongClickListener != null) { 96 | mItemLongClickListener.onItemLongClickListener(v, position); 97 | } 98 | return true; 99 | } 100 | }); 101 | } 102 | 103 | @Override 104 | public int getItemCount() { 105 | return mData.size(); 106 | } 107 | 108 | public void setItemLongClickListener(ItemLongClickListener listener) { 109 | mItemLongClickListener = listener; 110 | notifyDataSetChanged(); 111 | } 112 | 113 | public interface ItemLongClickListener { 114 | void onItemLongClickListener(View view, int position); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/chat/adapter/ChatBaseVH.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.chat.adapter; 2 | 3 | 4 | import androidx.databinding.ViewDataBinding; 5 | import androidx.recyclerview.widget.RecyclerView; 6 | 7 | /** 8 | * base {@link androidx.recyclerview.widget.RecyclerView} for chatting pager. 9 | * Created by yummyLau on 18-7-11 10 | * Email: yummyl.lau@gmail.com 11 | * blog: yummylau.com 12 | */ 13 | public abstract class ChatBaseVH extends RecyclerView.ViewHolder { 14 | 15 | protected dataBinding binding; 16 | protected data data; 17 | 18 | public ChatBaseVH(dataBinding binding) { 19 | super(binding.getRoot()); 20 | this.binding = binding; 21 | } 22 | 23 | @SuppressWarnings("unchecked") 24 | public abstract void bindData(data data, int position); 25 | } 26 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/chat/adapter/ChatInfo.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.chat.adapter; 2 | 3 | /** 4 | * the information of chatting item 5 | * Created by yummyLau on 18-7-11 6 | * Email: yummyl.lau@gmail.com 7 | * blog: yummylau.com 8 | */ 9 | public class ChatInfo { 10 | 11 | public String message; 12 | public boolean owner; 13 | public static boolean sBoolean = true; 14 | 15 | public ChatInfo(String message, boolean owner) { 16 | this.message = message; 17 | this.owner = owner; 18 | } 19 | 20 | public static ChatInfo CREATE(String message) { 21 | ChatInfo chatInfo = new ChatInfo(message, sBoolean); 22 | sBoolean = !sBoolean; 23 | return chatInfo; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/chat/adapter/ChatLeftVH.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.chat.adapter; 2 | 3 | 4 | import android.view.View; 5 | import android.widget.Toast; 6 | 7 | import com.effective.databinding.VhChatLeftLayoutBinding; 8 | import com.example.demo.scene.chat.ChatFragmentActivity; 9 | import com.example.demo.scene.chat.emotion.EmojiSpanBuilder; 10 | import com.example.demo.util.DisplayUtils; 11 | 12 | /** 13 | * the left of chatting item 14 | * Created by yummyLau on 18-7-11 15 | * Email: yummyl.lau@gmail.com 16 | * blog: yummylau.com 17 | */ 18 | public class ChatLeftVH extends ChatBaseVH { 19 | 20 | public ChatLeftVH(VhChatLeftLayoutBinding binding) { 21 | super(binding); 22 | } 23 | 24 | @Override 25 | public void bindData(ChatInfo chatInfo, int position) { 26 | binding.text.setText(EmojiSpanBuilder.buildEmotionSpannable(binding.getRoot().getContext(), chatInfo.message)); 27 | binding.avatar.setOnLongClickListener(new View.OnLongClickListener() { 28 | @Override 29 | public boolean onLongClick(View view) { 30 | Toast.makeText(view.getContext(),"长按了头像",Toast.LENGTH_SHORT).show(); 31 | return true; 32 | } 33 | }); 34 | binding.avatar.setOnClickListener(new View.OnClickListener() { 35 | @Override 36 | public void onClick(View view) { 37 | Toast.makeText(view.getContext(),"点击了头像",Toast.LENGTH_SHORT).show(); 38 | } 39 | }); 40 | binding.text.setOnLongClickListener(new View.OnLongClickListener() { 41 | @Override 42 | public boolean onLongClick(View view) { 43 | Toast.makeText(view.getContext(),"长按了消息",Toast.LENGTH_SHORT).show(); 44 | return true; 45 | } 46 | }); 47 | binding.text.setOnClickListener(new View.OnClickListener() { 48 | @Override 49 | public void onClick(View view) { 50 | Toast.makeText(view.getContext(),"点击了消息",Toast.LENGTH_SHORT).show(); 51 | } 52 | }); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/chat/adapter/ChatRightVH.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.chat.adapter; 2 | 3 | import android.view.View; 4 | import android.widget.Toast; 5 | 6 | import com.effective.databinding.VhChatRightLayoutBinding; 7 | import com.example.demo.scene.chat.emotion.EmojiSpanBuilder; 8 | 9 | /** 10 | * the right of chatting item 11 | * Created by yummyLau on 18-7-11 12 | * Email: yummyl.lau@gmail.com 13 | * blog: yummylau.com 14 | */ 15 | public class ChatRightVH extends ChatBaseVH { 16 | 17 | public ChatRightVH(VhChatRightLayoutBinding binding) { 18 | super(binding); 19 | } 20 | 21 | @Override 22 | public void bindData(ChatInfo chatInfo, int position) { 23 | binding.text.setText(EmojiSpanBuilder.buildEmotionSpannable(binding.getRoot().getContext(), chatInfo.message)); 24 | binding.avatar.setOnLongClickListener(new View.OnLongClickListener() { 25 | @Override 26 | public boolean onLongClick(View view) { 27 | Toast.makeText(view.getContext(),"长按了头像",Toast.LENGTH_SHORT).show(); 28 | return true; 29 | } 30 | }); 31 | binding.avatar.setOnClickListener(new View.OnClickListener() { 32 | @Override 33 | public void onClick(View view) { 34 | Toast.makeText(view.getContext(),"点击了头像",Toast.LENGTH_SHORT).show(); 35 | } 36 | }); 37 | binding.text.setOnLongClickListener(new View.OnLongClickListener() { 38 | @Override 39 | public boolean onLongClick(View view) { 40 | Toast.makeText(view.getContext(),"长按了消息",Toast.LENGTH_SHORT).show(); 41 | return true; 42 | } 43 | }); 44 | binding.text.setOnClickListener(new View.OnClickListener() { 45 | @Override 46 | public void onClick(View view) { 47 | Toast.makeText(view.getContext(),"点击了消息",Toast.LENGTH_SHORT).show(); 48 | } 49 | }); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/chat/emotion/CenterImageSpan.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.chat.emotion; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.Rect; 6 | import android.graphics.drawable.Drawable; 7 | import android.text.style.ImageSpan; 8 | 9 | /** 10 | * 处理图文混排时图片居中 11 | * ascent 为字体最上端到基线的距离,为负值 12 | * descent 为字体最下端到基线的距离,为正值 13 | * Created by yummyLau on 2018/6/15. 14 | * Email: yummyl.lau@gmail.com 15 | * blog: yummylau.com 16 | */ 17 | public class CenterImageSpan extends ImageSpan { 18 | 19 | public CenterImageSpan(Drawable drawable) { 20 | super(drawable); 21 | } 22 | 23 | /** 24 | * @param paint 25 | * @param text 26 | * @param start 27 | * @param end 28 | * @param fontMetricsInt 29 | * @return 30 | */ 31 | public int getSize(Paint paint, CharSequence text, int start, int end, 32 | Paint.FontMetricsInt fontMetricsInt) { 33 | Drawable drawable = getDrawable(); 34 | Rect rect = drawable.getBounds(); 35 | if (fontMetricsInt != null) { 36 | 37 | //获取绘制字体的度量 38 | Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt(); 39 | int fontHeight = fmPaint.bottom - fmPaint.top; 40 | int drHeight = rect.bottom - rect.top; 41 | 42 | int top = drHeight / 2 - fontHeight / 4; 43 | int bottom = drHeight / 2 + fontHeight / 4; 44 | 45 | fontMetricsInt.ascent = -bottom; 46 | fontMetricsInt.top = -bottom; 47 | fontMetricsInt.bottom = top; 48 | fontMetricsInt.descent = top; 49 | } 50 | return rect.right; 51 | } 52 | 53 | /** 54 | * @param canvas 55 | * @param text 56 | * @param start 57 | * @param end 58 | * @param x 要绘制的image的左边框到textview左边框的距离。 59 | * @param top 替换行的最顶部位置 60 | * @param y 要替换的文字的基线坐标,即基线到textview上边框的距离 61 | * @param bottom 替换行的最底部位置。注意,textview中两行之间的行间距是属于上一行的,所以这里bottom是指行间隔的底部位置 62 | * @param paint 63 | */ 64 | @Override 65 | public void draw(Canvas canvas, CharSequence text, int start, int end, 66 | float x, int top, int y, int bottom, Paint paint) { 67 | 68 | Drawable drawable = getDrawable(); 69 | Paint.FontMetricsInt fm = paint.getFontMetricsInt(); 70 | 71 | /** 72 | * y + fm.descent 字体的descent线 y坐标 73 | * y + fm.ascent 字体的ascent线 y坐标 74 | * drawble.getBounds().bottom 图片的高度 75 | */ 76 | int transY = (int) (1f / 2 * (y + fm.descent + y + fm.ascent - drawable.getBounds().bottom)); 77 | canvas.save(); 78 | canvas.translate(x, transY); 79 | drawable.draw(canvas); 80 | canvas.restore(); 81 | } 82 | } -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/chat/emotion/EditTextSelector.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.chat.emotion; 2 | 3 | import android.widget.EditText; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | /** 8 | * author : linzheng 9 | * e-mail : z.hero.dodge@gmail.com 10 | * time : 2022/11/3 11 | * desc : 当页面含有多个EditText时,根据业务选中当前获得焦点的EditText 12 | * version: 1.0 13 | */ 14 | public interface EditTextSelector { 15 | 16 | @NonNull 17 | EditText getEditText(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/chat/emotion/EmojiSpanBuilder.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.chat.emotion; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.Drawable; 5 | import android.text.Spannable; 6 | import android.text.SpannableString; 7 | 8 | import androidx.core.content.ContextCompat; 9 | 10 | import com.example.demo.util.DisplayUtils; 11 | 12 | import java.util.regex.Matcher; 13 | import java.util.regex.Pattern; 14 | 15 | /** 16 | * Created by yummyLau on 18-7-11 17 | * Email: yummyl.lau@gmail.com 18 | * blog: yummylau.com 19 | */ 20 | public class EmojiSpanBuilder { 21 | 22 | private static Pattern sPatternEmotion = 23 | Pattern.compile("\\[([\u4e00-\u9fa5\\w])+\\]|[\\ud83c\\udc00-\\ud83c\\udfff]|[\\ud83d\\udc00-\\ud83d\\udfff]|[\\u2600-\\u27ff]"); 24 | 25 | public static Spannable buildEmotionSpannable(Context context, String text) { 26 | Matcher matcherEmotion = sPatternEmotion.matcher(text); 27 | SpannableString spannableString = new SpannableString(text); 28 | while (matcherEmotion.find()) { 29 | String key = matcherEmotion.group(); 30 | int imgRes = Emotions.getDrawableResByName(key); 31 | if (imgRes != -1) { 32 | int start = matcherEmotion.start(); 33 | Drawable drawable = ContextCompat.getDrawable(context, imgRes); 34 | drawable.setBounds(0, 0, DisplayUtils.dip2px(context, 20f), DisplayUtils.dip2px(context, 20f)); 35 | CenterImageSpan span = new CenterImageSpan(drawable); 36 | spannableString.setSpan(span, start, start + key.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 37 | } 38 | } 39 | 40 | return spannableString; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/chat/emotion/Emotion.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.chat.emotion; 2 | 3 | 4 | import androidx.annotation.DrawableRes; 5 | 6 | /** 7 | * Created by yummyLau on 18-7-11 8 | * Email: yummyl.lau@gmail.com 9 | * blog: yummylau.com 10 | */ 11 | public class Emotion { 12 | 13 | public String text; 14 | 15 | @DrawableRes 16 | public int drawableRes; 17 | 18 | public Emotion(String text, @DrawableRes int drawableRes) { 19 | this.text = text; 20 | this.drawableRes = drawableRes; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/chat/view/AutoHidePanelRecyclerView.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.chat.view; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.MotionEvent; 6 | import android.view.View; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.annotation.Nullable; 10 | import androidx.recyclerview.widget.LinearLayoutManager; 11 | import androidx.recyclerview.widget.RecyclerView; 12 | 13 | import com.effective.R; 14 | import com.effective.android.panel.PanelSwitchHelper; 15 | 16 | public class AutoHidePanelRecyclerView extends RecyclerView { 17 | 18 | PanelSwitchHelper panelSwitchHelper; 19 | 20 | public void setPanelSwitchHelper(PanelSwitchHelper panelSwitchHelper) { 21 | this.panelSwitchHelper = panelSwitchHelper; 22 | } 23 | 24 | public AutoHidePanelRecyclerView(Context context) { 25 | this(context, null); 26 | } 27 | 28 | public AutoHidePanelRecyclerView(Context context, @Nullable AttributeSet attrs) { 29 | this(context, attrs, 0); 30 | } 31 | 32 | 33 | public AutoHidePanelRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { 34 | super(context, attrs, defStyle); 35 | setLayoutManager(new LinearLayoutManager(context)); 36 | } 37 | 38 | @Override 39 | public boolean onTouchEvent(MotionEvent e) { 40 | if (e != null && e.getAction() != MotionEvent.ACTION_CANCEL) { 41 | if (panelSwitchHelper != null) { 42 | panelSwitchHelper.hookSystemBackByPanelSwitcher(); 43 | } 44 | } 45 | return super.onTouchEvent(e); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/viewpager/ChatFragmentPagerAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.viewpager 2 | 3 | import android.os.Bundle 4 | import androidx.fragment.app.Fragment 5 | import androidx.fragment.app.FragmentManager 6 | import androidx.fragment.app.FragmentPagerAdapter 7 | import com.example.demo.Constants 8 | import com.example.demo.anno.ChatPageType 9 | import com.example.demo.scene.chat.ChatFragment 10 | 11 | /** 12 | * author : linzheng 13 | * e-mail : z.hero.dodge@gmail.com 14 | * time : 2023/6/29 15 | * desc : 16 | * version: 1.0 17 | */ 18 | class ChatFragmentPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { 19 | 20 | 21 | override fun getCount(): Int { 22 | return 3 23 | } 24 | 25 | override fun getItem(position: Int): Fragment { 26 | val chatFragment = ChatFragment() 27 | val arguments = Bundle().apply { 28 | putInt(Constants.KEY_PAGE_TYPE, ChatPageType.DEFAULT) 29 | putBoolean(Constants.RELEASE_WITH_PAGER, true) 30 | } 31 | chatFragment.arguments = arguments 32 | return chatFragment 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/viewpager/ViewPager2Activity.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.viewpager 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.graphics.Color 6 | import android.os.Bundle 7 | import android.view.Window 8 | import androidx.appcompat.app.AppCompatActivity 9 | import androidx.fragment.app.Fragment 10 | import androidx.fragment.app.FragmentActivity 11 | import androidx.viewpager2.adapter.FragmentStateAdapter 12 | import androidx.viewpager2.widget.ViewPager2 13 | import com.effective.R 14 | import com.example.demo.Constants 15 | import com.example.demo.anno.ChatPageType 16 | import com.example.demo.scene.chat.ChatFragment 17 | import com.example.demo.systemui.StatusbarHelper 18 | import kotlinx.android.synthetic.main.activity_view_pager_2_layout.view_pager 19 | 20 | /** 21 | * author : linzheng 22 | * e-mail : z.hero.dodge@gmail.com 23 | * time : 2023/6/29 24 | * desc : 25 | * version: 1.0 26 | */ 27 | class ViewPager2Activity : AppCompatActivity() { 28 | 29 | 30 | val orientation by lazy { intent.getIntExtra("extras_orientation", ViewPager2.ORIENTATION_VERTICAL) } 31 | 32 | 33 | companion object { 34 | @JvmStatic 35 | fun start(context: Context, orientation: Int) { 36 | val intent = Intent(context, ViewPager2Activity::class.java) 37 | intent.putExtra("extras_orientation", orientation) 38 | context.startActivity(intent) 39 | } 40 | } 41 | 42 | 43 | override fun onCreate(savedInstanceState: Bundle?) { 44 | super.onCreate(savedInstanceState) 45 | supportRequestWindowFeature(Window.FEATURE_NO_TITLE) 46 | StatusbarHelper.setStatusBarColor(this, Color.TRANSPARENT) 47 | setContentView(R.layout.activity_view_pager_2_layout) 48 | view_pager.orientation = orientation 49 | view_pager.adapter = ChatFragmentPager2Adapter(this) 50 | } 51 | 52 | } 53 | 54 | 55 | class ChatFragmentPager2Adapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) { 56 | 57 | override fun getItemCount(): Int { 58 | return 5 59 | } 60 | 61 | override fun createFragment(position: Int): Fragment { 62 | val chatFragment = ChatFragment() 63 | val arguments = Bundle().apply { 64 | putInt(Constants.KEY_PAGE_TYPE, ChatPageType.DEFAULT) 65 | putBoolean(Constants.RELEASE_WITH_PAGER, true) 66 | } 67 | chatFragment.arguments = arguments 68 | return chatFragment 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/scene/viewpager/ViewPagerActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.viewpager 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.graphics.Color 6 | import android.os.Bundle 7 | import android.view.Window 8 | import androidx.appcompat.app.AppCompatActivity 9 | import com.effective.R 10 | import com.example.demo.systemui.StatusbarHelper 11 | import kotlinx.android.synthetic.main.activity_view_pager_layout.view_pager 12 | 13 | /** 14 | * author : linzheng 15 | * e-mail : z.hero.dodge@gmail.com 16 | * time : 2023/6/29 17 | * desc : 18 | * version: 1.0 19 | */ 20 | class ViewPagerActivity : AppCompatActivity() { 21 | 22 | 23 | companion object { 24 | 25 | @JvmStatic 26 | fun start(context: Context) { 27 | val intent = Intent(context, ViewPagerActivity::class.java) 28 | context.startActivity(intent) 29 | } 30 | } 31 | 32 | override fun onCreate(savedInstanceState: Bundle?) { 33 | super.onCreate(savedInstanceState) 34 | supportRequestWindowFeature(Window.FEATURE_NO_TITLE) 35 | StatusbarHelper.setStatusBarColor(this, Color.TRANSPARENT) 36 | setContentView(R.layout.activity_view_pager_layout) 37 | view_pager.adapter = ChatFragmentPagerAdapter(supportFragmentManager) 38 | } 39 | 40 | 41 | } -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/systemui/StatusBarView.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.systemui; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.os.Build; 6 | import android.util.AttributeSet; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.widget.LinearLayout; 10 | 11 | import com.effective.R; 12 | 13 | import java.lang.reflect.Field; 14 | 15 | import androidx.annotation.ColorRes; 16 | import androidx.annotation.Nullable; 17 | import androidx.core.content.ContextCompat; 18 | 19 | /** 20 | * 状态栏view 21 | * Created by yummylau on 2017/9/09. 22 | */ 23 | 24 | public class StatusBarView extends LinearLayout { 25 | 26 | @ColorRes 27 | private int mStatusBarColor; 28 | 29 | public StatusBarView(Context context) { 30 | this(context, null); 31 | } 32 | 33 | public StatusBarView(Context context, @Nullable AttributeSet attrs) { 34 | this(context, attrs, 0); 35 | } 36 | 37 | public StatusBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 38 | super(context, attrs, defStyleAttr); 39 | initView(attrs, defStyleAttr); 40 | } 41 | 42 | private void initView(AttributeSet attrs, int defStyle) { 43 | View view = LayoutInflater.from(getContext()).inflate(R.layout.view_status_bar_layout, this, true); 44 | final TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.StatusBarView, defStyle, 0); 45 | if (typedArray != null) { 46 | mStatusBarColor = typedArray.getResourceId(R.styleable.StatusBarView_status_bar_color, R.color.colorPrimary); 47 | } else { 48 | mStatusBarColor = R.color.colorPrimary; 49 | } 50 | setBackgroundColor(ContextCompat.getColor(getContext(), mStatusBarColor)); 51 | view.findViewById(R.id.status_bar).setMinimumHeight(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? getStatusBarHeight(getContext()) : 0); 52 | } 53 | 54 | public void setColor(@ColorRes int statusBarColor) { 55 | mStatusBarColor = statusBarColor; 56 | setBackgroundColor(ContextCompat.getColor(getContext(), mStatusBarColor)); 57 | } 58 | 59 | 60 | public static int getStatusBarHeight(Context context) { 61 | int sbar = 0; 62 | try { 63 | Class c = Class.forName("com.android.internal.R$dimen"); 64 | Object obj = c.newInstance(); 65 | Field field = c.getField("status_bar_height"); 66 | int x = Integer.parseInt(field.get(obj).toString()); 67 | sbar = context.getResources().getDimensionPixelSize(x); 68 | } catch (Exception var7) { 69 | // var7.printStackTrace(); 70 | } 71 | return sbar; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app-androidx/src/main/java/com/example/demo/util/DisplayUtils.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.util; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.pm.ActivityInfo; 6 | import android.content.res.Configuration; 7 | import android.util.DisplayMetrics; 8 | import android.util.Pair; 9 | 10 | import java.lang.reflect.Field; 11 | 12 | /** 13 | * Created by yummyLau on 18-7-11 14 | * Email: yummyl.lau@gmail.com 15 | * blog: yummylau.com 16 | */ 17 | public class DisplayUtils { 18 | 19 | public static int dip2px(Context context, float dipValue) { 20 | final float scale = context.getResources().getDisplayMetrics().density; 21 | return (int) (dipValue * scale + 0.5f); 22 | } 23 | 24 | public static Pair getScreenSize(Context context) { 25 | DisplayMetrics dm = context.getResources().getDisplayMetrics(); 26 | return new Pair(dm.widthPixels, dm.heightPixels); 27 | } 28 | 29 | public static boolean isPortrait(Context context){ 30 | return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; 31 | 32 | } 33 | 34 | public static void checkoutOrientation(Activity activity) { 35 | activity.setRequestedOrientation(isPortrait(activity) ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 36 | } 37 | 38 | public static int getStatusBarHeight(Context context) { 39 | int result = 0; 40 | try { 41 | Class c = Class.forName("com.android.internal.R$dimen"); 42 | Object o = c.newInstance(); 43 | Field field = c.getField("status_bar_height"); 44 | int x = (Integer)field.get(o); 45 | result = context.getResources().getDimensionPixelSize(x); 46 | } catch (Exception var6) { 47 | var6.printStackTrace(); 48 | } 49 | 50 | if (result == 0) { 51 | result = dip2px(context, 25.0F); 52 | } 53 | 54 | return result; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app-androidx/src/main/kotlin/com/example/demo/scene/api/CusPanelView.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.api 2 | 3 | import android.content.Context 4 | import android.graphics.Color 5 | import android.util.AttributeSet 6 | import android.view.Gravity 7 | import androidx.appcompat.widget.AppCompatTextView 8 | import com.effective.R 9 | import com.effective.android.panel.view.panel.IPanelView 10 | 11 | class CusPanelView : IPanelView, AppCompatTextView { 12 | 13 | private var triggerViewId = 0 14 | private var isToggle = true 15 | 16 | constructor(context: Context?) : this(context, null) 17 | constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0) 18 | constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { 19 | initView(attrs, defStyleAttr, 0) 20 | } 21 | 22 | private fun initView(attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) { 23 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CusPanelView, defStyleAttr, defStyleRes) 24 | triggerViewId = typedArray.getResourceId(R.styleable.CusPanelView_cus_panel_trigger, -1) 25 | isToggle = typedArray.getBoolean(R.styleable.CusPanelView_cus_panel_toggle, isToggle) 26 | typedArray.recycle() 27 | setBackgroundColor(Color.BLACK) 28 | text = "自定义面板" 29 | gravity = Gravity.CENTER 30 | setTextColor(Color.WHITE) 31 | textSize = 20f 32 | } 33 | 34 | override fun getBindingTriggerViewId(): Int = triggerViewId 35 | 36 | override fun isTriggerViewCanToggle(): Boolean = isToggle 37 | 38 | override fun isShowing(): Boolean = isShown 39 | 40 | override fun assertView() { 41 | if (triggerViewId == -1) { 42 | throw RuntimeException("PanelView -- you must set 'panel_layout' and panel_trigger by Integer id") 43 | } 44 | } 45 | 46 | override fun onFinishInflate() { 47 | super.onFinishInflate() 48 | assertView() 49 | } 50 | } -------------------------------------------------------------------------------- /app-androidx/src/main/kotlin/com/example/demo/scene/api/FloatContentView.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.api 2 | 3 | import android.annotation.TargetApi 4 | import android.app.Activity 5 | import android.content.Context 6 | import android.util.AttributeSet 7 | import android.util.Log 8 | import android.view.KeyEvent 9 | import android.view.LayoutInflater 10 | import android.widget.FrameLayout 11 | import androidx.databinding.DataBindingUtil 12 | import androidx.recyclerview.widget.LinearLayoutManager 13 | import com.effective.R 14 | import com.effective.android.panel.PanelSwitchHelper 15 | import com.effective.databinding.ViewFloatContentLayoutBinding 16 | import com.example.demo.scene.chat.adapter.ChatAdapter 17 | 18 | /** 19 | * author : linzheng 20 | * time : 2022/6/17 21 | * desc : 22 | * version: 1.0 23 | */ 24 | class FloatContentView : FrameLayout { 25 | 26 | companion object { 27 | 28 | private const val TAG = "FloatContentView" 29 | 30 | } 31 | 32 | private lateinit var dataBinding: ViewFloatContentLayoutBinding 33 | var backPressedListener: (() -> Boolean)? = null 34 | 35 | 36 | @JvmOverloads 37 | constructor(context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(context!!, attrs, defStyleAttr) { 38 | initView() 39 | } 40 | 41 | @TargetApi(21) 42 | constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context!!, attrs, defStyleAttr, defStyleRes) { 43 | initView() 44 | } 45 | 46 | private fun initView() { 47 | val layoutInflater = LayoutInflater.from(context) 48 | dataBinding = DataBindingUtil.inflate(layoutInflater, R.layout.view_float_content_layout, this, true) 49 | dataBinding.recyclerView.layoutManager = LinearLayoutManager(context) 50 | dataBinding.recyclerView.adapter = ChatAdapter(context, 30) 51 | dataBinding.ivBack.setOnClickListener { FloatWindowManager.removeViewWithoutPermission(context) } 52 | } 53 | 54 | 55 | override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { 56 | Log.d(TAG, "onKeyDown: ") 57 | return super.onKeyDown(keyCode, event) 58 | } 59 | 60 | 61 | override fun onAttachedToWindow() { 62 | super.onAttachedToWindow() 63 | val activity = context as? Activity 64 | val helper = PanelSwitchHelper.Builder(activity?.window, this) 65 | .setWindowInsetsRootView(this) 66 | .addKeyboardStateListener { 67 | onKeyboardChange { visible, height -> 68 | Log.d(TAG, "系统键盘是否可见 : $visible ,高度为:$height") 69 | } 70 | } 71 | .addPanelChangeListener { 72 | onKeyboard { 73 | Log.d(TAG, "唤起系统输入法") 74 | } 75 | onNone { 76 | Log.d(TAG, "隐藏所有面板") 77 | } 78 | onPanel { 79 | Log.d(TAG, "唤起面板 : $it") 80 | } 81 | } 82 | .build() 83 | } 84 | 85 | private var downTime = 0L 86 | 87 | override fun dispatchKeyEvent(event: KeyEvent?): Boolean { 88 | if (event?.keyCode == KeyEvent.KEYCODE_BACK) { 89 | if (event.action == KeyEvent.ACTION_UP) { 90 | if (event.downTime == downTime && !event.isCanceled && backPressedListener?.invoke() == true) { 91 | downTime = 0L 92 | return true 93 | } 94 | downTime = 0L 95 | } else if (event.action == KeyEvent.ACTION_DOWN) { 96 | downTime = event.eventTime 97 | } 98 | } 99 | return super.dispatchKeyEvent(event) 100 | } 101 | 102 | 103 | override fun dispatchKeyEventPreIme(event: KeyEvent?): Boolean { 104 | return super.dispatchKeyEventPreIme(event) 105 | } 106 | 107 | override fun dispatchKeyShortcutEvent(event: KeyEvent?): Boolean { 108 | return super.dispatchKeyShortcutEvent(event) 109 | } 110 | 111 | 112 | } 113 | -------------------------------------------------------------------------------- /app-androidx/src/main/kotlin/com/example/demo/scene/api/SystemProperties.kt: -------------------------------------------------------------------------------- 1 | package com.example.demo.scene.api 2 | 3 | import android.text.TextUtils 4 | import java.lang.reflect.Method 5 | 6 | /** 7 | * author : linzheng 8 | * desc : 9 | * version: 1.0 10 | */ 11 | object SystemProperties { 12 | 13 | private val getStringProperty = getMethod(getClass("android.os.SystemProperties")) 14 | 15 | private fun getClass(name: String): Class<*>? { 16 | return try { 17 | val cls = Class.forName(name) ?: throw ClassNotFoundException() 18 | cls 19 | } catch (e: ClassNotFoundException) { 20 | try { 21 | ClassLoader.getSystemClassLoader().loadClass(name) 22 | } catch (e1: ClassNotFoundException) { 23 | null 24 | } 25 | } 26 | } 27 | 28 | private fun getMethod(clz: Class<*>?): Method? { 29 | return if (clz == null) null else try { 30 | clz.getMethod("get", String::class.java) 31 | } catch (e: Exception) { 32 | null 33 | } 34 | } 35 | 36 | operator fun get(key: String?): String? { 37 | if (getStringProperty != null) { 38 | try { 39 | val value = getStringProperty.invoke(null, key) ?: return "" 40 | return trimToEmpty(value.toString()) 41 | } catch (ignored: Exception) { 42 | } 43 | } 44 | return "" 45 | } 46 | 47 | operator fun get(key: String, def: String?): String? { 48 | if (getStringProperty != null) { 49 | try { 50 | val value = getStringProperty.invoke(null, key) as String 51 | return defaultString(trimToNull(value), def) 52 | } catch (ignored: Exception) { 53 | } 54 | } 55 | return def 56 | } 57 | 58 | private fun defaultString(str: String?, defaultStr: String?): String? { 59 | return str ?: defaultStr 60 | } 61 | 62 | private fun trimToNull(str: String): String? { 63 | val ts = trim(str) 64 | return if (TextUtils.isEmpty(ts)) null else ts 65 | } 66 | 67 | private fun trimToEmpty(str: String?): String? { 68 | return str?.trim { it <= ' ' } ?: "" 69 | } 70 | 71 | private fun trim(str: String?): String? { 72 | return str?.trim { it <= ' ' } 73 | } 74 | 75 | } -------------------------------------------------------------------------------- /app-androidx/src/main/res/anim/anim_feed_pop_hide.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/anim/anim_feed_pop_show.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/color/color_send_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/avatar_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/avatar_android.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/avatar_cat.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/avatar_cat.jpeg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/bg_gradient.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/bg_gradient.jpeg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/chat_left_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/chat_left_bg.9.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/chat_right_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/chat_right_bg.9.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_1.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_10.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_101.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_101.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_102.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_102.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_103.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_103.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_104.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_104.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_105.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_105.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_106.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_106.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_107.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_107.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_108.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_108.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_109.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_109.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_11.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_111.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_111.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_113.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_113.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_114.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_115.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_115.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_116.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_116.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_117.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_117.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_118.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_118.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_119.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_119.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_12.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_13.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_14.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_15.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_16.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_18.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_19.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_2.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_20.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_21.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_22.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_23.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_24.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_26.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_27.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_28.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_29.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_3.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_30.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_31.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_32.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_33.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_34.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_35.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_37.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_38.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_39.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_4.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_40.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_41.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_42.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_43.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_45.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_46.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_47.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_48.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_49.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_5.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_50.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_51.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_52.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_53.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_55.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_56.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_57.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_58.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_6.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_61.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_61.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_63.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_63.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_64.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_65.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_65.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_66.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_66.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_67.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_67.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_68.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_68.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_69.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_69.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_7.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_71.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_71.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_75.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_76.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_77.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_77.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_79.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_79.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_8.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_80.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_81.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_81.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_82.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_82.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_83.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_83.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_84.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_84.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_85.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_85.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_86.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_86.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_9.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_90.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_93.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_93.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_94.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_94.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_95.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_95.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_96.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_97.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_97.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_98.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_98.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/expression_99.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/expression_99.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_input_send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_input_send.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_input_send_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_input_send_select.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_input_tip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_input_tip.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_panel_key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_panel_key.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_panel_key_l.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_panel_key_l.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_panel_key_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_panel_key_select.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_video_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_video_back.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_video_checkout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_bilibili_video_checkout.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_douyin_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_douyin_close.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_douyin_gift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_douyin_gift.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_douyin_live_user.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_douyin_live_user.jpg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_douyin_love.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_douyin_love.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_douyin_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_douyin_more.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_douyin_send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_douyin_send.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_feed_action_comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_feed_action_comment.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_feed_action_like.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_feed_action_like.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_feed_avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_feed_avatar.jpg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_feed_cover.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_feed_cover.jpeg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_icon.png -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_0.jpg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_1.jpg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_2.jpg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_3.jpg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_4.jpg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_5.jpg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_6.jpg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_7.jpg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_8.jpg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/drawable-xxhdpi/ic_uzi_9.jpg -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/icon_account.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/icon_add.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/icon_camera.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/icon_emotion.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/icon_image.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/icon_keyboard.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/icon_location.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/icon_video.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/icon_voice.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/se_bilibili_input_send.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/se_bilibili_panel_key_l.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/se_bilibili_panel_key_p.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/se_douyin_action_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/se_huya_comment_send_p.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/se_wechat_comment_send.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/selector_edit_focus.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/selector_emotion_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/selector_send_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_activity_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_bilibili_input_l.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_bilibili_input_l_but_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_bilibili_input_p.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_bilibili_panel_item_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_bilibili_panel_item_select_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_content_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_douyin_follow_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_douyin_time_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_douyin_user_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_feed_action.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_fragment_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_huya_edit_cursor.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_panel_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_pop_feed_action.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_reset_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_special_page_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_tip_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_video_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/sh_wechat_comment_input.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/shape_edit_cursor.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/shape_edit_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/shape_edit_unselected.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/shape_input_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/drawable/shape_video_input_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/activity_chat_fragment_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/activity_feed_dialog_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 13 | 14 | 18 | 19 | 23 | 24 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/activity_fix_issues_layout3.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | 18 | 28 | 29 | 44 | 45 | 46 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/activity_main_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 16 | 17 | 24 | 25 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/activity_test_second_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/activity_view_pager_2_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/activity_view_pager_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/holder_douyin_chat_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 20 | 21 | 31 | 32 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/holder_feed_cover_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 13 | 23 | 24 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/holder_feed_item_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 15 | 16 | 27 | 28 | 39 | 40 | 52 | 53 | 64 | 65 | 80 | 81 | 87 | 88 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/holder_huya_chat_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/list_parent_title_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14 | 15 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/list_sub_title_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 20 | 21 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/panel_emotion_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 28 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/panel_include_edit_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 20 | 21 | 35 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/pop_feed_action_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 17 | 18 | 24 | 25 | 34 | 35 | 36 | 37 | 38 | 43 | 44 | 51 | 52 | 53 | 59 | 60 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/pop_huya_live_comment_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 19 | 20 | 25 | 26 | 43 | 44 | 51 | 52 | 66 | 67 | 68 | 69 | 74 | 75 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/vh_chat_left_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 16 | 17 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/vh_chat_right_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 20 | 21 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/vh_emotion_item_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/layout/view_status_bar_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/raw/uzi.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/raw/uzi.mp4 -------------------------------------------------------------------------------- /app-androidx/src/main/res/raw/yexiaoma.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/app-androidx/src/main/res/raw/yexiaoma.mp4 -------------------------------------------------------------------------------- /app-androidx/src/main/res/values/attr.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | #FAFAFA 8 | #F5F5F5 9 | #EEEEEE 10 | #E0E0E0 11 | #BDBDBD 12 | #9E9E9E 13 | #757575 14 | #616161 15 | #424242 16 | #212121 17 | 18 | #ebebeb 19 | @android:color/white 20 | #2196F3 21 | #009688 22 | #FFC107 23 | #FF5722 24 | #673AB7 25 | #8BC34A 26 | #E91E63 27 | #212121 28 | #00BCD4 29 | 30 | #5FFFFFFF 31 | 32 | 33 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | -1dp 3 | 1dp 4 | 3dp 5 | 5dp 6 | 7.5dp 7 | 10dp 8 | 15dp 9 | 20dp 10 | 30dp 11 | 35dp 12 | 40dp 13 | 50dp 14 | 60dp 15 | 80dp 16 | 200dp 17 | 250dp 18 | 19 | 20 | 10sp 21 | 12sp 22 | 14sp 23 | 16sp 24 | 20sp 25 | 15sp 26 | 27 | 1px 28 | -1px 29 | 30 | 25dp 31 | 32 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 切换面板框架演示 - Androidx 3 | 我是一个dialog 4 | 我是一个pupupwindow 5 | 我是一个dialogfragment 6 | 发送 7 | 提示信息:\n框架支持任何页面的沉浸,基本满足绝大部分 app 页面 UI 涉及。完全全屏的页面接入请参考视频场景下的横屏处理。框架 Demo 提供 聊天/视频/信息流/直播 等主流场景方案,如遇到疑惑请备注\n \"机型-版本-框架版本-场景简述\" 作为标题提交 issue 并附上伪代码或者代码进行详细描述。所有问题都会第一时间得到作者回应。 8 | 9 | 相册 10 | 拍摄 11 | 视频通话 12 | 位置 13 | 语音输入 14 | 名片 15 | 16 | -------------------------------------------------------------------------------- /app-androidx/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 17 | 18 | 22 | 23 | 29 | 30 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | apply from: 'versions.gradle' 5 | ext { 6 | kotlin_version = '1.3.71' 7 | } 8 | 9 | repositories { 10 | google() 11 | jcenter() 12 | maven { url 'https://jitpack.io' } 13 | } 14 | dependencies { 15 | classpath "com.android.tools.build:gradle:$versions.android_gradle_plugin" 16 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 17 | } 18 | } 19 | 20 | allprojects { 21 | repositories { 22 | google() 23 | jcenter() 24 | maven { url 'https://jitpack.io' } 25 | } 26 | gradle.projectsEvaluated { 27 | tasks.withType(JavaCompile) { 28 | options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" 29 | } 30 | } 31 | 32 | tasks.withType(Javadoc) { 33 | options.addStringOption('Xdoclint:none', '-quiet') 34 | options.addStringOption('encoding', 'UTF-8') 35 | options.addStringOption('charSet', 'UTF-8') 36 | } 37 | } 38 | 39 | task clean(type: Delete) { 40 | delete rootProject.buildDir 41 | } 42 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | ## For more details on how to configure your build environment visit 2 | # http://www.gradle.org/docs/current/userguide/build_environment.html 3 | # 4 | # Specifies the JVM arguments used for the daemon process. 5 | # The setting is particularly useful for tweaking memory settings. 6 | # Default value: -Xmx1024m -XX:MaxPermSize=256m 7 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 8 | # 9 | # When configured, Gradle will run in incubating parallel mode. 10 | # This option should only be used with decoupled projects. More details, visit 11 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 12 | # org.gradle.parallel=true 13 | #Fri Jun 12 11:17:21 CST 2020 14 | android.enableJetifier=true 15 | android.useAndroidX=true 16 | android_gradle_plugin=4.1.2 17 | org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" 18 | # mac 升级到 BigSur java 环境发生改变,主动申明 19 | #org.gradle.java.home=/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Jul 09 17:35:50 CST 2018 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-7.2-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /panel-androidx/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /panel-androidx/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | apply plugin: 'maven-publish' 5 | 6 | android { 7 | compileSdkVersion config.compile_sdk_version 8 | 9 | defaultConfig { 10 | multiDexEnabled true 11 | minSdkVersion config.min_sdk_version 12 | targetSdkVersion config.target_sdk_version 13 | versionCode config.version_code 14 | versionName config.version_name 15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 16 | } 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | 25 | } 26 | 27 | dependencies { 28 | implementation fileTree(dir: 'libs', include: ['*.jar']) 29 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 30 | implementation deps.androidx.annotations 31 | implementation deps.androidx.core 32 | implementation deps.androidx.appcompat 33 | } 34 | 35 | task generateSourcesJar(type: Jar) { 36 | from android.sourceSets.main.java.srcDirs 37 | classifier 'sources' 38 | } 39 | 40 | def versionName = "1.5.12" 41 | 42 | // Because the components are created only during the afterEvaluate phase, you must 43 | // configure your publications using the afterEvaluate() lifecycle method. 44 | afterEvaluate { 45 | publishing { 46 | publications { 47 | Production(MavenPublication) { 48 | // Creates a Maven publication called "release". 49 | // Applies the component for the release build variant. 50 | from components.release 51 | // You can then customize attributes of the publication as shown below. 52 | groupId = 'com.github.Yummylau' 53 | artifactId = 'panelSwitchHelper-androidx' 54 | version = versionName 55 | // 上传source,这样使用放可以看到方法注释 56 | artifact generateSourcesJar 57 | } 58 | } 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /panel-androidx/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/panel-androidx/consumer-rules.pro -------------------------------------------------------------------------------- /panel-androidx/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 | -------------------------------------------------------------------------------- /panel-androidx/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/Constants.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel 2 | 3 | /** 4 | * Created by yummyLau on 18-7-07 5 | * Email: yummyl.lau@gmail.com 6 | * blog: yummylau.com 7 | */ 8 | object Constants { 9 | 10 | const val LOG_TAG = "Panel" 11 | //输入法高度 12 | const val KB_PANEL_PREFERENCE_NAME = "ky_panel_name" 13 | const val KEYBOARD_HEIGHT_FOR_L = "keyboard_height_for_l" 14 | const val KEYBOARD_HEIGHT_FOR_P = "keyboard_height_for_p" 15 | const val DEFAULT_KEYBOARD_HEIGHT_FOR_L = 198f 16 | const val DEFAULT_KEYBOARD_HEIGHT_FOR_P = 230f 17 | const val STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height" 18 | const val NAVIGATION_BAR_HEIGHT_RES_NAME = "navigation_bar_height" 19 | const val DIMEN = "dimen" 20 | const val ANDROID = "android" 21 | const val SHOW_NAV_BAR_RES_NAME = "config_showNavigationBar" 22 | 23 | /** 24 | * panel id, custom panel (PanelView) id is panelView's triggerViewId 25 | * [PanelView.getTriggerViewId] 26 | */ 27 | const val PANEL_NONE = -1 28 | const val PANEL_KEYBOARD = 0 29 | const val PROTECT_KEY_CLICK_DURATION = 500L 30 | 31 | @JvmField 32 | var DEBUG = false 33 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/compat/KeyboardHeightCompat.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.compat 2 | 3 | import com.effective.android.panel.utils.RomUtils 4 | import java.util.* 5 | 6 | /** 7 | * author : linzheng 8 | * e-mail : z.hero.dodge@gmail.com 9 | * time : 2022/11/4 10 | * desc : 11 | * version: 1.0 12 | */ 13 | object KeyboardHeightCompat { 14 | 15 | 16 | fun getMinLimitHeight(): Int { 17 | if (hasPhysicsKeyboard()) { 18 | return 100 19 | } 20 | return 300 21 | } 22 | 23 | fun hasPhysicsKeyboard(): Boolean { 24 | val rom = RomUtils.getRomInfo() 25 | if (rom.name == "blackberry") { 26 | return rom.model?.toLowerCase(Locale.ROOT)?.contains("bbf100") ?: false 27 | } 28 | return false 29 | } 30 | 31 | 32 | fun panelDefaultHeight(defaultHeight : Int): Int { 33 | if (hasPhysicsKeyboard()) { 34 | return 705 35 | } 36 | return defaultHeight 37 | } 38 | 39 | 40 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/device/DeviceInfo.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.device 2 | 3 | import android.view.Window 4 | 5 | /** 6 | * 保存当前设备信息不变的信息 7 | * Created by yummyLau on 2020-05-24 8 | * Email: yummyl.lau@gmail.com 9 | * blog: yummylau.com 10 | */ 11 | data class DeviceInfo(val window:Window, 12 | val isPortrait: Boolean, 13 | val statusBarH: Int, 14 | val navigationBarH: Int, 15 | val toolbarH: Int, 16 | val screenH: Int, 17 | val screenWithoutSystemUiH: Int, 18 | val screenWithoutNavigationH: Int) { 19 | 20 | /** 21 | * 由于pad的导航栏无论是横屏还是竖屏,都是在当前界面的底部 22 | * 而普通的手机,横屏状态下导航栏是在界面的两侧 23 | * 故需要做区分 24 | */ 25 | fun getCurrentNavigationBarHeightWhenVisible(isPortrait: Boolean, isPad: Boolean): Int { 26 | return if (isPortrait) { 27 | navigationBarH 28 | } else { 29 | if (isPad) { 30 | navigationBarH 31 | } else { 32 | 0 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/device/DeviceRuntime.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.device 2 | 3 | import android.content.Context 4 | import android.content.res.Configuration 5 | import android.view.Window 6 | import android.view.WindowInsets 7 | import com.effective.android.panel.utils.DisplayUtil 8 | 9 | /** 10 | * 保存当前设备信息跟随用户操作更改信息 11 | * Created by yummyLau on 2020-05-24 12 | * Email: yummyl.lau@gmail.com 13 | * blog: yummylau.com 14 | */ 15 | class DeviceRuntime(val context: Context, val window: Window) { 16 | 17 | var deviceInfoP: DeviceInfo? = null 18 | var deviceInfoL: DeviceInfo? = null 19 | 20 | var isNavigationBarShow: Boolean = false 21 | var isPortrait: Boolean = false 22 | var isPad: Boolean = false 23 | var isFullScreen: Boolean = false; 24 | 25 | init { 26 | isPad = (context.resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE 27 | isPortrait = DisplayUtil.isPortrait(context) 28 | isNavigationBarShow = DisplayUtil.isNavigationBarShow(context, window) 29 | isFullScreen = DisplayUtil.isFullScreen(window) 30 | } 31 | 32 | fun getDeviceInfoByOrientation(cache: Boolean = false): DeviceInfo { 33 | isPortrait = DisplayUtil.isPortrait(context) 34 | isNavigationBarShow = DisplayUtil.isNavigationBarShow(context, window) 35 | isFullScreen = DisplayUtil.isFullScreen(window) 36 | 37 | if (cache) { 38 | if (isPortrait && deviceInfoP != null) { 39 | return deviceInfoP!! 40 | } else if (!isPortrait && deviceInfoL != null) { 41 | return deviceInfoL!! 42 | } 43 | } 44 | 45 | val navigationBarHeight = DisplayUtil.getNavigationBarHeight(context,window) 46 | val statusBarHeight = DisplayUtil.getStatusBarHeight(window) 47 | //以这种方式计算出来的toolbar,如果和statusBarHeight一样,则实际上就是statusBar的高度,大于statusBar的才是toolBar的高度。 48 | var toolbarH = DisplayUtil.getToolbarHeight(window) 49 | if (toolbarH == statusBarHeight) { 50 | toolbarH = 0 51 | } 52 | val screenHeight = DisplayUtil.getScreenRealHeight(window) 53 | val screenWithoutSystemUIHeight = DisplayUtil.getScreenHeightWithoutSystemUI(window) 54 | val screenWithoutNavigationHeight = DisplayUtil.getScreenHeightWithoutNavigationBar(context) 55 | 56 | return if (isPortrait) { 57 | deviceInfoP = DeviceInfo(window, true, 58 | statusBarHeight, navigationBarHeight, toolbarH, 59 | screenHeight, screenWithoutSystemUIHeight, screenWithoutNavigationHeight) 60 | deviceInfoP!! 61 | } else { 62 | deviceInfoL = DeviceInfo(window, false, 63 | statusBarHeight, navigationBarHeight, toolbarH, 64 | screenHeight, screenWithoutSystemUIHeight, screenWithoutNavigationHeight) 65 | deviceInfoL!! 66 | } 67 | 68 | } 69 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/interfaces/ContentScrollMeasurer.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.interfaces 2 | 3 | /** 4 | * 当内容允许滑动时,即[com.effective.android.panel.view.PanelSwitchLayout.isContentScrollOutsizeEnable] 返回true,则默认内容区域会向上 layout 一个面板距离 5 | * 默认 getScrollDistance 为软键盘/面板的距离 6 | * Created by yummyLau on 2020-07-08 7 | * Email: yummyl.lau@gmail.com 8 | * blog: yummylau.com 9 | */ 10 | interface ContentScrollMeasurer { 11 | fun getScrollDistance(defaultDistance: Int): Int 12 | fun getScrollViewId(): Int 13 | } 14 | 15 | private typealias GetScrollDistance = (defaultDistance: Int) -> Int 16 | private typealias GetScrollViewId = () -> Int 17 | 18 | class ContentScrollMeasurerBuilder : ContentScrollMeasurer { 19 | 20 | private var getScrollDistance: GetScrollDistance? = null 21 | private var getScrollViewId: GetScrollViewId? = null 22 | 23 | override fun getScrollDistance(defaultDistance: Int): Int = getScrollDistance?.invoke(defaultDistance) ?: 0 24 | override fun getScrollViewId(): Int = getScrollViewId?.invoke() ?: -1 25 | 26 | fun getScrollDistance(getScrollDistance: GetScrollDistance) { 27 | this.getScrollDistance = getScrollDistance 28 | } 29 | 30 | fun getScrollViewId(getScrollViewId: GetScrollViewId) { 31 | this.getScrollViewId = getScrollViewId 32 | } 33 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/interfaces/PanelHeightMeasurer.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.interfaces 2 | 3 | interface PanelHeightMeasurer{ 4 | fun synchronizeKeyboardHeight() : Boolean 5 | fun getTargetPanelDefaultHeight(): Int 6 | fun getPanelTriggerId(): Int 7 | } 8 | 9 | private typealias GetTargetPanelDefaultHeight = () -> Int 10 | private typealias GetPanelId = () -> Int 11 | private typealias SynchronizeKeyboardHeight = () -> Boolean 12 | 13 | class PanelHeightMeasurerBuilder : PanelHeightMeasurer { 14 | 15 | private var getPanelDefaultHeight: GetTargetPanelDefaultHeight? = null 16 | private var getPanelId: GetPanelId? = null 17 | private var synchronizeKeyboardHeight: SynchronizeKeyboardHeight? = null 18 | 19 | override fun getTargetPanelDefaultHeight(): Int = getPanelDefaultHeight?.invoke() ?: 0 20 | 21 | override fun getPanelTriggerId(): Int = getPanelId?.invoke() ?: -1 22 | 23 | override fun synchronizeKeyboardHeight(): Boolean = synchronizeKeyboardHeight?.invoke() ?: true 24 | 25 | fun getTargetPanelDefaultHeight(getPanelDefaultHeight: GetTargetPanelDefaultHeight) { 26 | this.getPanelDefaultHeight = getPanelDefaultHeight 27 | } 28 | 29 | fun getPanelTriggerId(getPanelId: GetPanelId) { 30 | this.getPanelId = getPanelId 31 | } 32 | 33 | fun synchronizeKeyboardHeight(synchronizeKeyboardHeight: SynchronizeKeyboardHeight) { 34 | this.synchronizeKeyboardHeight = synchronizeKeyboardHeight 35 | } 36 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/interfaces/TriggerViewClickInterceptor.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.interfaces 2 | 3 | interface TriggerViewClickInterceptor { 4 | fun intercept(triggerId: Int): Boolean 5 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/interfaces/ViewAssertion.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.interfaces 2 | 3 | /** 4 | * -------------------- 5 | * | PanelSwitchLayout | 6 | * | ---------------- | 7 | * | | | | 8 | * | |ContentContainer| | 9 | * | | | | 10 | * | ---------------- | 11 | * | ---------------- | 12 | * | | PanelContainer | | 13 | * | ---------------- | 14 | * -------------------- 15 | * There are some rules that must be processed: 16 | * 17 | * 1. [com.effective.android.panel.view.PanelSwitchLayout] must have only two children 18 | * [com.effective.android.panel.view.content.IContentContainer] and [com.effective.android.panel.view.PanelContainer] 19 | * 20 | * 2. [com.effective.android.panel.view.content.IContentContainer] must set "edit_view" value to provide [android.widget.EditText] 21 | * 22 | * 3. [com.effective.android.panel.view.PanelContainer] has some Children that are [com.effective.android.panel.view.PanelView] 23 | * [com.effective.android.panel.view.PanelView] must set "panel_layout" value to provide panelView and set "panel_trigger" value to 24 | * specify layout for click to checkout panelView 25 | * 26 | * Created by yummyLau on 18-7-10 27 | * Email: yummyl.lau@gmail.com 28 | * blog: yummylau.com 29 | */ 30 | interface ViewAssertion { 31 | fun assertView() 32 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/interfaces/listener/OnEditFocusChangeListener.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.interfaces.listener 2 | 3 | import android.view.View 4 | 5 | /** 6 | * listen to [android.widget.EditText] focus change 7 | * Created by yummyLau on 18-7-07 8 | * Email: yummyl.lau@gmail.com 9 | * blog: yummylau.com 10 | * update 2020/05/08 支持 dsl 11 | */ 12 | interface OnEditFocusChangeListener { 13 | fun onFocusChange(view: View?, hasFocus: Boolean) 14 | } 15 | private typealias OnFocusChange = (view: View?, hasFocus: Boolean) -> Unit 16 | 17 | class OnEditFocusChangeListenerBuilder : OnEditFocusChangeListener { 18 | 19 | private var onFocusChange: OnFocusChange? = null 20 | 21 | override fun onFocusChange(view: View?, hasFocus: Boolean) { 22 | onFocusChange?.invoke(view, hasFocus) 23 | } 24 | 25 | fun onFocusChange(onFocusChange: OnFocusChange) { 26 | this.onFocusChange = onFocusChange 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/interfaces/listener/OnKeyboardStateListener.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.interfaces.listener 2 | 3 | 4 | /** 5 | * Created by yummyLau on 18-7-07 6 | * Email: yummyl.lau@gmail.com 7 | * blog: yummylau.com 8 | * update 2020/05/08 支持 dsl 9 | */ 10 | interface OnKeyboardStateListener { 11 | fun onKeyboardChange(visible: Boolean, height: Int) 12 | } 13 | private typealias OnKeyboardChange = (visible: Boolean, height: Int) -> Unit 14 | 15 | class OnKeyboardStateListenerBuilder : OnKeyboardStateListener { 16 | 17 | private var onKeyboardChange: OnKeyboardChange? = null 18 | 19 | override fun onKeyboardChange(visible: Boolean, height: Int) { 20 | onKeyboardChange?.invoke(visible, height) 21 | } 22 | 23 | fun onKeyboardChange(onKeyboardChange: OnKeyboardChange) { 24 | this.onKeyboardChange = onKeyboardChange 25 | } 26 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/interfaces/listener/OnPanelChangeListener.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.interfaces.listener 2 | import com.effective.android.panel.view.panel.IPanelView 3 | 4 | /** 5 | * Created by yummyLau on 18-7-07 6 | * Email: yummyl.lau@gmail.com 7 | * blog: yummylau.com 8 | * update 2020/05/08 支持 dsl 9 | * update 2020/06/01 不再直接回调可空的panelView,IPanelView 提供更开放的能力 10 | */ 11 | interface OnPanelChangeListener { 12 | fun onKeyboard() 13 | fun onNone() 14 | fun onPanel(panel: IPanelView?) 15 | fun onPanelSizeChange(panel: IPanelView?, portrait: Boolean, oldWidth: Int, oldHeight: Int, width: Int, height: Int) 16 | } 17 | 18 | private typealias OnKeyboard = () -> Unit 19 | private typealias OnNone = () -> Unit 20 | private typealias OnPanel = (view: IPanelView?) -> Unit 21 | private typealias OnPanelSizeChange = (panelView: IPanelView?, portrait: Boolean, oldWidth: Int, oldHeight: Int, width: Int, height: Int) -> Unit 22 | 23 | class OnPanelChangeListenerBuilder : OnPanelChangeListener { 24 | 25 | private var onKeyboard: OnKeyboard? = null 26 | private var onNone: OnNone? = null 27 | private var onPanel: OnPanel? = null 28 | private var onPanelSizeChange: OnPanelSizeChange? = null 29 | 30 | override fun onKeyboard() { 31 | onKeyboard?.invoke() 32 | } 33 | 34 | override fun onNone() { 35 | onNone?.invoke() 36 | } 37 | 38 | override fun onPanel(panel: IPanelView?) { 39 | onPanel?.invoke(panel) 40 | } 41 | 42 | override fun onPanelSizeChange(panel: IPanelView?, portrait: Boolean, oldWidth: Int, oldHeight: Int, width: Int, height: Int) { 43 | onPanelSizeChange?.invoke(panel, portrait, oldWidth, oldHeight, width, height) 44 | } 45 | 46 | fun onKeyboard(onKeyboard: OnKeyboard) { 47 | this.onKeyboard = onKeyboard 48 | } 49 | 50 | fun onNone(onNone: OnNone) { 51 | this.onNone = onNone 52 | } 53 | 54 | fun onPanel(onPanel: OnPanel) { 55 | this.onPanel = onPanel 56 | } 57 | 58 | fun onPanelSizeChange(onPanelSizeChange: OnPanelSizeChange) { 59 | this.onPanelSizeChange = onPanelSizeChange 60 | } 61 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/interfaces/listener/OnViewClickListener.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.interfaces.listener 2 | 3 | import android.view.View 4 | 5 | /** 6 | * preventing listeners that [com.effective.android.panel.PanelSwitchHelper] set these to view from being overwritten 7 | * Created by yummyLau on 18-7-07 8 | * Email: yummyl.lau@gmail.com 9 | * blog: yummylau.com 10 | * update 2020/05/08 支持 dsl 11 | */ 12 | interface OnViewClickListener { 13 | fun onClickBefore(view: View?) 14 | } 15 | 16 | private typealias OnClickBefore = (view: View?) -> Unit 17 | 18 | class OnViewClickListenerBuilder : OnViewClickListener { 19 | 20 | private var onClickBefore: OnClickBefore? = null 21 | 22 | override fun onClickBefore(view: View?) { 23 | onClickBefore?.invoke(view) 24 | } 25 | 26 | fun onClickBefore(onClickBefore: OnClickBefore) { 27 | this.onClickBefore = onClickBefore 28 | } 29 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/log/LogFormatter.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.log 2 | 3 | class LogFormatter { 4 | 5 | private val stringBuilder = StringBuilder() 6 | private val defaultKey = " " 7 | private var keyLength: Int = 0 8 | 9 | constructor(keyLength: Int) { 10 | this.keyLength = keyLength 11 | } 12 | 13 | companion object { 14 | fun setUp(int: Int = 50): LogFormatter { 15 | return LogFormatter(int) 16 | } 17 | } 18 | 19 | fun addContent(key: String = "", value: String): LogFormatter { 20 | if (key.isEmpty()) { 21 | stringBuilder.append("$value \n") 22 | } else { 23 | if (key.length < keyLength) { 24 | stringBuilder.append("$key${defaultKey.subSequence(0, keyLength - key.length)} = $value \n") 25 | } else { 26 | stringBuilder.append("$key = $value \n") 27 | } 28 | } 29 | return this 30 | } 31 | 32 | fun log(tag: String) { 33 | LogTracker.log(tag, stringBuilder.toString()) 34 | stringBuilder.clear() 35 | } 36 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/log/LogTracker.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.log 2 | 3 | import android.text.TextUtils 4 | import android.util.Log 5 | import android.view.View 6 | import com.effective.android.panel.Constants 7 | import com.effective.android.panel.interfaces.listener.OnEditFocusChangeListener 8 | import com.effective.android.panel.interfaces.listener.OnKeyboardStateListener 9 | import com.effective.android.panel.interfaces.listener.OnPanelChangeListener 10 | import com.effective.android.panel.interfaces.listener.OnViewClickListener 11 | import com.effective.android.panel.view.panel.IPanelView 12 | 13 | /** 14 | * single logTracker 15 | * Created by yummyLau on 18-7-07 16 | * Email: yummyl.lau@gmail.com 17 | * blog: yummylau.com 18 | */ 19 | object LogTracker : OnEditFocusChangeListener, OnKeyboardStateListener, OnPanelChangeListener, OnViewClickListener { 20 | 21 | private val TAG = LogTracker::class.java.simpleName 22 | 23 | @JvmStatic 24 | fun log(methodName: String, message: String) { 25 | if (TextUtils.isEmpty(methodName) || TextUtils.isEmpty(message)) { 26 | return 27 | } 28 | if (Constants.DEBUG) { 29 | Log.d(TAG, "$methodName => $message") 30 | } 31 | } 32 | 33 | override fun onFocusChange(view: View?, hasFocus: Boolean) { 34 | log("OnEditFocusChangeListener#onFocusChange", "EditText has focus ( $hasFocus )") 35 | } 36 | 37 | override fun onKeyboardChange(show: Boolean,height: Int) { 38 | log("OnKeyboardStateListener#onKeyboardChange", "Keyboard is showing ( $show ),height is $height") 39 | } 40 | 41 | override fun onKeyboard() { 42 | log("OnPanelChangeListener#onKeyboard", "panel: keyboard") 43 | } 44 | 45 | override fun onNone() { 46 | log("OnPanelChangeListener#onNone", "panel: none") 47 | } 48 | 49 | override fun onPanel(panel: IPanelView?) { 50 | log("OnPanelChangeListener#onPanel", "panel:" + (panel?.toString() 51 | ?: "null")) 52 | } 53 | 54 | override fun onPanelSizeChange(panel: IPanelView?, portrait: Boolean, oldWidth: Int, oldHeight: Int, width: Int, height: Int) { 55 | log("OnPanelChangeListener#onPanelSizeChange", "panelView is " + (panel?.toString() 56 | ?: "null" + 57 | " portrait : " + portrait + 58 | " oldWidth : " + oldWidth + " oldHeight : " + oldHeight + 59 | " width : " + width + " height : " + height)) 60 | } 61 | 62 | override fun onClickBefore(view: View?) { 63 | log("OnViewClickListener#onViewClick", "view is " + (view?.toString() 64 | ?: " null ")) 65 | } 66 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/utils/KeyboardExt.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.utils 2 | 3 | /** 4 | * author : linzheng 5 | * e-mail : z.hero.dodge@gmail.com 6 | * time : 2022/7/1 7 | * desc : 8 | * version: 1.0 9 | */ 10 | 11 | import android.app.Activity 12 | import android.content.Context 13 | import android.view.View 14 | import android.view.Window 15 | import android.view.inputmethod.InputMethodManager 16 | import android.widget.EditText 17 | import androidx.core.view.ViewCompat 18 | import androidx.core.view.WindowInsetsAnimationCompat 19 | import androidx.core.view.WindowInsetsCompat 20 | import androidx.fragment.app.Fragment 21 | 22 | 23 | /** 24 | * 弹出软键盘 25 | * 如果要求页面显示立刻弹出软键盘,建议在onResume方法中调用 26 | */ 27 | fun EditText.showSoftInput() { 28 | isFocusable = true 29 | isFocusableInTouchMode = true 30 | requestFocus() 31 | if (isSystemInsetsAnimationSupport()) { 32 | ViewCompat.getWindowInsetsController(this)?.show(WindowInsetsCompat.Type.ime()) 33 | } else { 34 | postDelayed({ 35 | val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager 36 | imm.showSoftInput(this, 0) 37 | }, 300) 38 | } 39 | } 40 | 41 | /** 隐藏软键盘 */ 42 | fun Activity.hideSoftInput() { 43 | currentFocus?.let { 44 | val imm = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager 45 | imm.hideSoftInputFromWindow(it.windowToken, InputMethodManager.HIDE_NOT_ALWAYS) 46 | } ?: let { 47 | ViewCompat.getWindowInsetsController(window.decorView)?.hide(WindowInsetsCompat.Type.ime()) 48 | } 49 | } 50 | 51 | /** 隐藏软键盘 */ 52 | fun Fragment.hideSoftInput() = requireActivity().hideSoftInput() 53 | 54 | /** 隐藏软键盘 */ 55 | fun EditText.hideSoftInput() { 56 | ViewCompat.getWindowInsetsController(this)?.hide(WindowInsetsCompat.Type.ime()) 57 | } 58 | 59 | 60 | // 61 | 62 | /** 软键盘是否显示 */ 63 | fun Activity.hasSoftInput(): Boolean { 64 | return ViewCompat.getRootWindowInsets(window.decorView)?.isVisible(WindowInsetsCompat.Type.ime()) ?: false 65 | } 66 | 67 | /** 软键盘是否显示 */ 68 | fun Fragment.hasSoftInput(): Boolean { 69 | return requireActivity().hasSoftInput() 70 | } 71 | 72 | /** 当前软键盘显示高度 */ 73 | fun Activity.getSoftInputHeight(): Int { 74 | val softInputHeight = ViewCompat.getRootWindowInsets(window.decorView)?.getInsets(WindowInsetsCompat.Type.ime())?.bottom 75 | return softInputHeight ?: 0 76 | } 77 | 78 | /** 当前软键盘显示高度 */ 79 | fun Fragment.getSoftInputHeight(): Int { 80 | return requireActivity().getSoftInputHeight() 81 | } 82 | 83 | 84 | /** 判断系统是否支持[WindowInsetsAnimationCompat] */ 85 | internal fun View.isSystemInsetsAnimationSupport(): Boolean { 86 | val windowInsetsController = ViewCompat.getWindowInsetsController(this) 87 | return !(windowInsetsController == null || windowInsetsController.systemBarsBehavior == 0) 88 | } 89 | 90 | fun Window.isSystemInsetsAnimationSupport() : Boolean { 91 | return this.decorView.isSystemInsetsAnimationSupport() 92 | } 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/view/content/IContentContainer.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.view.content 2 | 3 | import android.view.MotionEvent 4 | import android.view.View 5 | import android.view.View.OnFocusChangeListener 6 | import android.widget.EditText 7 | import androidx.annotation.IdRes 8 | import com.effective.android.panel.interfaces.ContentScrollMeasurer 9 | 10 | interface IContentContainer { 11 | //容器行为 12 | fun findTriggerView(@IdRes id: Int): View? 13 | fun layoutContainer(l: Int, t: Int, r: Int, b: Int, 14 | contentScrollMeasurer: MutableList, defaultScrollHeight: Int, canScrollOutsize: Boolean, 15 | reset: Boolean, changed: Boolean = false) 16 | 17 | fun translationContainer(contentScrollMeasurers: MutableList, defaultScrollHeight: Int, contentTranslationY: Float) 18 | 19 | 20 | fun changeContainerHeight(targetHeight: Int) 21 | 22 | //输入相关 23 | fun getInputActionImpl(): IInputAction 24 | 25 | //隐藏相关 26 | fun getResetActionImpl(): IResetAction 27 | } 28 | 29 | interface IInputAction { 30 | fun addSecondaryInputView(editText: EditText) 31 | fun removeSecondaryInputView(editText: EditText) 32 | fun setEditTextClickListener(l: View.OnClickListener) 33 | fun setEditTextFocusChangeListener(l: OnFocusChangeListener) 34 | fun requestKeyboard() 35 | fun hideKeyboard(isKeyboardShowing : Boolean,clearFocus : Boolean) 36 | fun showKeyboard() : Boolean 37 | fun getFullScreenPixelInputView(): EditText 38 | fun updateFullScreenParams(isFullScreen : Boolean, panelId : Int, panelHeight : Int) 39 | fun recycler() 40 | fun focusAndShowSelection() 41 | } 42 | 43 | interface IResetAction { 44 | fun enableReset(enable: Boolean) 45 | fun setResetCallback(runnable: Runnable) 46 | fun hookDispatchTouchEvent(ev: MotionEvent?, consume: Boolean): Boolean 47 | fun hookOnTouchEvent(ev: MotionEvent?): Boolean 48 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/view/panel/IPanelView.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.view.panel 2 | 3 | import androidx.annotation.IdRes 4 | import com.effective.android.panel.interfaces.ViewAssertion 5 | 6 | /** 7 | * 扩展panelView 8 | * 同时需要实现 ViewAssertion 校验 trigger 绑定的有效性,实现 IPanelView 应该是一个 ViewGroup 9 | * created by yummylau on 2020/06/01 🧒儿童节 10 | */ 11 | interface IPanelView : ViewAssertion { 12 | 13 | @IdRes 14 | fun getBindingTriggerViewId(): Int 15 | 16 | fun isTriggerViewCanToggle(): Boolean 17 | 18 | fun isShowing():Boolean 19 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/view/panel/PanelContainer.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.view.panel 2 | 3 | import android.annotation.TargetApi 4 | import android.content.Context 5 | import android.util.AttributeSet 6 | import android.util.Log 7 | import android.util.Pair 8 | import android.util.SparseArray 9 | import android.view.View 10 | import android.widget.FrameLayout 11 | import com.effective.android.panel.Constants 12 | import com.effective.android.panel.interfaces.ViewAssertion 13 | 14 | /** 15 | * -------------------- 16 | * | PanelSwitchLayout | 17 | * | ---------------- | 18 | * | | | | 19 | * | |ContentContainer| | 20 | * | | | | 21 | * | ---------------- | 22 | * | ---------------- | 23 | * | | PanelContainer | | 24 | * | ---------------- | 25 | * -------------------- 26 | * Created by yummyLau on 18-7-10 27 | * Email: yummyl.lau@gmail.com 28 | * blog: yummylau.com 29 | */ 30 | class PanelContainer : FrameLayout, ViewAssertion { 31 | var panelSparseArray = SparseArray() 32 | private set 33 | 34 | @JvmOverloads 35 | constructor(context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(context!!, attrs, defStyleAttr) { 36 | initView(attrs, defStyleAttr, 0) 37 | } 38 | 39 | @TargetApi(21) 40 | constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context!!, attrs, defStyleAttr, defStyleRes) { 41 | initView(attrs, defStyleAttr, defStyleRes) 42 | } 43 | 44 | private fun initView(attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) {} 45 | 46 | override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { 47 | super.onLayout(changed, left, top, right, bottom) 48 | } 49 | 50 | override fun onFinishInflate() { 51 | super.onFinishInflate() 52 | assertView() 53 | } 54 | 55 | override fun assertView() { 56 | panelSparseArray = SparseArray() 57 | for (i in 0 until childCount) { 58 | val panel = getChildAt(i) as? IPanelView 59 | ?: throw RuntimeException("PanelContainer -- PanelContainer's child should be IPanelView") 60 | panelSparseArray.put(panel.getBindingTriggerViewId(), panel) 61 | (panel as View).visibility = View.GONE 62 | } 63 | } 64 | 65 | fun getPanelView(panelId: Int): IPanelView? { 66 | return panelSparseArray[panelId] 67 | } 68 | 69 | fun getPanelId(panel: IPanelView?): Int { 70 | return panel?.getBindingTriggerViewId() ?: Constants.PANEL_KEYBOARD 71 | } 72 | 73 | fun showPanel(panelId: Int, size: Pair): Pair { 74 | val panel = panelSparseArray[panelId] 75 | for (i in 0 until panelSparseArray.size()) { 76 | val panelView = panelSparseArray[panelSparseArray.keyAt(i)] 77 | if (panelView is View) { 78 | panelView.visibility = if (panelView != panel) View.GONE else View.VISIBLE 79 | } 80 | } 81 | val layoutParams = (panel as View).layoutParams 82 | val curSize = Pair(layoutParams.width, layoutParams.height) 83 | if (curSize.first != size.first || curSize.second != size.second) { 84 | layoutParams.width = size.first 85 | layoutParams.height = size.second 86 | (panel as View).layoutParams = layoutParams 87 | } 88 | return curSize 89 | } 90 | 91 | fun changeContainerHeight(targetHeight: Int) { 92 | if (layoutParams != null && layoutParams.height != targetHeight) { 93 | layoutParams.height = targetHeight 94 | } 95 | } 96 | 97 | override fun setTranslationY(translationY: Float) { 98 | super.setTranslationY(translationY) 99 | } 100 | 101 | 102 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/view/panel/PanelView.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.view.panel 2 | 3 | import android.annotation.TargetApi 4 | import android.content.Context 5 | import android.util.AttributeSet 6 | import android.view.LayoutInflater 7 | import android.view.View 8 | import android.widget.FrameLayout 9 | import com.effective.android.panel.R 10 | 11 | /** 12 | * interface, everyPanel should implements 13 | * Created by yummyLau on 18-7-07 14 | * Email: yummyl.lau@gmail.com 15 | * blog: yummylau.com 16 | */ 17 | class PanelView : FrameLayout, IPanelView { 18 | private var panelLayoutId = 0 19 | private var triggerViewId = 0 20 | private var isToggle = true 21 | 22 | @JvmOverloads 23 | constructor(context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(context!!, attrs, defStyleAttr) { 24 | initView(attrs, defStyleAttr, 0) 25 | } 26 | 27 | @TargetApi(21) 28 | constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context!!, attrs, defStyleAttr, defStyleRes) { 29 | initView(attrs, defStyleAttr, defStyleRes) 30 | } 31 | 32 | private fun initView(attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) { 33 | val typedArray = context.obtainStyledAttributes(attrs, R.styleable.PanelView, defStyleAttr, 0) 34 | panelLayoutId = typedArray.getResourceId(R.styleable.PanelView_panel_layout, -1) 35 | triggerViewId = typedArray.getResourceId(R.styleable.PanelView_panel_trigger, -1) 36 | isToggle = typedArray.getBoolean(R.styleable.PanelView_panel_toggle, isToggle) 37 | typedArray.recycle() 38 | } 39 | 40 | override fun getBindingTriggerViewId(): Int = triggerViewId 41 | 42 | override fun isTriggerViewCanToggle(): Boolean = isToggle 43 | 44 | override fun isShowing(): Boolean = isShown 45 | 46 | override fun assertView() { 47 | if (panelLayoutId == -1 || triggerViewId == -1) { 48 | throw RuntimeException("PanelView -- you must set 'panel_layout' and panel_trigger by Integer id") 49 | } 50 | if (childCount > 0) { 51 | throw RuntimeException("PanelView -- you can't have any child!") 52 | } 53 | //默认实现 FrameLayout 恒为false,这里只是强调申明而已,可以不写。 54 | if (this !is View) { 55 | throw RuntimeException("PanelView -- should be a view!") 56 | } 57 | LayoutInflater.from(context).inflate(panelLayoutId, this, true) 58 | } 59 | 60 | override fun onFinishInflate() { 61 | super.onFinishInflate() 62 | assertView() 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/java/com/effective/android/panel/window/PanelDialog.kt: -------------------------------------------------------------------------------- 1 | package com.effective.android.panel.window 2 | 3 | import android.app.Dialog 4 | import android.content.Context 5 | import android.content.DialogInterface 6 | import android.graphics.Color 7 | import android.graphics.drawable.ColorDrawable 8 | import android.view.Gravity 9 | import android.view.LayoutInflater 10 | import android.view.View 11 | import android.view.WindowManager 12 | import androidx.annotation.LayoutRes 13 | import com.effective.android.panel.PanelSwitchHelper 14 | 15 | /** 16 | * 提供给外部使用的dialog,场景用于类 微博评论/微信朋友圈 17 | * created by yummylau on 2020/06/04 18 | */ 19 | abstract class PanelDialog : Dialog { 20 | 21 | @JvmField 22 | protected val rootView: View 23 | 24 | @JvmField 25 | protected var helper: PanelSwitchHelper? = null 26 | 27 | constructor(context: Context) : super(context) 28 | constructor(context: Context, themeResId: Int) : super(context, themeResId) 29 | constructor(context: Context, cancelable: Boolean, cancelListener: DialogInterface.OnCancelListener?) : super(context, cancelable, cancelListener) 30 | 31 | @LayoutRes 32 | abstract fun getDialogLayout(): Int 33 | 34 | init { 35 | rootView = LayoutInflater.from(context).inflate(getDialogLayout(), null, false) 36 | setContentView(rootView) 37 | 38 | window?.let { 39 | it.setGravity(Gravity.CENTER) 40 | it.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) 41 | val lp = it.attributes 42 | lp.width = WindowManager.LayoutParams.MATCH_PARENT 43 | lp.height = WindowManager.LayoutParams.MATCH_PARENT 44 | it.attributes = lp 45 | it.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) 46 | it.setDimAmount(0f) 47 | it.attributes.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE 48 | // it.setType(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) 49 | 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /panel-androidx/src/main/res/values/attr.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /panel-androidx/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | //include ':app' 2 | //include ':panel' 3 | 4 | //include ':app-androidx' 5 | include ':panel-androidx' 6 | -------------------------------------------------------------------------------- /source/api/arch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/api/arch.jpg -------------------------------------------------------------------------------- /source/api/cus_scroll_content.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/api/cus_scroll_content.gif -------------------------------------------------------------------------------- /source/api/mode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/api/mode.jpg -------------------------------------------------------------------------------- /source/demo.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/demo.apk -------------------------------------------------------------------------------- /source/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/demo.png -------------------------------------------------------------------------------- /source/qr_code_apk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/qr_code_apk.png -------------------------------------------------------------------------------- /source/qr_code_wx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/qr_code_wx.jpg -------------------------------------------------------------------------------- /source/scene/auto_adjust.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/scene/auto_adjust.gif -------------------------------------------------------------------------------- /source/scene/bilibili.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/scene/bilibili.gif -------------------------------------------------------------------------------- /source/scene/bilibili_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/scene/bilibili_demo.gif -------------------------------------------------------------------------------- /source/scene/chat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/scene/chat.gif -------------------------------------------------------------------------------- /source/scene/compat_navigation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/scene/compat_navigation.gif -------------------------------------------------------------------------------- /source/scene/douyin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/scene/douyin.gif -------------------------------------------------------------------------------- /source/scene/douyin_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/scene/douyin_demo.gif -------------------------------------------------------------------------------- /source/scene/huya.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/scene/huya.gif -------------------------------------------------------------------------------- /source/scene/huya_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/scene/huya_demo.gif -------------------------------------------------------------------------------- /source/scene/wechat_feed.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/scene/wechat_feed.gif -------------------------------------------------------------------------------- /source/scene/wechat_feed_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DSAppTeam/PanelSwitchHelper/bcd0083297eee6e2f3e8f35241218a8c59c29598/source/scene/wechat_feed_demo.gif -------------------------------------------------------------------------------- /versions.gradle: -------------------------------------------------------------------------------- 1 | ext.deps = [:] 2 | def versions = [:] 3 | versions.android_gradle_plugin = android_gradle_plugin 4 | versions.support = "27.1.1" 5 | versions.pageindicator = "v1.0.1" 6 | versions.panelSwitchHelper = "1.5.12" 7 | versions.multidex = "1.0.1" 8 | versions.constraint = "1.1.2" 9 | versions.circleimageview = "3.1.0" 10 | versions.androidx = "1.1.0" 11 | versions.androidx_core = "1.6.0" 12 | ext.versions = versions 13 | 14 | 15 | def support = [:] 16 | support.v7 = "com.android.support:appcompat-v7:$versions.support" 17 | support.annotations = "com.android.support:support-annotations:$versions.support" 18 | support.recyclerview = "com.android.support:recyclerview-v7:$versions.support" 19 | support.multidex = "com.android.support:multidex:$versions.multidex" 20 | support.constraint = "com.android.support.constraint:constraint-layout:$versions.constraint" 21 | ext.deps.support = support 22 | 23 | def androidx = [:] 24 | androidx.core = "androidx.core:core:$versions.androidx_core" 25 | androidx.appcompat = "androidx.appcompat:appcompat:$versions.androidx" 26 | androidx.annotations = "androidx.annotation:annotation:$versions.androidx" 27 | androidx.recyclerview = "androidx.recyclerview:recyclerview:$versions.androidx" 28 | androidx.multidex = "androidx.multidex:multidex:$versions.androidx" 29 | androidx.constraint = "androidx.constraintlayout:constraintlayout:$versions.androidx" 30 | ext.deps.androidx = androidx 31 | 32 | ext.deps.pageindicator = "com.github.romandanylyk:PageIndicatorView:$versions.pageindicator" 33 | ext.deps.android_gradle_plugin = "com.android.tools.build:gradle:$versions.android_gradle_plugin" 34 | ext.deps.panelSwitchHelper_androidx = "com.github.YummyLau:PanelSwitchHelper:$versions.panelSwitchHelper" 35 | ext.deps.circleimageview = "de.hdodenhof:circleimageview:$versions.circleimageview" 36 | 37 | def config = [:] 38 | config.min_sdk_version = 16 39 | config.target_sdk_version = 31 40 | config.compile_sdk_version = 31 41 | config.build_tool_version = "30.0.3" 42 | config.version_code = 1 43 | config.version_name = "1.0" 44 | config.java_source_version = "1.8" 45 | config.java_target_version = "1.8" 46 | ext.config = config 47 | 48 | --------------------------------------------------------------------------------