熟悉Viewpager之轮播图的小实例----小白上路----知识梳理

本次的目标是用轮播图实现app中植入广告

最终实现效果

在这里插入图片描述就是最上面这一部分啦
下面丑不拉叽的recyclerview请忽视,还有我自己定义的更加丑不拉叽的groupview导航栏(因为都是自己ps的图标,所以真的奇丑无比)

需要用到的是Viewpager

先在布局xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="200dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent">

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:layout_editor_absoluteY="0dp"
            tools:layout_editor_absoluteX="8dp"/>

        <LinearLayout
            android:weightSum="10"
            android:background="#33000000"
            android:orientation="horizontal"
            android:layout_gravity="bottom"
            android:gravity="center_vertical"
            android:layout_width="match_parent"
            android:layout_height="35dip">
            <TextView
                android:layout_weight="8"
                android:id="@+id/adv_pager_title"
                android:paddingLeft="8dip"
                android:gravity="center_vertical"
                android:textColor="@color/fragment_4"
                android:layout_width="0dp"
                android:layout_height="35dip"/>
            <!--用来动态添加轮播小点-->
            <LinearLayout
                android:id="@+id/lineLayout_dot"
                android:layout_weight="2"
                android:gravity="center|right"
                android:layout_marginRight="5dp"
                android:paddingLeft="3dp"
                android:paddingRight="3dp"
                android:orientation="horizontal"
                android:layout_width="0dp"
                android:layout_height="match_parent">
                <View
                    android:id="@+id/small_point_1"
                    android:layout_weight="0.25"
                    android:layout_width="0dp"
                    android:layout_height="18dp"
                    android:background="@drawable/small_point"/>
                <View
                    android:id="@+id/small_point_2"
                    android:layout_weight="0.25"
                    android:layout_width="0dp"
                    android:layout_height="18dp"
                    android:background="@drawable/small_point"/>
                <View
                    android:id="@+id/small_point_3"
                    android:layout_weight="0.25"
                    android:layout_width="0dp"
                    android:layout_height="18dp"
                    android:background="@drawable/small_point"/>
                <View
                    android:id="@+id/small_point_4"
                    android:layout_weight="0.25"
                    android:layout_width="0dp"
                    android:layout_height="18dp"
                    android:background="@drawable/small_point"/>

            </LinearLayout>

        </LinearLayout>
    </FrameLayout>

那四个view是用来添加四个小圆点的
下面是小圆点的资源绘制

<?xml version="1.0" encoding="utf-8"?>
<!--vector 矢量图-->
<vector
    android:height="5dp"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0"
    android:width="5dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
<!--
android:viewportHeight="24.0"
android:viewportWidth="24.0"  定义画布宽高

android:fillColor="#fff"  填充颜色

-->
    <path android:fillColor="#fff"
        android:pathData="M12,12 m-8,0a8,8 0,1 1 16,0  a8,8 0,1 1,-16 0"
        />
</vector>

  <!--  基本语法
    M:move to 移动绘制点,作用相当于把画笔落在哪一点。
    L:line to 直线,就是一条直线,注意,只是直线,直线是没有宽度的,所以你什么也看不到。

    android:strokeColor="#333330" android:strokeWidth="10" 设置颜色和线宽

    Z:close 闭合,嗯,就是把图封闭起来。
    C:cubic bezier 三次贝塞尔曲线
    Q:quatratic bezier 二次贝塞尔曲线
    A:ellipse 圆弧-->

    <!--  命令
    M (x y) 把画笔移动到x,y,要准备在这个地方画图了。
    L (x y) 直线连到x,y,还有简化命令H(x) 水平连接、V(y)垂直连接。
    Z,没有参数,连接起点和终点
    C(x1 y1 x2 y2 x y),控制点(x1,y1)( x2,y2),终点x,y 。
    Q(x1 y1 x y),控制点(x1,y1),终点x,y

    A(rx ry x-axis-rotation large-arc-flag sweep-flag x y)
    rx ry 椭圆半径
    x-axis-rotation x轴旋转角度
    large-arc-flag 为0时表示取小弧度,1时取大弧度 (舍取的时候,是要长的还是短的)
    sweep-flag 0取逆时针方向,1取顺时针方向

例:
    android:pathData=" M50,50 a10,5 90,1 0 1,0"
    M50,50  :(5050)落笔
    a10,5:  x轴半径10,y轴半径5画一个椭圆
    90  X轴旋转901:  取大弧度
    0:  逆时针取弧度
    10:    (5150)为终点
    -->

这是一个画矢量图的方法

同样的如法炮制再来个蓝色的圆

准备每一个page的布局界面

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/txt_viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.constraint.ConstraintLayout>

这里我放了个Textview

正式开工

