获取网格行绝对宽度

Posted

技术标签:

【中文标题】获取网格行绝对宽度【英文标题】:Get grid row absolute width 【发布时间】:2015-12-21 16:27:34 【问题描述】:

我正在尝试模仿 ios UICollectionView 来获取硬编码数据。真的,我只需要在由 2 列和 3 行组成的网格中显示 5 个方格(最后一个是半员工...满员)

每列的宽度应该是屏幕的一半,这是使用Star (*) 完成的。而且我需要高度总是比宽度小一点。这个想法是有厚的矩形。

现在 Grid 位于滚动视图中,我不确定这是否相关,但我们永远不知道。我这样做是为了让较小的手机始终能够在网格中滚动,而其他手机可能只有空白。

我一直在尝试获取屏幕大小或列宽。我根本无法获得列宽或屏幕宽度的绝对值(总是-1!?)。我可以轻松获得网格项的星值,即 1,但我真的只需要帧大小,double 值,所以我可以在视图的构造函数中调整网格大小并给它一个绝对值价值。

问题:

    如何获得列的绝对宽度?或者如何将行高设置为与列宽相关的值?

    如果不可能,我如何获得屏幕宽度,这样我才能做到可怕的rowheight = screenWdith/2 - padding

    也许有一种非常简单的其他方法可以让这个过程变得微不足道?

或者这完全可能吗?

【问题讨论】:

关于#1 我对此有帮助吗? forums.xamarin.com/discussion/comment/152668/#Comment_152668 【参考方案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;
        
    

【讨论】:

以上是关于获取网格行绝对宽度的主要内容,如果未能解决你的问题,请参考以下文章

grid

获取边距的绝对宽度(边距问题:auto;)

宽度=“*”的网格列未按预期使用所有可用空间[重复]

如何使剑道网格列自动宽度

如何在更改后的Flexbox网格中获取Vue元素的更新CSS宽度?

Tkinter 网格动态布局