您好,登錄后才能下訂單哦!
如何在Android應用中實現一個無限循環輪播?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
一、自定義控件屬性
新建自定義控件SliderLayout繼承于RelativeLayout,首先要考慮的就是自定義的控件需要擴展那些屬性,把這些屬性列出來。在這里是要實現類似于京東淘寶的無限輪播廣告欄,那么首先想到的就是輪播的時長、輪播指示器的樣式等等。我在這里列舉了一些并且結合到了代碼中。
1、擴展屬性
(1)是否開啟自動輪播的功能。
(2)指示器的圖形樣式,一般為圓形和方形兩種。
(3)指示器的位置,一般為底部或者頂部。
(4)指示器被選中和不被選中時的樣式:顏色、高度、寬度、間隔等。
(5)輪播的時長。
(6)加載的如果是網絡圖片的話,需要默認圖片和錯誤圖片等。
2、在attrs.xml文件中添加這些擴展的屬性。
<declare-styleable name="SliderLayout"> <attr name="sl_is_auto_play" format="boolean"/> <attr name="sl_indicator_shape" format="enum"> <enum name="oval" value="0" /> <enum name="rect" value="1" /> </attr> <attr name="sl_indicator_position" format="enum"> <enum name="centerBottom" value="0" /> <enum name="rightBottom" value="1" /> <enum name="leftBottom" value="2" /> <enum name="centerTop" value="3" /> <enum name="rightTop" value="4" /> <enum name="leftTop" value="5" /> </attr> <attr name="sl_selected_indicator_color" format="color|reference" /> <attr name="sl_unselected_indicator_color" format="color|reference" /> <attr name="sl_selected_indicator_height" format="dimension|reference" /> <attr name="sl_selected_indicator_width" format="dimension|reference" /> <attr name="sl_unselected_indicator_height" format="dimension|reference" /> <attr name="sl_unselected_indicator_width" format="dimension|reference" /> <attr name="sl_indicator_space" format="dimension|reference" /> <attr name="sl_indicator_margin" format="dimension|reference" /> <attr name="sl_auto_play_duration" format="integer|reference" /> <attr name="sl_default_image" format="reference"/> <attr name="sl_error_image" format="reference"/> </declare-styleable>
二、自定義輪播控件的初始化
1、獲取到擴展屬性的值
在自定義SliderLayout中獲取到擴展的樣式,然后根據樣式獲取相應的屬性值,最好是要先設置好默認值。
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SliderLayout, defStyleAttr, 0); if (array != null) { isAutoPlay = array.getBoolean(R.styleable.SliderLayout_sl_is_auto_play, isAutoPlay); //get the shape of indicator int intShape = array.getInt(R.styleable.SliderLayout_sl_indicator_shape, indicatorShape.ordinal()); for (IndicatorShape shape : IndicatorShape.values()) { if (shape.ordinal() == intShape) { indicatorShape = shape; break; } } //get the position of indicator int intPosition = array.getInt(R.styleable.SliderLayout_sl_indicator_position, IndicatorPosition.centerBottom.ordinal()); for (IndicatorPosition position : IndicatorPosition.values()) { if (position.ordinal() == intPosition) { indicatorPosition = position; break; } } unSelectedIndicatorColor = array.getColor(R.styleable.SliderLayout_sl_unselected_indicator_color, unSelectedIndicatorColor); selectedIndicatorColor = array.getColor(R.styleable.SliderLayout_sl_selected_indicator_color, selectedIndicatorColor); unSelectedIndicatorHeight = array.getDimension(R.styleable.SliderLayout_sl_unselected_indicator_height, unSelectedIndicatorHeight); unSelectedIndicatorWidth = array.getDimension(R.styleable.SliderLayout_sl_unselected_indicator_width, unSelectedIndicatorWidth); selectedIndicatorHeight = array.getDimension(R.styleable.SliderLayout_sl_selected_indicator_height, selectedIndicatorHeight); selectedIndicatorWidth = array.getDimension(R.styleable.SliderLayout_sl_selected_indicator_width, selectedIndicatorWidth); indicatorSpace = array.getDimension(R.styleable.SliderLayout_sl_indicator_space, indicatorSpace); indicatorMargin = array.getDimension(R.styleable.SliderLayout_sl_indicator_margin, indicatorMargin); autoPlayDuration = array.getInt(R.styleable.SliderLayout_sl_auto_play_duration, autoPlayDuration); defaultImage = array.getResourceId(R.styleable.SliderLayout_sl_default_image, defaultImage); errorImage = array.getResourceId(R.styleable.SliderLayout_sl_error_image, errorImage); }
2、初始化控件
根據這里所需要實現的功能,首先需要一個圖像切換器ImageSwticher,還要指示器,這里就用ImageView了。
switcherImage = new ImageSwitcher(context); switcherImage.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); for (int i = 0; i < itemCount; i++) { ImageView indicator = new ImageView(context); indicator.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); indicator.setPadding((int) (indicatorSpace), (int) (indicatorSpace), (int) (indicatorSpace), (int) (indicatorSpace)); indicator.setImageDrawable(unSelectedDrawable); indicatorContainer.addView(indicator); final int finalI = i; indicator.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { stopAutoPlay(); switchIndicator(finalI); pictureIndex = finalI; handler.sendEmptyMessageDelayed(START_AUTO_PLAY,autoPlayDuration); } }); }
3、初始化選中第一張圖片
專門寫一個針對指示器切換的函數,然后在初始化的時候直接調用,選中第一個指示器,就是選中第一張圖片了。
函數代碼如下。
private void switchIndicator(int index) { for (int i = 0; i < indicatorContainer.getChildCount(); i++) { ((ImageView) indicatorContainer.getChildAt(i)).setImageDrawable(i == index ? selectedDrawable : unSelectedDrawable); } loadImage(index); }
調用選中第一張圖。
switchIndicator(0);
三、圖片的加載
1、網路圖片的加載
在這里使用Picasso框架來加載圖片,根據url來加載顯示圖片,同時也要顯示圖片的加載進度,這里就需要一個Dialog提示框了,Dialog的樣式最好是可以自定義的。
private void loadNetImage(int pictureIndex) { if (list != null && list.size() != 0) { Picasso.with(context) .load((String) list.get(pictureIndex)) .placeholder(defaultImage) .error(errorImage) .tag(context) .into(mTarget); } }
下面是圖片的加載提示過程。
private Target mTarget = new Target() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { dismissDialog(); ((ImageView) switcherImage.getCurrentView()).setScaleType(ImageView.ScaleType.CENTER_CROP); ((ImageView) switcherImage.getCurrentView()).setLayoutParams(new ImageSwitcher.LayoutParams(ImageSwitcher.LayoutParams.MATCH_PARENT, ImageSwitcher.LayoutParams.MATCH_PARENT)); ((ImageView) switcherImage.getCurrentView()).setImageBitmap(bitmap); } @Override public void onBitmapFailed(Drawable errorDrawable) { dismissDialog(); ((ImageView) switcherImage.getCurrentView()).setImageDrawable(errorDrawable); } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { showDialog(); } };
2、資源圖片的加載
只能加載網絡圖片是不夠的呢,還需要可以加載資源圖片,加載資源圖片的辦法就更加簡單了。
private void loadFileImage(int pictureIndex) { if (list != null && list.size() != 0) { switcherImage.setImageResource((Integer) list.get(pictureIndex)); } }
四、設置圖片切換的動畫
設置圖片從左往右以及從右往左的動畫效果,并且當滑動到該圖片時,指示器也要一起變化,這里就簡單說下從左往右的動畫了。
private void SliderLeftToRight() { // get current index pictureIndex = pictureIndex == 0 ? itemCount - 1 : pictureIndex - 1; // set Animation switcherImage.setInAnimation(AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left)); switcherImage.setOutAnimation(AnimationUtils.loadAnimation(context, android.R.anim.slide_out_right)); switchIndicator(pictureIndex); }
從右往左滑動時的代碼和這個是一樣的,就是換了下方向,需要自己定義下。
五、定義圖片的點擊事件
1、定義interface來監聽事件
在自定義控件中自定義一個interface來監聽事件就可以了。
public interface IOnClickListener { void onItemClick(View view, int position); }
2、在onTouch中調用點擊事件。
這里需要說明下為什么在onTouch中處理,因為onTouch是觸摸事件,在滑動的過程中,用戶是觸摸了屏幕的,所以根據用戶觸摸屏幕時點擊下的X坐標和點擊起來時的X坐標的對比來判斷是左滑還是右滑了,這樣的話,就會和onClick事件相沖了,所以就想到了一個辦法,那就是在范圍內的話,就默認為點擊事件,范圍外就是滑動事件了。
if (0==(Math.abs(touchUpX - touchDownX))||(Math.abs(touchUpX - touchDownX))<50) { if (listener != null) { stopAutoPlay(); listener.onItemClick(view, pictureIndex); handler.sendEmptyMessageDelayed(START_AUTO_PLAY,autoPlayDuration); } }
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。