-
-
Notifications
You must be signed in to change notification settings - Fork 561
Themes, styles and other conventions
Florian edited this page Sep 11, 2021
·
5 revisions
As of June 2021 a major overhaul of the c:geo UI is ongoing. This page tries to document some "best practice" approaches and conventions to use when working with styles, themes and components. Be warned, though: Most of c:geo is not yet following those conventions, there's still much work to do. And: This is WIP, some not so manifested "conventions" may still change over the next couple of months...
- We are migrating to using the material components library, see https://material.io/components. Before inventing your own mega cool UI element, have a look at the component library if there's something already existing which fits your needs.
- All activities should be based on
AppCompatActivity
(our only exception are our settings, which need to be migrated toPreferenceFragment
first, see #10579) - All of our themes are based on material themes, no "AppCompat" theme, no "Holo" etc.
- Basically: You need a very good reason to not base your activity on
cgeo
theme
(to be continued)
For now, let's start with what got changed with our base PR #10643 in contrast to older versions of c:geo:
- Based c:geo main theme on
MaterialComponents.DayNight.DarkActionBar
, which, besides other things, means that there will be only one theme for both dark (night) and light (day) mode, and we even have the option to set changing themes to "automatically by system". That also means, that theme checks inside the java code (e.g.:Settings.isLightSkin() ? R.style.light : R.style.dark
) shouldn't be implemented! See next section for more details... - Themes and theme hierarchy drastically reduced to a bare five themes:
-
cgeo
- is the basic theme for all of c:geo, except the following -
cgeo.popup
- used for cache and waypoint popups from map (based oncgeo
, but added transparency around the popup) -
settings
andsettings.light
are only temporarily needed, as our current implementation for settings is not yet based onAppCompatActivity
andPreferenceFragment
- both themes can be removed when migration of settings is done -
SplashScreenTheme
is a stripped-down theme for splash screen, based onMaterialComponents.DayNight.NoActionBar
-
- Divided our color definitions into a common part (still in
res/values/colors.xml
), a file for the day theme colors (res/values/colors_light.xml
) and a file for the night theme colors (located inres/values-night/colors_dark.xml
). Be aware that the file name does not matter, it's only for easier handling in the editor. It's the folder location that matters. Files invalues-night
override the color values in thevalues
folder when in night (dark) mode. - The same is true for drawables, so instead of naming a drawable
res/drawable/test_dark.png
andres/drawable/test_light.png
(and chosing the right one by defining an attribute, which gets prefilled in the theme), handling is way easier now: You place the day theme drawable inres/drawable
, and the night theme drawable inres/drawable-night
. Or even better, use a dynamic color reference in the SVG that depends on the current theme, so that two identical icon definitions are not necessary at all. Access is simply done by using the drawable id,R.drawable.test
in this case. (Same applies for the other drawable folders -res/drawable-mdpi
becomesres/drawable-night-mdpi
etc.) - Besides that, colors for the material components follow the color scheme described in https://material.io/blog/android-material-theme-color. Currently, we've set
colorPrimary
,colorSecondary
and its variants to our orangecolorAccent
(as it has been called earlier), but that's not really fixed by now. - (Nearly) all other explicit color definitions in the separate components have been removed to be based on material theme's set of colors.
- Instead of explicitly mentioning a certain
textSize
- and we have been very creative in doing so - all text sizes are now based on a defined set of text sizes, which you will find invalues/dimens.xml
- In all xml definitions where you need a text size, you refer to one of those attributes, e. g.
textSize="@dimen/textSize_detailsPrimary"
- So far I have defined the following text sizes:
-
detailsPrimary
will be the most commonly used text size for regular text, edit text etc. -
detailsSecondary
can be used for the same places, but for less important text -
listsPrimary
andlistsSecondary
are similar, but for use in lists -
headingPrimary
is for headings (not toolbar!), and sometimes you might have use for a subheading, which would beheadingSecondary
- for the toolbar you can use
toolbarSingle
if there is a single line of text, andtoolbarPrimary
/toolbarSecondary
if you have a two-liner - There are a few more for some special cases (e. g. wizard), but that's it so far - every text size is based on one of those, which gives a way more consistent look throughout the app
-
some of the following conventions are inspirited by this article
- always give visual touch feedback if the view is clickable. If the view does not do this automatically, apply an
selectableItemBackground
to the view, e.g.:
android:background="?android:attr/selectableItemBackground" // inside the whole view
android:background="?android:attr/selectableItemBackgroundBorderless" // beyond the view borders
- UI should provide feedback about their current status. Users should never wonder what state the system is in.
- Dangerous actions should either support undo or display a "do you really want to do this?" dialog
- But we should try to speed up user workflows as well (see 'efficiency') - Providing undo instead of asking for confirmation is often the preferable solution.
- default actions should be reachable in as fewer clicks as possible. Every additional click is somewhat annoying.
- popup dialogs should only be shown if there was a user action before.
- toasts are allowed to show up at any time, but always check users will really benefit or rather be confused by it.
- similar actions should use the same views / viewgroups. Try to make components reusable!
- Layouts / Activities should be as simple as possible. We never really managed this in c:geo. Somehow our screens always get too complicated ;-)
- Furthermore, don't use any form of implementation level terminology inside the UI. Software should be understandable for average users.
- Only release features when they are complete. It is better to not have a feature instead of having one that works poorly.
- For sure, there are many different user cases and sometimes a setting is simply necessary.
- However, when people ask for a setting, try to find out the root of the problem and fix that instead.
Information
Development
- Join the team
- Development Environment
- GitHub
- Coding conventions
- design conventions
- Working on c:geo for git beginners
- Creating custom Android icons
- Translation
- Release Preparation
- Continuous Integration
- c:geo notifications
- Logging
Usage
- Creating offline maps
- Send a debug log to the developers
- 'New Map' feature description
- Presenting a demo
Technical documentation
- Heading
- Screen densities
- GPS low power mode
- DB Schema
- Map usages
- Disk Usage Structure
- Trackable parsing
- UnifiedMap
Misc
Outdated: