Reliable way of getting initial size of QWidget - android

I have a custom widget. It's purpose is to display an image (with possibility of scaling, rotation etc).
My goal is to calculate initial scale of the image so its size would match widget's size.
My first attempt was to do it in constructor, but it wasn't right place (as widgets are usually put into layouts after construction, so their size change later).
Another way, which partially works is to override showEvent or resizeEvent and put there initial scaling. It works partially, because it works fine on desktop but for some reason it doesn't on android device - QWidget::size() returns the same size as in constructor.
Apparently on android first show/resize events are called before final window rearrangement.
Is there a clean way to achieve it?

You can try using a QLabel, either instead-of or inside the widget (you can set its border to 0px) and use setScaledContents.

Related

Android home screen widget textsize dynamically

There are applications that offer the ability to change the font size of a text in a home screen widget. One example is https://play.google.com/store/apps/details?id=org.zooper.zwfree
However home screen widgets only can carry RemoteViews so setting the textSize of a TextView dynamically will not work.
As I see it there are two possibilities to change the text size dynamically:
Add for every text size another layout.xml file. Those files merely differ in the TextView's textSize value. When the user wants to change the textsize, the respective layout has to be loaded.
Draw a Bitmap instead of creating a View like here https://stackoverflow.com/a/4411060/883083
My question is: Is there a third possibility left?
If you're targeting API level 16 or above, you can try the following:
Sadly the whole thing depends on knowing the widget size, which is only possible in API 16+.
Override the AppWidgetProvider.onAppWidgetOptionsChanged callback
or get the same Bundle later via AppWidgetManager.getAppWidgetOptions
Extract the size of the widget:
options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)
options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)
options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)
options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)
Deduce your TextView's width from the widget size
(best if you have it match_parent to the root of the widget, mind margins/paddings)
If you have complex layout you can alternatively
inflate the whole widget in your app space
widget = LayoutInflater.from(context).inflate(R.layout.widget, null)
Simulate a layout based on the framework:
widget.measure(MeasureSpec.makeMeasureSpec(widgetWidth, MeasureSpec.EXACTLY), ...).
Get your TextView's size: widget.findViewById(R.id.myText).getMeasuredWidth()
Use something like refitText here to find your optimal size
Set the calculated size via RemoteViews.setTextViewTextSize
Note: I didn't implement this method, just thought about it.
Try not to do this on every update, cache the results (even in preferences), widget options shouldn't change often.

Preview size wtith CWAC-Camera

I've been fighting for a while with https://github.com/commonsguy/cwac-camera
Managed to create my custom CameraFragment and a custom custom CameraHost.
I've overrode getPictureSize and getPreviewSize. With those two methods I'm able to find out which Sizes are able to be used. My overall idea is to capture a square image, and also preview it before capturing.
I've been testing and no device is returning a square-formatted Size, so I guess the best approach would be taking the Size nearest to my needs. Like if I need an 800x800 squared image, I will return the nearest Size, that would be (for example) 1280x1024
So far so good. The issue is the following:
Documentation states:
Usually, your CameraHost will be called with getPreviewSize()
Damn; my Nexus5 device never triggers this method, but a Genymotion emulator does. So in my emulator I can create a custom preview size, which I can't with my real device.
So I need some help with this issue. Why is it just "usually"? What can I do to change it to "always"?
On a second term, I need some tips: If I want an squared preview size, which I know it won't be available by default Sizes returned by getSupportedPreviewSizes, what can I do to display an square? Maybe overlaying a square on top of CameraFragment? Is it even possible? Or should I go for any other approach?
Anyways, congratulations on the library; it's absolutely clear and with so many options. No need to worry about "some devices". That's great as an Android Developer.
Thank you.
Why is it just "usually"? What can I do to change it to "always"?
Quoting the documentation:
If getRecordingHint() returns ANY or VIDEO_ONLY, though, CameraHost supplies the preview size via getPreferredPreviewSizeForVideo() instead of getPreviewSize(). If you wish to use a different preview size for video, return it, otherwise return null and we will use the results from getPreviewSize() instead.
On API Level 11+, the implementation of SimpleCameraHost getPreferredPreviewSizeForVideo() delegates to the getPreferredPreviewSizeForVideo() implementation on Camera.Parameters, except for devices known to return poor values for it.
what can I do to display an square? Maybe overlaying a square on top of CameraFragment?
I would try putting CameraView directly in your own UI, then layering something on top of it, using a FrameLayout or RelativeLayout to control the Z-axis ordering.

