为了实现广告轮播功能,在网上找了很多方法,有的效果很好,但是代码太麻烦,并且大多是用的viewpager,总之不是很满意。

于是看了一下sdk有个控件是ViewFlipper,使用比较方便,于是尝试了一下,最终实现了所需效果。在这里与大家分享。

首先看一下效果(主要是布局方面的效果,毕竟手势识别和滑动不太好显示,懒得弄成gif了):

1、布局文件.xml

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"> <ViewFlipper
android:layout_width="fill_parent"
android:layout_height="120dp"
android:id="@+id/details"
> </ViewFlipper>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="16dp"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="16dp"
android:orientation="horizontal"
android:gravity="right"
>
<View
android:id="@+id/v_dot0"
style="@style/dot_style"
android:background="@drawable/dot_focused"
/>
<View
android:id="@+id/v_dot1"
style="@style/dot_style"
/>
<View
android:id="@+id/v_dot2"
style="@style/dot_style"
/>
</LinearLayout>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:text="hello"
/>
</RelativeLayout> </LinearLayout>

我来解释一下这个布局

首先,最外层是一个LinearLayout布局来填充整个屏幕。 

   第二层就是控件ViewFlipper与RelativeLayout并列。其中ViewFlipper是实现图片轮播的,RelationLayout是图片下面的信息,比如图片的标题(如图中的&&)和图片在所有图片中的位置(表现形式为最右边的白色小点)

   第三层其实就是把第二层的RelativeLayout展开,里面有一个TextView控件来显示标题,和三个View控件来显示小点。

下面是要用到的一些style和drawable代码(该部分代码来自网络):

前5个放在res/drawable文件夹下

1、btn_back_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/btn_top_pressed" android:state_focused="true"></item>
<item android:drawable="@drawable/btn_top_pressed" android:state_pressed="true"></item>
<item android:drawable="@drawable/btn_top_pressed" android:state_selected="true"></item>
<item android:drawable="@drawable/title_bk"></item> </selector>

2、btn_top_pressed.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" > <gradient
android:angle="270"
android:endColor="#009ad6"
android:startColor="#11264f" /> </shape>

3、dot_focused.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" > <solid android:color="#aaFFFFFF" /> <corners android:radius="5dip" /> </shape>

4、dot_normal.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" > <solid android:color="#33000000" /> <corners android:radius="5dip" /> </shape>

5、title_bk.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" > <gradient
android:angle="270"
android:endColor="#11264f"
android:startColor="#009ad6" /> </shape>

6、styles.xml(放在values文件夹之下)

<?xml version="1.0" encoding="utf-8"?>
<resources> <style name="dot_style">
<item name="android:layout_width">5dip</item>
<item name="android:layout_height">5dip</item>
<item name="android:background">@drawable/dot_normal</item>
<item name="android:layout_marginLeft">1.5dip</item>
<item name="android:layout_marginRight">1.5dip</item>
</style> </resources>

这上面的代码我也不怎么懂,但是目的就是为了操作那些小点点。

下面问题来了,java代码呢。不要急,这就上来。

下面高能,胆小误入。

java代码(先全都发上来,容我慢慢解释)

package com.example.mynews;

import java.util.ArrayList;
import java.util.List; import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper; public class MainActivity extends Activity{ private ViewFlipper viewFlipper;
private String[] titles;
private TextView tv_title;
private List<View> dots;
float startx;
float x = 0;
float y = 0;
@Override
@SuppressWarnings("deprecation")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewFlipper = (ViewFlipper)findViewById(R.id.details);
tv_title = (TextView)findViewById(R.id.title);
int image[] = new int[]
{
R.drawable.a,R.drawable.b,R.drawable.c
};
for(int i=0;i<image.length;i++)
{
ImageView iv = new ImageView(getApplicationContext());
iv.setBackgroundResource(image[i]);
iv.setScaleType(ScaleType.CENTER_INSIDE);
iv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
viewFlipper.addView(iv);
}
titles = new String[image.length];
titles[0] = "hello";
titles[1] = "&&";
titles[2] = "world"; dots = new ArrayList<View>();
dots.add(findViewById(R.id.v_dot0));
dots.add(findViewById(R.id.v_dot1));
dots.add(findViewById(R.id.v_dot2)); handler.sendMessageDelayed(new Message(), 5000); viewFlipper.setOnTouchListener(new OnTouchListener() { @SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
{ x = event.getX();
Toast.makeText(getApplicationContext(), "down"+event.getX(), 1).show();
}break;
case MotionEvent.ACTION_UP:
{
y = event.getX();
if(y>x)
{
Log.v(null, "result:y>x");
showPre(); }
else if(x==y)
{
Log.v(null, "result:y=x");
showDetail();
}
else
{
Log.v(null, "result:x>y");
showNext();
}
}break;
}
return true;
}
});
} private Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
showNext();
handler.sendMessageDelayed(new Message(), 5000);
} }; private void showNext()
{
viewFlipper.showNext();
int cur = viewFlipper.getDisplayedChild();
if(cur == 0)
{
dots.get(2).setBackgroundResource(R.drawable.dot_normal);
}
else
{
dots.get(cur-1).setBackgroundResource(R.drawable.dot_normal);
}
dots.get(cur).setBackgroundResource(R.drawable.dot_focused);
tv_title.setText(titles[cur]);
}
private void showPre()
{
viewFlipper.showPrevious();
int cur = viewFlipper.getDisplayedChild();
if(cur == 2)
{
dots.get(0).setBackgroundResource(R.drawable.dot_normal);
}
else
{
dots.get(cur+1).setBackgroundResource(R.drawable.dot_normal);
}
dots.get(cur).setBackgroundResource(R.drawable.dot_focused);
tv_title.setText(titles[cur]);
}
private void showDetail()
{
Toast.makeText(getApplicationContext(),"x=y", 1).show();
} }

