android自动滚动,Android简单实现无限滚动自动滚动的ViewPager

经常我们会在应用中看到一个可以自动滚动,并且无限滚动的一个ViewPager,百度谷歌上面也有很多关于这方面的教程,但是感觉都略显麻烦,而且封装的都不是很彻底。所以试着封装一个比较好用的ViewPager

效果如下:

32cd5d664664e103b273c48b22f1e228.png

简单的说一下实现思路,要实现无限滚动的话就要在PagerAdapter上面做一些手脚,在PagerAdapter的getCount的函数的返回值设置成Integer.MXA_VALUE就可以实现向右无限滚动,但是要实现向左无限滚动呢?就是一开始的时候setCurrentItem的时候设置一个非常大的值(大到你向左滚动了一万年还是有东西)

@Override

public int getCount() {

return Integer.MAX_VALUE;

}

mPager.setCurrentItem(10000 * mDatas.size());//一开始设置成这样的话就可以向左无限滚动了

然后另外一个就是底部的游标了:

48b9e8a6f9d9e73464d4c2068f76ae3d.png

底部的游标是用一个自定义视图:无非就是画一个背景,然后在画一个高亮的游标

/**

* 指示游标

*/

private class TipView extends View {

private int mPadding;

private int mCount;

private int mCurPos;

private Paint mNorPaint;//未被选中的颜色

private Paint mSelPaint;//被选中的颜色 白色

private int mHeight;

public TipView(Context context, int count) {

super(context);

mNorPaint = new Paint();

mNorPaint.setAntiAlias(true);

int selHeight = ShowUtils.dip2px(2);

int norHeight = ShowUtils.dip2px(1);

mHeight = ShowUtils.dip2px(2);

mNorPaint.setStrokeWidth(norHeight);

mNorPaint.setColor(Color.argb(80, 255, 255, 255));

mSelPaint = new Paint();

mSelPaint.setAntiAlias(true);

mSelPaint.setStrokeWidth(selHeight);

mSelPaint.setColor(Color.WHITE);

mCount = count;

mPadding = ShowUtils.dip2px(0);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

int ow = (getWidth()-2 * mPadding)/ mCount;

int y = getHeight() / 2;

canvas.drawLine(mPadding, y, mCurPos * ow + mPadding, y, mNorPaint);

canvas.drawLine(mCurPos * ow + mPadding, y, (mCurPos + 1) * ow + mPadding, y, mSelPaint);

canvas.drawLine((mCurPos + 1) * ow + mPadding, y, getWidth() - mPadding, y, mNorPaint);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

ViewGroup.LayoutParams vp = getLayoutParams();

vp.width = ViewGroup.LayoutParams.MATCH_PARENT;

vp.height = mHeight;

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

public void setCurPostion(int pos) {

mCurPos = pos;

invalidate();

}

public void setCount(int count) {

mCount = count;

}

}

R.layout.layout_recommend_item的布局:

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/iv_pic"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:contentDescription="@null"

android:scaleType="fitXY"/>

android:layout_width="match_parent"

android:layout_height="48dp"

android:orientation="vertical"

android:layout_alignParentBottom="true"

android:background="@drawable/recommend"

android:gravity="center">

android:id="@+id/tv_desc"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:textColor="@color/white"

android:textSize="@dimen/text_normal"

android:maxLines="1"

android:ellipsize="end"

android:shadowColor="#ff333333"

android:shadowDx="2"

android:shadowDy="2"

android:paddingRight="8dp"

android:paddingLeft="8dp"

android:shadowRadius="1" />

还有一个是实现自动滚动,自动滚动的话就是监听OnPagerChangeListener里面的函数,在ViewPager状态改变的时候利用Handler发送一个切换界面的消息:

@Override

public void onPageScrollStateChanged(int i) {

curState = i;

if(i == ViewPager.SCROLL_STATE_DRAGGING){ //viewpager正在被拖动的时候

stopAnimation();

}else { //没有可执行消息时候添加消息 实现自动滚动

if(!(sHandler.hasMessages(START_SCROLL)&&sHandler.hasMessages(SCROLL_NEXT))){

startAnimation();

}

}

}

@Override

public void onPageSelected(final int i) { //页面跳转后得到调用

sHandler.removeMessages(SCROLL_NEXT);

sHandler.removeMessages(START_SCROLL);

if(curState == ViewPager.SCROLL_STATE_DRAGGING){

return;

}

Message msg = sHandler.obtainMessage(SCROLL_NEXT);

msg.arg1 = i + 1;

msg.obj = mPager;

sHandler.sendMessageDelayed(msg, SHOW_TIME);

mTipView.setCurPostion(i % mDatas.size());

}

整体的代码:

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.os.Handler;

import android.os.Message;

import android.support.v4.view.PagerAdapter;

import android.support.v4.view.ViewPager;

import android.util.DisplayMetrics;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ImageView;

import android.widget.RelativeLayout;

import android.widget.TextView;

import com.nostra13.universalimageloader.core.DisplayImageOptions;

import com.nostra13.universalimageloader.core.ImageLoader;

import com.papau.show.R;

import com.papau.show.entity.HeadViewEntity;

import com.papau.show.utils.ShowUtils;

import java.util.ArrayList;

import java.util.List;

public class RecommendView extends RelativeLayout implements IRecommend {

private static final int START_SCROLL = 1;

private static final int SCROLL_NEXT = 2;

private static final int SHOW_TIME = 5000;

private List mDatas = new ArrayList<>();

private ViewPager mPager;

private Context mContext;

private int mWidth, mHeight;

private ImageLoader mLoader;

private DisplayImageOptions mOptions;

private int mTitleHeight;

private TipView mTipView;

private static Handler sHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

int w = msg.what;

ViewPager pager = (ViewPager) msg.obj;

switch (w) {

case START_SCROLL:

pager.setCurrentItem(msg.arg1, true);

break;

case SCROLL_NEXT:

pager.setCurrentItem(msg.arg1, true);

break;

}

}

};

