上一篇写过一个轮播图,但上篇有一点遐思, 要是动图的话, 会有那么一点卡顿, 这对app来说那是不能忍的, 这篇介绍一下另一个轮播View,这个呢比较实用, 但是没有滑动动画的效果, 可谓是有利也有弊吧。 当然如果你既想要滑动动画效果又想支持gif图, 那么就要研究一下了, 我是够用了。 如果你有好的方法 或者 图片加载框架 或者一些其他的途径请@我
这篇介绍一下另一个轮播View,这个呢比较实用, 但是没有滑动动画的效果,下面就来看一看
新建一个自定义的可滚动的viewpager
/**
* 自定义的可滚动的viewpager
*/
@SuppressLint({"HandlerLeak", "ViewConstructor"})
public class CarouselDiagramViewPager<T> extends ViewPager {
}
这里这个泛型倒是无所谓的 只是一个数据类型,使用的时候可以用实体类直接代替
/**
* 1、要想重新刷新数据,首先拿到集合之前要清空之前的集合数据 刷新数据
* 2、拿到之后根据集合的大小去初始化视图下面的标记,在初始化viewpager
* 3、添加视图,刷新视图 view.addView();
*/
public CarouselDiagramViewPager(Context context) {
super(context);
this.mContext = context;
this.mDatas = new ArrayList<>();
mAdapter = new CarouselPagerAdapter<>(mContext);
this.setAdapter(mAdapter);
initView();
}
/**
* @param data 这里泛型可以用做实体类, 可以在具体列表适配器里面修改实体类的具体类型
*/
public void addData(List<T> data) {
if (data == null || data.size() == 0) return;
mDatas.clear();
mDatas.addAll(data);
mAdapter.addData(mDatas); // 添加数据之前要先清空集合
initSelected(); // 重新初始化下面标点
initData();
}
// 初始化视图下边的标点
public void initView() {
mLayoutScrollView = View.inflate(mContext, R.layout.layout_roll_viewpager, null);
mViewpagerContainer = (LinearLayout) mLayoutScrollView.findViewById(R.id.ll_viewpager_container);
mLayoutPoint = (LinearLayout) mLayoutScrollView.findViewById(R.id.ll_dots);
}
// 初始化下面标点
public void initSelected() {
initPoint(mLayoutPoint);
mViewpagerContainer.removeAllViews();
mViewpagerContainer.addView(this);
mCurrentPosition = mDatas.size() * 1000;
this.setCurrentItem(mCurrentPosition);
startScroll();
}
// 返回初始化之后的视图
public View getContentView() {
return mLayoutScrollView;
}
一般的轮播图都是在首页的, 也有在其他页面的, 这种页面大多数还是会有下拉刷新的功能,我是直接动态添加这个轮播图,也方便下拉刷新数据。
下面这个就是 layout_roll_viewpager 布局
<?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="wrap_content" >
<!-- 放置轮播图片位置 -->
<LinearLayout
android:id="@+id/ll_viewpager_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_alignParentBottom="true"
android:background="#00000000"
android:gravity="center"
android:orientation="vertical" >
<!-- 放置图片标题的位置 -->
<TextView
android:id="@+id/top_news_title"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:singleLine="true"
android:text="图片标题"
android:visibility="gone"
android:textColor="@android:color/darker_gray" />
<!-- 放置图片中选中点的位置 -->
<LinearLayout
android:id="@+id/ll_dots"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" />
</LinearLayout>
</RelativeLayout>
这个布局就是轮播的容器了, 上面是放置图片的地方, 下面是指示器 我这个是用 点 来标记, 也可以在下方或者其他的地方放置这个轮播图的标题,这个看需求了。
初始化指示器的点之后就是ViewPager的 也就是实现滚动的方法
/**
* 初始化指示器的点
*/
private void initPoint(LinearLayout point) {
point.removeAllViews();
mListPoint = new ArrayList<>();
for (int i = 0; i < mDatas.size(); i++) {
View view = new View(mContext);
view.setBackgroundResource(i == 0 ? R.drawable.dot_focus : R.drawable.dot_normal);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(Utils.dip2px(mContext, 6),
Utils.dip2px(mContext, 6));
if (i == (mDatas.size() - 1)) {
params.setMargins(Utils.dip2px(mContext, 4), 0, 0, 0);
} else {
params.setMargins(Utils.dip2px(mContext, 4), 0, Utils.dip2px(mContext, 4), 0);
}
view.setLayoutParams(params);
point.addView(view);
mListPoint.add(view);
}
}
// 初始化viewPager
private void initData() {
mRunnableTask = new RunnableTask();
this.addOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
if (mDatas == null || mDatas.size() == 0) return;
mCurrentPosition = position;
position = position % mDatas.size();
for (int i = 0; i < mDatas.size(); i++) {
if (position == i) {
CarouselDiagramViewPager.this.mListPoint.get(i).setBackgroundResource(R.drawable.dot_focus);
} else {
CarouselDiagramViewPager.this.mListPoint.get(i).setBackgroundResource(R.drawable.dot_normal);
}
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
这些之后还要重写一下触摸事件
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
this.getParent().requestDisallowInterceptTouchEvent(true);
downX = (int) ev.getX();
downY = (int) ev.getY();
stopScroll();
break;
case MotionEvent.ACTION_MOVE:
int moveX = (int) ev.getX();
int moveY = (int) ev.getY();
if (Math.abs(moveX - downX) > Math.abs(moveY - downY)) {
this.getParent().requestDisallowInterceptTouchEvent(true);
} else {
this.getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
startScroll();
break;
}
return super.dispatchTouchEvent(ev);
}
@Override
protected void onDetachedFromWindow() {
stopScroll();
super.onDetachedFromWindow();
}
到这这个自定义可滚动的View就完成了,剩下的在PagerAdapter
public class CarouselPagerAdapter<T> extends PagerAdapter {
private Context mContext;
private List<T> mData;
private OnItemViewPagerClickListener mOnItemClickListener;
public CarouselPagerAdapter(Context context){
mContext = context;
mData = new ArrayList<>();
}
public void setOnItemViewPagerClickListener(OnItemViewPagerClickListener onItemClick){
this.mOnItemClickListener = onItemClick;
}
// 添加数据 在添加数据之前要先清空集合
public void addData(List<T> data) {
clear();
mData.addAll(data);
notifyDataSetChanged();
}
public void clear() {
if (mData != null){
mData.clear();
}
notifyDataSetChanged();
}
@Override
public int getCount() {
return mData.size() * 2000;
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
if (mData == null || mData.size() == 0) return null;
final int newPosition = position % mData.size();
View view = View.inflate(mContext, R.layout.item_carousel_poster, null);
GifImageView imageView = view.findViewById(R.id.iv);
final String url = (String) mData.get(newPosition);
// 截取字符串网址后三位 (判断是否等于gif图) 如果等于转换成字节设置
if (url.substring(url.length() - 3).equals("gif")) {
try {
byte[] bytes = new GifDataAsyncTask().execute(url).get();
if (bytes != null) {
imageView.setBytes(bytes);
imageView.startAnimation(); //开始动画 (没有动画会不显示图片 或者 图片静态不会动)
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} else {
Picasso.with(mContext).load(url).into(imageView);
}
container.addView(view);
view.setOnTouchListener(new View.OnTouchListener() {
private int downX;
private long downTime;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = (int) event.getX();
downTime = System.currentTimeMillis();
break;
case MotionEvent.ACTION_UP:
int upX = (int) event.getX();
long upTime = System.currentTimeMillis();
if (downX == upX && upTime - downTime < 500) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick(url, newPosition);
}
}
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
});
return view;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
使用很简单
mViewPager = new CarouselDiagramViewPager<>(this);
// mLinearLayout是放置这个可滚动的容器
mLinearLayout.addView(mViewPager.getContentView());
// 添加数据
mViewPager.addData(data);
// 点击事件
mViewPager.setOnItemViewPagerClickListener(new OnItemViewPagerClickListener() {
@Override
public <T> void onItemClick(T data, int position) {
Toast.makeText(MainActivity.this, "点击第" + position+ "条", Toast.LENGTH_SHORT).show();
}
});
体验的直接可下载demo
地址:https://github.com/xiaobinAndroid421726260/Android_SnowBanner2019_11_5Demo.git
网友评论