Đây có thể là một chút tắt chủ đề, nhưng điều này là mã chúng tôi sử dụng để đảm bảo một số văn bản phù hợp với một nhãn. Bạn gọi hàm này trong trình xử lý sự kiện postLayout hoặc tại một số thời điểm khác khi kích thước của nhãn và màn hình được biết.
function fitTextInLabel(label,options)
{
/*
* Make the given text fit in the label by, well, just trying. Run this when the layout is complete
* IE in the onPostlayout of the view or the label. When using the cache-feature don't forget to
* check for orientation in creating the cache key: otherwise the font size will not be recalculated for the other orientation
* This is an alloy function: it requires underscore.js But rewriting it for plain titanium is not a big deal.
* Spin in het Web - www.spininhetweb.nl - Contact us for questions. Yes we build apps.
*
* Label: the Ti.UI.Label to fit the text in
* Options: an options object:
* text: the text to fit. When not given we will use the current text of the label. Use a lorum ipsum that's big enough.
* fitWidth: which width to fit the text in. Either the fixed width of the label ("current") or that of the parent ("parent"). When
* width is Ti.UI.SIZE use "parent". Default: current.
* fitHeight: which height to fit the text in. "current" or "parent". Default: current
* marginVertical: space to keep vertically. Will use marginVertical/2 for top and bottom. Default: 0
* marginHorizontal: space to keep horizontally. Will use marginHorizontal/2 for left and right. Default: 0
* cacheKey: string. When given, use caching. We will save the found fontsize as a persistant property. When called again with the same key
* we will not calculute, but just set the fontsize. The cache is only cleared when the user removes the app or its data
* We add the device orientation to the cacheKey, so we automatically differentiate between setting for portrait and landscape
* applyTo: array of labels. When given, we will set the same fontsize on the given labels.
* callback: function. When given, we will call this after setting the fontsize on the label. The prototype for the callback function is:
* fn(Ti.UI.Label lbl, int newFontSize)
*
* RETURNS boolean. False on some error, true when everything started out okay.
*
* This function runs on the event engine so it is basically async. After calling it, the font will not be changed until the callback runs
*/
//defaults
var o =
{
text: false,
fitWidth: "current",
fitHeight: "current",
marginVertical: 0,
marginHorizontal: 0,
cacheKey: false,
deleteCache: false, //special for development: set to true to recache without using the old value
callback: false,
applyTo: []
};
if (typeof(options) == "object")
{
_.each(options, function(v,k)
{
o[k] = v;
});
}
//o now contains all the chosen options plus defaults for the rest
//add orientation to the cachekey
if (o.cacheKey)
{
o.cacheKey = o.cacheKey + "_" + Ti.Gesture.orientation; //int
}
//log("*** fitTextInLabel label " + label.id + " tekst " + (o.text ? o.text : "(origineel)"),o);
var font = _.clone(label.font);
//cache?
if (o.cacheKey && (! o.deleteCache))
{
var cached = Ti.App.Properties.getInt(o.cacheKey,0);
if (cached)
{
font.fontSize = cached;
label.setFont(font);
//log("*** Cached op key " + o.cacheKey + " fontSize: " + cached);
_.each(o.applyTo,function(otherlabel)
{
//just set the font
var f = otherlabel.font;
f.fontSize = cached;
otherlabel.setFont(f);
});
//callback
if (o.callback)
{
o.callback(label,cached);
}
return; //done
}
}
//find the fontsize that fits in the label
//we use a different label outside of the view, to check it
var labelsize = label.getSize();
var parentsize = label.parent.getSize();
//which width and height to use?
var maxw = (o.fitWidth == "parent" ? parentsize : labelsize).width - (o.marginHorizontal/2);
var maxh = (o.fitHeight == "parent" ? parentsize : labelsize).height - (o.marginVertical/2);
//log("*** Moet passen in " + maxw + " X " + maxh);
font.fontSize = 40; //beginnen we mee, kan hoger en lager
var starting = true; //voor als we omhoog moeten
//create the test label in the parent container, using a postLayout callback for checking the fit
var testl = Ti.UI.createLabel({
text: (o.text ? o.text : label.getText()),
width: label.wordWrap ? maxw : Ti.UI.SIZE, //when wrapping, use a fixed with, otherwise just see how big it becomes
height: Ti.UI.SIZE, //we want to measure the height after setting the font size
wordWrap: label.wordWrap, //copy the wordWrap from the real label
font: font,
top: -5000 //somewhere out of view please (does this create scrollbars?)
});
var done = false;
var onPostLayout =
function()
{
//called when the test label is relayout because of the font change, so let's see how it all fits now
if (done)
{
return;
}
var lsize = testl.getSize();
//log("*** Proberen " + font.fontSize,lsize);
//We declare it a fit when the font becomes to small, fits inside the height of a wrapping label
//or fits inside the height AND width of a nonwrapping label
if (font.fontSize == 5 || (lsize.height <= maxh && (label.wordWrap || lsize.width < maxw)))
{
//it fits!
//did we startup with a too small font?
if (starting)
{
//the fontsize we started with fits. So let's try something bigger
font.fontSize += 10;
testl.setFont(font);
}
else
{
//we found it: it fits the space or is so small we stop trying
//log("*** Past!");
done = true; //stop the postLayout eventloop
label.setFont(font); //set the font
testl.parent.remove(testl);
testl = null; //garbace collect
if (o.cacheKey)
{
//let's cache this value
//log("*** Cachen naar " + o.cacheKey + ": " + font.fontSize);
Ti.App.Properties.setInt(o.cacheKey,font.fontSize);
}
//set the font for the applyTo array
_.each(o.applyTo,function(otherlabel)
{
//just set the font
var f = otherlabel.font;
f.fontSize = font.fontSize;
otherlabel.setFont(f);
});
//and callback
if (o.callback)
{
o.callback(label,font.fontSize);
}
}
}
else
{
//no fit yet. Let's try a pixel smaller
font.fontSize--;
testl.setFont(font); //this will fire a new postLayout event, running this function again
starting = false; //we are no longer starting up. When we find a fit, it's what we'll use
}
};
//let's go
testl.addEventListener("postlayout",onPostLayout);
label.parent.add(testl);
return true;
}
Hy vọng điều này sẽ giúp ai đó.
+1 cho câu hỏi của bạn. Các tài liệu tại http://docs.appcelerator.com/titanium/2.1/index.html#!/api/Font đề cập rằng Titanium trên Android sẽ hỗ trợ px, pt, dp, mm và in, nhưng chúng không đề cập đến sp. – Wytze