下面是自定义Banner轮播图
添加依赖
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
添加权限
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
values中的attrs类
<resources> <declare-styleable name="Banner"> <attr name="size" format="dimension"/> <attr name="margin" format="dimension"/> </declare-styleable> </resources>
drawable中的dot_normal类
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="@android:color/white"></solid> <size android:height="10dp" android:width="10dp"/> </shape>
drawable中的dot_selected类
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="@android:color/holo_green_dark"></solid> <size android:height="10dp" android:width="10dp"/> </shape>
App类
public class App extends Application { @Override public void onCreate() { super.onCreate(); init(); } private void init() { DisplayImageOptions options=new DisplayImageOptions.Builder() .cacheInMemory(true) .cacheOnDisk(true) .build(); ImageLoaderConfiguration build = new ImageLoaderConfiguration.Builder(this) .writeDebugLogs() .diskCacheFileNameGenerator(new Md5FileNameGenerator()) .defaultDisplayImageOptions(options) .build(); ImageLoader.getInstance().init(build); } }
NeworkUtils类
public class NeworkUtils { private String url; private ImageView imageView; private final String SDCARD_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/kson/"; //实例化hashmap对象 private HashMap<String ,SoftReference<Bitmap>> hashMap=new HashMap<>(); public NeworkUtils(String url, ImageView imageView) { this.url = url; this.imageView = imageView; } public void execute(){ new BitmapTask().execute(url); } class BitmapTask extends AsyncTask<String ,Void,Bitmap>{ @Override protected Bitmap doInBackground(String... strings) { try { URL url=new URL(strings[0]); HttpURLConnection connection= (HttpURLConnection) url.openConnection(); connection.connect(); if (200==connection.getResponseCode()){ InputStream inputStream = connection.getInputStream(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds=true; BitmapFactory.decodeStream(inputStream); options.inSampleSize=4; options.inJustDecodeBounds=false; Bitmap bitmap=BitmapFactory.decodeStream(inputStream); return bitmap; } } catch (Exception e) { e.printStackTrace(); } return null; } protected void onPreExecute(Bitmap bitmap) { imageView.setImageBitmap(bitmap); memory(url,bitmap); diskMemory(url,bitmap); } } public void diskMemory(String url,Bitmap bitmap){ try { File dir = new File(SDCARD_PATH); if (!dir.exists()){ dir.mkdirs(); } File file = new File(SDCARD_PATH + new Md5FileNameGenerator().generate(url)); FileOutputStream outputStream = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG,100,outputStream); } catch (FileNotFoundException e) { e.printStackTrace(); } } public Bitmap getDiskMemory(String url){ File file=new File(SDCARD_PATH+new Md5FileNameGenerator().generate(url)); if (file!=null && file.exists()){ try { FileInputStream inputStream = new FileInputStream(file); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); return bitmap; } catch (FileNotFoundException e) { e.printStackTrace(); }} return null; } public void memory(String url,Bitmap bitmap){ SoftReference<Bitmap> bmp=new SoftReference<Bitmap>(bitmap); hashMap.put(new Md5FileNameGenerator().generate(url),bmp); } public Bitmap getMemory(String url){ Bitmap bitmap=null; SoftReference<Bitmap> bitmapSoftReference=hashMap.get(new Md5FileNameGenerator().generate(url)); if (bitmapSoftReference!=null){ bitmap=bitmapSoftReference.get(); } return bitmap; } }
Banner类
pubic class Banner extends FrameLayout implements ViewPager.OnPageChangeListener { private final int DELAY_TIME = 5000;//自动轮播时间 private List<String> mUrls; private List<ImageView> mViewpagerViews; private List<ImageView> mDotImageviews; private Context context; private int size;//圆点的大小 private int margin;//圆点的间距 private int count;//viewpager中view的数量 private ViewPager mViewPager; private LinearLayout mDotlayout;//圆点布局 private MyPager mPagerAdapter; private int currentItem;//当前viewpager索引 private Handler handler = new Handler(); private BannerClicklistener mBannerClicklistener; public Banner(@NonNull Context context) { super(context); init(context, null); } public Banner(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context, attrs); } public Banner(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs); } /** * 初始化数据 * * @param context * @param attrs */ private void init(Context context, AttributeSet attrs) { this.context = context; mUrls = new ArrayList<>(); mViewpagerViews = new ArrayList<>(); mDotImageviews = new ArrayList<>(); //拿到自定义的属性数组 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Banner); //得到数组里的自定义的size(圆点大小) size = typedArray.getDimensionPixelSize(R.styleable.Banner_size, 10); //得到数组里的自定义的margin(圆点间距) margin = typedArray.getDimensionPixelSize(R.styleable.Banner_margin, 10); typedArray.recycle();//通知jvm的垃圾回收器,当你回收对象的时候,一定要把我回收了 View view = LayoutInflater.from(context).inflate(R.layout.banner_layout, this, true); // addView(view); // View child = LayoutInflater.from(context).inflate(R.layout.banner_layout,null); // addView(child); mViewPager = view.findViewById(R.id.viewpager); mDotlayout = view.findViewById(R.id.layout_dot); //添加viewpager页面改变监听 mViewPager.addOnPageChangeListener(this); } /** * 绘制自定义view的所有元素 */ public void display() { //绘制viewpager drawViewpager(); //绘制圆点 drawDots(); //设置自动滚动 setAuto(); } /** * 设置自动滚动 */ private void setAuto() { handler.postDelayed(mTask, DELAY_TIME); } /** * 定时任务 */ Runnable mTask = new Runnable() { @Override public void run() { currentItem++; if (currentItem >= count) { currentItem = 0; } mViewPager.setCurrentItem(currentItem); handler.postDelayed(this, DELAY_TIME); } }; /** * 传urls * * @param urls */ public Banner loadData(List<String> urls) { this.mUrls = urls; this.count = urls.size(); return this; } /** * 绘制圆点 */ private void drawDots() { for (int i = 0; i < count; i++) { ImageView iv = new ImageView(context); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(size, size); params.leftMargin = margin; params.rightMargin = margin; iv.setLayoutParams(params); mDotImageviews.add(iv); if (i == 0) { iv.setImageResource(R.drawable.dot_selected); } else { iv.setImageResource(R.drawable.dot_normal); } mDotlayout.addView(iv); } } private void drawViewpager() { for (int i = 0; i < count; i++) { ImageView iv = new ImageView(context); iv.setScaleType(ImageView.ScaleType.CENTER_CROP); mViewpagerViews.add(iv); } if (mViewpagerViews != null) { mPagerAdapter = new MyPager(); mViewPager.setAdapter(mPagerAdapter); } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } /** * 切换页面的监听 * @param position */ @Override public void onPageSelected(int position) { for (int i = 0; i < count; i++) { if (i == position) { mDotImageviews.get(i).setImageResource(R.drawable.dot_selected); } else { mDotImageviews.get(i).setImageResource(R.drawable.dot_normal); } } } @Override public void onPageScrollStateChanged(int state) { } class MyPager extends PagerAdapter { @Override public int getCount() { return mViewpagerViews.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, final int position) { ImageView view = mViewpagerViews.get(position); container.addView(view); view.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { //实现点击逻辑 mBannerClicklistener.onClickListener(position); } }); System.out.println("urls:"+mUrls.get(position)); ImageLoader.getInstance().displayImage(mUrls.get(position), view); return view; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } } /** * 处理自动轮播和手动滑动的冲突 * * @param ev * @return */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { int action = ev.getAction(); if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) { stopAuto(); } else if (action == MotionEvent.ACTION_UP) { setAuto(); } return super.dispatchTouchEvent(ev); } /** * 取消自动轮播任务 */ private void stopAuto() { handler.removeCallbacks(mTask);//取消任务 } /** * 供外部调用者调用的接口类 */ public interface BannerClicklistener { void onClickListener(int pos); } /** * 供外部调用者初始化接口对象 */ public void setBannerClicklistener(BannerClicklistener bannerClicklistener) { this.mBannerClicklistener = bannerClicklistener; } //取消轮播任务 public void cancel(){ handler.removeCallbacks(mTask); } }
MemoryActivity.xml布局
<ImageView android:id="@+id/iv" android:layout_width="match_parent" android:layout_height="wrap_content" />
MemoryActivity
private String url = "https://img6.bdstatic.com/img/image/xiaolu/wujingzhanlang2.jpg"; private ImageView iv; private NeworkUtils networkUtils; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_memory); initView(); networkUtils = new NeworkUtils(url, iv); if (networkUtils.getMemory(url) != null) {//首先加载内存缓存 iv.setImageBitmap(networkUtils.getDiskMemory(url)); } else if (networkUtils.getDiskMemory(url) != null) {//其次加载磁盘缓存 iv.setImageBitmap(networkUtils.getDiskMemory(url)); } else {//最后加载网络 networkUtils.execute(); } } private void initView() { iv = (ImageView) findViewById(R.id.iv); } }
banner_layout.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="150dp"> </android.support.v4.view.ViewPager> <LinearLayout android:id="@+id/layout_dot" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_gravity="bottom" android:gravity="center" android:paddingBottom="10dp" /> </FrameLayout>
acticity显示主页面
private Banner banner; private List<String> urls; private String url = "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=511209731,3971680570&fm=26&gp=0.jpg"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getSupportActionBar().hide(); banner = (Banner) findViewById(R.id.banner); urls = new ArrayList<>(); urls.add("https://www.zhaoapi.cn/images/quarter/ad1.png"); urls.add("https://www.zhaoapi.cn/images/quarter/ad2.png"); urls.add("https://www.zhaoapi.cn/images/quarter/ad3.png"); urls.add("https://www.zhaoapi.cn/images/quarter/ad4.png"); //解耦 banner.loadData(urls).display();//构建者模式返回对象本身 banner.setBannerClicklistener(new Banner.BannerClicklistener() { @Override public void onClickListener(int pos) { Toast.makeText(MainActivity.this, "pos====" + pos, Toast.LENGTH_SHORT).show(); } }); } }