我有一个包含多个viewpage的expandablelistview,每个viewpager包含多个页面,每个页面都有一个linearlayout数据。 linearlayout中的数据是动态的(可能有5行或者可能有20行),每行有一个动态高度(它可以有1行文本或2-3行)。
由于viewpager需要设置硬编码高度才能显示,我需要在每个页面中显示所有内容的linearlayout,我不能允许viewpager中的内容滚动,我处于困难的情况下,试图计算viewpager的活动页面视图的高度,然后动态更新viewpager的高度,以便整个线性布局内容可见。在刷新新页面时,它应该相应地更新viewpager高度。
我试图在寻呼机适配器的SetPrimaryItem方法中执行此操作,但是返回的高度接近但不准确。在我的寻呼机页面视图中,我有一个带有蓝色背景的外部相对布局,然后是一个带有红色背景的内部布局。出于某种原因,外部(蓝色)布局可能比数据底部的距离大70dp,我猜测寻呼机正在操纵幕后的高度。内部的一个(红色)表现正确,并将数据包装在其中,所以这是我试图计算高度的那个,所以我可以更新viewpager的高度,但是它的高度被错误计算因为它比我更大,所以在我更新viewpager高度后,底部有空的空间。请参阅屏幕截图,因为它可能比我刚输入的内容更有意义:
另一个可接受的解决方案是计算最长页面的高度,并将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;
}
}
答案 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;
}