-
-
Notifications
You must be signed in to change notification settings - Fork 160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closes #1092 - Fixed contents cut off on smaller screen issue. #1095
Conversation
While it is nice to be able to scroll, I'm not sure this is a better design. I think focusing on scaling would be much better. For example, for me, the + button is over the "Welcome to Catima" text and there is no way users would know to scroll, so they don't get the hint about how to add cards: In the ScanActivity the problem is worse, as the buttons are now pushed outside of the view, so users on small screens may not be aware they have other options than enabling the camera: I know some logic exists to the scale text dynamically, maybe that will help? It may be useless for this case, but I figured I'd point it out just in case: Android/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java Lines 730 to 732 in 3179644
Aside from scaling the text it may also be good to hide the icon under certain screen heights to save some more space. |
No problem, I will look into this and find a solution to properly scale it. |
I made a new fix to this. Does it look better to you? video |
That looks much much better! I do worry a bit about the "We can't access the camera" text disappearing, but there indeed is very little space for it so it may be the best possible option. Definitely seems like the right direction :) |
Added a new mechanism to dynamically scale UI based on the screen ratio.
The updated code is now pushed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't quite work right and there are some parts I don't understand
} else | ||
scaleScreen(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For single if statements I kinda get the no-brackets style (although I personally wouldn't use it), but I'd really prefer brackets here. For me personally, it is a lot more readable.
private void scaleScreen() { | ||
DisplayMetrics metrics = getResources().getDisplayMetrics(); | ||
float ratio = (float) metrics.heightPixels / metrics.widthPixels; | ||
boolean shouldScaleSmaller = ratio <= 0.8f; | ||
boolean shouldScaleMedium = ratio <= 1.1f && !shouldScaleSmaller; | ||
if (shouldScaleMedium) { | ||
customBarcodeScannerBinding.cameraPermissionDeniedLayout.cameraPermissionDeniedIcon.setVisibility( View.GONE ); | ||
} else { | ||
int buttonMinHeight = getResources().getDimensionPixelSize(R.dimen.scan_button_min_height); | ||
customBarcodeScannerBinding.cameraPermissionDeniedLayout.cameraPermissionDeniedTitle.setVisibility(shouldScaleSmaller ? View.GONE : View.VISIBLE); | ||
customBarcodeScannerBinding.cameraPermissionDeniedLayout.cameraPermissionDeniedIcon.setVisibility(shouldScaleSmaller ? View.GONE : View.VISIBLE); | ||
customBarcodeScannerBinding.cameraPermissionDeniedLayout.cameraPermissionDeniedMessage.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(shouldScaleSmaller ? R.dimen.no_data_min_textSize : R.dimen.no_data_max_textSize)); | ||
customBarcodeScannerBinding.addFromImage.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(shouldScaleSmaller ? R.dimen.scan_button_min_textSize : R.dimen.scan_button_max_textSize)); | ||
customBarcodeScannerBinding.addManually.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(shouldScaleSmaller ? R.dimen.scan_button_min_textSize : R.dimen.scan_button_max_textSize)); | ||
customBarcodeScannerBinding.addFromImage.setMinimumHeight(shouldScaleSmaller ? getResources().getDimensionPixelSize(R.dimen.scan_button_min_height) : buttonDefaultMinHeight); | ||
customBarcodeScannerBinding.addFromImage.setMinimumWidth(shouldScaleSmaller ? buttonMinHeight : buttonDefaultMinHeight); | ||
customBarcodeScannerBinding.addManually.setMinimumHeight(shouldScaleSmaller ? buttonMinHeight : buttonDefaultMinHeight); | ||
customBarcodeScannerBinding.addManually.setMinimumWidth(shouldScaleSmaller ? buttonMinHeight : buttonDefaultMinHeight); | ||
customBarcodeScannerBinding.addFromImage.setMinHeight(shouldScaleSmaller ? buttonMinHeight : buttonDefaultMinHeight); | ||
customBarcodeScannerBinding.addFromImage.setMinWidth(shouldScaleSmaller ? buttonMinHeight : buttonDefaultMinHeight); | ||
customBarcodeScannerBinding.addManually.setMinHeight(shouldScaleSmaller ? buttonMinHeight : buttonDefaultMinHeight); | ||
customBarcodeScannerBinding.addManually.setMinWidth(shouldScaleSmaller ? buttonMinHeight : buttonDefaultMinHeight); | ||
} | ||
} | ||
|
||
private void saveDefaultUIValues() { | ||
buttonDefaultMinHeight = customBarcodeScannerBinding.addFromImage.getMinHeight(); | ||
buttonDefaultMaxHeight = customBarcodeScannerBinding.addFromImage.getMinWidth(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally I was going to suggest moving the saving the default UI values into the start of scaleScreen
, but looking at it more I realize I'm not quite sure what all the setMin*
is for. As I understand Android UI (which, admittedly, I don't really do well) the fact that the buttons use wrap_content
for both width and height means they should scale to whatever the font size is.
I also tried this on my Fairphone 3 and the buttons still overlayed the text, so I guess the scaling isn't quite right. On top of that I tried removing all the setMin*
and noticed no difference at all, not even when comparing the screenshots before and after my change by rapidly alt-tabbing between them.
I have the feeling this way of resizing may simply not be the correct way to go about it. Even when tweaking the numbers, we may still run into unexpected cases.
I think it would possibly be cleaner to just tell Android the buttons at the bottom should keep their regular space and the help text at the top should be squashed to fit in the rest of the space, possibly using setAutoSizeTextTypeUniformWithConfiguration
to scale. But again, UI is one of my weakest points, especially in the way Android XML works. I'm hoping some Android community could perhaps help us figure out the best way to go about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally I was going to suggest moving the saving the default UI values into the start of
scaleScreen
, but looking at it more I realize I'm not quite sure what all thesetMin*
is for. As I understand Android UI (which, admittedly, I don't really do well) the fact that the buttons usewrap_content
for both width and height means they should scale to whatever the font size is.
Yes, buttons will be scaled based on the size of the text, however, there's a minimum size for buttons to be scaled. When I set the button text size to smaller, the buttons' sizes won't change because they have already reached the minimum size. To solve this problem, I have to override the minimum size of those buttons to scale them down even further.
I also tried this on my Fairphone 3 and the buttons still overlayed the text, so I guess the scaling isn't quite right. On top of that I tried removing all the setMin* and noticed no difference at all, not even when comparing the screenshots before and after my change by rapidly alt-tabbing between them.
I think maybe it is not reliable to set a specific screen ratio for the UI to scale, I'd better find another way to do it.
I think it would possibly be cleaner to just tell Android the buttons at the bottom should keep their regular space and the help text at the top should be squashed to fit in the rest of the space, possibly using setAutoSizeTextTypeUniformWithConfiguration to scale. But again, UI is one of my weakest points, especially in the way Android XML works. I'm hoping some Android community could perhaps help us figure out the best way to go about this.
Thank you for the advice and I will look into this to try to find a better way to scale it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After having tried to solve the problem with TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration()
, I found out this function may only be meant for scaling texts based on the font size setting in Android system settings.
When I was poking around with Google's documents about support for different sizes of screens(the link is here), I realized that it might be a good idea to use screen's height as the scale factor other than ratio, this is because for most of the phones, whether the content can be vertically contained or not is mainly decided by the height of the screen. I think using height as the scale factor might be more universally compatible with most phones. I have run it on my Android emulator with different screen sizes and it looked fine.
I made a new commit b44d998 to push the code.
Used screen height as the scaling factor instead of screen ratio.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really appreciate all your research and all you've been trying, it's been great to see what code leads to what result. However, I think the current method is a lot of code that still has some edge cases so maybe we should give up on trying to make it "perfect" and just go for something simple that will work well enough :)
I feel sorry for making you "throw away" all your hard work, especially because it was mostly caused by me trying to find the perfect solution without realizing the complexity of it. I know that can be really frustrating. However, your hard work did help tremendously to see what did and didn't work so it was still very useful from a research perspective.
float mediumSizePx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,MEDIUM_SCALE_FACTOR_DIP,getResources().getDisplayMetrics()); | ||
boolean shouldScaleSmaller = screenHeight < mediumSizePx; | ||
|
||
binding.include.welcomeIcon.setVisibility(shouldScaleSmaller ? View.GONE : View.VISIBLE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't notice this before but it seems this crashes the archive option (you can confirm this by putting 1 card in archive and then clicking the menu in the top right and choosing "Archive"):
E/AndroidRuntime: FATAL EXCEPTION: main
Process: me.hackerchick.catima.debug, PID: 19126
java.lang.RuntimeException: Unable to resume activity {me.hackerchick.catima.debug/protect.card_locker.MainActivity}: java.lang.NullPointerException: Attempt to read from field 'protect.card_locker.databinding.ContentMainBinding protect.card_locker.databinding.MainActivityBinding.include' on a null object reference
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4824)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4857)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:54)
at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2253)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7870)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Caused by: java.lang.NullPointerException: Attempt to read from field 'protect.card_locker.databinding.ContentMainBinding protect.card_locker.databinding.MainActivityBinding.include' on a null object reference
at protect.card_locker.MainActivity.scaleScreen(MainActivity.java:857)
at protect.card_locker.MainActivity.onResume(MainActivity.java:407)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1488)
at android.app.Activity.performResume(Activity.java:8197)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4814)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4857)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:54)
at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2253)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7870)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooops.. I didn't think about this scenario. It's now fixed in commit b0008cd
Fixed a crash issue in MainActivity when card is archived.
Co-authored-by: Sylvia van Os <[email protected]>
Fixed a compile error. Deleted some unused variables in ScanActivity.
6682515
to
89ab029
Compare
Looks great now, thank you! :) |
It's always my pleasure. :) |
Hi,
This PR closes #1092.
Change details are listed below.
Implemented
Small screens optimization
NestedScrollView
toMainActivity
to make it scrollable when the screen space is not enough for the UI to expand.NestedScrollView
toScanActivity
to make it scrollable when the screen space is not enough for the UI to expand.Known issue
Visual