Android--ViewPager的使用

ViewPager一般来说都是用于完成图片的翻页,画面的翻页之类的效果。

布局文件:外层是一个相对布局

    <androidx.viewpager.widget.ViewPager
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:id="@+id/vp_main"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_alignBottom="@+id/vp_main"
        android:background="#44000000"
        android:orientation="vertical">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="标题信息"
            android:textColor="#ffffff"
            android:gravity="center"
            android:id="@+id/tv_main"/>
        <LinearLayout
            android:id="@+id/ll_point"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
        </LinearLayout>
    </LinearLayout>

对应的java:

public class MyViewPager extends AppCompatActivity {

    private ViewPager vp_main;
    private TextView tv_main;
    private LinearLayout ll_point;
    private MyPagerAdapter myPagerAdapter;

    private MyImage myImage;
    private List<ImageView> imageViews;

	//得到上一个位置
    private int prePosition=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_view_pager);

        vp_main=(ViewPager)findViewById(R.id.vp_main);
        tv_main=(TextView)findViewById(R.id.tv_main);
        ll_point=(LinearLayout)findViewById(R.id.ll_point);
        imageViews=new ArrayList<ImageView>();
        myImage=new MyImage();

        for(int i=0;i<myImage.getImage.length;i++){

            ImageView imageView=new ImageView(this);
            imageView.setBackgroundResource(myImage.getImage[i]);
            imageViews.add(imageView);
			

			//下面点操作,包括添加点,设置颜色,设置间距。还有就是通过viewpager改变颜色
			ImageView point_main=new ImageButton(this);
            point_main.setBackgroundResource(R.drawable.point_background);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(25, 25);
            if(i==0){
                point_main.setEnabled(true);
            }else {
                point_main.setEnabled(false);
                layoutParams.leftMargin=60;
            }
            point_main.setLayoutParams(layoutParams);
            ll_point.addView(point_main);
            //----------------------------------------------//

        }
          //初始化适配器
        myPagerAdapter=new MyPagerAdapter(this,imageViews);
        //设置适配器
        vp_main.setAdapter(myPagerAdapter);

        //设置监听
        vp_main.addOnPageChangeListener(new MyClickListener());
    }

}

然后就是适配器:
在继承适配器时,它不会强制让你实现四个主要方法。但是还是得实现四个方法。所以这四个方法可以将鼠标移动到
PagerAdapter(也就是继承类)。然后ctrl+q。有四个方法写在那里

public class MyPagerAdapter extends PagerAdapter {

    private Context context;
    private List<ImageView> data;

    public MyPagerAdapter(Context context, List<ImageView> data) {
        this.context = context;
        this.data = data;
    }


    /**
     * @return 得到图片的总数
     */
    @Override
    public int getCount() {
        return data.size();
    }


    /***
     *比较View和Oject是否同一实例
     * @param view 页面
     * @param object 这个方法instantiateItem返回的结果
     * @return
     */
    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view==object;
    }

    /**
     *释放资源,因为Viewpage最多加载3个页面。开始是加载两个。果然不释放资源切换之后会报错闪退。
     * @param container Viewpager
     * @param position 要释放的位置
     * @param object 要释放的页面
     */
    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View) object);
    }


    /**
     *相当于getView方法
     * @param container Viewpager自身
     * @param position 当前实例化位置
     * @return
     */
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        ImageView imageView=data.get(position);
        container.addView(imageView);
        return imageView;
    }
}


设置viewpage监听

  public class MyClickListener implements ViewPager.OnPageChangeListener {

        /**
         *当页面滑动的时候回调这个方法
         * @param position 当前页面的位置
         * @param positionOffset 滑动页面的百分比
         * @param positionOffsetPixels  在屏幕上滑动的像素
         */
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }
        /**
         *当某个页面呗选中了回调
         * @param position 被选中页面的位置
         */
        @Override
        public void onPageSelected(int position) {
            ll_point.getChildAt(prePosition).setEnabled(false);
            ll_point.getChildAt(position).setEnabled(true);

            prePosition=position;
        }
        /**
         * 当页面滑动状态变化的时候回调这个方法
         * 静止-》滑动  滑动-》静止  静止-》拖拽
         * @param state
         */
        @Override
        public void onPageScrollStateChanged(int state) {

        }
    }

如果设置可以无限拖动。
则该适配器得代码改一下:


    public Object instantiateItem(@NonNull ViewGroup container, int position) {

		//求余得到位置
        int realPosition=position%data.size();
        
        ImageView imageView=data.get(realPosition);
        container.addView(imageView);
        return imageView;
    }
   public int getCount() {
        //return data.size();
        return Integer.MAX_VALUE;
    }

