├── .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 |
--------------------------------------------------------------------------------