自定義View實例(二)廣告輪播

學習使用自定義View實現一個可以自動無限循環輪播的廣告輪播圖,效果圖如下:
在這裏插入圖片描述

具體實現思路:

  1. 首先利用view pager實現圖片輪播
  2. 使用handle發送延時消息來實現圖片自動播放
  3. 通過設置viewpager的item數量爲Integer.MAX_VALUE,然後在adapter中獲取當前位置item的方法裏對position和我們實際的item數量進行求餘來獲取當前的item,以此達到無限循環滾動的效果

完整代碼如下:

package com.car.customview;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.car.customview.adapter.MyPageAdapter;

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

/**
 * Created by pulian on 2019/2/26.
 * 無限循環自動輪播的廣告條
 * 自動循環的方式:1.Timer 2.開子線程  無限循環 3.ClockManager 4.handler發送延時消息
 */

public class Banner extends AppCompatActivity {
    private final static int MSG_CHANGE_PAGE = 0;
    //圖片切換時間
    private final long interval = 2000;
    private ViewPager viewPager;
    //指示點容器
    private LinearLayout pointGroup;
    private TextView imgDesc;
    private List<ImageView> imgList;
    private MyPageAdapter adapter;
    //上一次view pager item的位置
    private int lastPagePosition = 0;
    private boolean isRunning = false;
    //圖片資源
    private final int[] imgIds = {R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e};
    //文字資源
    private final String[] msgs = {"鞏俐不低俗,我就不能低俗", "朴樹又回來了,引發萬人大合唱",
            "揭祕北京電影如何升級", "樂視TV大放送", "屌絲的逆襲"};

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_banner);
        initView();
        initData();
        isRunning = true;
        handler.sendEmptyMessageDelayed(MSG_CHANGE_PAGE, interval);

    }
    
    private void initData() {
        imgList = new ArrayList<>();
        imgDesc.setText(msgs[0]);
        for (int i = 0; i < imgIds.length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setBackgroundResource(imgIds[i]);
            imgList.add(imageView);
            //添加指示點
            ImageView point = new ImageView(this);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20, 20);
            params.rightMargin = 20;
            point.setLayoutParams(params);
            point.setBackgroundResource(R.drawable.point_bg);
            if (i == 0) {
                point.setEnabled(true);
            } else {
                point.setEnabled(false);
            }
            pointGroup.addView(point);
        }
        adapter = new MyPageAdapter(imgList);
        viewPager.setAdapter(adapter);
        //無限循環播放初始化第一個位置
        viewPager.setCurrentItem(Integer.MAX_VALUE / 2 - (Integer.MAX_VALUE / 2) % imgList.size());
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
            	//對position求餘換算出實際的位置
                position = position % imgList.size();
                imgDesc.setText(msgs[position]);
                //改變指示點的狀態
                pointGroup.getChildAt(position).setEnabled(true);
                pointGroup.getChildAt(lastPagePosition).setEnabled(false);
                lastPagePosition = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

    }

    private void initView() {
        viewPager = findViewById(R.id.view_pager);
        pointGroup = findViewById(R.id.point_group);
        imgDesc = findViewById(R.id.msg);
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case MSG_CHANGE_PAGE:
                    viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
                    if (isRunning){
                        handler.sendEmptyMessageDelayed(MSG_CHANGE_PAGE, interval);
                    }
                    break;
            }
        }
    };

    @Override
    protected void onDestroy() {
        isRunning = false;
        super.onDestroy();
    }
}

viewpager的adapter代碼:

package com.car.customview.adapter;

import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.util.List;

public class MyPageAdapter extends PagerAdapter {
    private List<ImageView> mList;
    private int count;

    public MyPageAdapter(List<ImageView> list) {
        mList = list;
        count = mList.size();
    }

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

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

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView(mList.get(position % count));
        object = null;
    }
    /*
        獲得相應位置上的view
     */
    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        container.addView(mList.get(position % count));
        return mList.get(position % count);
    }
}

佈局文件:

<?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">

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

    </android.support.v4.view.ViewPager>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_alignBottom="@id/view_pager"
        android:background="#33000000">

        <TextView
            android:id="@+id/msg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/app_name"
            android:textColor="@android:color/white"
            android:textSize="18sp"/>
        <LinearLayout
            android:id="@+id/point_group"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:orientation="horizontal">

        </LinearLayout>

    </LinearLayout>

</RelativeLayout>

用到的drawable文件
兩種狀態的指示點

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >
    
    <size  android:width="5dp" android:height="5dp"/>
    <solid android:color="#aaFFFFFF"/>

</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >
    
    <size  android:width="5dp" android:height="5dp"/>
    <solid android:color="#55000000"/>

</shape>

指示點選擇器

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    
    <item android:drawable="@drawable/point_normal"  android:state_enabled="false"/>
    <item android:drawable="@drawable/point_focused"  android:state_enabled="true"/>
</selector>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章