1. 程式人生 > >Android viewpager輪播圖

Android viewpager輪播圖

主要注意的點
自動輪播+手動+home鍵之後頁面onResume接著輪播+下拉重新整理輪播圖一起重新整理
下拉重新整理的時候遇到了bug:下拉重新整理之後不再自動,小白點也不動,圖片也不輪播了
修復:需要重新設定recycleview的adapter,因為輪播圖是作為recycleview的header存在的

public class FiveActivity extends AutoLayoutActivity implements BaseQuickAdapter.RequestLoadMoreListener {
    FiveActivityBinding binding;
    private int page = 1;
    private int pagesize = 10;
    public static final String TAG = "FourActivity";
    private BannerBean bannerBean;
    private ViewPager viewPager;
    private TextView textView;
    private LinearLayout pointLl;
    private RotateVpAdapter vpAdapter;
    private int mAllPage;
    private StudyHomeAdapter mThirdLevelAdapter;
    private List<StudyHomeBean.DataBean.ListBean> mList = new ArrayList<>();
    private boolean isLoad;
    private int nowIndex;
    private static final int TIME = 3000;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_five);
        initdata();
    }
    private void initdata() {
**下拉重新整理的時候重新設定一下recyclerView的adapter,因為輪播圖是作為recycle的頭部載入的**
        /**        Explain : 初始化下拉重新整理
         * @author LiXaing create at 2017/7/22 21:56*/
        binding.refresh.setBackgroundColor(0XFFFFFFFF);
        binding.refresh.setColorSchemeColors(Color.parseColor("#4158B0"));
        binding.refresh.setProgressViewOffset(true, 0, 100);
        binding.refresh.setRefreshing(false);
        binding.refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                binding.refresh.setRefreshing(true);//當前是測試效果,正式用的時候,當前要設定為true
                **handler.removeCallbacks(rotateRunnable);**
                RefreshingList();
            }
        });

        /**        Explain : 列表初始化
         * @author ZhangYu create at 2018/1/19 0019 */
        mThirdLevelAdapter = new StudyHomeAdapter(R.layout.item_study_home, null);
        LinearLayoutManager layoutManager3 = new LinearLayoutManager(this);
        layoutManager3.setOrientation(LinearLayoutManager.VERTICAL);
        mThirdLevelAdapter.setOnLoadMoreListener(this);
        binding.recyclerView.setLayoutManager(layoutManager3);
        //如果Item高度固定  增加該屬效能夠提高效率
        binding.recyclerView.setHasFixedSize(true);
        binding.recyclerView.setAdapter(mThirdLevelAdapter);
        LoadData();
    }
    @Override
    public void onResume() {
        super.onResume();
        //**當頁面重現的時候,remove掉之前auto的runnable。延遲將由這次決定**
        isRotate = true;
        if(rotateRunnable!=null&&handler!=null) {
            handler.removeCallbacks(rotateRunnable);
            handler.postDelayed(rotateRunnable, TIME);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        **//暫停的時候,remove掉之前auto的runnable**
        isRotate=false;
        if(rotateRunnable!=null&&handler!=null) {
            handler.removeCallbacks(rotateRunnable);

        }
    }

    private void LoadData() {
        if (page == 1 && (null == binding.refresh || !binding.refresh.isRefreshing())) {
            binding.loadingProgress.showLoading();
        }
        OkHttpUtils
                .post()
                .url(NetWorkURLBean.STUDY_HOME_URL)
                .addParams("page", String.valueOf(page))
                .addParams("pagesize", String.valueOf(pagesize))
                .build()
                .execute(new StringCallback() {
                    @Override
                    public void onError(Call call, Exception e, int id) {
                        LogUtil.e(TAG, "onError====" + e.getMessage());
                        if (binding.refresh != null) {
                            binding.refresh.setRefreshing(false);
                        }
                        if (binding.loadingProgress != null) {
                            showError();
                        }

                    }

                    @Override
                    public void onResponse(String response, int id) {
                        LogUtil.e(TAG, "onResponse    response====" + response);
                        processResponse2(response);
                    }


                });
    }


    private void LoadBanner() {
        OkHttpUtils
                .post()
                .url(NetWorkURLBean.STUDY_HEAD_URL)
                .addParams("page", String.valueOf(page))
                .addParams("pagesize", String.valueOf(pagesize))
                .build()
                .execute(new StringCallback() {
                    @Override
                    public void onError(Call call, Exception e, int id) {
                        LogUtil.e(TAG, "onError====" + e.getMessage());

                    }

                    @Override
                    public void onResponse(String response, int id) {
                        LogUtil.e(TAG, "onResponse    response====" + response);
                        processResponse3(response);
                    }


                });

    }


    /**
     * Explain : 處理列表 **可以替換成自己封裝的網路請求方法**
     *
     * @author Hyh create at 2018/10/16
     */
    private void processResponse2(String response) {
        StudyHomeBean findBean = new Gson().fromJson(response, StudyHomeBean.class);
        String code = findBean.getCode();
        if ("200".equals(code)) {
            List<StudyHomeBean.DataBean.ListBean> list = findBean.getData().getList();

            if (page == 1 && mList.size() != 0) {
                mList.clear();

            }
            if (page == 1) {
            **//載入輪播圖**
                LoadBanner();
            }
            if (null != list && list.size() > 0) {
                mList.addAll(list);
            }
            mAllPage = findBean.getData().getAll_page();
            LogUtil.e(TAG, "mAllPage----" + mAllPage);
            /**
             * Explain:載入更多資料處理
             */
            if (isLoad) {
                //當前頁下雨於總頁數,新增資料,可以載入更多
                if (page < mAllPage) {
                    mThirdLevelAdapter.notifyDataChangedAfterLoadMore(list, true);
                    //當前頁等總頁數,新增資料,不可以載入更多
                } else if (page == mAllPage) {
                    mThirdLevelAdapter.notifyDataChangedAfterLoadMore(list, false);
                    showLoadCompleteAllData();
                    //其他情況就展示沒有更多資料
                } else {
                    showLoadCompleteAllData();
                }
                /**
                 * Explain:首次載入或下拉重新整理資料處理
                 */
            } else {
                //沒有資料,展示空介面
                if (null == list || list.size() == 0) {
                    showEmpty();
                    //有資料,進行判斷展示
                } else {
                    binding.loadingProgress.showContent();
                    mThirdLevelAdapter.setNewData(list);//新增資料
                    //共1頁,展示沒有更多資料
                    if (mAllPage == 1) {
                        showLoadCompleteAllData();
                        //大於一頁,只展示資料
                    } else {
                        mThirdLevelAdapter.openLoadMore(pagesize, true);//設定是否可以下拉載入  以及載入條數
                    }
                }
            }
        }
    }


    /**
     * Explain : 處理輪播圖
     *
     * @author Hyh create at 2018/10/16
     */

    private void processResponse3(String response) {
        bannerBean = new Gson().fromJson(response, BannerBean.class);
        View inflate = View.inflate(this, R.layout.item_study_head, null);
        viewPager = (ViewPager) inflate.findViewById(R.id.rotate_vp);
        pointLl = (LinearLayout) inflate.findViewById(R.id.rotate_point_container);
        textView = (TextView) inflate.findViewById(R.id.item_tv);
        if (bannerBean.getData().size() >= 0) {
            textView.setText(bannerBean.getData().get(0).getTitle());
        }
        vpAdapter = new RotateVpAdapter(bannerBean.getData(), this, textView);
        viewPager.setAdapter(vpAdapter);
        vpAdapter.notifyDataSetChanged();
        // ViewPager的頁數為int最大值,設定當前頁多一些,可以上來就向前滑動
        // 為了保證第一頁始終為資料的第0條 取餘要為0,因此設定資料集合大小的倍數
        viewPager.setCurrentItem(bannerBean.getData().size() * 100);
//        mThirdLevelAdapter.notifyDataSetChanged();
        // 開始輪播
        handler = new Handler();

        startRotate();
        // 新增輪播小點
        addPoints();
        // 隨著輪播改變小點
        changePoints();
        mThirdLevelAdapter.addHeaderView(inflate);
    }
    //========================================輪播設定
    private Handler handler;
    private boolean isRotate = false;
    private Runnable rotateRunnable;
    private void changePoints() {
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                if (isRotate) {
                    // 把所有小點設定為白色
                    for (int i = 0; i < bannerBean.getData().size(); i++) {
                        ImageView pointIv = (ImageView) pointLl.getChildAt(i);
                        pointIv.setImageResource(R.drawable.point_white);
                    }
                    // 設定當前位置小點為灰色
                    ImageView iv = (ImageView) pointLl.getChildAt(position % bannerBean.getData().size());
                    iv.setImageResource(R.drawable.point_grey);
                    textView.setText(bannerBean.getData().get(position % bannerBean.getData().size()).getTitle());
                    **//當有手動操作時,remove掉之前auto的runnable。延遲將由手動的這次決定。**
                    handler.removeCallbacks(rotateRunnable);
                    handler.postDelayed(rotateRunnable, TIME);
                }

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    /**
     * 新增輪播切換小點
     */
    private void addPoints() {
        // 有多少張圖載入多少個小點
        for (int i = 0; i < bannerBean.getData().size(); i++) {
            ImageView pointIv = new ImageView(this);
            pointIv.setPadding(5,5,5,5);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20,20);
            pointIv.setLayoutParams(params);

            // 設定第0頁小點的為灰色
            if (i == 0) {
                pointIv.setImageResource(R.drawable.point_grey);
            } else {
                pointIv.setImageResource(R.drawable.point_white);
            }
            pointLl.addView(pointIv);
        }
    }

    /**
     * 開始輪播
     */
    private void startRotate() {
        rotateRunnable = new Runnable() {
            @Override
            public void run() {
                nowIndex = viewPager.getCurrentItem();
                viewPager.setCurrentItem(++nowIndex);
                if (isRotate) {
                    handler.postDelayed(rotateRunnable, TIME);
                }
            }
        };
        handler.postDelayed(rotateRunnable, TIME);
    }
    @Override
    public void onLoadMoreRequested() {
        if (page <= mAllPage) {
            page++;
            System.out.println("onLoadMoreRequested");
        }
        LoadData();
        isLoad = true;
    }

    /**
     * Explain : 載入完所有資料後展示
     *
     * @author LianHaiLin
     * create at  19:31
     */
    private void showLoadCompleteAllData() {
        //所有資料載入完成後顯示
        ToastUtil.showToast(this, "已經全部載入");
    }

    /**
     * Explain: 展示介面為空
     *
     * @author LianHaiLin
     * create at  23:23
     */
    private void showEmpty() {
        binding.loadingProgress.showEmpty(this.getResources().getDrawable(R.drawable.load_no_data), "暫無資料", "");
    }
//網路請求錯誤
    private void showError() {
        binding.loadingProgress.showError(this.getResources().getDrawable(R.drawable.jc_error_normal), "網路異常", "請檢查網路後重試", "重新訪問", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                initdata();
            }
        });
    }
