Skip to content
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

Size and color is different on Android #1673

Closed
leocavalcante opened this issue Aug 13, 2017 · 8 comments
Closed

Size and color is different on Android #1673

leocavalcante opened this issue Aug 13, 2017 · 8 comments

Comments

@leocavalcante
Copy link

From left to right: flash, android, html5.

Why does the elements on Android version looks smaller and the RGB order doesn't seams the same?

image

Main.hx:

package;

import openfl.display.DisplayObjectContainer;
import openfl.display.Sprite;
import openfl.display.StageAlign;
import openfl.display.StageScaleMode;
import openfl.events.Event;
import openfl.system.Capabilities;
import openfl.text.TextField;
import ru.stablex.ui.UIBuilder;

class Main extends Sprite
{	
	private var size: Float = 100;
	
	private var r: Sprite;
	private var g: Sprite;
	private var b: Sprite;
	
	public function new()
	{
		super();		
		addEventListener(Event.ADDED_TO_STAGE, addedToStage, false, 0, true);
	}
	
	private function addedToStage(event: Event): Void
	{
		stage.scaleMode = StageScaleMode.NO_SCALE;
		stage.align = StageAlign.TOP_LEFT;
		
		r = createSquare(this, 0x00FF0000, size);
		g = createSquare(this, 0x0000FF00, size);
		b = createSquare(this, 0x000000FF, size);
		
		stage.addEventListener(Event.RESIZE, resize, false, 0, true);
		resize(null);
	}
	
	private function resize(event: Event): Void
	{
		r.x = 0;
		r.y = 0;
		
		g.x = (stage.stageWidth / 2) - (size / 2);
		g.y = (stage.stageHeight / 2) - (size / 2);
		
		b.x = stage.stageWidth - size;
		b.y = stage.stageHeight - size;
	}
	
	private function createSquare(parent: DisplayObjectContainer, color: Int, size: Float): Sprite
	{
		var box: Sprite = new Sprite();
		
		box.graphics.beginFill(color);
		box.graphics.drawRect(0, 0, size, size);
		box.graphics.endFill();
		
		parent.addChild(box);
		
		return box;
	}
}

project.xml:

<?xml version="1.0" encoding="utf-8"?>
<project>
	
	<meta title="HelloOpenFl2" package="com.sample.helloopenfl2" version="1.0.0" company="Company Name" />
	<app main="Main" path="Export" file="HelloOpenFl2" />
	
	<source path="Source" />
	
	<haxelib name="stablexui" />
    <haxelib name="openfl" />
    <haxelib name="actuate" />
	
	<assets path="Assets" rename="assets" />
	
	<android target-sdk-version="23" />
	<architecture name="x86" if="android" />
	
</project>
@RblSb
Copy link

RblSb commented Aug 14, 2017

This depends on the different density of the screen pixels. When FullHD resolution fits into a smartphone - an individual pixel will look very shallow on it. You need to use a variable with a relative square size or try Capabilities.screenDPI.
Perhaps there is an easier way through scaleMode, which I do not know yet.

@guruas3
Copy link
Contributor

guruas3 commented Aug 14, 2017

Exactly, even if the window/app may seem the same size on your screen, Galaxy S6 from your screenshot has 1440 x 2560 pixels resolution so obviously the squares are smaller. I'm not sure why the order is different though. Have you tested on real android device or just using the emulator?

@leocavalcante
Copy link
Author

Thank you folks. And there is some standard way/library to handle DPI scale? How do you usually overcome this? It's a very common problem people ran into I guess. Or aren't HaXe/OpenFl used for mobile?

I'll setup a real device to check the colors, brb.

@jgranick
Copy link
Member

On native, we use the BGRA color order, which might not be supported properly in the emulator there. You should be able to check stage.window.dpi to get the density of the current screen, and scale based on how you want to handle it. On the flip-side, if you specify a width and height in your project.xml, OpenFL should automatically scale and letterbox content for you.

@leocavalcante
Copy link
Author

Right, I could get device DPI by stage.window.display.dpi and also openfl.system.Capabilities.screenDPI, but what exact calculation should I work on using it?
Is this the same thing that Feathers ScreenDensityScaleFactorManager solves?

By the way, colors are ok on real device.

@leocavalcante
Copy link
Author

Ok, cool, so:

size = dp(100);

And:

private function dp(value: Float): Float
{
	return value * scaleFactorFor(Capabilities.screenDPI);
}

private function scaleFactorFor(dpi: Float): Float
{
	var factorMap: Map<Int, Float> = [
		160 => 1.0,
		240 => 1.5,
		320 => 2.0,
		480 => 3.0,
		640 => 4.0
	];
	
	for (density in factorMap.keys()) {
		if (dpi <= density) {
			return factorMap[density];
		}
	}
	
	return 6.0;
}

The adventure for tomorrow then will be to debug what f... happen with the window when changing from portrait to landscape. It messes it in a way that even when bring back to portrait it doesn't looks the same anymore:

Initial portrait:
screenshot_20170814-230739 1

Landscape
screenshot_20170814-230747 1

Back to portrait:
screenshot_20170814-230802 1

@leocavalcante
Copy link
Author

leocavalcante commented Aug 15, 2017

AHA! Did the trick:

First
resizable="true" at a <window /> tag on project.xml.

Then add a Event.CHANGE to stage along side with the current RESIZE:

stage.addEventListener(Event.RESIZE, resize, false, 0, true);
stage.addEventListener(Event.CHANGE, resize, false, 0, true);
resize(null);

And update window dimensions to match the stage on resize():

stage.window.width = stage.stageWidth;
stage.window.height = stage.stageHeight;

@leocavalcante
Copy link
Author

Very, very cool platform to work on.
'll play more and I hope to contribute soon with my Flash background and React Native experience.
Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants