打造好用的App首頁輪播圖~~


我們在項目中首頁經常會有一個輪播圖模塊
是利用viewpager實現的 每次都要重新寫一遍所有的邏輯沒有復用的效果
所以就把這個東西封裝好來達到復用的效果使用起來也特別簡單
這篇博客會先給一個簡單使用的例子之后再分析實現的過程
雖然寫的很爛
看到后面應該會有一點點東西的
吧~

先看一個效果圖:
這里寫圖片描述

好單調~~~~不過能看到
就是個基本的輪播圖
和別的控件配合起來就會很好多
我已經封裝好了
先說說怎么用

第一步:

在git上把我寫好的這個類下載下來Git_ViewPagerClass
git上是一個完整的例子啊

在你的項目里面加入這個類就是這個ViewPagerClass ~~~~我一般就直接復制了因為別的我也不會
然后項目結構就大概是這樣:
這里寫圖片描述

第二步:

在你要使用的xml文件中直接使用這個類:
這里寫圖片描述

因為我的包名是com.example.katherine_qj.viewpagerdemo
所以控件的名字是這樣
那你的肯定就是你的包名加類名這樣子
我也
不知道我說的清楚不

大概就是在xml中引用你項目中的這個類~~~
ViewPagerClass

第三步:

這里寫圖片描述

很清楚吧
就是實例化viewPager之后給他暴露出來的setViewPagerViews( )方法中傳入一個list集合就好了
集合里面是你要輪播的圖片 底部指示物會根據你添加的圖片自動生成相應的個數
~~

如果你只是想使用一個現成的輪播圖 以上就可以了

—————————————————————

以下
來分析一下這個輪播圖是如何封裝的:

我想把我大概的思路寫一下
首先想一下寫一個輪播圖需要什么?

需要裝圖片
需要小圓點顯示播放到哪一張了
還需要把viewpager和小圓點聯系起來
跑的時候圖片輪播小圓點也要動

所以我們先畫一張圖這樣子
這里寫圖片描述

我們第一步就是要把這些小控件組在一起
把他們都放到RelativeLayout中

第二步 我們采用線程的方式讓他們跑起來
這樣分為兩步就清楚很多

這個類的創建思路我先畫圖表示出來

是怎么把控件放在一起的
這里寫圖片描述

看一下這部分的代碼

  • 這是初始化viewpager和小圓點部分 可以看到就是把viewpager和linearLayout放到Relativelayout中

public void initViewPager() {
viewPager = new ViewPager(getContext());
LayoutParams viewPagerLp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
addView(viewPager,viewPagerLp);
}
/* 初始化LinearLayout*/
public void initLinearLayout(){
viewDots = new LinearLayout(getContext());
LayoutParams viewDotsLp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
viewDotsLp.addRule(ALIGN_PARENT_BOTTOM);
viewDotsLp.bottomMargin = dpTopx(5);
viewDots.setGravity(gravity);
addView(viewDots,viewDotsLp);
}
  • 這是我們為Viewpager構造的適配器
    繼承自pagerAdapter重載了四個方法 方法的解釋代碼中都有
class ViewPagerAdapter extends PagerAdapter{
/*以下四個方法是必須被重載的*/
@Override
public int getCount() {
if (views==null){
return 0;
}
return views.size();
}
/*
該函數用來判斷instantiateItem(ViewGroup, int)函數所返回來的Key
與一個頁面視圖是否是代表的同一個視圖(即它倆是否是對應的,對應的表示同一個View)
*/

@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
/*為即將展示頁做操作*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (views.get(position).getParent()!=null){
((ViewGroup)views.get(position).getParent()).removeView(views.get(position));
}
container.addView(views.get(position));
return views.get(position);
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(views.get(position));
}
}
  • 根據圖片數量生成圓點 圓點的兩種樣式可以 自己設置放在drawable文件夾下
 /*根據圖片數量生成圓點*/
private void addDots(int size){
dots = new ArrayList<ImageView>();
for (int i = 0; i < size; i++) {
ImageView dot = new ImageView(getContext());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
dpTopx(dotsRedio), dpTopx(dotsRedio));
params.setMargins(dpTopx(dotsSpacing), 0, dpTopx(dotsSpacing), 0);
dot.setLayoutParams(params);
if (i == 0) {
dot.setBackgroundResource(R.drawable.dot_focused);
} else {
dot.setBackgroundResource(R.drawable.dot_normal);
}
dots.add(dot);
viewDots.addView(dot);
}
}
  • 下面就是我們暴露出來的一個方法 傳入一個圖片集合我們 在里面通過 設置適配生成圓點 設置滑動事件等把之前的准備聯系在一起
 public void setViewPagerViews(List<View> views){
this.views = views;
addDots(views.size());
viewPager.setAdapter(new ViewPagerAdapter());
/*滑動的時候要改變圓點的顏色*/
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int positiona) {
position = positiona;
for (int i = 0; i < dots.size(); i++) {
if (position == i) {
dots.get(i).setBackgroundResource(
R.drawable.dot_focused);
} else {
dots.get(i)
.setBackgroundResource(R.drawable.dot_normal);
}
}
}