public RecommendView(Context context) {

super(context);

}

public RecommendView(Context context, int w, int h) {

super(context);

mContext = context;

mWidth = w;

mHeight = h;

initView();

// mPager.setAdapter(new RecommendAdapter());

mPager.setOnPageChangeListener(new MOnPagerChangeListener());

mLoader = ImageLoaderManager.getImageLoader(mContext);

mOptions = ImageLoaderManager.getCacheOnDiskOptions(mContext);

init();

// DisplayMetrics dm = mContext.getResources().getDisplayMetrics();

mTitleHeight = ShowUtils.dip2px(48);//设置游标高度

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

ViewGroup.LayoutParams vp = getLayoutParams();

if (vp != null) { //设置视图的宽高

vp.width = mWidth;

vp.height = mHeight;

}

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

private void initView() {

mPager = new ViewPager(mContext);

RelativeLayout.LayoutParams rp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);

addView(mPager, rp);

}

/**

* 初始化指示游标

*/

private void initTipView() {

if (mTipView == null) {

RelativeLayout.LayoutParams rp = new RelativeLayout.LayoutParams(10, 10);

rp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);//显示在父控件的底部

rp.bottomMargin = mTitleHeight;//游标的高度

mTipView = new TipView(mContext, mDatas.size());

addView(mTipView, rp);

} else {

mTipView.setCount(mDatas.size());

}

}

@Override

public void upDate() {

getData();

}

@Override

public void init() {

getData();

}

@Override

public void startAnimation() {

if (mDatas.size() == 0) {

return;

}

Message msg = sHandler.obtainMessage(START_SCROLL);

msg.obj = mPager;

msg.arg1 = (mPager.getCurrentItem() + 1);

sHandler.sendMessageDelayed(msg, SHOW_TIME);

}

@Override

public void stopAnimation() {

sHandler.removeMessages(START_SCROLL);

sHandler.removeMessages(SCROLL_NEXT);

}

/**

* 获取viewpager要显示的数据

*/