//重新整理的方法
    private void RefreshingList() {
        page = 1;
        isLoad = false;
        initdata();
    }

}

public class RotateVpAdapter extends PagerAdapter {
    private List<BannerBean.DataBean> datas;
    private Context context;
    private LayoutInflater inflater;
    private TextView textView;

    public RotateVpAdapter(List<BannerBean.DataBean> datas, Context context,  TextView textView) {
        this.datas = datas;
        this.context = context;
        this.textView = textView;
        inflater = LayoutInflater.from(context);
    }

    public RotateVpAdapter(List<BannerBean.DataBean> data, Context context) {
        this.context = context;

        inflater = LayoutInflater.from(context);

    }

    public void setDatas(List<BannerBean.DataBean> datas) {
        this.datas = datas;
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        // 為了讓ViewPager到最後一頁不會像翻書一樣回到第一頁
        // 設定頁數為int最大值,這樣向下滑動永遠都是下一頁
        return datas == null ? 0 : Integer.MAX_VALUE;
    }

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        // position是int最大值所以這裡可能是幾百甚至上千,因此取餘避免陣列越界
        int newPosition = position % datas.size();
        View convertView = inflater.inflate(R.layout.item_vp, container, false);
        ImageView imageView = (ImageView) convertView.findViewById(R.id.item_iv);
        Glide.with(context)
                .load(datas.get(newPosition).getImage_url())
                .into(imageView);


////如果View已經在之前新增到了一個父元件,則必須先remove,否則會丟擲IllegalStateException。
        ViewParent viewParent = convertView.getParent();
        if (viewParent != null) {
            ViewGroup parent = (ViewGroup) viewParent;
            parent.removeView(convertView);
        }

        container.addView(convertView);
        return convertView;
    }

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

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}

佈局檔案
item_study_head

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="334px">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="334px">

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

        <LinearLayout
            android:id="@+id/rotate_point_container"
            android:layout_width="match_parent"
            android:layout_height="50px"
            android:layout_alignParentBottom="true"
            android:layout_gravity="bottom|center"
            android:background="#5f000000"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:paddingLeft="20px"/>

        <TextView
            android:id="@+id/item_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_gravity="bottom|right"
            android:layout_marginBottom="6px"
            android:layout_marginRight="20px"
            android:text=""
            android:textColor="#fff"
            android:textSize="30px"/>
    </RelativeLayout>


</RelativeLayout>

item_vp

<?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="324px">


    <ImageView
        android:id="@+id/item_iv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:scaleType="fitXY" />


</RelativeLayout>

從專案中抽取部分程式碼,不便上傳原始碼