ViewPager实现一个无限轮播的轮播图, 将数据绑定自定义的view

上一节我们已经写好了自定义的view并且成功运行了,这一节我们把数据绑定进自定义的view

首先我们给自定义view中的几个控件设定好id并且在自定义的java类中进行声明和绑定

    package com.example.viewpager.views;


    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.widget.LinearLayout;
    import android.widget.TextView;

    import androidx.annotation.Nullable;
    import androidx.viewpager.widget.ViewPager;

    import com.example.viewpager.R;


    public class LooperPager extends LinearLayout {


        private ViewPager viewPager;
        private TextView textView;
        private LinearLayout linearLayout;

        public LooperPager(Context context) {
            this(context,null);
        }

        public LooperPager(Context context, @Nullable AttributeSet attrs) {
            this(context,attrs,0);
        }

        /**
         * java必须有一个声明super的构造器,而且必须在开头,所以其他构造器声明的this,、
         * 所以无论使用其他哪个构造器都必须要调用该构造器
         * @param context
         * @param attrs
         * @param defStyleAttr
         */
        public LooperPager(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            //自定义布局绑定当前类,this:当前类,ture:确定绑定
            LayoutInflater.from(context).inflate(R.layout.looper_pager,this,true);
            inti();
        }

        /**
         *
         */

        private void inti() {
        intiView();
        }

        /**
         * 设置数据的方法
         */
        public void setData(){

        }

        /**
         * 加载view的方法
         */
        private void intiView() {
            viewPager = findViewById(R.id.viewPager);
            textView = findViewById(R.id.looper_title_tv);
            linearLayout = findViewById(R.id.looper_point_container_lv);
        }

    }

绑定好之后就是设置数据的方法

首先是设置标题的方法,我们给ViewPager写一个监听,三个状态:滑动中,停止和状态改变,我们在监听停止状态的方法内获得标题,用一个自制的强制获得String类型的接口的实例来获得当前停止状态下页面的标题来作为标题(有点绕哈)。

然后是设置ViewPager,这里我们直接让外部填一个适配器类型的数据就行,就能设置ViewPager的数据了

    package com.example.viewpager.views;


    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.widget.LinearLayout;
    import android.widget.TextView;

    import androidx.annotation.Nullable;
    import androidx.viewpager.widget.PagerAdapter;
    import androidx.viewpager.widget.ViewPager;

    import com.example.viewpager.R;


    public class LooperPager extends LinearLayout {


        private ViewPager viewPager;
        private TextView textView;
        private LinearLayout linearLayout;
        private BindTitleLisener bindTitleLisener = null;//标题,先设为空

        public LooperPager(Context context) {
            this(context,null);
        }

        public LooperPager(Context context, @Nullable AttributeSet attrs) {
            this(context,attrs,0);
        }

        /**
         * java必须有一个声明super的构造器,而且必须在开头,所以其他构造器声明的this,、
         * 所以无论使用其他哪个构造器都必须要调用该构造器
         * @param context
         * @param attrs
         * @param defStyleAttr
         */
        public LooperPager(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            //自定义布局绑定当前类,this:当前类,ture:确定绑定
            LayoutInflater.from(context).inflate(R.layout.looper_pager,this,true);
            inti();
        }

        /**
         *
         */

        private void inti() {
        intiView();
        initEven();
        }

        /**
         * 对页面进行滑动监听的方法
         */
        private void initEven() {
            viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                //切换的回调方法
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

                }

                @Override
                //切换停止的回调方法
                public void onPageSelected(int position) {

                    //当页面切换停止后获得标题
                    //如果标题不是空的,就设定标题为当前停止的页面标题里的数据
                    if (bindTitleLisener != null){

                        textView.setText(bindTitleLisener.getTitle(position));
                    }
                }

                @Override
                //状态改变的回调方法
                public void onPageScrollStateChanged(int state) {

                }
            });
        }


        /**
         * 获得标题的接口,里面有一个获得标题的抽象方法
         */
        public interface BindTitleLisener{
            String getTitle(int position);
        }
        /**
         * 设置数据的方法
         */
        public void setData(PagerAdapter adapter,BindTitleLisener lisener){
            bindTitleLisener = lisener;
            viewPager.setAdapter(adapter);

        }

        /**
         * 加载view的方法
         */
        private void intiView() {
            viewPager = findViewById(R.id.viewPager);
            textView = findViewById(R.id.looper_title_tv);
            linearLayout = findViewById(R.id.looper_point_container_lv);
        }

    }

