欧酷网

您的位置:主页>移动开发>

玩Android项目开发-----首页2(使用ViewPager自定义banner轮播图)

在上一节

《玩Android项目开发------首页(ViewPager+BottomNavigationBar实现导航栏)》

中,实现了基本框架的搭建,现在就从首页,也就是MainFragment开始实现功能的填充。

1、Fragment的MVP框架搭建
在之前,我们都是使用Activity作为View层,那么本项目中,涉及到Fragment的使用,因为Fragment也是属于View层,因此先将BaseFragment搭建MVP框架。

public abstract class BaseFragment<V,P extends BasePresenter<V>> extends Fragment {
    protected P fPresenter;

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        fPresenter = createPresenter();
        if(fPresenter != null) {
            fPresenter.attachView((V) this);
        }
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return view();
    }

    protected abstract P createPresenter();

    protected abstract View view();

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initData();
    }

    public void initData() {

    }

    @Override
    public void onDetach() {
        super.onDetach();
        if(fPresenter != null){
            fPresenter.detachView((V) view());
            fPresenter = null;
        }
    }}

其实和Activity类似,只不过是Fragment和Activity的生命周期有些不同,其他的思想和Activity一样。

2、实现首页轮播图
其实在实现轮播图时,有一个Banner开源框架可以直接使用,但是我还是使用ViewPager来自定义一个轮播图。

(1)还是通过网络请求获取轮播图的数据信息。
具体网络请求的API网站都有,就不在这里一一列举了,将获取的数据回调到MainFragment的showBanner方法中。

(2)得到的轮播图数据,是一个List集合,List集合的大小就是轮播图的个数。

 public void showBanner(List<BannerBean.DataBean> data) {
        //轮播图的容器
        List<ImageView> imageList = new ArrayList<>();
        titleList = new ArrayList<>();
        for (int i = 0; i < data.size(); i++) {
            ImageView imageView = new ImageView(getContext());
            //获取当前ImageView的url
            String url = data.get(i).getImagePath();
            Log.e("TAG","url===="+url);
            //Glide加载图片
            Glide.with(getContext()).load(url).into(imageView);
            imageList.add(imageView);

            //有几张图就几个圆点
            ImageView point = new ImageView(getContext());
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            params.gravity = Gravity.CENTER;
            params.rightMargin = 10;
            point.setLayoutParams(params);
            point.setBackgroundResource(R.drawable.point_selector);
            ll_point.addView(point);

            //设置红点颜色
            if(i == 0){
                point.setEnabled(true);
                //刚进入界面就显示标题
                tv_title.setText(data.get(i).getTitle());
            }else{
                point.setEnabled(false);
            }
            //标题数组
            titleList.add(data.get(i).getTitle());
        }
		//设置适配器
        adapter = new MainFragmentPagerAdapter(getContext(),imageList);
        vp_banner.setAdapter(adapter);
         //发送延时消息
		handler.sendEmptyMessageDelayed(MSG_WHAT,3000);
    }

适配器代码:

public class MainFragmentPagerAdapter extends PagerAdapter {
    private final Context context;
    private final List<ImageView> imageList;

    public MainFragmentPagerAdapter(Context context, List<ImageView> imageList){
        this.context = context;
        this.imageList = imageList;
    }
    @Override
    public int getCount() {
        return imageList.size();
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        ImageView imageView = imageList.get(position);
        container.addView(imageView);
        return imageView;
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {//        super.destroyItem(container, position, object);
        container.removeView((View) object);
    }}

(3)添加底部圆点,有几张图就几个圆点,一样的逻辑思路;将创建好的圆点添加到LinearLayout。

//有几张图就几个圆点
            ImageView point = new ImageView(getContext());
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            params.gravity = Gravity.CENTER;
            params.rightMargin = 10;
            point.setLayoutParams(params);
            point.setBackgroundResource(R.drawable.point_selector);
            ll_point.addView(point);

(4)滑动界面,对应的圆点也变化。
这个的实现就是根据ViewPager当前的位置,来设置当前位置的圆点的颜色:设置ViewPager监听,监听当前页面的位置,先设置一个prePosition为上一个页面的位置,当滑动到下一个页面时,将上一个页面的状态改变。

 //preposition
    private int prePosition = 0;
private class MainPagerChangedListener implements ViewPager.OnPageChangeListener {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            ll_point.getChildAt(prePosition).setEnabled(false);
            ll_point.getChildAt(position).setEnabled(true);
            prePosition = position;
            //设置标题
            tv_title.setText(titleList.get(position));
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    }

(5)同样也在此设置标题,根据页面的切换切换标题。
注意:这里只是切换页面时,切换标题;刚进入应用的时候,也要显示标题。

//设置红点颜色
            if(i == 0){
                point.setEnabled(true);
                //刚进入界面就显示标题
                tv_title.setText(data.get(i).getTitle());
            }else{
                point.setEnabled(false);
            }

(6)设置页面自动滑动
通过handler实现,发送延迟消息。

 //发送延时消息handler.sendEmptyMessageDelayed(MSG_WHAT,3000);
//Handler
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            int item = vp_banner.getCurrentItem() + 1;
            vp_banner.setCurrentItem(item);
            //循环发送
            handler.sendEmptyMessageDelayed(MSG_WHAT,3000);
        }
    };

(7)支持左右无限滑动
在上边做了自动滑动操作之后,当滑动到最后一个图的时候,就不再滑动了,所以要支持无限滑动。

之所以不能无限滑动,因为在适配器中得到图的数量为imageList.size() = 4:

@Override
    public int getCount() {
        return imageList.size();
    }

因此将其设置为无限大,然后修改对应的position就可以实现无限滑动。
改动1:ViewPager适配器源码

@Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        int realPosition = position % imageList.size();
        ImageView imageView = imageList.get(realPosition);
        container.addView(imageView);
        return imageView;
    }

改动2:ViewPager监听器源码

@Override
        public void onPageSelected(int position) {
            int realPosition = position % titleList.size();
            ll_point.getChildAt(prePosition).setEnabled(false);
            ll_point.getChildAt(realPosition).setEnabled(true);
            prePosition = realPosition;
            //设置标题
            tv_title.setText(titleList.get(realPosition));
        }

效果如下。
在这里插入图片描述
目前首页轮播图功能已经实现了,后边还会继续更新!

相关文章推荐