本人新手一枚,請大家多多指教!!!
先來看效果圖
首先自定義一個(gè)RelativeLayout,里面添加viewpager,及其所需要的banner底部描述的TextView 和指示器(imageview)
思路:無限滑動(dòng)其實(shí)是左右兩邊各多出對應(yīng)序號(hào)的相同頁面,如下有5個(gè)頁面,當(dāng)當(dāng)前頁面為第一個(gè)頁面時(shí)(序號(hào)3)迅速設(shè)置當(dāng)前頁面為第四個(gè)頁面(序號(hào)也是3的相同頁面)ViewPager.setCurrentItem(3,false)設(shè)置無動(dòng)畫切換,同理當(dāng)當(dāng)前頁面為第五頁面時(shí),切換當(dāng)前頁面為第二個(gè)相同頁面(序號(hào)1)ViewPager.setCurrentItem(1,false)
點(diǎn)擊事件在adapter里面
具體的操作:先給ViewPager.addOnPageChangeListener,(如果不了解可以先看看這篇文章https://www.cnblogs.com/Dionexin/p/5727297.html)接著在onPageScrollStateChanged()方法中實(shí)現(xiàn)
當(dāng)監(jiān)聽到當(dāng)前頁面為第一個(gè)或最后一個(gè)時(shí),便會(huì)執(zhí)行切換當(dāng)前頁面操作:/*無滑動(dòng)動(dòng)畫,直接跳轉(zhuǎn)*/? ?vp_Banner.setCurrentItem(pageIndex, false);??
實(shí)現(xiàn)圓角:主要有以下類,可以自定義圓角view 和圓形view ,主要是以下三個(gè)類,
ViewStyleSetter、RoundViewOutlineProvider、OvalViewOutlineProvider。
使用的時(shí)候只需要實(shí)例化ViewStyleSetter對象,調(diào)用里面的setRound(float radius) 和 setOval() 方法實(shí)現(xiàn)圓角或者圓形;
原文:https://blog.csdn.net/zhqw_csdn/article/details/82120451 ,原文寫的很詳細(xì),還有更多實(shí)現(xiàn)的方法,想了解更多可以進(jìn)去加強(qiáng)知識(shí)哦。
package com.example.his.cloudlibaray.utils;
import android.support.annotation.RequiresApi;
import android.view.View;
/*、
*
* 自定義圓角view*/
public class ViewStyleSetter {
private ViewmView;
public ViewStyleSetter(View view) {
this.mView = view;
}
public void setRound(float radius) {
this.mView.setClipToOutline(true);//用outline裁剪內(nèi)容區(qū)域
? ? ? ? this.mView.setOutlineProvider(new RoundViewOutlineProvider(radius));
}
public void setOval() {
this.mView.setClipToOutline(true);//用outline裁剪內(nèi)容區(qū)域
? ? ? ? this.mView.setOutlineProvider(new OvalViewOutlineProvider());
}
public void clearShapeStyle() {
this.mView.setClipToOutline(false);
}
}
package com.example.his.cloudlibaray.utils;
import android.graphics.Outline;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewOutlineProvider;
/*、
*
* 圓角繪制*/
public class OvalViewOutlineProviderextends ViewOutlineProvider {
public OvalViewOutlineProvider() {
}
@Override
? ? public void getOutline(final View view,final Outline outline) {
Rect selfRect;
Rect rect =new Rect();
view.getGlobalVisibleRect(rect);
selfRect = getOvalRect(rect);
outline.setOval(selfRect);
}
/**
* 以矩形的中心點(diǎn)為圓心,較短的邊為直徑畫圓
*
? ? * @param rect
? ? * @return
? ? */
? ? private Rect getOvalRect(Rect rect) {
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
int left, top, right, bottom;
int dW = width /2;
int dH = height /2;
if (width > height) {
left = dW - dH;
top =0;
right = dW + dH;
bottom = dH *2;
}else {
left = dH - dW;
top =0;
right = dH + dW;
bottom = dW *2;
}
return new Rect(left, top, right, bottom);
}
}
package com.example.his.cloudlibaray.utils;
import android.graphics.Outline;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewOutlineProvider;
/*、
*
* 圓角矩形繪制*/
public class RoundViewOutlineProviderextends ViewOutlineProvider {
private float mRadius;//圓角弧度
? ? public RoundViewOutlineProvider(float radius) {
this.mRadius = radius;
}
@Override
? ? public void getOutline(View view, Outline outline) {
Rect rect =new Rect();
view.getGlobalVisibleRect(rect);//將view的區(qū)域保存在rect中
? ? ? ? Rect selfRect =new Rect(0,0, rect.right - rect.left, rect.bottom - rect.top);//繪制區(qū)域
? ? ? ? outline.setRoundRect(selfRect,mRadius);
}
}
全部代碼:
package com.example.his.cloudlibaray.model;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.example.his.cloudlibaray.R;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import com.example.his.cloudlibaray.activity.BannerDescribe;
import com.example.his.cloudlibaray.model.CloudLibrary.CloudLibraryData.Topic;
import com.example.his.cloudlibaray.utils.Utils;
import com.example.his.cloudlibaray.utils.ViewStyleSetter;
/*
* banner輪播無限播放+
* 自動(dòng)播放+
* 圓角view
*
* */
public class BannerViewextends RelativeLayout {
private final StringTAG = BannerView.class.getSimpleName();
private int mPosition =1;
private ContextmContext;
public ViewPagervp_Banner;
private LinearLayoutll_indicator;//指示器
/*Banner 展示的view*/
? ? private int vp_Views =5;
private Listdot_images =new ArrayList<>();
private ListmData;
/*指示器的圖片資源*/
? ? private int[]indicatorImgRes = {R.drawable.indicator_off, R.drawable.indicator_on};
private TimermTimer;
@SuppressLint("HandlerLeak")
private HandlermHandler =new Handler() {
@Override
? ? ? ? public void handleMessage(Message msg) {
super.handleMessage(msg);
/*實(shí)現(xiàn)viewpager自動(dòng)播放效果*/
? ? ? ? ? ? vp_Banner.setCurrentItem(mPosition +1);
Log.d(TAG,"頁面的大小: " +vp_Banner.getChildCount());
Log.d(TAG,"handleMessage: " +mPosition);
}
};
private IndexViewPagerAdapterbannerAdapter;
private TextViewbannerTv;
public BannerView(Context context, List data) {
super(context);
mData = data;
initView(context);
}
public BannerView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public BannerView(Context context, AttributeSet attrs,int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
initView(context);
}
/*用java代碼創(chuàng)建布局*/
? ? private void initView(Context context) {
mContext = context;
vp_Banner =new ViewPager(mContext);
LinearLayout.LayoutParams vp_param =new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
vp_Banner.setLayoutParams(vp_param);
/*banner底部詳情線性布局*/
? ? ? ? ll_indicator =new LinearLayout(mContext);
RelativeLayout.LayoutParams dot_param =new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
dot_param.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
dot_param.setMargins(0,0,0,0);
/*給ll_indicator設(shè)置布局*/
? ? ? ? ll_indicator.setLayoutParams(dot_param);
ll_indicator.setOrientation(LinearLayout.HORIZONTAL);
ll_indicator.setGravity(Gravity.CENTER_HORIZONTAL);
ll_indicator.setBackgroundResource(R.color.trans_gray);
bannerTv =new TextView(mContext);
LinearLayout.LayoutParams bannerTvlp =new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT);
bannerTvlp.weight =1;
bannerTv.setTextSize(Utils.sp2px(mContext,6));
bannerTv.setGravity(CENTER_HORIZONTAL);
/*設(shè)置初始的banner描述*/
? ? ? ? bannerTv.setText(mData.get(0).getDescribe());
bannerTv.setTextColor(mContext.getResources().getColor(android.R.color.white));
ll_indicator.addView(bannerTv, bannerTvlp);
/*添加view到布局上面*/
? ? ? ? this.addView(vp_Banner);
this.addView(ll_indicator);
setView(vp_Views);
startAutoPlay(3000);
setCorner(20);
}
/*
* 設(shè)置banner展示的view,指示器圖片為默認(rèn)圖片
* @param views banner展示的view
*
* */
? ? private void setView(int views) {
setView(views,indicatorImgRes);
}
/*
* 設(shè)置banner展示的圖片和指示器的圖片
*
*
* */
? ? private void setView(int views,int[] indicatorRes) {
if (views !=0) {
vp_Views = views;
}
bannerAdapter =new IndexViewPagerAdapter(mContext,mData);
vp_Banner.setAdapter(bannerAdapter);
vp_Banner.setOffscreenPageLimit(1);
vp_Banner.setCurrentItem(1);
vp_Banner.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
? ? ? ? ? ? public void onPageScrolled(int i,float v,int i1) {
/*滑動(dòng)時(shí)*/
? ? ? ? ? ? ? ? bannerTv.setText(mData.get(i).getDescribe());
}
@Override
? ? ? ? ? ? public void onPageSelected(int position) {
/*選中時(shí),指示器跳轉(zhuǎn)*/
? ? ? ? ? ? ? ? mPosition = position;
int pageIndex =mPosition;
if (mPosition ==0) {
pageIndex =dot_images.size();
}else if (mPosition ==dot_images.size() +1) {
pageIndex =1;
}
setIndicator(pageIndex);
}
@Override
? ? ? ? ? ? public void onPageScrollStateChanged(int i) {
switch (i) {
case 0://靜止?fàn)顟B(tài)
? ? ? ? ? ? ? ? ? ? ? ? startAutoPlay(3000);
break;
case 1://正在滑動(dòng)
? ? ? ? ? ? ? ? ? ? ? ? stopAutoPlay();
break;
case 2://滑動(dòng)完成
? ? ? ? ? ? ? ? ? ? ? ? stopAutoPlay();
break;
}
/*狀態(tài)發(fā)生改變時(shí),viewpager跳轉(zhuǎn)*/
? ? ? ? ? ? ? ? int pageIndex =mPosition;
if (mPosition ==0) {
pageIndex =dot_images.size();
}else if (mPosition ==dot_images.size() +1) {
/*、如果滑動(dòng)超出總頁面大小*/
? ? ? ? ? ? ? ? ? ? pageIndex =1;
}
if (pageIndex !=mPosition) {
/*無滑動(dòng)動(dòng)畫,直接跳轉(zhuǎn)*/
? ? ? ? ? ? ? ? ? ? vp_Banner.setCurrentItem(pageIndex,false);
return;
}
}
});
/*加載指示器*/
? ? ? ? if (indicatorRes !=null && indicatorRes.length >=2) {
indicatorImgRes = indicatorRes;
}
for (int i =0; i
ImageView imageView =new ImageView(mContext);
if (i ==0) {
imageView.setBackgroundResource(indicatorImgRes[1]);
}else {
imageView.setBackgroundResource(indicatorImgRes[0]);
}
dot_images.add(imageView);
LinearLayout.LayoutParams lp =new LinearLayout.LayoutParams(Utils.dip2px(mContext,5), Utils.dip2px(mContext,5));
int margin_h = (int) (0.016 *mContext.getResources().getDisplayMetrics().widthPixels);
int margin_v = (int) (0.02 *mContext.getResources().getDisplayMetrics().widthPixels);
lp.setMargins(Utils.dip2px(mContext,2), margin_v, Utils.dip2px(mContext,2), margin_v);
if (i == (vp_Views -2)) {
lp.setMargins(Utils.dip2px(mContext,2), margin_v, margin_h, margin_v);
}
ll_indicator.addView(imageView, lp);
}
}
/*
*設(shè)置指示器的位置
* @param position 當(dāng)前banner所在的位置
* */
? ? private void setIndicator(int position) {
for (int i =0; i
if (position == i +1) {
/*on*/
? ? ? ? ? ? ? ? dot_images.get(i).setBackgroundResource(indicatorImgRes[1]);
}else {
/*off*/
? ? ? ? ? ? ? ? dot_images.get(i).setBackgroundResource(indicatorImgRes[0]);
}
}
}
/*、
*
* 開啟自動(dòng)輪播
*@param period banner的輪播周期
* */
? ? public void startAutoPlay(long period) {
//banner的vp_views大于1時(shí)才允許開啟輪播
? ? ? ? if (vp_Views >1) {
mTimer =new Timer();
TimerTask timerTask =new TimerTask() {
@Override
? ? ? ? ? ? ? ? public void run() {
mHandler.sendEmptyMessage(1);
}
};
mTimer.schedule(timerTask,2000, period);
}
}
/*
* 關(guān)閉自動(dòng)輪播
* */
? ? public void stopAutoPlay() {
if (mTimer !=null) {
mTimer.cancel();
}
}
/*
* 初始化數(shù)據(jù)
*
* */
? ? public void initData(List data) {
mData = data;
}
/*
* 更新數(shù)據(jù)
*
* */
? ? public void updateData(List data) {
bannerAdapter.setData(data);
bannerAdapter.notifyDataSetChanged();
}
public void setCorner(float angle){
ViewStyleSetter viewStyleSetter =new ViewStyleSetter(this);
viewStyleSetter.setRound(angle);
}
}
adapter
package com.example.his.cloudlibaray.model;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.example.his.cloudlibaray.R;
import com.example.his.cloudlibaray.activity.BannerDescribe;
import com.example.his.cloudlibaray.model.CloudLibrary.CloudLibraryData.Topic;
import java.util.List;
/*
* 主頁面viewpager的adapter
*
* ①利用adapter實(shí)現(xiàn)onclickListener接口實(shí)現(xiàn)點(diǎn)擊事件
* ②values下面創(chuàng)建ids文件 創(chuàng)建id,在adapter里面的imageView添加監(jiān)聽
* */
public class IndexViewPagerAdapterextends PagerAdapterimplements View.OnClickListener{
private final StringTAG = IndexViewPagerAdapter.class.getSimpleName();
private ContextmContext;
private ListmUrlList;
private int[]imageIds={R.id.banner_image_3,R.id.banner_image_1,R.id.banner_image_2,R.id.banner_image_3,R.id.banner_image_1};
public IndexViewPagerAdapter(Context context,List urlList) {
mContext = context;
mUrlList = urlList;
}
@Override
? ? public int getCount() {
return mUrlList.size();
}
@NonNull
@Override
? ? public Object instantiateItem(@NonNull ViewGroup container,int position) {
ImageView imageView =new ImageView(mContext);
if (!(position ==0 || position ==4)){
imageView.setId(imageIds[position]);
}
imageView.setOnClickListener(this);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageResource(R.drawable.home_scroll_default);
Log.d(TAG,"instantiateItem: 圖片的路徑"+mUrlList.get(position).getImageurl());
Glide.with(mContext)
.load(mUrlList.get(position).getImageurl())
.placeholder(R.drawable.home_scroll_default)
.error(R.drawable.home_scroll_default)
.into(imageView);
container.addView(imageView);
return imageView;
}
@Override
? ? public void destroyItem(@NonNull ViewGroup container,int position,@NonNull Object object) {
container.removeView((View)object);
}
public void setData(List data ){
this.mUrlList = data;
}
@Override
? ? public boolean isViewFromObject(@NonNull View view,@NonNull Object o) {
return view == o;
}
@Override
? ? public void onClick(View v) {
switch (v.getId()){
case R.id.banner_image_1:
Intent intent =new Intent(mContext,BannerDescribe.class);
mContext.startActivity(intent);
break;
case R.id.banner_image_2:
Toast.makeText(mContext,"2",Toast.LENGTH_SHORT).show();
break;
case R.id.banner_image_3:
Toast.makeText(mContext,"3",Toast.LENGTH_SHORT).show();
break;
}
}
}
values下的ids.xml文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
? ? <item name="banner_image_1" type="id"/>
? ? <item name="banner_image_2" type="id"/>
? ? <item name="banner_image_3" type="id"/>
</resources>
使用
/*初始化自定義的banner*/
mBannerView =new BannerView(getContext(),mTopicList);//向里面?zhèn)鬟f數(shù)據(jù)
RelativeLayout.LayoutParams banner_rl =new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Utils.dip2px(getContext(),150));
banner_rl.addRule(RelativeLayout.CENTER_IN_PARENT);
banner_rl.setMargins(Utils.dip2px(getContext(),10),0,Utils.dip2px(getContext(),10),0);
mRl.addView(mBannerView,banner_rl);
寫的不好,希望多多指教!!!!!!