摘要:项目要求做一个广告页,实现几秒更换一次广告页,下方还有指示第几张广告页,同样也支持手动左滑或右滑。

  1.准备好粘贴5个有关广告页的类。

    ①BaseViewPager==>自定义高度的ViewPager

 public class BaseViewPager extends ViewPager {
private boolean scrollable = true; public BaseViewPager(Context context) {
super(context);
} public BaseViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
} /**
* 设置viewpager是否可以滚动
*
* @param enable
*/
public void setScrollable(boolean enable) {
scrollable = enable;
} @Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (scrollable) {
return super.onInterceptTouchEvent(event);
} else {
return false;
}
}
}

    ②CycleViewPager==>实现可循环、可轮播的viewPager

 @SuppressLint("NewApi")
public class CycleViewPager extends Fragment implements OnPageChangeListener { private List<ImageView> imageViews = new ArrayList<ImageView>();
private ImageView[] indicators;
private FrameLayout viewPagerFragmentLayout;
private LinearLayout indicatorLayout; // 指示器
private BaseViewPager viewPager;
private BaseViewPager parentViewPager;
private ViewPagerAdapter adapter;
private CycleViewPagerHandler handler;
private int time = ; // 默认轮播时间
private int currentPosition = ; // 轮播当前位置
private boolean isScrolling = false; // 滚动框是否滚动着
private boolean isCycle = false; // 是否循环
private boolean isWheel = false; // 是否轮播
private long releaseTime = ; // 手指松开、页面不滚动时间,防止手机松开后短时间进行切换
private int WHEEL = ; // 转动
private int WHEEL_WAIT = ; // 等待
private ImageCycleViewListener mImageCycleViewListener;
private List<MyImage> infos; @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = LayoutInflater.from(getActivity()).inflate(
R.layout.view_cycle_viewpager_contet, null); viewPager = (BaseViewPager) view.findViewById(R.id.viewPager);
indicatorLayout = (LinearLayout) view.findViewById(R.id.layout_viewpager_indicator);//就是那个白点吧
viewPagerFragmentLayout = (FrameLayout) view.findViewById(R.id.layout_viewager_content); handler = new CycleViewPagerHandler(getActivity()) { @Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == WHEEL && imageViews.size() != ) {
if (!isScrolling) {
int max = imageViews.size() + ;
int position = (currentPosition + ) % imageViews.size();
viewPager.setCurrentItem(position, true);
if (position == max) { // 最后一页时回到第一页
viewPager.setCurrentItem(, false);
}
} releaseTime = System.currentTimeMillis();
handler.removeCallbacks(runnable);
handler.postDelayed(runnable, time);
return;
}
if (msg.what == WHEEL_WAIT && imageViews.size() != ) {
handler.removeCallbacks(runnable);
handler.postDelayed(runnable, time);
}
}
}; return view;
} public void setData(List<ImageView> views, List<MyImage> list, ImageCycleViewListener listener) {
setData(views, list, listener, );
} /**
* 初始化viewpager
*
* @param views
* 要显示的views
* @param showPosition
* 默认显示位置
*/
public void setData(List<ImageView> views, List<MyImage> list, ImageCycleViewListener listener, int showPosition) {
mImageCycleViewListener = listener;
infos = list;
this.imageViews.clear(); if (views.size() == ) {
viewPagerFragmentLayout.setVisibility(View.GONE);
return;
} for (ImageView item : views) {
this.imageViews.add(item);
} int ivSize = views.size(); // 设置指示器
indicators = new ImageView[ivSize];
if (isCycle)
indicators = new ImageView[ivSize - ];
indicatorLayout.removeAllViews();
for (int i = ; i < indicators.length; i++) {
View view = LayoutInflater.from(getActivity()).inflate(
R.layout.view_cycle_viewpager_indicator, null);
indicators[i] = (ImageView) view.findViewById(R.id.image_indicator);
indicatorLayout.addView(view);
} adapter = new ViewPagerAdapter(); // 默认指向第一项,下方viewPager.setCurrentItem将触发重新计算指示器指向
setIndicator(); viewPager.setOffscreenPageLimit();
viewPager.setOnPageChangeListener(this);
viewPager.setAdapter(adapter);
if (showPosition < || showPosition >= views.size())
showPosition = ;
if (isCycle) {
showPosition = showPosition + ;
}
viewPager.setCurrentItem(showPosition); } /**
* 设置指示器居中,默认指示器在右方
*/
public void setIndicatorCenter() {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
params.addRule(RelativeLayout.CENTER_HORIZONTAL);
indicatorLayout.setLayoutParams(params);
}
/**
* 是否循环,默认不开启,开启前,请将views的最前面与最后面各加入一个视图,用于循环
*
* @param isCycle
* 是否循环
*/
public void setCycle(boolean isCycle) {
this.isCycle = isCycle;
} /**
* 是否处于循环状态
*
* @return
*/
public boolean isCycle() {
return isCycle;
} /**
* 设置是否轮播,默认不轮播,轮播一定是循环的
*
* @param isWheel
*/
public void setWheel(boolean isWheel) {
this.isWheel = isWheel;
isCycle = true;
if (isWheel) {
handler.postDelayed(runnable, time);
}
} /**
* 是否处于轮播状态
*
* @return
*/
public boolean isWheel() {
return isWheel;
} final Runnable runnable = new Runnable() { @Override
public void run() {
if (getActivity() != null && !getActivity().isFinishing()
&& isWheel) {
long now = System.currentTimeMillis();
// 检测上一次滑动时间与本次之间是否有触击(手滑动)操作,有的话等待下次轮播
if (now - releaseTime > time - ) {
handler.sendEmptyMessage(WHEEL);
} else {
handler.sendEmptyMessage(WHEEL_WAIT);
}
}
}
}; /**
* 释放指示器高度,可能由于之前指示器被限制了高度,此处释放
*/
public void releaseHeight() {
getView().getLayoutParams().height = RelativeLayout.LayoutParams.MATCH_PARENT;
refreshData();
} /**
* 设置轮播暂停时间,即没多少秒切换到下一张视图.默认5000ms
*
* @param time
* 毫秒为单位
*/
public void setTime(int time) {
this.time = time;
} /**
* 刷新数据,当外部视图更新后,通知刷新数据
*/
public void refreshData() {
if (adapter != null)
adapter.notifyDataSetChanged();
} /**
* 隐藏CycleViewPager
*/
public void hide() {
viewPagerFragmentLayout.setVisibility(View.GONE);
} /**
* 返回内置的viewpager
*
* @return viewPager
*/
public BaseViewPager getViewPager() {
return viewPager;
} /**
* 页面适配器 返回对应的view
*
* @author Yuedong Li
*
*/
private class ViewPagerAdapter extends PagerAdapter { @Override
public int getCount() {
return imageViews.size();
} @Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
} @Override
public View instantiateItem(ViewGroup container, final int position) {
ImageView v = imageViews.get(position);
if (mImageCycleViewListener != null) {
v.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
mImageCycleViewListener.onImageClick(infos.get(currentPosition - ), currentPosition, v);
}
});
}
container.addView(v);
return v;
} @Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
} @Override
public void onPageScrollStateChanged(int arg0) {
if (arg0 == ) { // viewPager在滚动
isScrolling = true;
return;
} else if (arg0 == ) { // viewPager滚动结束
if (parentViewPager != null)
parentViewPager.setScrollable(true); releaseTime = System.currentTimeMillis(); viewPager.setCurrentItem(currentPosition, false); }
isScrolling = false;
} @Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
} @Override
public void onPageSelected(int arg0) {
int max = imageViews.size() - ;
int position = arg0;
currentPosition = arg0;
if (isCycle) {
if (arg0 == ) {
currentPosition = max - ;
} else if (arg0 == max) {
currentPosition = ;
}
position = currentPosition - ;
}
setIndicator(position);
} /**
* 设置viewpager是否可以滚动
*
* @param enable
*/
public void setScrollable(boolean enable) {
viewPager.setScrollable(enable);
} /**
* 返回当前位置,循环时需要注意返回的position包含之前在views最前方与最后方加入的视图,即当前页面试图在views集合的位置
*
* @return
*/
public int getCurrentPostion() {
return currentPosition;
} /**
* 设置指示器
*
* @param selectedPosition
* 默认指示器位置
*/
private void setIndicator(int selectedPosition) {
for (int i = ; i < indicators.length; i++) {
indicators[i].setBackgroundResource(R.mipmap.icon_point);
}
if (indicators.length > selectedPosition)
indicators[selectedPosition].setBackgroundResource(R.mipmap.icon_point_pre);
} /**
* 如果当前页面嵌套在另一个viewPager中,为了在进行滚动时阻断父ViewPager滚动,可以 阻止父ViewPager滑动事件
* 父ViewPager需要实现ParentViewPager中的setScrollable方法
*/
public void disableParentViewPagerTouchEvent(BaseViewPager parentViewPager) {
if (parentViewPager != null)
parentViewPager.setScrollable(false);
} /**
* 轮播控件的监听事件
*
* @author minking
*/
public static interface ImageCycleViewListener { /**
* 单击图片事件
*
* @param position
* @param imageView
*/
public void onImageClick(MyImage info, int postion, View imageView);
}
}

       ③CycleViewPagerHandler==>为了防止内存泄漏,定义外部类,防止内部类对外部类的引用

 public class CycleViewPagerHandler extends Handler {
Context context; public CycleViewPagerHandler(Context context) {
this.context = context;
}
}

        ④ViewFactory==>创建ImageView工厂,获取ImageView视图的同时加载显示url

 public class ViewFactory {

     /**
* 获取ImageView视图的同时加载显示url
*
* @param
* @return
*/
public static ImageView getImageView(Context context, String url) {
ImageView imageView = (ImageView)LayoutInflater.from(context).inflate(
R.layout.view_banner, null);
ImageLoader.getInstance().displayImage(url, imageView);//最核心的部分
return imageView;
}
}

         ⑤MyImage==>这是广告页的bean类

 class MyImage {

     var link: String? = null
var image:String?=null
var title:String?=null constructor():super()
constructor(image: String) : super() {
this.image = image
}
constructor(image:String,link:String,title:String){
this.image=image
this.link=link
this.title=title
} override fun toString(): String {
return "MyImage[link=$link,image=$image,title=$title]"
}
}

   

   2.从服务器中拿到图片的链接地址,一般广告页都是从服务器拿到的数据。本地的也可以,而且更加简单了。我就拿前者举例吧。

    下面的代码是我自己的一个请求,里面有很多东西都是自己定义的东西。 

    如:LogUtils.d_debugprint()是自己封装好的一个日志输出的类。

      Constant也是自己封装好的常量。

      HttpUtil.httpPost也是自己封装的网络请求的类。

      JsonUtil.get_key_string也是自己封装Json解析的类。

      MyImage是自己定义的一个Bean类。

      Toasty是引用的第三方库toast的类,用来提示用户。

      initialize()是自己初始化广告页,后面第三步就是写这个函数了。

    

      解释清楚之后,请求的函数如下:

  private fun getADfromServer() {
var urlPath = ""
var sign = ""
val encode = Constant.ENCODE
val school = Constant.SCHOOLDEFULT
if (LogUtils.APP_IS_DEBUG) {
urlPath = Constant.BASEURLFORTEST + Constant.School_AD
sign = MD5Util.md5(Constant.SALTFORTEST)
} else {
urlPath = Constant.BASEURLFORRELEASE + Constant.School_AD
sign = MD5Util.md5(Constant.SALTFORRELEASE)
}
val params = mapOf<String, Any?>("school" to school,"sign" to sign)
LogUtils.d_debugprint(TAG, Constant.TOSERVER + urlPath + "\n提交的map=" + params.toString())
Thread(Runnable {
getAdfromServer= HttpUtil.httpPost(urlPath,params,encode)
// LogUtils.d_debugprint(TAG,Constant.GETDATAFROMSERVER+getAdfromServer)
val getCode:String
var msg:String?=null
var result:String
var getData:List<Map<String,Any?>>
getCode= JsonUtil.get_key_string(Constant.Server_Code,getAdfromServer!!)
if(Constant.RIGHTCODE.equals(getCode)) {
handler_result1.post {
msg = JsonUtil.get_key_string(Constant.Server_Msg, getAdfromServer!!)
result = JsonUtil.get_key_string(Constant.Server_Result, getAdfromServer!!)
getData = JsonUtil.getListMap("data", result)//=====这里可能发生异常
LogUtils.d_debugprint(TAG, "json解析出来的对象是=" + getData.toString())
if (getData != null&&getData.size>) {
for (i in getData.indices) {
val myImage=MyImage()
if(getData[i].getValue("link").toString()!=null&&getData[i].getValue("image").toString()!=null&&getData[i].getValue("title").toString()!=null) {
myImage.link = getData[i].getValue("link").toString()
myImage.image = getData[i].getValue("image").toString()
myImage.title = getData[i].getValue("title").toString()
myImageList.add(myImage)//=====这里保存了所有广告信息
}else{
Toasty.error(context,Constant.SERVERBROKEN).show()
}
}
initialize() //初始化顶部导航栏
}else{
val myImage=MyImage()
myImage.link=""
myImage.image=""
myImage.title=""
myImageList.add(myImage)
//Toasty.error(context,Constant.SERVERBROKEN).show()
}
}
}
}).start()
}

   3.然后就是initialize()函数了

    说明一下==>>

    myImageOverAD是覆盖在广告页上的一张默认图片,如果没有网,或者请求失败的时候,将显示这张图片。

    cycleViewPager是广告栏中的一个叫fragment的布局。

    views是广告栏的一个ArrayList<ImageView>(),可以动态添加ImageView

    mAdCycleViewListener是广告页点击的监听器,第四步会详细讲。

  @SuppressLint("NewApi")