private void getData() {

String[] imageData = new String[]{"http://f.hiphotos.baidu.com/image/h%3D360/sign=e105b9f1d61b0ef473e89e58edc651a1/b151f8198618367a9f738e022a738bd4b21ce573.jpg",

"http://c.hiphotos.baidu.com/image/h%3D360/sign=b8cea9e92b738bd4db21b437918b876c/f7246b600c3387448982f948540fd9f9d72aa0bb.jpg",

"http://a.hiphotos.baidu.com/image/h%3D360/sign=3da95d01e7dde711f8d245f097eecef4/71cf3bc79f3df8dc39cb6295cf11728b461028c4.jpg",

"http://d.hiphotos.baidu.com/image/h%3D360/sign=410c3c96a60f4bfb93d09852334f788f/10dfa9ec8a136327a1de913a938fa0ec08fac78c.jpg",

"http://e.hiphotos.baidu.com/image/h%3D360/sign=f6600b1613dfa9ece22e501152d1f754/342ac65c10385343ff41ee2b9113b07eca808829.jpg"};

for (int i = 0; i < 5; i++) {

HeadViewEntity info = new HeadViewEntity();

info.setImageUrl(imageData[i]);

info.setTitle("我不做大哥好多年"+i);

info.setUrl("www.baidu.com");

mDatas.add(info);

}

sHandler.postDelayed(new Runnable() {

@Override

public void run() {

stopAnimation();

initTipView();

mPager.setAdapter(new RecommendAdapter());

mPager.setCurrentItem(10000 * mDatas.size());//一开始设置成这样的话就可以向左无限滚动了

}

},2000);

}

/**

* viewpager子项内容

*/

private class RecommendAdapter extends PagerAdapter {

/**

* 填充子项视图的内容

* @param container 父控件 viewpager

* @param position 子项的位置

* @return 返回子项视图

*/

@Override

public Object instantiateItem(ViewGroup container, int position) {

int curPos = position % mDatas.size();

View view = View.inflate(mContext, R.layout.layout_recommend_item, null);

ViewGroup.LayoutParams vp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

ImageView iv = (ImageView) view.findViewById(R.id.iv_pic);

TextView tv = (TextView) view.findViewById(R.id.tv_desc);

tv.setText(mDatas.get(curPos).getTitle());

mLoader.displayImage(mDatas.get(curPos).getImageUrl(), iv, mOptions);

container.addView(view, vp);

view.setTag(curPos);

view.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

}

});

return view;

}

@Override

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

container.removeView((View) object);

}

@Override

public int getCount() {

return Integer.MAX_VALUE;

}

@Override

public boolean isViewFromObject(View view, Object o) {

return view == o;

}

}

private class MOnPagerChangeListener implements ViewPager.OnPageChangeListener {

private int curState;

@Override

public void onPageScrolled(int i, float v, int i1) {

}

@Override

public void onPageScrollStateChanged(int i) {

curState = i;

if(i == ViewPager.SCROLL_STATE_DRAGGING){ //viewpager正在被拖动的时候

stopAnimation();

}else { //没有可执行消息时候添加消息 实现自动滚动

if(!(sHandler.hasMessages(START_SCROLL)&&sHandler.hasMessages(SCROLL_NEXT))){

startAnimation();

}

}

}

@Override

public void onPageSelected(final int i) { //页面跳转后得到调用

sHandler.removeMessages(SCROLL_NEXT);

sHandler.removeMessages(START_SCROLL);

if(curState == ViewPager.SCROLL_STATE_DRAGGING){

return;

}

Message msg = sHandler.obtainMessage(SCROLL_NEXT);

msg.arg1 = i + 1;

msg.obj = mPager;

sHandler.sendMessageDelayed(msg, SHOW_TIME);

mTipView.setCurPostion(i % mDatas.size());

}

}

/**

* 指示游标

*/

