I have added a view to my app defined as follows:
Ti.UI.createView({
top: 0,
left: 0,
width: '50%'
height: '460dp',
backgroundColor: 'red'
});
What I want to find out is whether the above view fits on the screen. I.e. whether the user's screen is tall enough to totally display my entire view. I tried it in the following way:
function getPixels(dp) {
return (dp + (Ti.Platform.displayCaps.dpi / 160));
}
alert(460); // 920
alert(Ti.Platform.displayCaps.platformHeight); // 1136
Which seems about right on the iphone simulator. However when running that exact same code on my android device I get the result:
screenheight: 1200
height of the view: 690
Which doesn't seem correct, because the view with the red background takes almost as much space on the iphone simulator as on my android device.
Is there any way to get consistent results on all devices (ios and android). Or is there some other way to solve my problem?
If you are trying to support all sizes, why don't you set your height to a % value as well?
In answer to your question, the main thing you need to consider is thatTi.Platform.displayCaps.platformHeight returns values in platform-specific units; so pixels on Android and density-independent pixels (dip) on iOS. Since you are setting your view height with density independent pixels, you instead want to convert these platform units to density independent and platform independent units.
I usually just use the measurement library provided by Titanium and Alloy.
var measurement = require('alloy/measurement');
var dpHeight = measurement.pxToDP(Ti.Platform.displayCaps.platformHeight);
if(460 < dpHeight) {
alert('Fits');
} else {
alert("does not fit');
}
But really I find it much easier to just use relative layouts with percentage values.
Another way to figure out if the view is in bounds (after the fact) is to just add a postlayout event listener, when this event is fired it means layout bounds have been calculated in system units and are now accesible:
view.addEventListener('postlayout', function(e) {
if(view.rect.height + view.rect.y > Ti.Platform.displayCaps.platformHeight) {
alert('Does not fit")
}
});
To get constant results of width and height properties between platforms you have to add
<property name="ti.ui.defaultunit" type="string">dip</property>
to tiapp.xml and provide sizes as plain numbers:
Ti.UI.createView({
top: 0,
left: 0,
width: 50,
height: 460,
});
Related
The question of it is quite similar with Same DPI but different inch size. But it is in case of react native for android.
For example, I made a following element.
<View style={{width: 280, height: 300, backgroundColor: '#00B0F0'}}>
</View>
And I saw it in different device simulator, one is 320x480px, mdpi, 3.2inch and another is 480x854px, mdpi, 5.4inch.
And each device show it like below.
I think, since the used values for width and height are dp, the real size of the element is different for each devices, because of different inch size not dpi.
I am web developer and in some situations I faced to make app with react native. And the issue of setting dimension is very confused.
Do I use flex? like developing responsive web ? or Is there other any other way or tips?
Thank you.
I have created simple functions that scale the dimensions according to screen sizes.
export const myWidth = Dimensions.get("window").width;
export const myHeight = Dimensions.get("window").height;
const standardWidth = 375.0;
const standardHeight = 667.0;
export function widthScale (dimension) {
return (dimension / standardWidth) * myWidth;
}
export function heightScale (dimension) {
return (dimension / standardHeight) * myHeight;
}
Set standardWidth and standardHeight equals to window fame in zeplin or any other design tool. And simply call functions widthScale when setting horizontal dimensions like with, paddingLeft, paddingRight, marginLeft, marginRight, borderRadius.
And use heightScale in vertical dimensions. If you want to draw a square or a circle use widthScale for both dimensions.
I am currently coding a android application using flutter, dart. I have a settings page that gives the user the ability to change theme. I have created 7 identical Raw Material Button in the shape of a circle. I have been reading around the best way to size the circle base on the users resolution/dpi.
themeButton.dart:
final _themeColour;
final VoidCallback _onPressed;
ThemeButton(this._themeColour, this._onPressed);
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
double ratio = width/height;
return RawMaterialButton (
shape: CircleBorder(),
fillColor: _themeColour,
elevation: 0.0,
highlightElevation: 0.0,
onPressed: () => _onPressed(),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
constraints: BoxConstraints(minHeight: width * ratio * 0.2),
);
}
At the moment I currently take the users device width and then size the button from that. When I try to look this up, everywhere talks about Pixel Density, however we I tried to use the dpi value as a multiplier the circles were extremely large on high dpi devices.
Using the device width works to a certain extent, however I would like to know if there is a preferred standard to completing this task.
Flutter handles high dpi automatically for you; see the devicePixelRatio documentation.
Multiplying by DPI will do it twice (which is why you're seeing them be larger on high dpi devices), whereas if you just set a width that happens automatically. What doesn't happen automatically is resizing to different aspect ratios, but it seems as though you've already come up with a solution to that. I'm not sure if there's anything else you're trying to do that doesn't accomplish - let me know and maybe I can help.
For anyone else dealing with a problem like this, the flutter wiki has an entry that might be helpful.
I am contributing to an Open Source Project where I am developing Material design for React Native. I am blocked at work,I am unable to make some UI level enhancements w.r.t. padding, alignment etc.,
This is the Official Spec of Material Design for Drawer-
In the above image, the UNIT of measurement is dp.
But, in my React Native code, I see there is no such units mentioned. Considering it is "react native" I am confused whether it is px or dp.
I even went over the Official Docs of React Native for Style component. I don't see a mention anywhere.
My Code looks like-
const styles = {
touchable: {
paddingHorizontal: 16,
marginVertical: 8,
height: 48
},
item: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
},
icon: {
position: 'relative',
},
value: {
flex: 1,
paddingLeft: 34,
top: 2
},
label: {
top: 2
}
},
Please can you tell me, if this is pixels or dp? And also, is 1px = 1dp?
From the docs:
All dimensions in React Native are unitless, and represent
density-independent pixels. Setting dimensions this way is common for components that should always render at exactly the same size, regardless of screen dimensions.
So yes, units in React Native are in dp. If you want to convert them to pixels, use PixelRatio.getPixelSizeForLayoutSize()
I share your confusion somewhat, not being able to actively inspect with a developer console as we are used to in the browser.
I am not familiar with the 'dp' unit, but from what I gather width: 1 renders differently on each device depending on the pixel density of the screen (see link). The information in the react-native docs say that 1 would render thicker on screens with high pixel density. Which then sounds logical as you have more precision on high density screens than you would have on low density screens and react-native aims at being universal so it would not assume high dpi.
It is my understanding that you can use the below linked PixelRatio API to calculate sizes for detail elements (think borders, icons, etc), that way you can dynamically adjust the rendered size according to the device's screen density.
https://facebook.github.io/react-native/docs/pixelratio.html#content
It is the pixel ratio that you have to consider. pixel represents an absolute value. pixel ratio is a relative value. to make app screen and components responsive you have to use pixel ratio.
i have been using in multiple apps already. and i think that is how you have to do it. hope this answers your question.
From what I know, the javascript styling that we use in react js or react native uses pixels. Pixel ratio is only needed to support different size of mobile device screens.
In my Cardboard app for Android, I want to display an overlay in each eye that centers. Simply creating a LinearLayout with two centered views is fairly easy and works for most phones as the eyes are drawn to best fit:
When that's not the case, getting something to center in each eye becomes a problem. It's most clearly illustrated when using a tablet:
I'm trying to get the message "Buffering, 0%..." centered inside each eye view.
The size of the render boxes for the eyes has a fixed dimension (of course, because the distance between human eyes has a fairly fixed size). Unfortunately, CardboardView doesn't appear to provide information about the exact size and/or position of the eyes.
I've looked into obtaining the left and right Eye through cardboardView.getCurrentEyeParams() (oddly undocumented), for which each Eye contains a Viewport. This appears to give a size and position, but its values don't appear to have an immediate relation with the size and placement on the screen.
On a LG G2 with a screen resolution of 1920×1080, the Viewports are:
Viewport left: {
x: 0,
y: 0,
width: 1150,
height: 1177,
}
Viewport right: {
x: 1150,
y: 0,
width: 1150,
height: 1177,
}
On a Nexus 9 with a screen resolution of 2048×1536, the Viewports are:
Viewport left: {
x: 0,
y: 0,
width: 802,
height: 802,
}
Viewport right: {
x: 802,
y: 0,
width: 802,
height: 802,
}
Both of these dimensions (if they're in pixels) are much larger than the actual image displayed, and in the case of the LG G2, the width and height indeed larger than the screen size of 1080px.
Looking into some decompiled code of the Cardboard SDK, it appears that the vignetted square around the eyes is drawn through an internal class called DistortionMesh, and is rendered through some somewhat complex code. (Note that some logic appears to be missing through decompilation, such as lines 195 and 199.)
The creation of the Viewport suggests that the values are indeed pixels (offset in meters, multiplied by pixels per meter). Perhaps that DistortionMesh or the EyeView matrix is applied to the Viewport before rendering? In any case, I get the feeling I'm not looking in the right place.
I've also taken a look at obtaining the ScreenParams, as it provides a width and height as well. Unfortunately, this returns the entire screen size on both devices and also doesn't appear to be relevant.
My current approach overlay is a custom ViewGroup that centers two children through calling child.layout() using the ScreenParams' height and half of its width.
How can I figure out how large the Eyes are drawn into StereoRenderer? Can I find a different way to center a different view in the eyes?
When using fancyBox, whether its an image or an iFrame (YouTube), and open this on a mobile device and then rotate (landscape to portrait or vice versa), fancyBox doesn't scale or fit to width of device window?
fancyBox Options:
$(document).ready(function() {
$(".fancybox").fancybox({
helpers : {
media: true,
title: null
},
width : 800,
height : 450,
aspectRatio : true,
scrolling : 'no',
openEffect : 'fade',
closeEffect : 'fade'
});
});
Device: SAM GALXY S3
OS: ANDROID 4.2
Browser: FF / CHRME / DOLPHIN
fancyBox version: 2.1.5 PACK
p.s. this is happening also on the examples, both versions 2 and beta! :/
Your code appears to be setting a static width and height value for your fancy box. That's not a bad thing to do, but it does explain why your fancybox is not fitting the device screen: mobile devices tend to be less than 800px in width.
To fix this, you can easily use css styles to set max-widths for fancybox classes "fancybox-wrap" and "fancybox-inner".
Example:
.fancybox-wrap{max-width: 95%!important;}
.fancybox-inner {max-width: 100%!important;}
These rules use !important because they need to be able to overwrite the html width/height set by the fancybox options.
You can easily set the same styles using a jquery function to set css styles in fancybox's afterLoad option (though there may be more efficient methods to use than afterLoad, it should still get the job done.)