private fun initialize() {
myImageOverAD!!.visibility=View.GONE
cycleViewPager = activity.fragmentManager.findFragmentById(R.id.oneFm_fragment_cycle_viewpager_content) as CycleViewPager views.add(ViewFactory.getImageView(context, myImageList[myImageList.size - ].image)) // 将最后一个ImageView添加进来
for (i in myImageList.indices) {
views.add(ViewFactory.getImageView(context, myImageList[i].image))
}
views.add(ViewFactory.getImageView(context, myImageList[].image)) // 将第一个ImageView添加进来
cycleViewPager!!.isCycle = true // 设置循环,在调用setData方法前调用
cycleViewPager!!.setData(views, myImageList, mAdCycleViewListener) // 在加载数据前设置是否循环
cycleViewPager!!.isWheel = true //设置轮播
cycleViewPager!!.setTime() // 设置轮播时间,默认5000ms
cycleViewPager!!.setIndicatorCenter() //设置圆点指示图标组居中显示,默认靠右
}

   4.然后是mAdCycleViewListener监听器的实现了。

    说明一下==>>

    ADWebView是点击广告页要调整的webView。

    R.anim.slide_left_out是一个从左边出去的动画。

    源码如下:

 private val mAdCycleViewListener = CycleViewPager.ImageCycleViewListener { info, position, imageView ->
var position = position
if (cycleViewPager!!.isCycle) {
position = position -
//Toasty.info(context,"标题:"+info.title+ "\n链接:" + info.link).show() val bundle=Bundle()
bundle.putString("title",info.title)
bundle.putString("link",info.link)
val intent:Intent=Intent(context,ADWebView::class.java)
intent.putExtras(bundle)
startActivity(intent)
activity.overridePendingTransition(,R.anim.slide_left_out)
}
}

   5.广告页的布局代码差点忘记了。

      说明一下==>>

    这里的fragment才是主角,下方的ImageView是覆盖在广告页上的一张默认图片,在没有网获取没有成功请求到服务器的时候显示的图片。

  <RelativeLayout