1、先准备图片,这里我准备了三张,初始化代码如下:

int image[] = new int[]//用int型数组来储存三张照片的编号
{
R.drawable.a,R.drawable.b,R.drawable.c
};
for(int i=0;i<image.length;i++)//将三张照片加入viewflipper里
{
ImageView iv = new ImageView(getApplicationContext());
iv.setBackgroundResource(image[i]);
iv.setScaleType(ScaleType.CENTER_INSIDE);//这里设置图片变换格式
iv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
viewFlipper.addView(iv);
}

2、对ViewFlipper设置监听事件(进行手势操作的核心),注意,这里的监听不是onclicklistener,而是ontouchlistener

viewFlipper.setOnTouchListener(new OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN://手指按下
{ x = event.getX();//全局变量,接收按下是的手指坐标
Toast.makeText(getApplicationContext(), "down"+event.getX(), 1).show();
}break;
case MotionEvent.ACTION_UP://手指松开
{
y = event.getX();//全局变量,接收松开是的手指坐标
//下面就是简单的逻辑判断,从而区分向左滑、向右滑以及不滑(也就是点击事件)
if(y>x)
{
Log.v(null, "result:y>x");
showPre(); }
else if(x==y)
{
Log.v(null, "result:y=x");
showDetail();
}
else
{
Log.v(null, "result:x>y");
showNext();
}
}break;
}
return true;
}
});

这里要重点说下,本来我采用的不是这种方法,而是将activity使用ontouch接口、ViewFlipper使用onclicklistener,而且还要声明一个gesturedetector变量,这样会出现一个问题,就是ontouch与onclick的事件会相互影响,具体怎么回事,我也没搞明白。有事件会仔细研究研究。此外,如果使用gesturedetector又会增加复杂度。

然后是图片切换动作,也就是上段代码中的showPre()、showNext()、showDetail()方法。作用分别是向左滑、向右滑、不滑(这里可以用来实现点击事件)代码如下:

private void showNext()
{
viewFlipper.showNext();//sdk封装好的,使用非常方便
int cur = viewFlipper.getDisplayedChild();
if(cur == 0)
{
dots.get(2).setBackgroundResource(R.drawable.dot_normal);//这是控制那些小点点的,逻辑应该能看懂,就不解释了
}
else
{
dots.get(cur-1).setBackgroundResource(R.drawable.dot_normal);
}
dots.get(cur).setBackgroundResource(R.drawable.dot_focused);
tv_title.setText(titles[cur]);
}
private void showPre()
{
viewFlipper.showPrevious();//sdk封装好的,使用非常方便
int cur = viewFlipper.getDisplayedChild();
if(cur == 2)
{
dots.get(0).setBackgroundResource(R.drawable.dot_normal);
}
else
{
dots.get(cur+1).setBackgroundResource(R.drawable.dot_normal);
}
dots.get(cur).setBackgroundResource(R.drawable.dot_focused);
tv_title.setText(titles[cur]);
}
private void showDetail()
{
Toast.makeText(getApplicationContext(),"x=y", 1).show();
}

下面又到了另外一个重点,handler机制,其实和定时器差不多(至少在这里是)  

handler.sendMessageDelayed(new Message(), 5000);

没5000ms也就是5s发送一次消息,这个消息是干嘛的?请看下端代码

private Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
showNext();
handler.sendMessageDelayed(new Message(), 5000);
} };

简单的讲,它是给他自己发消息,提醒自己时间到了,该吃药了(该做某件事了)。然后做完之后还要告诉自己,过5s还要吃药,就这样一直吃药,不放弃治疗。

我想,说到这里,应该明白,这段代码的功能就是实现图片的自动切换。 

