Android實(shí)現(xiàn)輪播圖片效果
本文實(shí)例為大家分享了Android實(shí)現(xiàn)輪播圖片效果的具體代碼,供大家參考,具體內(nèi)容如下
一、原理
首先,將這些要輪播的圖片和一些文本分別放置在不同的數(shù)據(jù)集合中,程序啟動(dòng)的時(shí)候默認(rèn)顯示一組圖片和文本數(shù)據(jù),然后啟動(dòng)一個(gè)定時(shí)器,每隔一段時(shí)間便替換掉顯示的圖片和文本數(shù)據(jù),同時(shí)加入一些動(dòng)畫(huà)效果,已達(dá)到輪播的特效。同時(shí),我們也要實(shí)現(xiàn)手指滑動(dòng)圖片達(dá)到輪播的效果。
二、實(shí)現(xiàn)
1、程序啟動(dòng)界面MainActivity
public class MainActivity extends AppCompatActivity implements ImageBannerFramLayout.FramLayoutLisenner{ private ImageBannerFramLayout mGroup; private int[] ids = new int[] { R.drawable.i1,//圖片資源1 R.drawable.i2,//圖片資源2 }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //計(jì)算當(dāng)前手機(jī)寬度 DisplayMetrics displayMetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); int width = displayMetrics.widthPixels; mGroup = (ImageBannerFramLayout) findViewById(R.id.image_group); mGroup.setLisenner(this); List<Bitmap> list = new ArrayList<>(); for (int i = 0; i < ids.length; i++) { Bitmap bitmap = BitmapFactory.decodeResource(getResources(),ids[i]); list.add(bitmap); } mGroup.addBitmaps(list); } @Override public void chickImageIndex(int pos) { Toast.makeText(this,"索引值 = " + pos,Toast.LENGTH_SHORT).show(); } }
2、新建包view下面新建兩個(gè)類(lèi)
1)新建ImageBarnnerViewGroup類(lèi)繼承自ViewGroup
public class ImageBarnnerViewGroup extends ViewGroup { private int children;//我們View Group的子視圖總個(gè)數(shù) private int childwidth;//子視圖的寬度 private int childheight;//子視圖的高度 private int x;//此時(shí)的x的值代表的是第一次按下的位置的橫坐標(biāo),每一次移動(dòng)過(guò)的過(guò)程中 移動(dòng)之前的位置橫坐標(biāo) private int index = 0;//代表名為每張圖片的索引 private Scroller scroller; /** * 利用一個(gè)單擊變量開(kāi)關(guān)進(jìn)行判斷,離開(kāi)屏幕的一瞬間判斷用戶的操作是點(diǎn)擊 */ private boolean isClick;//true的時(shí)候點(diǎn)擊事件,false的時(shí)候不是點(diǎn)擊事件 private ImageBarnnerLister lister; private ImageBarnnerViewGroupLisnner barnnerViewGroupLisnner; public ImageBarnnerLister getLister() { return lister; } public void setLister(ImageBarnnerLister lister) { this.lister = lister; } public ImageBarnnerViewGroupLisnner getBarnnerViewGroupLisnner() { return barnnerViewGroupLisnner; } public void setBarnnerViewGroupLisnner(ImageBarnnerViewGroupLisnner barnnerViewGroupLisnner) { this.barnnerViewGroupLisnner = barnnerViewGroupLisnner; } public interface ImageBarnnerLister { void chickImageIndex(int pos);//pos代表的是我們當(dāng)前的圖片的具體索引值 } /** * 實(shí)現(xiàn)輪播圖底部圓點(diǎn)切換效果 * 自定義一個(gè)繼承自FragmenLayou布局,利用FragmeLayout布局特性 */ //自動(dòng)輪播 private boolean isAuto = true;//默認(rèn)情況下開(kāi)啟輪播 private Timer timer = new Timer(); private TimerTask timerTask; @SuppressLint("HandlerLeak") private android.os.Handler autohandler = new android.os.Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 0://我們需要圖片的自動(dòng)輪播 if (++index >= children) {//如果是最后一張圖片,從第一張開(kāi)始 index = 0; } scrollTo(childwidth * index,0); barnnerViewGroupLisnner.selectImage(index); break; default: } } }; private void startAuto() { isAuto = true; } private void stopAuto() { isAuto = false; } /** * 采用Timer,TimerTask,Handler三者結(jié)合的方式來(lái)實(shí)現(xiàn)自動(dòng)輪播 */ public ImageBarnnerViewGroup(Context context) { super(context); initObj(); } public ImageBarnnerViewGroup(Context context, AttributeSet attrs) { super(context, attrs); initObj(); } public ImageBarnnerViewGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); initObj(); } private void initObj() { scroller = new Scroller(getContext()); timerTask = new TimerTask() { @Override public void run() { if (isAuto) {//開(kāi)啟輪播圖 autohandler.sendEmptyMessage(0); } } }; timer.schedule(timerTask,100,3000); } @Override public void computeScroll() { super.computeScroll(); if (scroller.computeScrollOffset()) { scrollTo(scroller.getCurrX(),0); invalidate();//重繪 } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //1.求出子視圖的個(gè)數(shù) children = getChildCount();//我們可以知道自試圖的個(gè)數(shù) if (0 == children) { setMeasuredDimension(0,0); } else { measureChildren(widthMeasureSpec, heightMeasureSpec); //此時(shí)我們以第一個(gè)子視圖=為基準(zhǔn),也就是說(shuō)我們的View Group View view = getChildAt(0); childwidth = view.getMeasuredWidth(); childheight = view.getMeasuredHeight(); int width = view.getMeasuredWidth() * children; setMeasuredDimension(width,childheight); } //2.測(cè)量子視圖的寬度和高度 //3.根據(jù)子視圖的狂賭和高度,求出該ViewGroup的寬度和高度 } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev); } /** * 用兩種方式來(lái)實(shí)現(xiàn)輪播圖的手動(dòng)輪播 * 1,利用scrollTo,scrollBy 完成輪播圖的手動(dòng)輪播 * 1,利用Scroller 對(duì)象完成輪播圖的手動(dòng)效果 * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN://表示用戶按下的一瞬間 stopAuto();//停止圖片輪播 if (!scroller.isFinished()) { scroller.abortAnimation(); } isClick = true; x=(int)event.getX(); break; case MotionEvent.ACTION_MOVE://表示用戶按下之后在屏幕上移動(dòng)的過(guò)程 int moveX = (int) event.getX(); int distance = moveX - x; scrollBy(-distance,0); x = moveX; isClick = false; break; case MotionEvent.ACTION_UP://標(biāo)識(shí)的是用戶抬起的一瞬間 int scrollX = getScrollX(); index = (scrollX + childwidth / 2) / childwidth; if (index < 0) { //已經(jīng)滑動(dòng)到了最左邊 index = 0; } else if (index > children - 1) {//說(shuō)明已經(jīng)滑動(dòng)到了最右邊 index = children - 1; } if (isClick) { //點(diǎn)擊事件 lister.chickImageIndex(index); } else { int dx = index * childwidth - scrollX; scroller.startScroll(scrollX,0,dx,0); postInvalidate(); barnnerViewGroupLisnner.selectImage(index); } startAuto();//開(kāi)啟圖片輪播 break; default: } return true; //返回true的目的是告訴該View Group容器的父View 我們已經(jīng)處理好了該事件 } @Override protected void onLayout(boolean b, int i, int i1, int i2, int i3) { if (b) { int lefrMargin = 0; for (int j = 0; j < children; j++) { View view = getChildAt(j); view.layout(lefrMargin,0,lefrMargin + childwidth,childheight); lefrMargin += childwidth; } } } public interface ImageBarnnerViewGroupLisnner{ void selectImage(int index); } }
2)新建ImageBannerFramLayout類(lèi)繼承自FrameLayout實(shí)現(xiàn)兩個(gè)接口
public class ImageBannerFramLayout extends FrameLayout implements ImageBarnnerViewGroup.ImageBarnnerViewGroupLisnner,ImageBarnnerViewGroup.ImageBarnnerLister{ private ImageBarnnerViewGroup imageBarnnerViewGroup; private LinearLayout linearLayout; private FramLayoutLisenner lisenner; public FramLayoutLisenner getLisenner() { return lisenner; } public void setLisenner(FramLayoutLisenner lisenner) { this.lisenner = lisenner; } public ImageBannerFramLayout(@NonNull Context context) { super(context); initImageBarnnerViewGroup(); initDotLinearlayout(); } public ImageBannerFramLayout(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); initImageBarnnerViewGroup(); initDotLinearlayout(); } public ImageBannerFramLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initImageBarnnerViewGroup(); initDotLinearlayout(); } public void addBitmaps(List<Bitmap> list) { for (int i = 0; i < list.size(); i++) { Bitmap bitmap = list.get(i); addBitmapToImageBarnnerViewGroup(bitmap); addDotToLinearlayout(); } } private void addDotToLinearlayout() { ImageView iv = new ImageView(getContext()); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams (LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.MATCH_PARENT); layoutParams.setMargins(5,5,5,5); iv.setLayoutParams(layoutParams); iv.setImageResource(R.drawable.dot_normal); linearLayout.addView(iv); } private void addBitmapToImageBarnnerViewGroup(Bitmap bitmap) { ImageView imageView = new ImageView(getContext()); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT)); imageView.setImageBitmap(bitmap); imageBarnnerViewGroup.addView(imageView); } //初始化自定義圖片輪播功能核心類(lèi) private void initImageBarnnerViewGroup() { imageBarnnerViewGroup = new ImageBarnnerViewGroup(getContext()); FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams (FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); imageBarnnerViewGroup.setLayoutParams(layoutParams); imageBarnnerViewGroup.setBarnnerViewGroupLisnner(this);//將linsnner傳遞給Framlayout imageBarnnerViewGroup.setLister(this); addView(imageBarnnerViewGroup); } //初始化底部圓點(diǎn)布局 private void initDotLinearlayout() { linearLayout = new LinearLayout(getContext()); FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams (FrameLayout.LayoutParams.MATCH_PARENT, 40); linearLayout.setLayoutParams(layoutParams); linearLayout.setOrientation(LinearLayout.HORIZONTAL); linearLayout.setGravity(Gravity.CENTER); linearLayout.setBackgroundColor(Color.RED); addView(linearLayout); FrameLayout.LayoutParams layoutParams1 = (LayoutParams) linearLayout.getLayoutParams(); layoutParams.gravity = Gravity.BOTTOM; linearLayout.setLayoutParams(layoutParams1); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { linearLayout.setAlpha(0.5f); } else { linearLayout.getBackground().setAlpha(100); } } @Override public void selectImage(int index) { int count = linearLayout.getChildCount(); for (int i = 0;i < count; i++) { ImageView iv = (ImageView) linearLayout.getChildAt(i); if (i == index) { iv.setImageResource(R.drawable.dot_select); } else { iv.setImageResource(R.drawable.dot_normal); } } } @Override public void chickImageIndex(int pos) { lisenner.chickImageIndex(pos); } public interface FramLayoutLisenner{ void chickImageIndex(int pos); } }
3、程序布局頁(yè)面activity_main
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="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=".MainActivity"> <com.example.tony.imagegroup.view.ImageBannerFramLayout android:id="@+id/image_group" android:layout_width="match_parent" android:layout_height="200dp"> </com.example.tony.imagegroup.view.ImageBannerFramLayout> </RelativeLayout>
4、新建兩個(gè)drawable資源文件dot_normal.xml和dot_select.xml,實(shí)現(xiàn)輪播圖底部小圓點(diǎn)
不同的是前者顏色為白色后者為黑色
<?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"/> <size android:height="10dp" android:width="10dp"/> </shape>
三、運(yùn)行結(jié)果
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android使用RollViewPager實(shí)現(xiàn)輪播圖
- Android實(shí)現(xiàn)背景圖片輪播
- Android輪播圖點(diǎn)擊圖片放大效果的實(shí)現(xiàn)方法
- Android實(shí)現(xiàn)圖片輪播列表
- Android仿京東快報(bào)無(wú)限輪播效果
- 詳解android 視頻圖片混合輪播實(shí)現(xiàn)
- Android開(kāi)發(fā)實(shí)現(xiàn)的自動(dòng)換圖片、輪播圖效果示例
- Android實(shí)現(xiàn)輪播圖片展示效果
- android常見(jiàn)手動(dòng)和自動(dòng)輪播圖效果
- Android基于AdapterViewFlipper實(shí)現(xiàn)的圖片/文字輪播動(dòng)畫(huà)控件
相關(guān)文章
Android中使用tcpdump、wireshark進(jìn)行抓包并分析技術(shù)介紹
這篇文章主要介紹了Android中使用tcpdump、wireshark進(jìn)行抓包并分析技術(shù)介紹,本文講解了下載并安裝tcpdump、pc上安裝wireshark等內(nèi)容,需要的朋友可以參考下2015-04-04Android UI設(shè)計(jì)系列之HTML標(biāo)簽實(shí)現(xiàn)TextView設(shè)置中文字體加粗效果(6)
這篇文章主要介紹了Android UI設(shè)計(jì)系列之使用HTML標(biāo)簽,實(shí)現(xiàn)在TextView中對(duì)中文字體加粗的效果,具有一定的實(shí)用性和參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06Android 安全退出應(yīng)用程序的方法總結(jié)
這篇文章主要介紹了Android 安全退出應(yīng)用程序的方法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-03-03Android ListView實(shí)現(xiàn)無(wú)限循環(huán)滾動(dòng)
這篇文章主要為大家詳細(xì)介紹了Android ListView實(shí)現(xiàn)無(wú)限循環(huán)滾動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06Android studio導(dǎo)入項(xiàng)目的方法詳解(簡(jiǎn)單快速)
最近開(kāi)課移動(dòng)互聯(lián)網(wǎng)應(yīng)用開(kāi)發(fā),實(shí)驗(yàn)課老師發(fā)了代碼讓我們導(dǎo)入,在網(wǎng)上找了各種方法,發(fā)現(xiàn)不是每一個(gè)項(xiàng)目都適合,有些能夠成功,有些還是有錯(cuò),頭大的很。后面發(fā)現(xiàn)一個(gè)比較簡(jiǎn)單的方法,沒(méi)翻過(guò)車(chē),新手可以試試2017-06-06簡(jiǎn)單實(shí)現(xiàn)Android刮刮卡效果
這篇文章主要教大家如何簡(jiǎn)單的實(shí)現(xiàn)Android刮刮卡效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07