android:layout_width="match_parent"
android:layout_height="350pt"> <fragment
android:id="@+id/oneFm_fragment_cycle_viewpager_content"
android:name="com.guangdamiao.www.mew_android_debug.banner.CycleViewPager"
android:layout_width="match_parent"
android:layout_height="350pt"
/> <ImageView
android:id="@+id/oneFm_fragment_cycle_viewpager_content_over"
android:layout_width="match_parent"
android:layout_height="360pt"
android:src="@drawable/one_overad"
android:visibility="visible"
android:scaleType="centerCrop"
/> </RelativeLayout>

  效果如下:

  

  

Android广告页循环播放的更多相关文章

  1. android 自定义无限循环播放的viewPager。轮播ViewPager。实现循环播放 广告,主题内容,活动,新闻内容时。

    前言 实际项目需要一个 播放广告的控件,可能有多个广告图片.每个一段时间更换该图片.简单来说,就是一个 “循环播放图片”的控件. 间隔时间更换图片 一般来说,图片切换时需要有动画效果 需要支持手势,用 ...

  2. php广告图片循环播放 幻灯片效果

    <!DOCTYPE> <html> <head> <meta http-equiv="content-type" content=&quo ...

  3. Android实现Banner界面广告图片循环轮播(包括实现手动滑动循环)

    前言:经常会看到有一些app的banner界面可以实现循环播放多个广告图片和手动滑动循环.本以为单纯的ViewPager就可以实现这些功能.但是蛋疼的事情来了,ViewPager并不支持循环翻页.所以 ...

  4. android 随手记 videoview循环播放网络视频 和mediaplayer+sufaceview播放网络视频

    1:videoview循环播放视频 1>xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res ...

  5. Android videoview循环播放视频

    如何在一个activity里实现videoview对一个文件夹下的所有视频文件顺序循环播放,当切换界面时暂停, 切换回来继续原来的视频播放呢.所谓的 自动循环播放就是监听到视频播放结束之后继续重新播放 ...

  6. 深入理解MVC C#+HtmlAgilityPack+Dapper走一波爬虫 StackExchange.Redis 二次封装 C# WPF 用MediaElement控件实现视频循环播放 net 异步与同步

    深入理解MVC   MVC无人不知,可很多程序员对MVC的概念的理解似乎有误,换言之他们一直在错用MVC,尽管即使如此软件也能被写出来,然而软件内部代码的组织方式却是不科学的,这会影响到软件的可维护性 ...

  7. 5. apktool 给XX手机卫士加广告页

    一. 编写广告页 写一个广告页面,并调用其他页面的demo (1) 设计界面如下 (2) 编写代码如下 public class SplashActivity extends Activity {   ...

  8. android中无限循环滑动的gallery实例

    android中无限循环滑动的gallery实例 1.点击图片有变暗的效果,使用imageview.setAlpha(),并且添加ontouchListener public void init() ...

  9. Android实现简单音乐播放器(MediaPlayer)

    Android实现简单音乐播放器(MediaPlayer) 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 工程内容 实现一个简单的音乐播放器,要求功能 ...

随机推荐

  1. AngularJS(十):依赖注入

    本文也同步发表在我的公众号“我的天空” 依赖注入 依赖注入不是AngularJS独有的概念,而是现代软件开发与架构的范畴,但是在AngularJS中“依赖注入”是其核心思想之一,所以我们专门来学习一下 ...

  2. CSS文档优化

    首先了解下CSS的渲染逻辑,它是从标记的最后一位开始搜索的,例如:.myclass li a,首选它会遍历所有的<a>,然后看哪些<a>之前有<li>,然后再看哪些 ...

  3. C# 执行可执行文件

    可以用C#脚本执行可执行文件,一般可以用C# IO流写出.bat脚本,然后顺带执行脚本,然后滑稽.三连... Process proc = null; try { proc = new Process ...

  4. linux 下源码编译环境配置

    yum install -y apr* autoconf automake bison bzip2 bzip2* compat* cpp curl curl-devel \ fontconfig fo ...

  5. 有些其他程序设置为从 Outlook 下载并删除邮件。为防止发生此意外情况,我们将这些邮件放入一个特殊的 POP 文件夹中

    最近使用FOXMAIL接收MSN邮件时,发现有一些邮件收取不到,进到WEB页面,页面下方提示“你的邮件位于 POP 文件夹中!有些其他程序设置为从 Outlook 下载并删除邮件.为防止发生此意外情况 ...

  6. 微信jssdk实现分享到微信

    本来用的是这个插件http://overtrue.me/share.js/和百度分享 相同之处:在微信分享的时候,分享的链接都不能获取到缩略图... 不同之处:百度分享在微信低版本是可以看到缩略图的( ...

  7. linux 命令——2 cd (转)

    Linux cd 命令可以说是Linux中最基本的命令语句,其他的命令语句要进行操作,都是建立在使用 cd 命令上的. 所以,学习Linux 常用命令,首先就要学好 cd 命令的使用方法技巧. 1.  ...

  8. leetcode——1

    1. 题目  Two Sum Given an array of integers, find two numbers such that they add up to a specific targ ...

  9. BZOJ 3878: [Ahoi2014]奇怪的计算器

    BZOJ 3878: [Ahoi2014]奇怪的计算器 标签(空格分隔): OI-BZOJ OI-线段树 Time Limit: 10 Sec Memory Limit: 256 MB Descrip ...

  10. 【转】svn图标不显示的解决方案

    最近发现svn图标莫名其妙的不显示,其他操作都正常.在网上搜了一些方法. 解决方法一(失败): 升级最新版本,我的本来就是最新版本 解决方法二(失败): 右键->TortoiseSVN-> ...