既然放广告那就新建一个Advertisement类

public class Advertisement {
    private String mData;
    private String mTitle;

    public Advertisement(String data,String title){
        mData = data;
        mTitle = title;

    }
    public String getData() {
        return mData;
    }

    public void setData(String mData) {
        this.mData = mData;
    }

    public String getTitle() {
        return mTitle;
    }

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

敢敢单单两个变量,一个做广告文本,一个做广告标题,文本打算下次替换成图片。

新建一个类或者内部类

class ViewPagerAdapter extends PagerAdapter {
        List<View> smallPoints;
        List<Advertisement> mData;
        Context mContext;

        public ViewPagerAdapter(List<View> smallPoints,List<Advertisement> mData, Context context) {
            this.smallPoints = smallPoints;
            this.mContext = context;
            this.mData = mData;
        }
        @Override
        public int getCount() {
            return mData.size();
        }
        @Override
        public View instantiateItem(ViewGroup parent, int position) {
            View v = View.inflate(mContext, R.layout.item_fragment_1_view_pager, null);
            TextView txt = (TextView)v.findViewById(R.id.txt_viewpager) ;
            txt.setText(mAdvertisement.get(position).getData());
            parent.addView(v);
            return v;
        }

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

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

重写这几个方法,然后在instantiateItem()方法里实例化每个page的布局,每一次滑动page都会调用这个方法,据说Viewpager会根据你滑动的方向预先加载下一个page,暂时还没深究这个,小白嘛,先掌握使用方法嘻嘻。

初始化数据、控件,并初始化第一个page

class XXX{
private ViewPager mViewPager;
    //存放广告
    private List<Advertisement> mAdvertisement;
    //存放实例化后的小点
    private List<View> mSmallPointViews;
    private TextView txt_title;

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_1, container, false);
        
        initPoint(v);
        initAdvertisement();
        //实例化Viewpager
		mViewPager = (ViewPager) v.findViewById(R.id.viewPager);
		//设置Adapter
		mViewPager.setAdapter(new ViewPagerAdapter(mSmallPointViews,mAdvertisement, getContext()));

//初始化第一个page的标题、初始化第一个圆形的颜色为蓝色 
 		mSmallPointViews.get(0).setBackgroundResource(R.drawable.small_point_blue);
 			txt_title.setText(mAdvertisement.get(0).getTitle());
    //设置监听器
    	mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }
			//page被选中时的方法,
            @Override
            public void onPageSelected(int position) {
            //当前页面对应的小圆形变为蓝色,其他的变为白色
                for(int i = 0;i < mAdvertisement.size();i++) {
                    if(position == i) {
                        mSmallPointViews.get(i).setBackgroundResource(R.drawable.small_point_blue);
                    }else {
                        mSmallPointViews.get(i).setBackgroundResource(R.drawable.small_point);
                        }
                }
				//根据position设置对应的title
                txt_title.setText(mAdvertisement.get(position).getTitle());

            }
            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        return v;
}
}
	private void initPoint(View v){
        mSmallPointViews = new ArrayList<>();
        mSmallPointViews.add((View)v.findViewById(R.id.small_point_1));
        mSmallPointViews.add((View)v.findViewById(R.id.small_point_2));
        mSmallPointViews.add((View)v.findViewById(R.id.small_point_3));
        mSmallPointViews.add((View)v.findViewById(R.id.small_point_4));
    }
    private void initAdvertisement(){
        mAdvertisement = new ArrayList<>();
        mAdvertisement.add(new Advertisement("这是广告一的图片","这是广告一的标题"));
        mAdvertisement.add(new Advertisement("这是广告二的图片","这是广告二的标题"));
        mAdvertisement.add(new Advertisement("这是广告三的图片","这是广告三的标题"));
        mAdvertisement.add(new Advertisement("这是广告四的图片","这是广告四的标题"));
    }

运行!

虽然是很简单的一个练手Viewpager,但是也遇到了不少问题,比如一开始把加载每个poge的标题和内容都放在了Adapter内部类的instantiateItem()方法里,导致一直报空指针异常,然后日志显示在txt——title.setText()的时候加载的永远是下一个page的title,最后查了点资料,解决办法是

向ViewPager中的控件添加数据时在instantiateItem()中添加,在此处ViewPager只承载了一个一个TextView控件,填满了布局
向ViewPager外面的控件添加数据时,在onPageSelected()中添加数据,并要对数据进行第一个数据的手动添加

感悟

大致今天收获这么多吧,感觉一个人自学安卓真的好难啊,还是要细细的理解代码,一点点读,等熟练使用了以后再去深究源码,先会用再说2333,还有其他Viewpager的很多知识没学,先暂时满足需求了,等有空再回来充实一下~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值