Android 滑动页面的实现,ViewPager使用详解

本文详细介绍了如何在Android中使用ViewPager实现滑动页面,包括懒加载优化和去除滑动动画。通过自定义NoScrollViewPager阻止滑动,并调整缓存策略以节约流量。此外,还讲解了生成小点指示器的布局实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先来看看ViewPager使用到的场景,是十分的普遍
比如第一次进入程序闪屏页上的应用:
这里写图片描述

标题栏:这里写图片描述

以及类似网易新闻上带图片带内容的一个ViewPager
这里写图片描述

我们来实现这样的效果,话不多说,看代码,注释

红点和白点的代码

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval"
    >

    <corners android:radius="5dp"/>
    <solid android:color="@android:color/white"/>

</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval"
    >

    <corners android:radius="5dp"/>
    <solid android:color="#ff0000"/>

</shape>

布局文件,在几个小点不能写死,所以我们在代码再来生成几个小点

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="180dp">

        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="180dp"></android.support.v4.view.ViewPager>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#33000000"
            android:padding="5dp"
            android:layout_alignParentBottom="true"
            android:orientation="vertical"
            >

            <TextView
                android:id="@+id/tv_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="这是a的图片"
                android:textColor="@android:color/white"
                android:gravity="center_horizontal"
                />

            <LinearLayout
                android:id="@+id/ll_point_container"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dp"
                android:gravity="center"
                android:orientation="horizontal">

                <!--<View-->
                    <!--android:layout_width="10dp"-->
                    <!--android:layout_height="10dp"-->
                    <!--android:background="@drawable/point_selected"-->
                    <!--></View>-->

                <!--<View-->

                    <!--android:layout_width="10dp"-->
                    <!--android:layout_height="10dp"-->
                    <!--android:layout_marginLeft="8dp"-->
                    <!--android:background="@drawable/point_normal"-->
                    <!--></View>-->



            </LinearLayout>


        </LinearLayout>

    </RelativeLayout>
</RelativeLayout>
package com.example.administrator.layout;

import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

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

public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {

    private ViewPager mPager;
    private List<ImageView> mListDatas;
    private LinearLayout mPointContainer;
    private TextView mTvTitle;

    int[] imgs = {R.drawable.icon_1, R.drawable.icon_2, R.drawable.icon_3, R.drawable.icon_4, R.drawable.icon_5};

    String[] title = {"为梦想坚持","向阳的花","流水的女人","怒放的生命","就是爱音乐"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mPager = (ViewPager) findViewById(R.id.pager);
        mPointContainer = (LinearLayout) findViewById(R.id.ll_point_container);
        mTvTitle = (TextView) findViewById(R.id.tv_title);

        //初始化数据
        mListDatas = new ArrayList<ImageView>();
        MyPagerAdapter adapter = new MyPagerAdapter();
        for (int i = 0; i < imgs.length; i++) {
            ImageView iv = new ImageView(this);
            iv.setBackgroundResource(imgs[i]);

            mListDatas.add(iv);
            //动态添加点
            View child = new View(this);
            child.setBackgroundResource(R.drawable.point_normal);
            //需要设定点的宽高,注意params里面的单位都是像素,我们需要转换为dp,进行屏幕适配
            //dip与像素转化
            DisplayMetrics metrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(metrics);
            float scale = metrics.density;

            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams((int) (10 * scale),(int) (10 * scale));
            //间距
            if (i != 0) {
                params.leftMargin = (int) (10 * scale);
            }else{
                child.setBackgroundResource(R.drawable.point_selected);
                mTvTitle.setText(title[i]);
            }

            mPointContainer.addView(child, params);
        }
        mPager.setAdapter(adapter);
        mPager.setOnPageChangeListener(this);
        //为了实现最左页面到最右页面的滑动
        int middle = Integer.MAX_VALUE/2;
        int extra = middle % mListDatas.size();
        int item = middle - extra;
        mPager.setCurrentItem(item);
    }



    private class MyPagerAdapter extends PagerAdapter {
        //页面的数量
        @Override
        public int getCount() {
            if (mListDatas != null) {
                return Integer.MAX_VALUE;//为了实现无限滑动---->需要修改position
            }
            return 0;
        }

        /**
         * 记方法,用来判断缓存标记
         *
         * @param view   显示的view
         * @param object 标记
         * @return 有缓存返回true,没有缓存返回false
         */
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        //初始化item
        @Override
        public Object instantiateItem(ViewGroup container, int position) {

            position = position % mListDatas.size();
            ImageView iv = mListDatas.get(position);
            mPager.addView(iv);
            //记录缓存标记---return 标记
//            return super.instantiateItem(container, position);
            return iv;//返回iv,isViewFromObject方便的判定是否缓存
        }

        /**
         * 销毁item条目
         *
         * @param container
         * @param position
         * @param object    标记
         */
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            position = position % mListDatas.size();
            ImageView iv = mListDatas.get(position);
            mPager.removeView(iv);
        }
    }

    /**
     *回调方法,当viewPager滚动时的回调
     * @param position 当前选中的位置
     * @param positionOffset 滑动百分比
     * @param positionOffsetPixels 滑动的距离,单位像素
     */
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    /**
     * 回调方法,当viewpager某个页面选中时的回调
     * @param position
     */
    @Override
    public void onPageSelected(int position) {
        position = position % mListDatas.size();
        int count = mPointContainer.getChildCount();
        for (int i = 0; i < count ; i++) {
            View childAt = mPointContainer.getChildAt(i);
            if (i == position){
                childAt.setBackgroundResource(R.drawable.point_selected);
            }else{
                childAt.setBackgroundResource(R.drawable.point_normal);
            }

        }
        mTvTitle.setText(title[position]);

    }

    /**
     * 滑动状态改变时的回调
     * @param state:1的时候表示开始滑动,为2的时候表示手指松开了页面自动滑动,为0的时候表示停止在某页
     */
    @Override
    public void onPageScrollStateChanged(int state) {
    }
}

一种需求:仅需要实现的页面,不实现ViewPager的滑动方法
实现:
新建类NoScrollViewPager 继承ViewPager,重写两个方法

public class NoScrollViewPager extends ViewPager {
    public NoScrollViewPager(Context context) {
        super(context);
    }

    public NoScrollViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return false;
    }
}

在布局文件中将原来v4包的ViewPager改为引用我们的NoScrollViewPager 即可

还可以设置ViewPager显示的页面

viewPager.setCurrentItem(selectedIndex);

ViewPager的懒加载

需求:不让其缓存节约流量
实现:新建类,自己找一个更低版本的ViewPager复制代码到该类,修改包名后导包 将DEFAULT_SCREEN_PAGES值改为0。
在我们程序中使用自定义ViewPager即可

去掉ViewPager滑动时候的动画效果

mViewPager.setCurrentItem(0,false); 传入false即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值