我试图模仿iOS UICollectionView
的硬编码数据。真的,我只需要在一个由2列3行组成的网格中显示5个方块(最后一个是半个...完整的)
每列的宽度应该是屏幕的一半,这是使用Star
(*)完成的。我需要高度总是比宽度小一点。这个想法是有厚厚的矩形。
现在网格在滚动视图中,我不确定它是否相关但我们永远不知道。我这样做,所以较小的手机将始终能够滚动网格,而其他手机可能只有空白。
我一直在试图获取屏幕大小或列宽。我根本无法得到列宽或绝对值的绝对值(总是-1!?)。我可以很容易地得到我的网格项的星值,即1,但我真的只需要帧大小,double
值,所以我可以在我的视图的构造函数中调整我的网格并给它绝对值。
问题:
如何获得列绝对宽度?或者如何将行高设置为与列宽相关的值?
如果没有可能,我如何获得屏幕宽度,这样我就可以做出可怕的rowheight = screenWdith/2 - padding
?
也许有一种非常简单的方法可以使这个过程变得微不足道?
或者这一切都可能吗?
答案 0 :(得分:1)
我会回答#2,获得屏幕宽度和高度,你需要一个依赖服务来做你需要的东西:
interface IScreen
{
double Width { get; }
double Height { get; }
double convertPx(int px);
string locationName(double latitude, double longitude);
Task<string> locationNameAsync(double latitude, double longitude);
string Version { get; }
void ShowAlertMessage(string aTitle, string aMessage);
}
机器人:
class Screen_Android : Java.Lang.Object, IScreen
{
public Screen_Android() { }
public double Width
{
get
{
var ctx = Forms.Context;
var metrics = ctx.Resources.DisplayMetrics;
return (ConvertPixelsToDp(metrics.WidthPixels));
}
}
public double Height
{
get
{
var ctx = Forms.Context;
var metrics = ctx.Resources.DisplayMetrics;
return (ConvertPixelsToDp(metrics.HeightPixels));
}
}
private static int ConvertPixelsToDp(float pixelValue)
{
var ctx = Forms.Context;
var dp = (int)((pixelValue) / ctx.Resources.DisplayMetrics.Density);
return dp;
}
public double convertPx(int px)
{
var ctx = Forms.Context;
//var dp = (int)((px) / ctx.Resources.DisplayMetrics.Density);
//return (int)((dp * ctx.Resources.DisplayMetrics.Density) + 0.5);
double density = ctx.Resources.DisplayMetrics.Density;
if (density >= 4.0)
{
//"xxxhdpi";
return px * 4;
}
if (density >= 3.0 && density < 4.0)
{
//"xxhdpi";
return px * 3;
}
if(density >= 2.0)
{
//xhdpi
return px * 2;
}
if(density >= 1.5 && density < 2.0)
{
//hdpi
return px * 1.5;
}
if(density >= 1.0 && density < 1.5)
{
//mdpi
return px * 1;
}
return px;
//return (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, px, ctx.Resources.DisplayMetrics);
//var resources = ctx.Resources;
//var metrics = resources.DisplayMetrics;
//int dp = px * ((int)metrics.DensityDpi / 160);
//return dp;
}
public string locationName(double latitude, double longitude)
{
//List<Address> addresses;
Geocoder geocoder = new Geocoder(Forms.Context, Locale.Default);
try
{
var addresses = geocoder.GetFromLocation(latitude, longitude, 10);
if (addresses.All(item => item == null)) return "";
string address = addresses[0].GetAddressLine(0);
string city = addresses[0].GetAddressLine(1);
string country = addresses[0].GetAddressLine(2);
return address + " " + city + " " + country;
}
catch
{
return "";
}
}
public string Version
{
get { throw new NotImplementedException(); }
}
public void ShowAlertMessage(string aTitle, string aMessage)
{
Toast.MakeText(Forms.Context, aMessage, ToastLength.Short).Show();
}
public System.Threading.Tasks.Task<string> locationNameAsync(double latitude, double longitude)
{
throw new NotImplementedException();
}
的iOS:
public class Screen_iOS : IScreen
{
public double Width
{
get
{
return UIScreen.MainScreen.Bounds.Width;
}
}
public double Height
{
get
{
return UIScreen.MainScreen.Bounds.Height;
}
}
public double convertPx(int px)
{
throw new NotImplementedException();
}
public string locationName(double latitude, double longitude)
{
string locationName = "";
CLLocation c = new CLLocation(Math.Round(latitude, 2), Math.Round(longitude, 2));
CLGeocoder geocoder = new CLGeocoder();
geocoder.ReverseGeocodeLocation(c, (placemarks, error) =>
{
if ((placemarks != null) && (placemarks.Length > 0))
locationName = placemarks[0].Name + placemarks[0].PostalCode + placemarks[0].AdministrativeArea + placemarks[0].Country;
});
return locationName;
}
public string Version
{
get
{
NSObject ver = NSBundle.MainBundle.InfoDictionary["CFBundleShortVersionString"];
return ver.ToString();
}
//get { throw new NotImplementedException(); }
}
public void ShowAlertMessage(String aTitle, string aMessage)
{
UIAlertView error = new UIAlertView(aTitle, aMessage, null, "OK" , null);
error.Show();
}
public async Task<string> locationNameAsync(double latitude, double longitude)
{
string locationName = "";
CLLocation loc = new CLLocation(latitude, longitude);
CLGeocoder geocoder = new CLGeocoder();
CLPlacemark[] r = null;
var task = Task.Factory.StartNew(() =>
{
r = geocoder.ReverseGeocodeLocationAsync(loc).Result;
Console.WriteLine("it ran! {0}", r.Length);
});
task.Wait(TimeSpan.FromSeconds(10));
if ((r != null) && (r.Length > 0))
locationName = r[0].Name + r[0].PostalCode + r[0].AdministrativeArea + r[0].Country;
return locationName;
}
}