QMUI 2 has been on the drawing board for a long time, but at a snail’s pace of development, the first release has finally arrived. You can download the QMUIDemo experience from the official website, and then go to Github to give a star.
This release contains the following major changes:
- The support library was migrated to Androidx and the lowest supported version was upgraded to API 19.
- With support for night mode, QMUI is a bit more general, offering skin changes.
- Refactoring components such as QMUIPopup and QMUITabSegment to provide richer functions.
- Remove the old implementation method and related resources of dividing lines based on the background slice graph, and use the QMUILayout scheme instead.
First of all, this version is not fully compatible with 1.x. There are a lot of resource additions, deletions, and component interface and implementation changes, so upgrading to 2.x may take a bit of time. In particular, resource configuration changes may cause the UI display to be incorrect even though the compilation is ok. (Especially in the case of incomplete documentation, which I have memorized, but still can’t be perfected that quickly)
The introduction of QMUI 2
def qmui_version = '2.0.0 - alpha02'
implementation "com.qmuiteam:qmui:$qmui_version"
implementation "com.qmuiteam:arch:$qmui_version"
kapt "com.qmuiteam:arch-compiler:$qmui_version" // use annotationProcessor if java
Copy the code
Androidx
There is a lot of buzz on Github about moving to AndroidX, some people want to make it easier to view the source code, and some people, I suspect, are not aware of jetifier’s way of converting support packages to AndroidX at compile time.
Another change is that the minimum supported version has been upgraded to API 19. It’s 2019 and I want to upgrade to API 21, but I’m not going to go too far. I’ll just take it slow.
Dark Mode/skin change
Android 10 provides Dark Mode support, which can be implemented in two ways:
- One is to place Dark Mode resources on value-night and drawable-night. When Dark Mode is on,
Activity
Will be recreated and then read resources from the *-night directory. - The other is in the
AndroidManifest
File forActivity
的configChanges
adduiMode
Do not rebuildActivity
And goonConfigurationChanged
. inonConfigurationChanged
To judge the presentuiMode
And then do custom processing.
The first approach is simple, but it has two drawbacks:
- When Dark Mode switches, it needs to rebuild the whole
Activity
Normally, it’s fine. You don’t feel the reconstruction, but ifView
It’s too big, it takes too long to create a View, and you’ll notice a black screen (many products like to make their interface logic too complicated, for exampleViewPager
nestedViewPager
And nestingViewPager
And each Pager is extremely complex.) - The other point is, if you already support one skin, why can’t you support more? For example, full black and white (fake ink screen)
Therefore, QMUI recommends the second option, so QMUI provides support for peels, and night mode just calls the peels interface when onConfigurationChanged. Of course, developers can also create a *-night folder and configure various color/drawable Settings for QMUI in the first way to achieve night mode adaptation. QMUI simply attralizes the value of a component resource. It is up to the user to decide how to use it.
For general use, add your skin support to application.oncreate () :
QMUISkinManager skinManager = QMUISkinManager.defaultInstance(this); skinManager.addSkin(1, R.style.app_skin_blue); skinManager.addSkin(2, R.style.app_skin_dark); skinManager.addSkin(3, R.style.app_skin_white); skinManager.changeSkin(isDarkMode ? 2:1);Copy the code
R.style.app_skin_blue, R.style.app_skin_dark, r.style.app_skin_white, etc. Then in the Application. The onConfigurationChanged monitored uiMode information:
if((newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES){
QDSkinManager.changeSkin(QDSkinManager.SKIN_DARK);
}else if(QDSkinManager.getCurrentSkin() == QDSkinManager.SKIN_DARK){
QDSkinManager.changeSkin(QDSkinManager.SKIN_BLUE);
}
Copy the code
Of course, there is no chance of getting to QMUI’s skinning mechanism for the context in which LauncherActivity is launched, so it will revert to the first Dark Mode implementation.
So how do we set up the View in business? There are the following ways:
- If you are using XML, this can be provided through QMUI
qmui_skin_xxx
To set your skin. - If you want to set Skin in Java code, you need to
QMUISkinValueBuilder
To build value, and then passQMUISkinHelper.setSkinValue
To set, slightly more complicated, if the pass is Kotlin, QMUI providesView.skin
Method can be quickly implemented. - There’s another way that’s still being developed, and I’m going to call it
skin-maker
. The purpose is to allow designers to do skin Settings in a point-by-point manner, then export a configuration file, put it into the project, and complete skin Settings through bytecode injection. In this way, the whole configuration work can be entrusted to the design, and there is no need to consider skin changes for each new business. The ideal is beautiful, but the reality is that we have made a Demo version, and those who are interested can experience it on QMUIDemo. The process is familiar, but there are still many problems to be solved.
QMUIPopup rewrite
The previous implementation of QMUIPopup was quite bad, and the background shadow was implemented in the way of.9.png. Because the shadow occupies the position, the edge distance is too large. If anchorView is at a very edge position, the arrow will be misplaced or the display is not ideal, and many people step on this pit. The only solution is to provide a background with a smaller shadow.
Therefore, this version completely rewrites it, using the QMUILayout approach to shadows, so you can completely trim the edges if you want. In addition, 2.x version provides QMUIQuickAction and QMUIFullScreenPopup, the style of the former is derived from the shortcut menu of wechat reading reader, of course, the implementation is different (although the one on wechat reading is also written by me, but the implementation of that year is not easy to look at). The latter can be used to realize wechat reading various ideas floating layer, reading various floating layer rose last year, and there are keyboard interaction, I have some experience, but also extracted.
A simple use example:
QMUIPopups.popup(getContext(), QMUIDisplayHelper.dp2px(getContext(), 250))
.preferredDirection(QMUIPopup.DIRECTION_BOTTOM)
.view(textView)
.edgeProtection(QMUIDisplayHelper.dp2px(getContext(), 20))
.offsetX(QMUIDisplayHelper.dp2px(getContext(), 20))
.offsetYIfBottom(QMUIDisplayHelper.dp2px(getContext(), 5))
.shadow(true)
.arrow(true)
.animStyle(QMUIPopup.ANIM_GROW_FROM_CENTER)
.onDismiss(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
Toast.makeText(getContext(), "onDismiss", Toast.LENGTH_SHORT).show();
}
})
.show(v);
Copy the code
The organization is much more comfortable than before.
More changes
In addition to the QMUIPopup rewrite, there are also major changes to other components:
- QMUITabSegment large area rewrite, providing two pictures switch, different Tab Settings and other functions, expansion is also more flexible.
- QMUIBottomSheet. BottomListSheetBuilder added a lot of people are looking forward to the center of setting
- QMUICommonListItemView changes its parent class to ConstraintLayout, rewrites the layout, and can set the height wrAP_content to support super-long headings or subheadings
- The QMUISlider component is provided
- .
Finally, the current version has not been fully tested and practiced, so there may be a lot of problems. Welcome to issue.
Links: originally blog.cgsdream.org/2019/12/01/…