Tôi cũng gặp phải vấn đề này, nhưng trong trường hợp của tôi, tôi đã có một FragmentPagerAdapter
trang đang cung cấp các ViewPager
trang của nó. Vấn đề tôi đã là onMeasure()
của ViewPager
được gọi trước khi bất kỳ Fragments
đã được tạo ra (và do đó không thể kích thước riêng của mình một cách chính xác).
Sau một chút thử nghiệm và lỗi, tôi thấy rằng finishUpdate()
phương thức của FragmentPagerAd CHƯƠNG được gọi sau khi Fragments
đã được khởi tạo (từ instantiateItem()
trong FragmentPagerAdapter
) và cả sau / trong quá trình cuộn trang. Tôi đã tạo một giao diện nhỏ:
public interface AdapterFinishUpdateCallbacks
{
void onFinishUpdate();
}
mà tôi chuyển vào FragmentPagerAdapter
và gọi:
@Override
public void finishUpdate(ViewGroup container)
{
super.finishUpdate(container);
if (this.listener != null)
{
this.listener.onFinishUpdate();
}
}
do đó cho phép tôi để gọi setVariableHeight()
trên tôi CustomViewPager
thực hiện:
public void setVariableHeight()
{
// super.measure() calls finishUpdate() in adapter, so need this to stop infinite loop
if (!this.isSettingHeight)
{
this.isSettingHeight = true;
int maxChildHeight = 0;
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY);
for (int i = 0; i < getChildCount(); i++)
{
View child = getChildAt(i);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED));
maxChildHeight = child.getMeasuredHeight() > maxChildHeight ? child.getMeasuredHeight() : maxChildHeight;
}
int height = maxChildHeight + getPaddingTop() + getPaddingBottom();
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.measure(widthMeasureSpec, heightMeasureSpec);
requestLayout();
this.isSettingHeight = false;
}
}
Tôi không chắc đó là cách tiếp cận tốt nhất, sẽ thích bình luận nếu bạn nghĩ nó tốt / xấu / xấu, nhưng có vẻ như nó hoạt động khá tốt trong quá trình thực hiện của tôi :)
Hy vọng điều này sẽ giúp ai đó ngoài kia!
EDIT: Tôi đã quên thêm một requestLayout()
sau khi gọi super.measure()
(nếu không nó sẽ không vẽ lại khung nhìn).
Tôi cũng quên thêm phần đệm của cha mẹ vào chiều cao cuối cùng.
Tôi cũng bỏ việc giữ các biện pháp đo chiều rộng / chiều cao ban đầu để ủng hộ việc tạo một cái mới theo yêu cầu. Đã cập nhật mã cho phù hợp.
Một vấn đề khác mà tôi gặp phải là nó sẽ không có kích thước chính xác trong một ScrollView
và tìm ra thủ phạm là đo đứa trẻ MeasureSpec.EXACTLY
thay vì MeasureSpec.UNSPECIFIED
. Cập nhật để phản ánh điều này.
Những thay đổi này đã được thêm vào mã. Bạn có thể kiểm tra lịch sử để xem các phiên bản cũ (không chính xác) nếu bạn muốn.