至此,代码的重点部分解释完了。至于标题和那些小点点怎么处理,都在那三个方法里写好了,肯定可以看明白,就不多赘述了。

附:

1、代码出问题尽量不要找我,虽然是我写的,但是它自己长歪了。

2、转载请注明出处。

谢谢阅读,欢迎批评指正。 

  

  

  

  

Android 通过ViewFlipper实现广告轮播功能并可以通过手势滑动进行广告切换的更多相关文章

  1. BootStrap 轮播插件(carousel)支持左右手势滑动的方法(三种)

    原生的 Bootstrap 的 carousel.js 插件并没有支持手势,有下面3种解决方案 : 1. jQuery Mobile (http://jquerymobile.com/download ...

  2. android 项目学习随笔十六( 广告轮播条播放)

    广告轮播条播放 if (mHandler == null) {//在此初始化mHandler , 保证消息不重复发送 mHandler = new Handler() { public void ha ...

  3. Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View

    最近开发中需要做一个类似京东首页那样的广告轮播效果,于是采用ViewPager自己自定义了一个轮播图效果的View. 主要原理就是利用定时任务器定时切换ViewPager的页面. 效果图如下: 主页面 ...

  4. 安卓开发笔记——自定义广告轮播Banner(实现无限循环)

    关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户& ...

  5. Android学习笔记之图片轮播...

    PS:一个bug又折腾了一个下午....哎... 学习内容: 1.Android利用ViewPager和PagerAdapter实现图片轮播... 2.使用反射机制获取Android的资源信息... ...

  6. 自定义View(二)ViewPage广告轮播

    自定义View的第二个学习案例,使用ViewPage实现广告轮播,通过组合现有的View实现效果如下: 有关ViewPage使用可以学习谷歌官方API,和训练案例: 1.使用ViewPage实现屏幕滑 ...

  7. iOS回顾笔记(05) -- 手把手教你封装一个广告轮播图框架

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  8. android-自定义广告轮播Banner(无限循环实现)

    关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户& ...

  9. 个人练习:使用HTML+CSS3制作图片轮播功能(不使用JavaScript)

    先上效果图,不要在意用来当素材的图片: 在搜索相关资料的时候,查到有两种实现方式:一是使用JavaScript,二是使用CSS3中的Animation(动画),这里使用的是CSS3中的Animatio ...

随机推荐

  1. VB6 仿.netWinfrom控件 Anchor属性类

    vb6中控件没有anchor与dock属性,窗体变大后原来要在resize中调整控件的move属性,否则就面目全非了.网上找到一些调整控件大小的代码,发现并不太适合自己,于是按照思路自己做了一个类似a ...

  2. 使用 github.io 免费建站

    /*************************************************************************** * 使用 github.io 免费建站 * 说 ...

  3. 【JavaScript学习笔记】if使用

    <html> <body> <script language="JavaScript"> var a=4; var b=2; if(a==3) ...

  4. reverse(), extend(), sort() methods of list

    >>> l = list('sdf') >>> l ['s', 'd', 'f'] >>> id(l) 4520422000 >>&g ...

  5. KVM虚拟化技术简介

    kernel-based Virtual Machine的简称,是一个开源的系统虚拟化模块,自Linux 2.6.20之后集成在Linux的各个主要发行版本中.它使用Linux自身的调度器进行管理,所 ...

  6. JS面向对象组件 -- 继承的其他方式(类式继承、原型继承)

    继承的其他形式: •类式继承:利用构造函数(类)继承的方式 •原型继承:借助原型来实现对象继承对象   类 : JS是没有类的概念的 , 把JS中的构造函数看做的类 要做属性和方法继承的时候,要分开继 ...

  7. smarty缓存函数

    原来在Smarty中在3.0以上版本中不在使用这个clear_all_cache(),而是以$smarty->clearAllCache(); 代替.其中$smarty->clear_ca ...

  8. ASP.NET MVC之文件上传【一】

    前言 这一节我们来讲讲在MVC中如何进行文件的上传,我们逐步深入,一起来看看. Upload File(一) 我们在默认创建的项目中的Home控制器下添加如下: public ActionResult ...

  9. poj 3254(状态压缩基础题)

    题意:就是你给一个n行m列的矩阵,矩阵里的元素由0和1组成,1代表肥沃的土地可以种植作物,0则不可以种植作物,并且相邻的土地不能同时种植作物,问你有多少种种植方案. 分析:这是我做的第一道状态压缩dp ...

  10. oracle导入导出数据库和创建表空间和用户

    直入主题: 首先在本地创建2个文件,D:\oradata\jgszz\temp.dbf和 D:\oradata\jgszz\data.dbf. 然后执行下面的SQL. /*创建临时表空间 */ cre ...