ViewPager自适应高度问题

来源:互联网 发布:淘宝网买什么 编辑:程序博客网 时间:2024/05/21 09:06

最近在开发中有在一个界面做多组左右滑动的需求,当然平时最常见的就是利用ViewPager和Fragment结合,但是平时常见的只是在一个界面上存在一组左右滑动,且Fragment占满真个界面的情况。对于这个需求,一开始就遇到ViewPager的高度超出而没有自动适配高度的问题。不过网上很多大神已经解决了并分享了。参照:点击打开链接


记录一下,当做积累遇到的问题吧。

首先,定义一个CustomViewPager继承自ViewPager, 可以不用序列化实现Serializable,这里为了方面后面的Fragment传递参数才加的。

public class CustomViewPager extends ViewPager implements Serializable{    private int height = 0;    private int currPosition;    private HashMap<Integer, View> mChildViews = new LinkedHashMap<>();    public CustomViewPager(Context context) {        super(context);    }    public CustomViewPager(Context context, AttributeSet attrs) {        super(context, attrs);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        if (mChildViews.size() > currPosition){            View child = mChildViews.get(currPosition);            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));            height = child.getMeasuredHeight();        }        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    /** 通过设置LayoutParams来控制子View的高度 即重置当前位置下标(fragment)的高度*/    public void resetHeight(int position){        this.currPosition = position;        if (mChildViews.size() > currPosition){            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();            if (layoutParams == null){                layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, height);            }            layoutParams.height = height;            setLayoutParams(layoutParams);        }    }    public void setObjectForView(View view, int position){        mChildViews.put(position, view);    }}

自定义的CustomViewPager主要是测量ViewPager当前下标的高度,然后通过resetHeight()方法重置其高度。setObjectForView(View, int)是在实例Fragment的时候调用,目的是与ViewPager进行绑定,然后可以重新测量高度进行自适应。


下面就是一个简单的例子,在ScrollView里面嵌套ViewPager,并且让ViewPager能够自适应高度。

public class FirstFragment extends Fragment {    public FirstFragment() {        // Required empty public constructor    }    public static FirstFragment newInstance(CustomViewPager vp){        FirstFragment fragment = new FirstFragment();        Bundle bundle = new Bundle();        bundle.putSerializable("vp", vp);        fragment.setArguments(bundle);        return fragment;    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        // Inflate the layout for this fragment        return inflater.inflate(R.layout.fragment_first, container, false);    }    @Override    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {        super.onViewCreated(view, savedInstanceState);        if (getArguments() != null){            CustomViewPager vp = (CustomViewPager) getArguments().getSerializable("vp");            vp.setObjectForView(view, 0);        }    }}

public class SecondFragment extends Fragment {    public SecondFragment() {        // Required empty public constructor    }    public static SecondFragment newInstance(CustomViewPager vp){        SecondFragment fragment = new SecondFragment();        Bundle bundle = new Bundle();        bundle.putSerializable("vp", vp);        fragment.setArguments(bundle);        return fragment;    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        // Inflate the layout for this fragment        return inflater.inflate(R.layout.fragment_second, container, false);    }    @Override    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {        super.onViewCreated(view, savedInstanceState);        if (getArguments() != null){            CustomViewPager vp = (CustomViewPager) getArguments().getSerializable("vp");            vp.setObjectForView(view, 1);        }    }}

public class MainActivity extends AppCompatActivity implements View.OnClickListener{    private CustomViewPager mVp;    private TextView mTitle1, mTitle2;    private List<Fragment> mFragmentList = new ArrayList<>();    private Context mContext;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mContext = this;        mVp = (CustomViewPager) findViewById(R.id.vp);        mTitle1 = (TextView) findViewById(R.id.title1);        mTitle2 = (TextView) findViewById(R.id.title2);        mTitle1.setOnClickListener(this);        mTitle2.setOnClickListener(this);        mVp.setOffscreenPageLimit(2);        mFragmentList.add(FirstFragment.newInstance(mVp));        mFragmentList.add(SecondFragment.newInstance(mVp));        mVp.setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager(), mFragmentList));        mVp.resetHeight(0);        updateTitleWithViewPager(0);        mVp.addOnPageChangeListener(new PagerChangeListener(mVp));    }    private void updateTitleWithViewPager(int index){        switch (index){            case 0:                mTitle1.setTextColor(ContextCompat.getColor(mContext, R.color.colorAccent));                mTitle2.setTextColor(ContextCompat.getColor(mContext, R.color.text_666));                mVp.setCurrentItem(0);                break;            case 1:                mTitle1.setTextColor(ContextCompat.getColor(mContext, R.color.text_666));                mTitle2.setTextColor(ContextCompat.getColor(mContext, R.color.colorAccent));                mVp.setCurrentItem(1);                break;        }    }    @Override    public void onClick(View view) {        switch (view.getId()){            case R.id.title1:                updateTitleWithViewPager(0);                break;            case R.id.title2:                updateTitleWithViewPager(1);                break;        }    }    static class MyFragmentPagerAdapter extends FragmentPagerAdapter{        private List<Fragment> fragmentList;        public MyFragmentPagerAdapter(FragmentManager fm) {            super(fm);        }        public MyFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragmentList) {            super(fm);            this.fragmentList = fragmentList;        }        @Override        public Fragment getItem(int position) {            return fragmentList.get(position);        }        @Override        public int getCount() {            return fragmentList.size();        }    }    private class PagerChangeListener implements ViewPager.OnPageChangeListener {        private CustomViewPager customViewPager;        public PagerChangeListener(CustomViewPager viewPager){            this.customViewPager = viewPager;        }        @Override        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {        }        @Override        public void onPageSelected(int position) {            customViewPager.resetHeight(position);            updateTitleWithViewPager(position);        }        @Override        public void onPageScrollStateChanged(int state) {        }    }}

当然,上面提到Fragment和ViewPager通过setObjectForView进行绑定,上面用到了Fragment的传递参数方式进行绑定,从而在自定义CustomViewPager时实现了序列化接口Serializable,除了这种方式,还可以使用接口回调的方法,亦或最简单的直接使用Butterknife的发送和订阅事件进行传递。





原创粉丝点击