@Override
public void onPageScrollStateChanged(int state) {

}
});
viewPager.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
isContinue = false;
break;
case MotionEvent.ACTION_UP:
isContinue = true;
break;
default:
isContinue = true;
break;
}
return false;
}
});
new Thread(this).start();
}
  • 最后可以看見有一個線程開始執行的語句 那就是當我們都設置好 了之后就可以通過線程讓他輪播起來
 @Override
public void run() {
while (isAlive) {
if (isContinue) {
pagerHandler.sendEmptyMessage(position);
position = (position + 1) % views.size();
try {
Thread.sleep(changeTime);
} catch (InterruptedException e) {
}
}
}
}

Handler pagerHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
viewPager.setCurrentItem(msg.what);
/* setCurrentItem(int index)方法主要用來制定初始化的頁面。
例如加入3個頁面通過setCurrentItem(0)制定第一個頁面為當前頁面*/

super.handleMessage(msg);
}
};

以上就是實現過程
還有一些小細節

可以看一下我這個類全部的代碼

package com.example.katherine_qj.viewpagerdemo;

import android.content.Context;
import android.os.Handler;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.text.Layout;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;

import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

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

/**
* Created by Katherine-qj on 2016/11/20.
*/


public class ViewPagerClass extends RelativeLayout implements Runnable {
/*定義初始變量*/
/*定義關於ViewPager初始變量*/
private ViewPager viewPager;
private List<View> views;
/*定義關於小圓點的初始變量*/
private LinearLayout viewDots;
private List<ImageView> dots;
private int dotsSpacing = 2;
private int dotsRedio = 15;
/*定於關於輪播的初始變量*/
private int position = 0;
private boolean isContinue = true;
private boolean isAlive = true;
private int gravity = Gravity.RIGHT;
private int changeTime = 1500;



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

public ViewPagerClass(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public ViewPagerClass(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initViewPager();
initLinearLayout();
}
/*初始化viewPager*/
public void initViewPager() {
viewPager = new ViewPager(getContext());
LayoutParams viewPagerLp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
addView(viewPager,viewPagerLp);
}
/* 初始化LinearLayout*/
public void initLinearLayout(){
viewDots = new LinearLayout(getContext());
LayoutParams viewDotsLp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
viewDotsLp.addRule(ALIGN_PARENT_BOTTOM);
viewDotsLp.bottomMargin = dpTopx(5);
viewDots.setGravity(gravity);
addView(viewDots,viewDotsLp);
}
/*為viewPager構造適配器*/
class ViewPagerAdapter extends PagerAdapter{
/*以下四個方法是必須被重載的*/
@Override
public int getCount() {
if (views==null){
return 0;
}
return views.size();
}
/*
該函數用來判斷instantiateItem(ViewGroup, int)函數所返回來的Key
與一個頁面視圖是否是代表的同一個視圖(即它倆是否是對應的,對應的表示同一個View)
*/

@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
/*為即將展示頁做操作*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (views.get(position).getParent()!=null){
((ViewGroup)views.get(position).getParent()).removeView(views.get(position));
}
container.addView(views.get(position));
return views.get(position);
}

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


/*根據圖片數量生成圓點*/
private void addDots(int size){
dots = new ArrayList<ImageView>();
for (int i = 0; i < size; i++) {
ImageView dot = new ImageView(getContext());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
dpTopx(dotsRedio), dpTopx(dotsRedio));
params.setMargins(dpTopx(dotsSpacing), 0, dpTopx(dotsSpacing), 0);
dot.setLayoutParams(params);
if (i == 0) {
dot.setBackgroundResource(R.drawable.dot_focused);
} else {
dot.setBackgroundResource(R.drawable.dot_normal);
}
dots.add(dot);
viewDots.addView(dot);
}
}
public void setViewPagerViews(List<View> views){
this.views = views;
addDots(views.size());
viewPager.setAdapter(new ViewPagerAdapter());
/*滑動的時候要改變圓點的顏色*/
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int positiona) {
position = positiona;
for (int i = 0; i < dots.size(); i++) {
if (position == i) {
dots.get(i).setBackgroundResource(
R.drawable.dot_focused);
} else {
dots.get(i)
.setBackgroundResource(R.drawable.dot_normal);
}
}
}

@Override
public void onPageScrollStateChanged(int state) {

}
});
viewPager.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
isContinue = false;
break;
case MotionEvent.ACTION_UP:
isContinue = true;
break;
default:
isContinue = true;
break;
}
return false;
}
});
new Thread(this).start();


}
@Override
public void run() {
while (isAlive) {
if (isContinue) {
pagerHandler.sendEmptyMessage(position);
position = (position + 1) % views.size();
try {
Thread.sleep(changeTime);
} catch (InterruptedException e) {
}
}
}
}

Handler pagerHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
viewPager.setCurrentItem(msg.what);
/* setCurrentItem(int index)方法主要用來制定初始化的頁面。
例如加入3個頁面通過setCurrentItem(0)制定第一個頁面為當前頁面*/

super.handleMessage(msg);
}
};
private int dpTopx(int dp) {
float scale = getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
/*當調到其他頁面時 調用stop停止線程*/
public void stop() {
isAlive = false;
}
}

好久好久都沒寫博客了~~~~~~~~~~~~~~~~~
要堅持堅持


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com