还有就是修改一下监听的代码:

  public void onPageSelected(int position) {

            int realPosition=position%imageViews.size();


            ll_point.getChildAt(prePosition).setEnabled(false);
            ll_point.getChildAt(realPosition).setEnabled(true);

            prePosition=realPosition;
        }

设置自动滑动页面:
原理利用handler:
handler代码:

    private Handler handler=new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if(msg.what==GET_TIME) {
            	//得到viewpager当前页面值+1
                int currentItem = vp_main.getCurrentItem() + 1;
                //设置当前页面值
                vp_main.setCurrentItem(currentItem);
                //循环发延时消息
                handler.sendEmptyMessageDelayed(GET_TIME, 5000);
            }

        }
    };

还有就是在主方法里面加入一条开启发延时消息

 handler.sendEmptyMessageDelayed(GET_TIME, 5000);

设置viewpager的滑动监听,包括点击,滑动,离开,还有取消。

在适配去的instantiateItem方法里面添加

imageView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN://手指按下
                        break;
                    case MotionEvent.ACTION_MOVE://移动
                        break;
                    case MotionEvent.ACTION_UP://手指离开
                        break;
                    case MotionEvent.ACTION_CANCEL://页面拖后时,会触发对上一个页面操作的取消,因为上个页面触发了按下,但是按下和离开时绑定一起的连贯的动作
                        break;
                }
                return true;
            }
        });

练习:

添加点击时不会自动滑动:

   imageView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN://手指按下
                        Log.e("TAG", "手指点击");
                        handler.removeCallbacksAndMessages(null);
                        break;
                    case MotionEvent.ACTION_MOVE://移动
                        Log.e("TAG", "手指移动");
                        break;
                    case MotionEvent.ACTION_UP://手指离开
                        Log.e("TAG", "手指离开");
                        break;
                    case MotionEvent.ACTION_CANCEL://页面拖后时,会触发对上一个页面操作的取消,因为上个页面触发了按下,但是按下和离开时绑定一起的连贯的动作
                        Log.e("TAG", "页面取消");
                        break;
                }
                return true;
            }
        });

原理是:当我们点下去的时候。触发点击,拖到一半回来,触发取消。所以不会触发离开的动作。

并在viewpager监听中修改函数:


	/**
   	* 当页面滑动状态变化的时候回调这个方法
   	* 静止-》滑动  滑动-》静止  静止-》拖拽
   	* @param state
   	*/
   private boolean isDragging;
        @Override
        public void onPageScrollStateChanged(int state) {
            if(state==ViewPager.SCROLL_STATE_IDLE){//静止的时候
                Log.e("TAG", "SCROLL_STATE_IDLE");
                isDragging=true;
                handler.removeCallbacksAndMessages(null);
                handler.sendEmptyMessageDelayed(GET_TIME, 5000);

            }else if(state==ViewPager.SCROLL_STATE_DRAGGING&&isDragging){//拉的时候
                isDragging=false;
                Log.e("TAG", "SCROLL_STATE_DRAGGING");
                handler.removeCallbacksAndMessages(null);

            }else if(state==ViewPager.SCROLL_STATE_SETTLING){//用户手放开的时候            Log.e("TAG", "SCROLL_STATE_SETTLING");

            }

        }

上面代码private boolean isDragging;这个我作用还不是太清楚。好像有没有作用都一样。以后搞明白了再来。


设置点击事件:

		imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, ""+position%data.size(), Toast.LENGTH_SHORT).show();
            }
        });

为了完成点击监听,记得把触摸监听返回设置位false,这样就不会被触摸监听消费了。才可以完成触发点击监听


为切换ViewPager设置动画

这里做的是一个缩放的动画

 vp_main.setPageTransformer(true, new ScaleTransformer());

第一个参数不知道是什么,没研究过,第二个参数是自定义动画类

public class ScaleTransformer implements ViewPager.PageTransformer {

    private static float MIN_CONTENT=0.75f;
    @Override
    public void transformPage(@NonNull View page, float position) {
        
        if(position<-1){
            page.setScaleX(MIN_CONTENT);
            page.setScaleY(MIN_CONTENT);

        }else if(position<=1){

            //左边页面
            if(position<0){

                //a->b:(0,-1)
                float v = MIN_CONTENT + (1 - MIN_CONTENT) * (1 + position);
                page.setScaleX(v);
                page.setScaleY(v);

            }else {//右边页面

                //a->b:(1,0)
                float v = MIN_CONTENT + (1 - MIN_CONTENT) * (1 - position);
                page.setScaleX(v);
                page.setScaleY(v);
            }

        }else {
            page.setScaleX(MIN_CONTENT);
            page.setScaleY(MIN_CONTENT);

        }
    }
}
原创文章 158 获赞 2 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43616001/article/details/104621035
今日推荐