在手机app应用中我们经常会看到图片轮播动画效果,Android中想要实现图片轮播,主要用到ViewPager这个控件来实现,这个控件的主要功能是实现图片的滑动效果。
那么有了滑动,在滑动的基础上附上图片也就实现了图片轮播的效果...这个控件类似于ListView,需要使用到适配器这个东西,适配器在这里的作用是为轮播时设置一些效果...这里需要使用到PagerAdapter适配器...下面来一个例子,这个例子的效果是在图片轮播的同时显示播放的是第几张图片的信息...并且下面的点也是会随之进行变化的...
先上一下布局文件的代码...这个布局文件其实还是有点说道的...这句话必须要引进...否则会出现错误...意思就是我设置了一个滑动的效果,这个效果填充整个FrameLayout...每一个View表示一个控件,这个控件的显示方式在另外的xml文件当中...下面是两个xml文件...
上面通过配置xml文件来完成View的显示方式,因为这五个点的形状,大小,甚至是显示方式基本都是相同的,如果再去找5个点图片或者是一个点图片,然后通过Drawable资源的调用完成图片的显示...通过加载5次的方式...这样显然是没有必要的,会浪费不必要的资源..因此我们可以使用xml提供的自定义图形来完成这个过程...xml为我们提供了shape属性,自定义控件..这里我定义了一个实心圆...这个实心圆来完成随着图像的滑动,这个点也随之进行相应的变化...看起来并不是什么难理解的东西...
重要的部分还是如何去实现这个过程...这个过程的实现就再下面的代码中,详细解释也在代码当中...
package com.example.picture_change; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.Map.Entry; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.annotation.SuppressLint; import android.app.Activity; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; /* * HashMap存储的键是不允许重复的...但是值是可以重复的... * * */ public class MainActivity extends Activity { ArrayList imageSource=null; //存放图像控件... ArrayList dots=null; //存放5个点... int []images=null; //存放图像的资源... String []titles=null; //伴随着图像的变动,标题也会随之变动... TextView tv=null; //TextView来来显示title的变化... ViewPager viewpager; //ViewPager来完成滑动效果... MyPagerAdapter adapter; //适配器... Mapmap=new HashMap(); @SuppressLint("UseSparseArrays") MapmapValues=new HashMap(); private int curr=0; private int old=0; int o=0; int mapsize; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toast.makeText(MainActivity.this, "a", Toast.LENGTH_LONG).show(); /* 下面利用反射来完成Drawable的资源获取... * 在这里我获取了5张图片的资源数据..这5张图片分别为a.jpg b.jpg c.jpg d.jpg e.jpg * 这里使用了一个length<=1来完成数据的获取...其实这个方式并不好,是我自己想出来的... * 暂时没有更好的方法...我这里使用反射的目的在下面会进行介绍... * */ Field [] field=R.drawable.class.getFields(); for(Field f:field){ if(f.getName().length()<=1){ try { o++; String str="image"+"_"+o; map.put(str, f.getInt(R.drawable.class));//使用map以键值对的形式来保存图片的数据资源... } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } mapsize=map.size()-1; /* 这里我再次使用了一个map以键值对的形式只保存上一个map的Value值... * 这么做的目的在下面进行说明... * * */ for(Entry entry:map.entrySet()){ mapValues.put(mapsize, entry.getValue()); mapsize--; } init(); } public void init(){ //数据信息的初始化... images=new int[]{R.drawable.a,R.drawable.b,R.drawable.c,R.drawable.d,R.drawable.e}; titles=new String[]{"this is the one picture","this is two picture","this is three picture","this is four picture","this is five picture"}; imageSource=new ArrayList(); //这里初始化imageSource... for(int i=0;i<images.length;i++){ ImageView iamgeview =new ImageView(this); iamgeview.setBackgroundResource(images[i]); imageSource.add(iamgeview); } //这里使用了一个方法...我们没有必要一次一次的findViewById()...使用下面的方法很有效的解决了多次findViewById()函数的引用... dots=new ArrayList(); for(int j=0;j<5;j++){ String dotid="dot"+"_"+j; int resId=getResources().getIdentifier(dotid, "id", "com.example.picture_change"); dots.add(findViewById(resId)); } tv=(TextView) findViewById(R.id.tv); tv.setText(titles[0]); viewpager=(ViewPager) findViewById(R.id.vp); adapter=new MyPagerAdapter(); //这里定义了一个适配器对象... viewpager.setAdapter(adapter); //传递对象,绑定适配器... viewpager.setOnPageChangeListener(new onpagelistener()); //这里设置了一个当图片发生滑动后的一个监听效果... ScheduledExecutorService scheduled = Executors.newSingleThreadScheduledExecutor();//这里我们开启一个线程... scheduled.scheduleAtFixedRate(new Runnable() { @Override public void run() { // TODO Auto-generated method stub curr=(curr+1)%images.length; handler.sendEmptyMessage(0);//将信息发送给Handler,让Handler处理数据,完成一些操作... } }, 2, 2, TimeUnit.SECONDS); //实现内部方法,设置播放时间... } private class MyPagerAdapter extends PagerAdapter{ @Override public int getCount() { // TODO Auto-generated method stub return images.length; } @Override public boolean isViewFromObject(View arg0, Object arg1) { // TODO Auto-generated method stub //判断前后两张的显示图片是否相同... return arg0==arg1; } @Override public void destroyItem(ViewGroup container, int position, Object object) { //销毁...释放内存... container.removeView(imageSource.get(position)); } @Override public Object instantiateItem(ViewGroup container, int position) { /* 这个方法表示的是滑动到了第几张图片的定位...通过传递一个ViewGroup来完成数据的传递... * 我们上面使用到了一个Map来保存上一个Map的Value值,这个的真正目的就在这里..目的是为了 * 获取当前显示图片的资源信息..说白了就是要获取(R.drawable.属性),为什么要实现这个目的 * 因为我们要实现,当这个显示的图片被点击的时候,我们应该进行哪些操作... * */ ImageView v=imageSource.get(position);//获取当前图片... //position是从0-4的值...因此可以获取到Map中的值了... v.setClickable(true); //设置图片是可以点击的... final int values=(Integer)mapValues.get(position); //这里我们获取map中保存的Values值... System.out.println(values); //下面就是实现触发图片时的监听... v.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub switch(values){ case R.drawable.a: Toast.makeText(MainActivity.this, "a", Toast.LENGTH_LONG).show(); break; case R.drawable.b: Toast.makeText(MainActivity.this, "b", Toast.LENGTH_LONG).show(); break; case R.drawable.c: Toast.makeText(MainActivity.this, "c", Toast.LENGTH_LONG).show(); break; case R.drawable.d: Toast.makeText(MainActivity.this, "d", Toast.LENGTH_LONG).show(); break; case R.drawable.e: Toast.makeText(MainActivity.this, "e", Toast.LENGTH_LONG).show(); break; } } }); container.addView(imageSource.get(position)); //将所有的图片都加载到了container中... return imageSource.get(position); } } //定义一个内部类实现图片在变化的时候的监听... class onpagelistener implements OnPageChangeListener{ @Override public void onPageScrollStateChanged(int arg0) { // TODO Auto-generated method stub } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { // TODO Auto-generated method stub } @Override public void onPageSelected(int arg0) { // TODO Auto-generated method stub //当发生滑动后,要完成的一些相应操作... tv.setText(titles[arg0]); dots.get(arg0).setBackgroundResource(R.drawable.dot); dots.get(old).setBackgroundResource(R.drawable.dot_1); old=arg0; curr=arg0; } } @SuppressLint("HandlerLeak") private Handler handler=new Handler(){ public void handleMessage(Message msg) { //接收到消息后,更新页面 viewpager.setCurrentItem(curr); }; }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
这里我使用了反射机制来获取Drawable的图像资源,然后通过switch方法来完成了当图片被点击的时候需要完成的操作...这是笔者我自己想出来的一种方法...因为Android没有提供ImageClickListener()这类的方法,因此我们只能够自己去进行书写图片被点击的方法...至于更好的方法,我是还没有发现...也是确实是能力有限制了,这个方法今天也想了整整一个下午才折腾出来的...
注意:给自己的一个提醒,HashMap的键是绝对不能够重复保存的...但是值是可以保存重复的数据的,如果保存了重复的键,那么在map只会保存第一个数据,不会对后续数据进行保存...这个也是一个很大的注意点,自己就栽这里很久,虽然很低级的错误,但是很有可能在不注意的情况下就犯下了...因此在这里也算是给自己提个醒...下次不会再犯下这样的错误的
Android图片轮播效果的几种实现方法
第一种:使用动画的方法实现:(代码繁琐)
这种发放需要:两个动画效果,一个布局,一个主类来实现,不多说了,来看代码吧:
public class IamgeTrActivity extends Activity { /** Called when the activity is first created. */ public ImageView imageView; public ImageView imageView2; public Animation animation1; public Animation animation2; public TextView text; public boolean juage = true; public int images[] = new int[] { R.drawable.icon, R.drawable.expriment, R.drawable.changer, R.drawable.dataline, R.drawable.preffitication }; public int count = 0; public Handler handler = new Handler(); public Runnable runnable = new Runnable() { @Override public void run() { // TODO Auto-generated method stub AnimationSet animationSet1 = new AnimationSet(true); AnimationSet animationSet2 = new AnimationSet(true); imageView2.setVisibility(0); TranslateAnimation ta = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, -1f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f); ta.setDuration(2000); animationSet1.addAnimation(ta); animationSet1.setFillAfter(true); ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f); ta.setDuration(2000); animationSet2.addAnimation(ta); animationSet2.setFillAfter(true); //iamgeView 出去 imageView2 进来 imageView.startAnimation(animationSet1); imageView2.startAnimation(animationSet2); imageView.setBackgroundResource(images[count % 5]); count++; imageView2.setBackgroundResource(images[count % 5]); text.setText(String.valueOf(count)); if (juage) handler.postDelayed(runnable, 6000); Log.i(handler, handler); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); imageView = (ImageView) findViewById(R.id.imageView); imageView2 = (ImageView) findViewById(R.id.imageView2); text=(TextView)findViewById(R.id.text); text.setText(String.valueOf(count)); //将iamgeView先隐藏,然后显示 imageView2.setVisibility(4); handler.postDelayed(runnable, 2000); } public void onPause() { juage = false; super.onPause(); } }
布局代码:
android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent android:id=@+id/rl> android:id=@+id/imageView android:layout_width=fill_parent android:background=@drawable/icon android:layout_below=@+id/rl android:layout_height=120dp /> android:id=@+id/imageView2 android:layout_width=fill_parent android:background=@drawable/expriment android:layout_below=@+id/rl android:layout_height=120dp /> android:id=@+id/text android:layout_width=fill_parent android:layout_height=wrap_content android:layout_below=@id/imageView/>
第二种:使用ViewFlipper实现图片的轮播
Android系统自带的一个多页面管理控件,它可以实现子界面的自动切换:
首先 需要为ViewFlipper加入View
(1) 静态导入:在layout布局文件中直接导入
(2) 动态导入:addView()方法
ViewPlipper常用方法:
setInAnimation:设置View进入屏幕时候使用的动画
setOutAnimation:设置View退出屏幕时候使用的动画
showNext:调用该函数来显示ViewFlipper里面的下一个View
showPrevious:调用该函数来显示ViewFlipper里面的上一个View
setFlipInterval:设置View之间切换的时间间隔
startFlipping使用上面设置的时间间隔来开始切换所有的View,切换会循环进行
stopFlipping:停止View切换
讲了这么多,那么我们今天要实现的是什么呢?
(1) 利用ViewFlipper实现图片的轮播
(2) 支持手势滑动的ViewFlipper
我们需要先准备几张图片:把图片放进drawable中
创建两个动画:在res下面新建一个folder里面新建两个xml:
left_in:
android:duration=5000 android:fromXDelta=100%p android:toXDelta=0/>
left_out:
android:fromXDelta=0 android:toXDelta=-100%p android:duration=5000/>
一个布局文件:
xmlns:tools=http://schemas.android.com/tools android:layout_width=match_parent android:layout_height=match_parent tools:context=.MainActivity > android:id=@+id/flipper android:layout_width=fill_parent android:layout_height=fill_parent/>
一个主类:
public class MainActivity extends Activity { private ViewFlipper flipper; private int[] resId = {R.drawable.pc1,R.drawable.pc2,R.drawable.pc3,R.drawable.pc4}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); flipper = (ViewFlipper) findViewById(R.id.flipper); /* * 动态导入的方式为ViewFlipper加入子View * */ for (int i = 0; i < resId.length; i++) { flipper.addView(getImageView(resId[i])); } /* * 为ViewFlipper去添加动画效果 * */ flipper.setInAnimation(this, R.anim.left_in); flipper.setOutAnimation(this, R.anim.left_out); flipper.setFlipInterval(5000); flipper.startFlipping(); } private ImageView getImageView(int resId){ ImageView image = new ImageView(this); image.setBackgroundResource(resId); return image; } }
那么这样就实现了一个图片轮询的功能效果了
我们还可以添加点击,滑动效果:
我们还需要添加两个向右的滑动效果:
right_in:
android:fromXDelta=0 android:toXDelta=-100%p android:duration=2000/>
right_out:
android:fromXDelta=100%p android:toXDelta=0 android:duration=2000/>
然后我们还需要在主类里面添加(如果你不想让图片自动播放,只想通过手势来实现图片播放那么你需要把“为ViewFlipper添加动画效果的代码”删掉):
public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startX = event.getX(); break; case MotionEvent.ACTION_MOVE://判断向左滑动还是向右滑动 if (event.getX() - startX > 100) { flipper.setInAnimation(this, R.anim.left_in); flipper.setOutAnimation(this, R.anim.left_out); flipper.showPrevious(); }else if (startX - event.getX() > 100) { flipper.setInAnimation(this, R.anim.right_in); flipper.setOutAnimation(this, R.anim.right_out); flipper.showNext(); } case MotionEvent.ACTION_UP: break; } return super.onTouchEvent(event); }
这样我们利用我们的ViewFlipper完成的图片轮询的功能就做完了。
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
, 文件
, view
, 控件
, 代码
资源
android实现图片轮播、android轮播图实现、android实现广告轮播、android实现无限轮播、android轮播图的实现,以便于您获取更多的相关知识。