Android自定义控件之应用程序首页轮播图

现在基本上大多数的Android应用程序的首页都有轮播图,就是像下图这样的(此图为转载的一篇博文中的图,拿来直接用了):

像这样的组件我相信大多数的应用程序都会使用到,本文就是自定义一个这样的组件,可以动态设置图片的张数。下面就开始本次的自定义之旅吧,首先看一下自定义控件的的布局文件:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android=""android:layout_width="match_parent"android:layout_height="match_parent" ><android.support.v4.view.ViewPagerandroid:id="@+id/viewPager"android:layout_width="match_parent"android:layout_height="match_parent" /><span style="white-space:pre"></span><!–此LinearLayout用来小圆点–><LinearLayoutandroid:id="@+id/linearlayout"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:gravity="center"android:orientation="horizontal"android:padding="5dp" ></LinearLayout></RelativeLayout>布局文件看完之后,我们再来看一下自定义控件相对应的java类吧:具体代码如下:<pre name="code" class="java">package com.gc.flashview;import java.lang.ref.WeakReference;import java.lang.reflect.Field;import java.util.ArrayList;import java.util.List;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;import com.gc.flashview.effect.AccordionTransformer;import com.gc.flashview.effect.CubeTransformer;import com.gc.flashview.effect.DefaultTransformer;import com.gc.flashview.effect.DepthPageTransformer;import com.gc.flashview.effect.InRightDownTransformer;import com.gc.flashview.effect.InRightUpTransformer;import com.gc.flashview.effect.RotateTransformer;import com.gc.flashview.effect.ZoomOutPageTransformer;import com.gc.flashview.listener.FlashViewListener;import android.annotation.SuppressLint;import android.content.Context;import android.content.res.TypedArray;import android.graphics.drawable.Drawable;import android.os.Handler;import android.os.Message;import android.os.Parcelable;import android.provider.ContactsContract.CommonDataKinds.Im;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.support.v4.view.ViewPager.PageTransformer;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.view.ViewParent;import android.view.animation.AccelerateInterpolator;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import android.view.animation.Interpolator;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.ImageView.ScaleType;import android.widget.LinearLayout;import android.widget.RelativeLayout;import android.widget.Scroller;import android.widget.Toast;/** * * @author Android将军 * * */@SuppressLint("HandlerLeak")public class FlashView extends FrameLayout{private ImageLoaderTools imageLoaderTools;private ImageHandler mhandler = new ImageHandler(new WeakReference<FlashView>(this));private List<String> imageUris;private List<ImageView> imageViewsList;private List<ImageView> dotViewsList;private LinearLayout mLinearLayout;private ViewPager mViewPager;private FlashViewListener mFlashViewListener;//向外提供接口private int effect;//图片切换的动画效果public FlashView(Context context) {this(context, null);}public FlashView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public FlashView(Context context, AttributeSet attrs, int defStyle){super(context, attrs, defStyle);// TODO Auto-generated constructor stub//读取该自定义控件自定义的属性TypedArray mTypedArray=context.obtainStyledAttributes(attrs, R.styleable.FlashView);effect=mTypedArray.getInt(R.styleable.FlashView_effect, 2);initUI(context);if (!(imageUris.size() <= 0)) {setImageUris(imageUris);//}}private void initUI(Context context) {imageViewsList = new ArrayList<ImageView>();dotViewsList = new ArrayList<ImageView>();imageUris = new ArrayList<String>();imageLoaderTools = ImageLoaderTools.getInstance(context.getApplicationContext());LayoutInflater.from(context).inflate(R.layout.layout_slideshow, this,true);mLinearLayout = (LinearLayout) findViewById(R.id.linearlayout);mViewPager = (ViewPager) findViewById(R.id.viewPager);//mFlashViewListener必须实例化try {mFlashViewListener = (FlashViewListener) context;} catch (ClassCastException e) {throw new ClassCastException(context.toString()+ " must implement mPhotoListener");}}public void setImageUris(List<String> imageuris) {if (imageuris.size() <= 0)// 如果得到的图片张数为0,则增加一张默认的图片{imageUris.add("drawable://" + R.drawable.defaultflashview);}else {for (int i = 0; i < imageuris.size(); i++){imageUris.add(imageuris.get(i));}}LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);lp.setMargins(5, 0, 0, 0);for (int i = 0; i < imageUris.size(); i++) {ImageView imageView = new ImageView(getContext());imageView.setScaleType(ScaleType.FIT_XY);// X和Y方向都填满imageLoaderTools.displayImage(imageUris.get(i), imageView);imageViewsList.add(imageView);ImageView viewDot = new ImageView(getContext());if (i == 0){viewDot.setBackgroundResource(R.drawable.dot_white);} else{viewDot.setBackgroundResource(R.drawable.dot_light);}viewDot.setLayoutParams(lp);dotViewsList.add(viewDot);mLinearLayout.addView(viewDot);}mViewPager.setFocusable(true);mViewPager.setAdapter(new MyPagerAdapter());mViewPager.setOnPageChangeListener(new MyPageChangeListener());setEffect(effect);if (imageUris.size() <= 1){} else {// 利用反射修改自动轮播的动画持续时间try{Field field = ViewPager.class.getDeclaredField("mScroller");field.setAccessible(true);FixedSpeedScroller scroller = new FixedSpeedScroller(mViewPager.getContext(), new AccelerateInterpolator());field.set(mViewPager, scroller);scroller.setmDuration(1000);mViewPager.setCurrentItem(100 * imageViewsList.size());mhandler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE,ImageHandler.MSG_DELAY);} catch (Exception e){}}}/** * 切换轮播小点的显示 * * @param selectItems */private void setImageBackground(int selectItems) {for (int i = 0; i < dotViewsList.size(); i++) {if (i == selectItems % dotViewsList.size()){dotViewsList.get(i).setBackgroundResource(R.drawable.dot_white);} else{dotViewsList.get(i).setBackgroundResource(R.drawable.dot_light);}}}/** * * 数据适配器 * */private class MyPagerAdapter extends PagerAdapter {@Overridepublic void destroyItem(View container, int position, Object object) {}@Overridepublic Object instantiateItem(View container, int position) {position = position % imageViewsList.size();if (position < 0){position = position + imageViewsList.size();}final int pos=position;View view = imageViewsList.get(position);view.setTag(position);view.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v){// TODO Auto-generated method stubmFlashViewListener.onClick(pos);}});ViewParent vp = view.getParent();if (vp != null){ViewPager pager = (ViewPager) vp;pager.removeView(view);}((ViewPager) container).addView(view);return view;}@Overridepublic int getCount() {if (imageUris.size() <= 1){return 1;} else {return Integer.MAX_VALUE;}}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}}private class MyPageChangeListener implements OnPageChangeListener {@Overridepublic void onPageScrollStateChanged(int arg0) {// TODO Auto-generated method stubswitch (arg0){case ViewPager.SCROLL_STATE_DRAGGING:mhandler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);break;case ViewPager.SCROLL_STATE_IDLE:mhandler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE,ImageHandler.MSG_DELAY);break;default:break;}}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {// TODO Auto-generated method stub}@Overridepublic void onPageSelected(int pos) {// TODO Auto-generated method stubmhandler.sendMessage(Message.obtain(mhandler,ImageHandler.MSG_PAGE_CHANGED, pos, 0));setImageBackground(pos);}}@SuppressWarnings("unused")private void destoryBitmaps() {for (int i = 0; i < imageViewsList.size(); i++) {ImageView imageView = imageViewsList.get(i);Drawable drawable = imageView.getDrawable();if (drawable != null){drawable.setCallback(null);}}}public void setEffect(int selectEffect){switch (selectEffect) {case 0:setPageTransformer(true,new AccordionTransformer());break;case 1:setPageTransformer(true,new CubeTransformer());break;case 2:setPageTransformer(true,new DefaultTransformer());break;case 3:setPageTransformer(true,new DepthPageTransformer());break;case 4:setPageTransformer(true,new InRightDownTransformer());break;case 5:setPageTransformer(true,new InRightUpTransformer());break;case 6:setPageTransformer(true,new RotateTransformer());break;case 7:setPageTransformer(true,new ZoomOutPageTransformer());break;default:break;}}/** * 设置切换效果 * @param b * @param rotateTransformer */public void setPageTransformer(boolean b, PageTransformer rotateTransformer){// TODO Auto-generated method stubmViewPager.setPageTransformer(b, rotateTransformer);}/** * * FixedSpeedScroller类的源码来源于网络,在此谢过贡献此代码的道友 * */public class FixedSpeedScroller extends Scroller {private int mDuration = 1500;public FixedSpeedScroller(Context context) {super(context);}public FixedSpeedScroller(Context context, Interpolator interpolator) {super(context, interpolator);}@Overridepublic void startScroll(int startX, int startY, int dx, int dy,int duration) {super.startScroll(startX, startY, dx, dy, mDuration);}@Overridepublic void startScroll(int startX, int startY, int dx, int dy) {super.startScroll(startX, startY, dx, dy, mDuration);}public void setmDuration(int time) {mDuration = time;}public int getmDuration() {return mDuration;}}private static class ImageHandler extends Handler {protected static final int MSG_UPDATE_IMAGE = 1;protected static final int MSG_KEEP_SILENT = 2;protected static final int MSG_BREAK_SILENT = 3;protected static final int MSG_PAGE_CHANGED = 4;protected static final long MSG_DELAY = 2000;private WeakReference<FlashView> weakReference;private int currentItem = 0;protected ImageHandler(WeakReference<FlashView> wk) {weakReference = wk;System.out.println("dsfdsfdsf:::" + currentItem);}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);FlashView activity = weakReference.get();if (activity == null){return;}if (activity.mhandler.hasMessages(MSG_UPDATE_IMAGE)){if (currentItem > 0)// 这里必须加入currentItem>0的判断,否则不能完美的自动轮播{activity.mhandler.removeMessages(MSG_UPDATE_IMAGE);}}switch (msg.what){case MSG_UPDATE_IMAGE:System.out.println("cccccc:::" + currentItem);currentItem++;activity.mViewPager.setCurrentItem(currentItem);activity.mhandler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE,MSG_DELAY);break;case MSG_KEEP_SILENT:break;case MSG_BREAK_SILENT:activity.mhandler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE,MSG_DELAY);break;case MSG_PAGE_CHANGED:currentItem = msg.arg1;break;default:break;}}}}说过自定义控件的布局和相应类之后,我们就要来使用它了,那么我们怎么去使用这个呢,请看下面的内容。在你的工程中如果想要使用该自定义控件,你需要把自定义控件的布局文件拷贝到你的layout文件夹下,然后将上面的类拷贝到你的工程里去,在你自己的布局文件中这样引用该控件,代码,如下: <com.gc.flashview.FlashView         android:id="@+id/flash_view"        android:layout_width="match_parent"        android:layout_height="300dp"        android:layout_margin="10dp"        app:effect="cube"                />然后在相应的Activity或Fragment中这样动态设置图片:(1)先通过findviewbyid获得该控件】

(2)调用该控件的setImageUris的方法

只要相信,期待就会成真

Android自定义控件之应用程序首页轮播图

相关文章:

你感兴趣的文章:

标签云: