Android中使用自定义view实现轮播图
16lz
2022-06-14
先导依赖:(可以选择使用imageloder,或者gilde加载图片)
compile 'com.github.bumptech.glide:glide:3.6.1'compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
-----------------MainActivity------------------
package com.example.earl.myviewpager_banner;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.Toast;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity { private Banner banner; private List urls; @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("http://img2.imgtn.bdimg.com/it/u=3585804305,763553611&fm=27&gp=0.jpg"); urls.add("http://img0.imgtn.bdimg.com/it/u=3281146250,5393266&fm=27&gp=0.jpg"); urls.add("http://img5.imgtn.bdimg.com/it/u=2496610138,254842195&fm=27&gp=0.jpg"); urls.add("http://img5.imgtn.bdimg.com/it/u=2951375427,1212049814&fm=27&gp=0.jpg"); //解耦 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(); } }); } @Override protected void onDestroy() { super.onDestroy(); if (banner != null) { banner.cancel(); banner = null; } }}
------------------Banner------------------- package com.example.earl.myviewpager_banner;import android.content.Context;import android.content.res.TypedArray;import android.os.Handler;import android.support.annotation.AttrRes;import android.support.annotation.NonNull;import android.support.annotation.Nullable;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.LinearLayout;import com.bumptech.glide.Glide;import com.nostra13.universalimageloader.core.ImageLoader;import java.util.ArrayList;import java.util.List;public class Banner extends FrameLayout implements ViewPager.OnPageChangeListener{ private final int DELAY_TIME = 3000;//自动轮播时间 private List mUrls; private List mViewpagerViews; private List 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 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);// Glide.with(context)// .load(mUrls.get(position))// .into(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); }}
-----------------App-----------------
package com.example.earl.myviewpager_banner;import android.app.Application;import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;import com.nostra13.universalimageloader.core.DisplayImageOptions;import com.nostra13.universalimageloader.core.ImageLoader;import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;public class App extends Application{ @Override public void onCreate() { super.onCreate(); init(); } private void init() { DisplayImageOptions o = new DisplayImageOptions.Builder() .cacheInMemory(true) .cacheOnDisk(true) .build(); ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this) .writeDebugLogs() .diskCacheFileNameGenerator(new Md5FileNameGenerator()) .defaultDisplayImageOptions(o) .build(); ImageLoader.getInstance().init(config); }}
<----------在drawable中创建xml文件,绘制出小圆点----------->
------------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="@android:color/white">solid> <size android:height="10dp" android:width="10dp"/>shape>
-------------dot_selected.xml----------
<?xml version="1.0" encoding="utf-8"?><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>
---------------activity_main.xml-------------
<?xml version="1.0" encoding="utf-8"?><LinearLayout android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:banner="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.earl.myviewpager_banner.MainActivity"> <com.example.earl.myviewpager_banner.Banner android:id="@+id/banner" android:layout_width="match_parent" android:layout_height="200dp" android:visibility="visible" banner:margin="10dp" banner:size="10dp">com.example.earl.myviewpager_banner.Banner>LinearLayout>
--------------banner_layout.xml-------------
<?xml version="1.0" encoding="utf-8"?><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="200dp" /> <LinearLayout android:id="@+id/layout_dot" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:gravity="center" android:orientation="horizontal" android:paddingBottom="10dp" />FrameLayout>
<------------在value中创建 attrs.xml----------->
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="Banner"> <attr name="size" format="dimension"/> <attr name="margin" format="dimension"/> declare-styleable>resources>
更多相关文章
- Android图形解锁的绘制
- Android——自定义ProgressBar显示文字(有缺陷)
- Android(安卓)中文 API (18) ―― AbsSeekBar
- android中使用定时任务
- Android--(6)--详解ImageButton属性
- android中获得屏幕、视图、任务栏、状态栏的高宽以及屏幕的设置
- android 同步框架分析
- Android(安卓)图片裁剪之三剑式(二)
- Android(安卓)View的绘制过程复习