安卓入门项目-模仿某商城day01-ViewPager实现轮播图

       在公司是经常用到安卓的,所以我一有空就会自学,并把学到的记下来。下面介绍的是我自己练手的一个模仿某商城的小项目,用到的都是安卓很基础的知识点,今天要说的是轮播图涉及到的知识点-ViewPager(也可以用Banner实现),同时会涉及到一些其他的基础知识。先看看界面:

安卓入门项目-模仿某商城day01-ViewPager实现轮播图_第1张图片

 

ViewPager简介:

视图翻页工具,可以切换多个页面。我们使用的是最新的androidx包下的。用法就是通过创建适配器adapter给它填充多个View(常见的ImageView),这样就可以左右翻动切换为不同的视图。
 

(1)activity_main.xml中加入:

        

            
                
                

                


                

            

        

把轮播图(id为vp_main_banner的ViewPager)和它下方的一排小圆点(id为ll_main_points_container的LinearLayout)一起放在一个RelativeLayout(相对布局)中

(2)ViewPager需要一个适配器,自定义一个BannerPagerAdapter.java:

package com.alibaba.taobao.controller.adapter;

import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;


import androidx.viewpager.widget.PagerAdapter;

import com.alibaba.taobao.model.bean.ArcImageView;

import java.util.List;

public class BannerPagerAdapter extends PagerAdapter {
    private List bannerImgs = null;


    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        ArcImageView imageView = new ArcImageView(container.getContext());
        imageView.setImageResource(bannerImgs.get(position % bannerImgs.size()));
        imageView.setScaleType(ImageView.ScaleType.FIT_XY);
        container.addView(imageView);
        return imageView;
    }

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

    @Override
    public int getCount() {
        if (bannerImgs != null) {
            return Integer.MAX_VALUE;
        }
        return 0;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {

        return view == object;
    }

    public void setData(List bannerImgs) {
        this.bannerImgs = bannerImgs;
    }

    public int getDataRealSize() {
        if (null != bannerImgs) {
            return bannerImgs.size();
        }
        return 0;
    }

}

注意这个PagerAdapter是直接用androidx包下面的,如果你还停留在support包,可以在项目根目录下将gradle.properties中

将以上两项都改为false就好啦.

我们自定义的BannerPagerAdapter重写了instantiateItem()、destroyItem()、getCount()、isViewFromObject()这四个方法,并添加了setData()和getDataRealSize()方法。类中的bannerImgs是数据源,会在setData()方法中被初始化。重写的第一个方法作用就是创建ImageView (ArcImageView是我们自己写的ImageView),并把它设置到容器中。第二个方法是为了回收不必要的资源。第三个方法是返回ViewPager总共有几页,就像一本书有多少页可以翻,我们为了实现自动无限轮播,就把这个返回值设为Int最大值:Integer.MAX_VALUE。

 

(3)我们本来是在适配器往ViewPager加入广告图(ImageView类型,只能为矩形),但是我想把那块区域做成下边拱起一个弧形,所以ImageView需要重写onDraw()方法,自己写一个ArcImageView.java:

package com.alibaba.taobao.model.bean;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Path;

import android.util.AttributeSet;
import android.widget.ImageView;

import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;

import com.alibaba.taobao.R;


/**
 * Android 实现弧形View
 * 
 */
public class ArcImageView extends AppCompatImageView {
    /*
     *弧形高度
     */
    private int mArcHeight;
    private static final String TAG = "ArcImageView";


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

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

    public ArcImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ArcImageView);
        mArcHeight = typedArray.getDimensionPixelSize(R.styleable.ArcImageView_arcHeight, 20);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Path path = new Path();
        path.moveTo(0, 0);
        path.lineTo(0, getHeight());
        path.quadTo(getWidth() / 2, getHeight() - 2 * mArcHeight, getWidth(), getHeight());//贝塞尔曲线
        path.lineTo(getWidth(), 0);
        path.close();
        canvas.clipPath(path);
        super.onDraw(canvas);
    }


}

(4)在项目资源目录res下values目录下新建一个attrs.xml:



    


    
        
    

(5)最后是MainActivity.java ,不要忘了实现翻页监听接口ViewPager.OnPageChangeListener:

package com.alibaba.taobao;

import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;

import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.LinearLayout;

import com.alibaba.taobao.controller.adapter.BannerPagerAdapter;

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

public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {

    private ViewPager vp_main_banner;
    private BannerPagerAdapter bannerPagerAdapter;
    private static List bannerImgs;
    private LinearLayout ll_main_points_container;
    private final int POINT_NORMAL_ALPHA = 120;



    //准备数据源
    static {
        bannerImgs = new ArrayList<>();
        bannerImgs.add(R.drawable.banner01);
        bannerImgs.add(R.drawable.banner02);
        bannerImgs.add(R.drawable.banner03);
        bannerImgs.add(R.drawable.banner04);

    }

    private Handler handler;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);

        //透明状态栏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        //透明导航栏
        //getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        setContentView(R.layout.activity_main);
        initView();

        //用handler自动轮播
        handler = new Handler();
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        handler.post(autoPlayTask);
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        handler.removeCallbacks(autoPlayTask);
    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {

    }


    private Runnable autoPlayTask = new Runnable() {
        @Override
        public void run() {
            //实现自动轮播,每两秒切换ViewPager里的图片到下一个
            int item = vp_main_banner.getCurrentItem();
            vp_main_banner.setCurrentItem(++item, false);
            handler.postDelayed(this, 2000);
        }
    };

    private void initView() {
        
        vp_main_banner = findViewById(R.id.vp_main_banner);
        bannerPagerAdapter = new BannerPagerAdapter();
        vp_main_banner.setAdapter(bannerPagerAdapter);
        vp_main_banner.addOnPageChangeListener(this);

        bannerPagerAdapter.setData(bannerImgs);
        bannerPagerAdapter.notifyDataSetChanged();

        ll_main_points_container = findViewById(R.id.ll_main_points_container);
        initPoints();
        vp_main_banner.setCurrentItem(bannerPagerAdapter.getDataRealSize() * 100, false);
    }

    //初始化下方的一排小圆点,全为白色半透明
    private void initPoints() {
        for (int i = 0; i < bannerImgs.size(); i++) {
            View point = new View(this);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(20, 20);
            layoutParams.leftMargin = 10;
            point.setBackgroundResource(R.drawable.point_normal_shape);
            point.getBackground().setAlpha(POINT_NORMAL_ALPHA);
            point.setLayoutParams(layoutParams);
            ll_main_points_container.addView(point);

        }

    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        int realPosition = 0;
        if (bannerPagerAdapter.getDataRealSize() != 0) {
            realPosition = position % bannerPagerAdapter.getDataRealSize();
        }

        for (int i = 0; i < ll_main_points_container.getChildCount(); i++) {
            View point = ll_main_points_container.getChildAt(i);
            if (realPosition != i) {//未播放到的图片,它对应的小圆点是白色
                point.setBackgroundResource(R.drawable.point_normal_shape);
                point.getBackground().setAlpha(POINT_NORMAL_ALPHA);
            } else {//当前播放到的图片,它对应的小圆点是橙色
                point.setBackgroundResource(R.drawable.point_selected_shape);
            }
        }

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}

自动轮播我们用一个Hander实现,不断地postDelayed,这个大家可以去了解下安卓的消息机制。然后是监听翻页接口ViewPager.OnPagChangeListener,重写它的几个方法中,onPageSelected(int position)这里可以获取当前翻到了哪一页,然后将它对应的小圆点突出显示为橙色,否则就是白色半透明。

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(安卓,安卓入门,ViewPager)