private class TipView extends View {

private int mPadding;

private int mCount;

private int mCurPos;

private Paint mNorPaint;//未被选中的颜色

private Paint mSelPaint;//被选中的颜色 白色

private int mHeight;

public TipView(Context context, int count) {

super(context);

mNorPaint = new Paint();

mNorPaint.setAntiAlias(true);

int selHeight = ShowUtils.dip2px(2);

int norHeight = ShowUtils.dip2px(1);

mHeight = ShowUtils.dip2px(2);

mNorPaint.setStrokeWidth(norHeight);

mNorPaint.setColor(Color.argb(80, 255, 255, 255));

mSelPaint = new Paint();

mSelPaint.setAntiAlias(true);

mSelPaint.setStrokeWidth(selHeight);

mSelPaint.setColor(Color.WHITE);

mCount = count;

mPadding = ShowUtils.dip2px(0);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

int ow = (getWidth()-2 * mPadding)/ mCount;

int y = getHeight() / 2;

canvas.drawLine(mPadding, y, mCurPos * ow + mPadding, y, mNorPaint);

canvas.drawLine(mCurPos * ow + mPadding, y, (mCurPos + 1) * ow + mPadding, y, mSelPaint);

canvas.drawLine((mCurPos + 1) * ow + mPadding, y, getWidth() - mPadding, y, mNorPaint);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

ViewGroup.LayoutParams vp = getLayoutParams();

vp.width = ViewGroup.LayoutParams.MATCH_PARENT;

vp.height = mHeight;

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

public void setCurPostion(int pos) {

mCurPos = pos;

invalidate();

}

public void setCount(int count) {

mCount = count;

}

}

}

然后提供了一个接口调用:

/**

* RecommendView接口

*/

public interface IRecommend {

void upDate();

void init();

void startAnimation();

void stopAnimation();

}

图片的加载用到了ImageLoad库:

import android.content.Context;

import android.graphics.Bitmap;

import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;

import com.nostra13.universalimageloader.core.DisplayImageOptions;

import com.nostra13.universalimageloader.core.ImageLoader;

import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;

import com.nostra13.universalimageloader.core.assist.ImageScaleType;

import com.papau.show.constant.Constants;

import java.io.File;

public class ImageLoaderManager {

/**

* 不带硬盘缓存的options

*

* @param context

* @return

*/

public static synchronized DisplayImageOptions getCacheOnMemoryOptions(Context context) {

DisplayImageOptions options = new DisplayImageOptions.Builder()

.cacheInMemory(true)

.cacheOnDisk(false)

.imageScaleType(ImageScaleType.EXACTLY_STRETCHED)

.bitmapConfig(Bitmap.Config.ARGB_8888)

// .showImageOnLoading(

// context.getResources().getDrawable(

// R.drawable.loading_wait))

// .showImageOnFail(

// context.getResources().getDrawable(

// R.drawable.loading_wait))

.build();

return options;

}

public static synchronized DisplayImageOptions getCircleOptions(Context context) {

DisplayImageOptions options = new DisplayImageOptions.Builder()

.cacheInMemory(true)

.cacheOnDisk(false)

.imageScaleType(ImageScaleType.EXACTLY_STRETCHED)

.bitmapConfig(Bitmap.Config.ARGB_8888)

// .showImageOnLoading(

// context.getResources().getDrawable(

// R.drawable.ic_user_head_hint))

// .showImageOnFail(

// context.getResources().getDrawable(

// R.drawable.ic_user_head_hint))

.build();

return options;

}

/**

* 获取在硬盘中缓存options

*

* @param context

* @return options

*/

public static synchronized DisplayImageOptions getCacheOnDiskOptions(

Context context) {

DisplayImageOptions options = new DisplayImageOptions.Builder()

.cacheInMemory(true)

.cacheOnDisk(true)

.imageScaleType(ImageScaleType.EXACTLY)

.bitmapConfig(Bitmap.Config.ARGB_8888)

// .showImageOnLoading(

// context.getResources().getDrawable(

// R.drawable.loading_wait))

// .showImageOnFail(

// context.getResources().getDrawable(

// R.drawable.loading_wait))

.build();

return options;

}

/**

* 获取imageLoader 单例

*

* @param context

* @return

*/

public static synchronized ImageLoader getImageLoader(Context context) {

ImageLoader imageLoader = ImageLoader.getInstance();

File cacheDir = new File(Constants.sPicCacheLocalPath);

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(

context).diskCache(new UnlimitedDiskCache(cacheDir))

.threadPoolSize(3)

.diskCacheExtraOptions(480, 320, null)

.build();

imageLoader.init(config);

return imageLoader;

}

}

使用方法

DisplayMetrics dm = getActivity().getResources().getDisplayMetrics();

RecommendView rv = new RecommendView(getActivity(),dm.widthPixels ,(dm.widthPixels)/2);

headViewPager.addView(rv);

以上所述是小编给大家介绍的Android简单实现无限滚动自动滚动的ViewPager,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值