ScrollView巢狀ViewPager自適應高度,圖片高度小的會顯示空白
阿新 • • 發佈:2019-01-27
最近專案中遇到ScrollView巢狀ViewPager,ViewPager中存放的是ImagView,要求是,ImagView高度不定,接下來就是各種方法嘗試,比較普遍的方式就是自定義一個viewpager。程式碼如下:
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
/**
* 自動適應高度的ViewPager
* @author
*
*/
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec, View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
if (h > height)
height = h;
}
heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
可以看出,此自定義ViewPager的高度是根據子view的高度來決定的, if (h > height)
height = h;迴圈過後,就是將高度最大的子view的高度賦值給ViewPager的高度,這樣可以解決ViewPager不顯示的問題,但是潛在的問題是,當view的高度小的時候,ViewPager中的view下面會留白。
不符合需求,而且不美觀。
接下來在csdn中找到如下自定義的ViewPager:
方式一:ViewPager中放的是View
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import java.util.HashMap;
import java.util.LinkedHashMap;
/**
* Created by lzq
*/
public class SignViewPager extends ViewPager{
private int current;
private int height = 0;
/**
* 儲存position與對於的View
*/
private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>();
private boolean scrollble = true;
public SignViewPager(Context context) {
super(context);
}
public SignViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mChildrenViews.size() > current) {
View child = mChildrenViews.get(current);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
height = child.getMeasuredHeight();
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void resetHeight(int current) {
this.current = current;
if (mChildrenViews.size() > current) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
if (layoutParams == null) {
layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height);
} else {
layoutParams.height = height;
}
setLayoutParams(layoutParams);
}
}
/**
* 儲存position與對於的View
*/
public void setObjectForPosition(View view, int position)
{
mChildrenViews.put(position, view);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (!scrollble) {
return true;
}
return super.onTouchEvent(ev);
}
public boolean isScrollble() {
return scrollble;
}
public void setScrollble(boolean scrollble) {
this.scrollble = scrollble;
}
}
接下來需要注意的是:
條件1:
pager.setOffscreenPageLimit(3);
條件2:
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
pager.resetHeight(position);//重置viewpager的高度
//num.setText((position+1)+"/"+imageInfo.size());
pager.resetHeight(0);
}
@Overridepublic void onPageScrollStateChanged(int state) {}});
條件3:在instantiateItem()方法中pager.setObjectForPosition(view1,position);setObjectForPosition方法是為了呼叫存放你的view和他對應的position這樣就完美解決了。
方式二:ViewPager中放Fragment
條件1:
setObjectForPosition()方法中是為了呼叫存放你的view和他對應的position,這個是參考了鴻洋大神的一篇文章,連結:http://blog.csdn.net/lmj623565791/article/details/38026503
,為了防止預載入導致的高度不匹配,我們加自身的fragment和position對應起來放在linkedmap裡。
好了,剩下的就是呼叫vp.setObjectForPosition(view,1);
setObjectForPosition()這個方法了,請看我的一個SecurityInfoFragment
public SecurityInfoFragment(CustomViewpager pager) { //CustomViewpager 的引用傳到Fragment中,用來呼叫
this.pager = pager;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fg_sc_filght_info, null);
pager.setObjectForPosition(view,1);
return view;
}
條件2:
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
activityScdetailsBottomVp.resetHeight(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
pager.resetHeight(0); //預設設定第0個頁面或view高度,當滑動的時候setOnPageChangeListener 呼叫activityScdetailsBottomVp.resetHeight(position);
}