ListView實(shí)現(xiàn)頂部和底部?jī)?nèi)容指示器的方法
頂部指示器?
這是什么?
好吧,我承認(rèn)這是我自己想出來(lái)的詞,因?yàn)槲也恢浪惺裁磳W(xué)名,究竟是什么呢?看下這個(gè)圖就知道了。
這是我們的美工MM畫的,偶的神吶,這雖然很漂亮,不過(guò)也讓人頭疼,這個(gè)箭頭應(yīng)該在滾到頂部的時(shí)候消失,滾下來(lái)的時(shí)候(即有條目隱藏的時(shí)候)才顯示,類似的底部指示器也要有這樣的效果。事實(shí)上默認(rèn)的ListView和ScrollView都已經(jīng)有了類似的效果,在頂部或底部還有更多內(nèi)容時(shí),會(huì)有部分漸變虛化的效果,不過(guò)美工已經(jīng)設(shè)計(jì)了這樣的效果,那么我們就來(lái)做吧。
出于省事的目的,本教程中的例子會(huì)基于上一篇教程來(lái)修改,主要是添加1個(gè)繼承自ListView的類,以及修改布局定義文件。
ArrowListView控件的編寫
package net.learningandroid.lib.view; import net.learningandroid.lib.R; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.ListView; /** * 支持上下箭頭的ListView * * <a class="referer" target="_blank">@author</a> Mr. Lu */ public class ArrowListView extends ListView { private final float scale = getContext().getResources().getDisplayMetrics().density; private float topArrowPadding; private float bottomArrowPadding; private static float DEFAULT_TOP_PADDING_DP = 2.0f; private static float DEFAULT_BOTTOM_PADDING_DP = 2.0f; public ArrowListView(Context context, AttributeSet attrs) { super(context, attrs); String strTopArrowPadding = attrs.getAttributeValue(null, "topArrowPadding"); String strBottomArrowPadding = attrs.getAttributeValue(null, "bottomArrowPadding"); topArrowPadding = convertDisplayUom(strTopArrowPadding, DEFAULT_TOP_PADDING_DP); bottomArrowPadding = convertDisplayUom(strBottomArrowPadding, DEFAULT_BOTTOM_PADDING_DP); Log.v("ArrowListView", String.valueOf(topArrowPadding)); } /** * 單位轉(zhuǎn)換 */ private float convertDisplayUom(String sour, float defaultValue) { try { if (sour.toLowerCase().endsWith("px")) { return Float.parseFloat(sour.toLowerCase().replace("px", "")); } else if (sour.toLowerCase().endsWith("dp")) { return Integer.parseInt(sour.toLowerCase().replace("dp", "")) * scale + 0.5f; } } catch (Exception e) { } return (defaultValue * scale + 0.5f); } /** * onDraw方法,根據(jù)ListView滾動(dòng)位置繪出箭頭. */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); // 取得箭頭的圖片,此處是固定圖片,其實(shí)上可以做成配置方式 Bitmap topPic = ((BitmapDrawable) getResources().getDrawable( R.drawable.arrow_up)).getBitmap(); Bitmap bottomPic = ((BitmapDrawable) getResources().getDrawable( R.drawable.arrow_down)).getBitmap(); // 取得ListView的繪制區(qū)域大小 Rect r = new Rect(); this.getDrawingRect(r); // 計(jì)算箭頭的繪制位置 float top = r.top + topArrowPadding; float bottom = r.bottom - bottomArrowPadding - bottomPic.getHeight(); float left = r.left + (r.right - r.left - topPic.getWidth()) / 2; // 計(jì)算是否需要繪制 boolean drawTop = false; boolean drawBottom = false; if (this.getChildCount() > 0) { Rect rTop = new Rect(); this.getChildAt(0).getLocalVisibleRect(rTop); Rect rBottom = new Rect(); View lastChild = this.getChildAt(this.getChildCount() - 1); lastChild.getLocalVisibleRect(rBottom); drawTop = (this.getFirstVisiblePosition() > 0 || this .getFirstVisiblePosition() == 0 && rTop.top > 0); drawBottom = (this.getLastVisiblePosition() < this.getAdapter() .getCount() - 1 || this.getLastVisiblePosition() == this .getAdapter().getCount() - 1 && rBottom.bottom < lastChild.getHeight()); } // 繪出箭頭 if (drawTop) { canvas.drawBitmap(topPic, left, top, paint); } if (drawBottom) { canvas.drawBitmap(bottomPic, left, bottom, paint); } } }
就要點(diǎn)解釋一下上面這段代碼:
注意構(gòu)造方法,我們必須繼承public ArrowListView(Context context, AttributeSet attrs),這樣才可以讓這個(gè)類在xml定義文件中使用。
還要注意到,這里用了attrs.getAttributeValue來(lái)讀取XML定義文件中的屬性,其實(shí)有更好的方法,容我下次再講解,這里先偷個(gè)懶。
convertDisplayUom方法是用來(lái)將dp轉(zhuǎn)換成px的,可以看到由于我們用了getAttributeValue的方式,所以需要手動(dòng)將String轉(zhuǎn)成Float,很麻煩。
最后就是onDraw啦,計(jì)算出畫箭頭的位置,畫出來(lái)就行了。
接下來(lái)就是布局文件的編寫了
ArrowListView在XML文件中的使用
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:text="Arrow List View Sample" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <net.learningandroid.lib.view.ArrowListView android:id="@+id/arrowListView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingTop="15dp" android:paddingBottom="20dp" android:layout_margin="10dp" android:background="@drawable/float_panel" android:layout_weight="1" android:cacheColorHint="#FFEDEDED" android:divider="#00EDEDED" topArrowPadding="5dp" bottomArrowPadding="10dp" /> </LinearLayout>
這里需要注意的是自定義控件和其中的屬性的寫法,不再是ListView了,而是你自己編寫的控件類的類名。其它的內(nèi)容就是定義padding,background,以及取消了分隔線的顯示。
用這個(gè)布局文件替代上一篇教程中的布局文件,但Adapter的定義不變,因?yàn)锳rrowListView是繼承自ListView的,所以原先的Adapter的使用是一樣的。
最后我們來(lái)看下效果:
如何?只需要小心的調(diào)整ListView的Padding和ArrowPadding的值就可以控制箭頭出現(xiàn)的位置,如果需要控制更多,比如更換圖片,或者當(dāng)頂部無(wú)內(nèi)容時(shí)讓箭頭變暗、有內(nèi)容時(shí)變亮,都可以用同樣的方法。
并且,如果修改了Attribute的讀取方法之后,還可以通過(guò)xml文件來(lái)指定箭頭的圖片。
- Android實(shí)現(xiàn)仿網(wǎng)易新聞的頂部導(dǎo)航指示器
- Android應(yīng)用中仿今日頭條App制作ViewPager指示器
- Android應(yīng)用中使用ViewPager和ViewPager指示器來(lái)制作Tab標(biāo)簽
- Android中自定義控件之液位指示器
- 僅需幾行代碼實(shí)現(xiàn)方便易用的狀態(tài)欄指示器
- JQuery分屏指示器圖片輪換效果實(shí)例
- Android之IphoneTreeView帶組指示器的ExpandableListView效果
- Android之帶group指示器的ExpandableListView(自寫)
- jquery動(dòng)畫1.加載指示器
- Android自定義ViewPager指示器
相關(guān)文章
Android自定義ImageView實(shí)現(xiàn)在圖片上添加圖層效果
這篇文章給大家主要介紹了利用Android自定義ImageView如何實(shí)現(xiàn)在圖片上添加圖層的效果,實(shí)現(xiàn)的效果類似在圖片增加秒殺、搶光等標(biāo)簽圖片,對(duì)大家開發(fā)的時(shí)候具有一定的參考借鑒價(jià)值,有需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2016-11-11Android編程實(shí)現(xiàn)播放視頻時(shí)切換全屏并隱藏狀態(tài)欄的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)播放視頻時(shí)切換全屏并隱藏狀態(tài)欄的方法,結(jié)合實(shí)例形式分析了Android視頻播放事件響應(yīng)及相關(guān)屬性設(shè)置操作技巧,需要的朋友可以參考下2017-08-08Android三種方式實(shí)現(xiàn)ProgressBar自定義圓形進(jìn)度條
這篇文章主要介紹了Android三種方式實(shí)現(xiàn)ProgressBar自定義圓形進(jìn)度條的相關(guān)資料,需要的朋友可以參考下2016-03-03Android listview定位到上次顯示的位置的實(shí)現(xiàn)方法
這篇文章主要介紹了Android listview定位到上次顯示的位置的實(shí)現(xiàn)方法的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-08-08android避免彈出軟鍵盤遮蓋listview的簡(jiǎn)單方法
下面小編就為大家?guī)?lái)一篇android避免彈出軟鍵盤遮蓋listview的簡(jiǎn)單方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09Android開發(fā)中Intent傳遞對(duì)象的方法分析
這篇文章主要介紹了Android開發(fā)中Intent傳遞對(duì)象的方法,結(jié)合實(shí)例分析了Intent傳遞對(duì)象所涉及的具體方法、實(shí)現(xiàn)步驟與相關(guān)注意事項(xiàng),需要的朋友可以參考下2016-02-02