Is there a way to allow an image to extend past the boundary of the window?

I'm trying (and not finding) a way to have an image that acts as a background, which is larger than the the screen, to not squish and instead to just flow off the right and bottom of the screen.
In other words, I have a background image that is, say, 3000x3000 pixels.
I want it to originate at 0x0 and then rather than being squished into whatever the resolution of the device is, to just get naturally cropped by said resolution, allowing the excess to flow off the sides.
I've tried every combination of wrapping content and scaleType(ing) that I can think of and none of them produce the intended result. Is there a way to do this? Or am I just out of luck?
setScaleType to MATRIX and call setClipChildren with false on the parent ViewGroup container

Image as Background for UI

I am newbi in android world and working on an android app.
I have used many of buttons and image buttons in my app.
Now i want to replace them with an background image. (So i can make nice gui easily)
I know i can use view listener and i can find the clicked x and y coordinate from onclick method.
But I want to how can i find which part of the image was clicked. Because different phones have different resolutions how can i do this efficiently ?
And one more thing, Is it good to handle gui this way ?
Thanks !
You first need to set the initial window width and height before execution of other code and load an image of quality based on the screen size. so for example you can have 3 sets of images of different size. One for 5 inch screens and below. Another for 7 inch tablets. Another for 10 and possibly another super high quality image for anything above. As many devices coming on in the near future are reaching resolutions much higher then previously developed for. Just run code initially that detects the initial window size at hand and load image based on resolution of that device. From their program as you plan to.
Also to jump on answer above. Detect rotation event and adjust image accordingly. and update accordingly. You are adding more programming of course but no reason what you are asking could not be done. Just a few extra events detection and you should be good to go to accomplish exactly what you are looking to do
AFAIK it is not good practice to handle the GUI this way. Mostly because android screen size is not standard and so you can never be sure that it will work perfectly in all the devices. You can ofcourse handle the events using onTouchListener and see which part of image was clicked from the coordinates in the MotionEvent Object. But, I would not recommend doing so.
Creating layouts of different screen sizes and handling the events using Buttons and ImageButtons will be good.
you can use android:background attribute for background images in the layout xml files...
however you also can set the background of UI element programatically

Android LIVE Wallpaper approach?

I'm entirely new to Android development, and I'm interested in making a live wallpaper. I was thinking about looping a set of pictures instead of drawing the animation. Is this a possible approach? If possible is this a suitable or ideal way of doing it, does it eat up memory and would i need images with different resolutions because of the fragmentation?(hundreds of different devices)
Thanks in advance :)
Sure, it should be fairly simple.
The main part of the Wallpaper engine is the Drawing of course. You need to handle the drawing manually, there is no easy way to loop through images... you need to code it. You will have to continuously monitor the time which has passed and adjust the displayed image based on that. You are given a Canvas object to draw to and it is all done during run-time in code.
The Wallpaper engine class has a event called onSurfaceChanged which gives you the width and height of the Surface which you will be drawing to. It will be called everytime the screen dimensions change (like if the phone is put into Landscape mode for instance). You need to have code that will handle any combination of width or height for all the device types out there. You will need to decide if you are going to stretch, center, tile or crop (Or a combination of those) the source images to fit any particular screen size. I would recommend scale to fit so that the image is either taller or wider than the screen and center the image either vertically or horizontally (cropping the extra bits) once that is done. I personally just use one source size and resize it to fit. You can opt to use several source files if you want which is the recommended approach I believe, but it's a little confusing.
I would start by creating a Live Wallpaper which just draws something basic like a shape to the screen. Then work out how to display an custom image and take it from there.
Good luck
You will need to be very careful about memory if taking a frame approach to animation--probably will not be possible to animate full frames--much more practical to move sprites on a background. See, fr'instance: http://davidjhinson.wordpress.com/2010/05/19/scarce-commodities-google-android-memory-and-bitmaps/
what if you have a png frame animation that is set at a certain x and y position that sits in a spot on the background image, both would have to be rescaled

Categories

Resources