下一步就是在主页面进行设置数据,首先是把我们自定义view类的实例化绑定主页面内的自定义view,当然设置数据就不和ViewPager设置数据一样了,我们需要用我们自定义view的java类里面自己写的设置数据的方法,然后把两个形参    “设置ViewPager的适配器”  和   “获得标题的接口实例”填进去

package com.example.viewpager;

import android.os.Bundle;
import android.os.PersistableBundle;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.PagerAdapter;

import com.example.viewpager.views.LooperPager;

public class supper_MainActivity extends AppCompatActivity {

    private LooperPager looperPager;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.supper_activity_main);
        intiView();
    }

    private void intiView() {
        //绑定布局
        looperPager = findViewById(R.id.Looperpager);
        //设置数据
        looperPager.setData(new PagerAdapter() {
            @Override
            public int getCount() {
                return 0;
            }

            @Override
            public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
                return false;
            }
        }, new LooperPager.BindTitleLisener() {
            @Override
            public String getTitle(int position) {
                return null;
            }
        });
    }
}

下一步把图片数据设置进去,这里我们先创建一个Java类用来当做容器,这个类有两个属性,string类型的标题和integer类型的地址,然后构造器和get set都写上

package com.example.viewpager.views;

public class PagerItem {
    private String title;//标题

    private Integer  picResId; //图片地址

    public PagerItem() {
    }

    public PagerItem(String title, Integer picResId) {
        this.title = title;
        this.picResId = picResId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Integer getPicResId() {
        return picResId;
    }

    public void setPicResId(Integer picResId) {
        this.picResId = picResId;
    }
}

然后在主页面声明一个泛型为这个容器的集合,接着把图片和标题填入集合。最后就是把我们的集合放进ViewPager的适配器里面和后面的获得标题的方法里面来获得各种数据,

package com.example.viewpager;

import android.os.Bundle;
import android.os.PersistableBundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.PagerAdapter;

import com.example.viewpager.views.LooperPager;
import com.example.viewpager.views.PagerItem;

import java.util.ArrayList;
import java.util.List;

public class supper_MainActivity extends AppCompatActivity {

    private LooperPager looperPager;
    private List<PagerItem> list = new ArrayList<>();


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.supper_activity_main);
        intiData();//这里数据填充要写在加载组件上面,如果写在下面,需要在方法内部写上刷新数据的方法
        intiView();//加载组件的方法
    }

    /**
     * 填充数据
     */
    private void intiData(){
        list.add(new PagerItem("第一张图片",R.mipmap.img1));
        list.add(new PagerItem("第二张图片",R.mipmap.mig2));
        list.add(new PagerItem("第三张图片",R.mipmap.mig3));
        list.add(new PagerItem("第四张图片",R.mipmap.mig4));
    }
    private void intiView() {
        //绑定布局
        looperPager = findViewById(R.id.Looperpager);
        //设置数据
        looperPager.setData(new PagerAdapter() {
            @Override
            public int getCount() {
                return list.size();
            }

            @Override
            public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
                return view == object;
            }
            /**
             * 初始化
             * @param container
             * @param position
             * @return
             */
            @NonNull
            @Override
            public Object instantiateItem(@NonNull ViewGroup container, int position) {
                //绑定布局
                View item = LayoutInflater.from(container.getContext()).inflate(R.layout.item,container,false);
                //设置数据
                ImageView imageView = item.findViewById(R.id.imageView);
                //先把imageview绑定
                int realPosition = position % list.size();
                imageView.setImageResource(list.get(realPosition).getPicResId());
                //然后在imageview中填入集合中的图片数据
                if (imageView.getParent() instanceof  ViewGroup){
                    ((ViewGroup) imageView.getParent()).removeView(imageView);
                }
                //不添加这行代码会报错,改子类已经拥有一个父类,这里我们判断如果父类是group就在父类中删除,
                // 如果不是就直接添加进pager里面
                container.addView(imageView);

                return imageView;
            }

            /**
             * 销毁
             * 作用是达到循环使用,不会导致溢出
             * @param container
             * @param position
             * @param object
             */
            @Override
            public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
                //删除数据
                container.removeView((View) object);

            }

        }, new LooperPager.BindTitleLisener() {
            @Override
            //获得当前位置图片的标题
            public String getTitle(int position) {
                return list.get(position).getTitle();
            }
        });
    }
}

最终效果会随着图片的滑动上面的标题随之改变 

 这一节里我们创建了一个自定义控件的类,我们只有一个需要向外部要数据的方法,就是setData,我们向外部要两个数据,一个是一个适配器,用来给ViewPager填充数据,一个是自定义的接口用来给标题填充数据

下一节我们再对节的代码进行下一步优化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值