如何获取布局的高度,以编程方式填充元素

How to get height of Layout, fiiled with elements programmatically

各位程序员大家好。在为 android 创建应用程序时,我遇到了一个问题。我想以编程方式创建 LinearLayout。然后我想以编程方式用不同的元素填充它。之后,我想获得此 LinearLayout 的高度以在将来使用它(例如,用于动画)并将其可见性设置为消失。我在 Activity 的 OnCreate 中执行的所有这些操作,所以如果我尝试获取高度,我得到 0。 谁能帮我解决这个问题。所有建议将不胜感激。

已更新

对于 GotiasitsAbbas 这里的代码

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    SetContentView(Resource.Layout.TestLayout);
    ScrollView contentScroll = FindViewById<ScrollView>(Resource.Id.contentScroll);
    LinearLayout contentContainer = FindViewById<LinearLayout>(Resource.Id.contentContainer);
    List<DetailsData> dataList = new List<DetailsData>();
    for (int i = 0; i < 3; i++)
    {
        string header = "Header " + " " + i.ToString();
        string title = "Title " + i.ToString();
        string subtitle = "Subtitle";
        string pretext = "Some words in pretext. Some words in pretext. Some words in pretext. Some words in pretext. Some words in pretext. Some words in pretext.Some words in pretext. Some words in pretext.";
        int[] images = { Resource.Drawable.detail_main1, Resource.Drawable.detail_main2, Resource.Drawable.detail_main3, Resource.Drawable.detail_main1,
            Resource.Drawable.detail_main2, Resource.Drawable.detail_main3, Resource.Drawable.detail_main1 };
        string[] features =
        {
            "OSome words in featurelist.",
            "OSome words in featurelist.",
            "OSome words in featurelist.",
            "OSome words in featurelist.",
            "OSome words in featurelist.",
            "OSome words in featurelist.",
            "OSome words in featurelist.",
            "OSome words in featurelist.",
            "OSome words in featurelist.",
            "OSome words in featurelist.",
        };
        dataList.Add(new DetailsData(i, header, title, subtitle, pretext, features, images));
    }
    testContainer = new TestContaier(this, dataList, contentContainer, contentScroll, false);
    testContainer.DataBind();
}

class TestContaier
{
    Activity _context;
    public List<DetailsData> _dataSource { get; private set; }
    LinearLayout _mainLayout;
    ScrollView _scrollContainer;
    public TestContaier(Activity context, List<HotelDetailsData> dataSource,  LinearLayout mainLayout, ScrollView scrollContainer)
    {
        _context = context;
        _dataSource = dataSource;
        _mainLayout = mainLayout;
        _firstExpanded = firstExpanded;
        _scrollContainer = scrollContainer;
    }
    public void DataBind()
    {
        bool isFirst = true;
        if (_dataSource != null)
        {
            foreach (var _dataItem in _dataSource)
            {
                TextView header = new TextView(_context)
                {
                    Text = _dataItem._header
                };
                LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MatchParent, LinearLayout.LayoutParams.WrapContent);
                header.SetTextColor(Color.ParseColor(_settings._headerTextColor));
                header.SetBackgroundColor(Color.ParseColor(_settings._headerBackgroundColor));
                header.LayoutParameters = lp;

                View contentView = _context.LayoutInflater.Inflate(Resource.Layout.DetailItem, null);
                ContentViewHolder holder = new ContentViewHolder();

                InitHolder(holder, contentView);

                FillHolder(holder, _dataItem);
                contentView.Visibility = ViewStates.Gone;
                holder.initialize(contentView);
                contentView.Tag = holder;
                header.AssociatedContent = contentView;
                _mainLayout.AddView(header);
                _mainLayout.AddView(contentView);
            }
        }
    }
    void InitHolder(ContentViewHolder holder, View view)
    {
        holder.imageSlider = view.FindViewById<ViewFlipper>(Resource.Id.imageSlider);
        holder.imagesContainer = view.FindViewById<LinearLayout>(Resource.Id.scrollImagesContainer);
        holder.detailTitle = view.FindViewById<TextView>(Resource.Id.detailTitle);
        holder.detailSubtitle = view.FindViewById<TextView>(Resource.Id.detailSubtitle);
        holder.detailPretext = view.FindViewById<TextView>(Resource.Id.detailPreText);
        holder.detailFeatureList = view.FindViewById<LinearLayout>(Resource.Id.detailFeatureList);
        holder.nextSliderButton = view.FindViewById<ImageButton>(Resource.Id.nextSliderButton);
        holder.prevSliderButton = view.FindViewById<ImageButton>(Resource.Id.prevSliderButton);
    }
    void FillHolder(AccordionContentViewHolder holder, HotelDetailsData dataItem)
    {
        /// filling holder with data
    }
}

您最好的猜测可能是,与其尝试获取托管 (LinearLayout) 高度,不如获取子项目的高度并将其乘以托管视图中的项目数。

编辑:这是可能满足您需要的解决方案。此函数可以在 onCreate()onResume() 中调用,只要它可以访问已初始化的 contentContainer

 public void getHeight(){

    contentContainer.post(new Runnable() {
        @Override
        public void run() {

            int sumHeight=0;
            for(int i=0; i<contentContainer.getChildCount(); i++){
                sumHeight+=contentContainer.getChildAt(i).getHeight();
            }
            Log.d("vidi", "Layout height = " + sumHeight);
        }
    });

另外,正如蒙面人很好地指出的那样,如果您的 LinearLayout 中有一些填充或边距,您可以使用 ex 获得它们。 contentContainer.getPaddingBottom 并将其添加到总和中。

.post(Runnable)的目的只是为了延迟Runnable中的代码,即在Layout绘制完成后将这段代码排队到运行。

线性布局需要一些时间来测量、传递给其子项并正确获取其高度。所以你必须等到它完成。这是代码

已尝试并成功:JAVA代码

    linearLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {

            int height = linearLayout.getMeasuredHeight();

            if( Build.VERSION.SDK_INT > 15){
                linearLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                linearLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
        }
    });

您为布局设置了一个侦听器,在获取高度后,取消注册 GlobalOnLayoutListener

您可以使用 linearLayout.getHeight()linearLayout.getMeasuredHeight()。两者在我的测试中提供了相同的值

XAMARIN 代码

  ViewTreeObserver vto = _linearLayout.ViewTreeObserver;       
  vto.GlobalLayout += (sender, args) => {      
    var ht = linearLayout.Height;
   };