将viewpager高度设置为内容的高度

时间:2014-08-15 14:55:36

标签: android android-viewpager xamarin xamarin.android android-linearlayout

我有一个包含多个viewpage的expandablelistview,每个viewpager包含多个页面,每个页面都有一个linearlayout数据。 linearlayout中的数据是动态的(可能有5行或者可能有20行),每行有一个动态高度(它可以有1行文本或2-3行)。

由于viewpager需要设置硬编码高度才能显示,我需要在每个页面中显示所有内容的linearlayout,我不能允许viewpager中的内容滚动,我处于困难的情况下,试图计算viewpager的活动页面视图的高度,然后动态更新viewpager的高度,以便整个线性布局内容可见。在刷新新页面时,它应该相应地更新viewpager高度。

我试图在寻呼机适配器的SetPrimaryItem方法中执行此操作,但是返回的高度接近但不准确。在我的寻呼机页面视图中,我有一个带有蓝色背景的外部相对布局,然后是一个带有红色背景的内部布局。出于某种原因,外部(蓝色)布局可能比数据底部的距离大70dp,我猜测寻呼机正在操纵幕后的高度。内部的一个(红色)表现正确,并将数据包装在其中,所以这是我试图计算高度的那个,所以我可以更新viewpager的高度,但是它的高度被错误计算因为它比我更大,所以在我更新viewpager高度后,底部有空的空间。请参阅屏幕截图,因为它可能比我刚输入的内容更有意义:

enter image description here

另一个可接受的解决方案是计算最长页面的高度,并将viewpager设置为一次,然后在页面更改时不要更新它,但我还没有走这条路线然而,仍然会遇到计算正确身高的相同问题。

我已经花了一天时间,对于如何准确更新viewpager高度以适应其内容的任何想法/建议将不胜感激。我已经在SO上尝试了很多其他解决方案,并且找不到真正有效的解决方案。这是我到目前为止所处的地方:

寻呼机观点:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <android.support.v4.view.ViewPager
        android:id="@+id/property_details_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</RelativeLayout>

寻呼机适配器:( SetPrimaryItem方法是我尝试动态更新寻呼机的高度)

public class PropertyDetailsPagerAdapter : PagerAdapter {
        private ViewPager pager;
        private List<List<KeyValuePair<string, string>>> lists;

        public PropertyDetailsPagerAdapter (View view, List<List<KeyValuePair<string, string>>> lists) {
            this.pager = view.FindViewById<ViewPager> (Resource.Id.property_details_pager);
            this.pager.OffscreenPageLimit = lists.Count;
            this.lists = lists;
        }

        public void Update (List<List<KeyValuePair<string, string>>> lists) {
            this.pager.Adapter = null;

            this.lists = lists;

            this.pager.Adapter = this;
            this.pager.Adapter.NotifyDataSetChanged ();
        }

        #region Setup Views

        public override Java.Lang.Object InstantiateItem (View collection, int position) {
            var layoutInflater = (LayoutInflater)ApplicationContext.Activity.GetSystemService (Context.LayoutInflaterService);
            var view = layoutInflater.Inflate (Resource.Layout.PropertyDetailsPagerItem, null);
            var pagerList = view.FindViewById<LinearLayout> (Resource.Id.property_details_pager_list); 

            var list = this.lists [position];
            new PropertyDetailsPagerListAdapter (pagerList, Resource.Layout.PropertyDetailsPagerKeyValueRow, list);

            var listViewSwipe = view.FindViewById<LinearLayout> (Resource.Id.property_details_pager_swipe);
            listViewSwipe.Visibility = this.lists.Count > 1 ? ViewStates.Visible : ViewStates.Gone;

            this.pager.AddView(view);

            return view;
        }

        public override void SetPrimaryItem (View container, int position, Java.Lang.Object @object) {
            base.SetPrimaryItem (container, position, @object);

            var view = this.pager.GetChildAt (position);
            var innerView = view.FindViewById<RelativeLayout> (Resource.Id.property_details_pager_item);
            innerView.Measure (0, 0);

            var parameters = this.pager.LayoutParameters as RelativeLayout.LayoutParams;
            parameters.Height = innerView.MeasuredHeight;// TODO: Why isn't this height accurate?!?!
            this.pager.LayoutParameters = parameters;
        }

        #endregion

        #region Infrastructure

        // Other irrelevant methods

        public override int Count {
            get {
                return this.lists.Count;
            }
        }

        #endregion

        public List<List<KeyValuePair<string, string>>> Lists { get { return this.lists; } }
    }

查看寻呼机中的每个页面:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/blue">
    <RelativeLayout
        android:id="@+id/property_details_pager_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/red">
        <LinearLayout
            android:id="@+id/property_details_pager_swipe"
            android:layout_below="@+id/dotted"
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone">
            <TextView
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:visibility="invisible" />
            <RelativeLayout
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:background="@color/light_gray">
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Swipe for\nmore records"
                    android:textColor="@color/gray"
                    android:gravity="right"
                    android:padding="@dimen/padding" />
            </RelativeLayout>
        </LinearLayout>
        <LinearLayout
            android:id="@+id/property_details_pager_list"
            android:layout_below="@+id/property_details_pager_swipe"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" />
    </RelativeLayout>
</RelativeLayout>

寻呼机中每个页面的适配器:

public class PropertyDetailsPagerListAdapter
    {
        private int resourceId;
        private List<KeyValuePair<string, string>> keyValuePairs;

        public PropertyDetailsPagerListAdapter (LinearLayout pagerList, int resourceId, List<KeyValuePair<string, string>> keyValuePairs) {
            this.resourceId = resourceId;
            this.keyValuePairs = keyValuePairs;

            pagerList.RemoveAllViews ();
            foreach (var keyValuePair in this.keyValuePairs) {
                pagerList.AddView (GetView (keyValuePair));
            }
        }

        public View GetView (KeyValuePair<string, string> keyValuePair) {
            var layoutInflater = (LayoutInflater)ApplicationContext.Activity.GetSystemService (Context.LayoutInflaterService);

            var view = layoutInflater.Inflate(resourceId, null);

            // Assumes Resource.Layout.PropertyDetailsPagerKeyValueRow
            view.FindViewById<TextView> (Android.Resource.Id.Text1).Text = keyValuePair.Key;
            view.FindViewById<TextView> (Android.Resource.Id.Text2).Text = keyValuePair.Value;

            return view;
        }
    }

1 个答案:

答案 0 :(得分:1)

我能够弄清楚。问题是我正在使用innerView.Measure(0,0),然后获得MeasuredHeight,但是这给出了一个虚假的高度。在正确调用Measure之后,需要将真正的宽度传递给它,然后返回正确的高度!!

public override void SetPrimaryItem (View container, int position, Java.Lang.Object @object) {
            base.SetPrimaryItem (container, position, @object);

            var view = this.pager.GetChildAt (position);
            var innerView = view.FindViewById<RelativeLayout> (Resource.Id.property_details_pager_item);

            var desiredWidth = MeasureSpec.MakeMeasureSpec (this.pager.Width, MeasureSpecMode.AtMost);
            innerView.LayoutParameters = new RelativeLayout.LayoutParams (RelativeLayout.LayoutParams.WrapContent, RelativeLayout.LayoutParams.WrapContent);
            innerView.Measure (desiredWidth, (int)MeasureSpecMode.Unspecified);

            var parameters = this.pager.LayoutParameters as RelativeLayout.LayoutParams;
            parameters.Height = innerView.MeasuredHeight;
            this.pager.LayoutParameters = parameters;
        }