AndroidCustomViews

AndroidCustomViews

方便安卓開發(fā)者使用的自定義控件庫

加入Gradle依賴

implementation 'com.ayvytr:custom-views:0.2.0'
或者
compile 'com.ayvytr:custom-views:0.2.0'

自定義控件列表

  1. NumberPickerView 數(shù)字選擇控件,支持多行和多種選項(xiàng)的數(shù)字選擇控件
  2. QuickIndexView 通訊錄右側(cè)字母索引控件
  3. SuperEditText 可以一鍵清空茵汰,點(diǎn)擊圖標(biāo)顯示/隱藏密碼的EditText
  4. SingleTextView 單行,居中,文本超出一行尾部省略的TextView
  5. ClearableEditText <font color=red>0.2.0新加入</font> 一鍵清空文本的EditText推姻,直接繼承AppCompatEditText
  6. PasswordEditText <font color=red>0.2.0新加入</font> 點(diǎn)擊或觸摸顯示/隱藏密碼的EditText拧廊,直接繼承AppCompatEditText

截圖(請看GitHub,圖片老是上傳失斪那濉)

使用和說明

NumberPickerView

NumberPickerView是一款與android原生NumberPicker具有類似界面以及類似功能的View六水。
主要功能同樣是從多個(gè)候選項(xiàng)中通過上下滾動的方式選擇需要的選項(xiàng),但是與NumberPicker相比較辣卒,有幾個(gè)主要不同點(diǎn)掷贾,下面是兩者的不同之處。

原始控件特性-NumberPicker

  1. 顯示窗口只能顯示3個(gè)備選選項(xiàng)荣茫;
  2. 在fling時(shí)阻力較大想帅,無法快速滑動;
  3. 在選中與非選中狀態(tài)切換比較生硬啡莉;
  4. 批量改變選項(xiàng)中的內(nèi)容時(shí)港准,沒有動畫效果旨剥;
  5. 動態(tài)設(shè)置wrap模式時(shí)(setWrapSelectorWheel()方法),會有“暫時(shí)顯示不出部分選項(xiàng)”的問題叉趣;
  6. 選中位置沒有文字說明泞边;
  7. 代碼中不能控制選項(xiàng)滑動滾動到某一item;

自定義控件特性-NumberPickerView

  1. 顯示窗口可以顯示多個(gè)備選選項(xiàng)疗杉;
  2. fling時(shí)滑動速度較快阵谚,且可以設(shè)置摩擦力,如下代碼使得摩擦力為默認(rèn)狀態(tài)的2倍
    mNumberPickerView.setFriction(2 * ViewConfiguration.get(mContext).getScrollFriction());
  3. 在選中與非選中的狀態(tài)滑動時(shí)烟具,具有漸變的動畫效果梢什,包括文字放大縮小以及顏色的漸變;
  4. 在批量改變選項(xiàng)中的內(nèi)容時(shí)朝聋,可以選擇是否采用友好的滑動效果嗡午;
  5. 可以動態(tài)的設(shè)置是否wrap,即冀痕,是否循環(huán)滾動荔睹;
  6. 選中位置可以添加文字說明,可控制文字字體大小顏色等言蛇;
  7. 具有在代碼中動態(tài)的滑動到某一位置的功能僻他;
  8. 支持wrap_content,支持item的padding
  9. 提供多種屬性腊尚,優(yōu)化UI效果
  10. 在滑動過程中不響應(yīng)onValueChanged()
  11. 點(diǎn)擊上下單元格吨拗,可以自動滑動到對應(yīng)的點(diǎn)擊對象。
  12. 可通過屬性設(shè)置onValueChanged等回調(diào)接口的執(zhí)行線程婿斥。
  13. 兼容NumberPicker的重要方法和接口

兼容的方法有:

setOnValueChangedListener()
setOnScrollListener()
setDisplayedValues()/getDisplayedValues()
setWrapSelectorWheel()/getWrapSelectorWheel()
setMinValue()/getMinValue()
setMaxValue()/getMaxValue()
setValue()/getValue()

兼容的內(nèi)部接口有:
OnValueChangeListener
OnScrollListener

添加的接口有:
OnValueChangeListenerInScrolling//滑動過程中響應(yīng)value change

NumberPickerView使用方法

  1. 通過布局聲明NumberPickerView
    <cn.carbswang.android.numberpickerview.library.NumberPickerView
        android:id="@+id/picker"
        android:layout_width="wrap_content"
        android:layout_height="240dp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:background="#11333333"
        android:contentDescription="test_number_picker_view"
        app:npv_ItemPaddingHorizontal="5dp"
        app:npv_ItemPaddingVertical="5dp"
        app:npv_ShowCount="5"
        app:npv_RespondChangeOnDetached="false"
        app:npv_TextSizeNormal="16sp"
        app:npv_TextSizeSelected="20sp"
        app:npv_WrapSelectorWheel="true"/>

  1. Java代碼中使用:
    1)若設(shè)置的數(shù)據(jù)(String[] mDisplayedValues)不會再次改變劝篷,可以使用如下方式進(jìn)行設(shè)置:(與NumberPicker的設(shè)置方式一致)
        picker.setMinValue(minValue);
        picker.setMaxValue(maxValue);
        picker.setValue(value);

2)若設(shè)置的數(shù)據(jù)(String[] mDisplayedValues)會改變,可以使用如下組合方式進(jìn)行設(shè)置:(與NumberPicker的更改數(shù)據(jù)方式一致)

        int minValue = getMinValue();
        int oldMaxValue = getMaxValue();
        int oldSpan = oldMaxValue - minValue + 1;
        int newMaxValue = display.length - 1;
        int newSpan = newMaxValue - minValue + 1;
        if (newSpan > oldSpan) {
            setDisplayedValues(display);
            setMaxValue(newMaxValue);
        } else {
            setMaxValue(newMaxValue);
            setDisplayedValues(display);
        }

或者直接使用NumberPickerView提供的方法:

refreshByNewDisplayedValues(String[] display)

使用此方法時(shí)需要注意保證數(shù)據(jù)改變前后的minValue值不變民宿,以及設(shè)置的display不能夠?yàn)閚ull娇妓,且長度不能夠?yàn)?。
3)添加了滑動過程中響應(yīng)value change的函數(shù)

    picker.setOnValueChangeListenerInScrolling(...);

4.另外活鹰,NumberPickerView提供了平滑滾動的方法:

public void smoothScrollToValue(int fromValue, int toValue, boolean needRespond)

此方法與setValue(int)方法相同之處是可以動態(tài)設(shè)置當(dāng)前顯示的item峡蟋,不同之處在于此方法可以使NumberPickerView平滑的從滾動,即從fromValue值挑選最近路徑滾動到toValue华望,第三個(gè)參數(shù)needRespond用來標(biāo)識在滑動過程中是否響應(yīng)onValueChanged回調(diào)函數(shù)蕊蝗。因?yàn)槎鄠€(gè)NumberPickerView在聯(lián)動時(shí),很可能不同的NumberPickerView的停止時(shí)間不同赖舟,如果在此時(shí)響應(yīng)了onValueChanged回調(diào)蓬戚,就可能再次聯(lián)動,造成數(shù)據(jù)不準(zhǔn)確宾抓,將needRespond置為false子漩,可避免在滑動中響應(yīng)回調(diào)函數(shù)豫喧。

另外,在使用此方法或者間接調(diào)用此方法時(shí)幢泼,需要注意最好不要在onCreate(Bundle savedInstanceState)方法中調(diào)用紧显,因?yàn)閟croll動畫需要一定時(shí)間,如需確要在onCreate(Bundle savedInstanceState)中調(diào)用缕棵,請使用如下方式:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //代碼省略
        mNumberPickerView.post(new Runnable() {
            @Override
            public void run() {
                //調(diào)用smoothScrollToValue()等方法的代碼
            }
        });
    }

5.各項(xiàng)自定義屬性的說明

    <declare-styleable name="NumberPickerView">
        <attr name="npv_ShowCount" format="reference|integer" />//顯示的條目個(gè)數(shù)孵班,默認(rèn)3個(gè)
        <attr name="npv_ShowDivider" format="reference|boolean" />//是否顯示兩條divider,默認(rèn)顯示
        <attr name="npv_DividerColor" format="reference|color" />//兩條divider的顏色
        <attr name="npv_DividerMarginLeft" format="reference|dimension" />//divider距左側(cè)的距離
        <attr name="npv_DividerMarginRight" format="reference|dimension" />//divider距右側(cè)的距離
        <attr name="npv_DividerHeight" format="reference|dimension" />//divider的高度
        <attr name="npv_TextColorNormal" format="reference|color" />//未選中文字的顏色
        <attr name="npv_TextColorSelected" format="reference|color" />//選中文字的顏色
        <attr name="npv_TextColorHint" format="reference|color" />//中間偏右側(cè)說明文字的顏色
        <attr name="npv_TextSizeNormal" format="reference|dimension" />//未選中文字的大小
        <attr name="npv_TextSizeSelected" format="reference|dimension" />//選中文字的大小
        <attr name="npv_TextSizeHint" format="reference|dimension" />//說明文字的大小
        <attr name="npv_TextArray" format="reference" />//文字內(nèi)容招驴,stringarray類型
        <attr name="npv_MinValue" format="reference|integer" />//最小值篙程,同setMinValue()
        <attr name="npv_MaxValue" format="reference|integer" />//最大值,同setMaxValue()
        <attr name="npv_WrapSelectorWheel" format="reference|boolean" />//設(shè)置是否wrap别厘,同setWrapSelectorWheel
        <attr name="npv_HintText" format="reference|string" />//設(shè)置說明文字
        <attr name="npv_EmptyItemHint" format="reference|string" />//空行的顯示文字虱饿,默認(rèn)不顯示任何文字。只在WrapSelectorWheel==false是起作用
        <attr name="npv_MarginStartOfHint" format="reference|dimension" />//說明文字距離左側(cè)的距離触趴,"左側(cè)"是指文字array最寬item的右側(cè)
        <attr name="npv_MarginEndOfHint" format="reference|dimension" />//說明文字距離右側(cè)的距離
        <attr name="npv_ItemPaddingHorizontal" format="reference|dimension" />//item的水平padding氮发,用于wrap_content模式
        <attr name="npv_ItemPaddingVertical" format="reference|dimension" />//item的豎直padding,用于wrap_content模式
        <attr name="npv_RespondChangeOnDetached" format="reference|boolean" />//在detach時(shí)如果NumberPickerView正好滑動冗懦,設(shè)置
        //是否響應(yīng)onValueChange回調(diào)折柠,用在一個(gè)Dialog/PopupWindow被顯示多次,
        //且多次顯示時(shí)記錄上次滑動狀態(tài)的情況批狐。建議Dialog/PopupWindow在顯示時(shí)每次都指定初始值,且將此屬性置為false
        <attr name="npv_RespondChangeInMainThread" format="reference|boolean" />//指定`onValueChanged`響應(yīng)事件在什么線程中執(zhí)行前塔。
        //默認(rèn)為`true`嚣艇,即在主線程中執(zhí)行。如果設(shè)置為`false`則在子線程中執(zhí)行华弓。

        //以下屬性用于在wrap_content模式下食零,改變內(nèi)容array并且又不想讓控件"跳動",那么就可以設(shè)置所有改變的內(nèi)容的最大寬度
        <!--just used to measure maxWidth for wrap_content without hint,
            the string array will never be displayed.
            you can set this attr if you want to keep the wraped numberpickerview
            width unchanged when alter the content list-->
        <attr name="npv_AlternativeTextArrayWithMeasureHint" format="reference" />//可能達(dá)到的最大寬度寂屏,包括說明文字在內(nèi)贰谣,最大寬度只可能比此String的寬度更大
        <attr name="npv_AlternativeTextArrayWithoutMeasureHint" format="reference" />//可能達(dá)到的最大寬度,不包括說明文字在內(nèi)迁霎,最大寬度只可能比此String的寬度+說明文字+說明文字marginstart +說明文字marginend 更大
        <!--the max length of hint content-->
        <attr name="npv_AlternativeHint" format="reference|string" />//說明文字的最大寬度
    </declare-styleable>


QuickIndexView

在布局文件中加入QuickIndexView吱抚,并且加入自定義屬性,或者代碼中動態(tài)創(chuàng)建和設(shè)置自定義屬性即可

<com.ayvytr.customview.custom.index.QuickIndexView
    android:id="@+id/quickIndexView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:background="#eee"
    android:gravity="center"
    android:lineSpacingExtra="@dimen/_10dp"
    app:indexArray="@array/defaultQuickIndexViewLetters"/>

API文檔

clearIndexList()    清空字母索引.
getGravity()        獲取當(dāng)前 indexList Gravity
getIndexList()      獲取 indexList
getLineSpacing()    獲取字體上下間距值
getTextColor()      獲取字體顏色 textColor
getTextSize()       獲取字體大小
setGravity(int gravity)設(shè)置字母索引重心,只有 Gravity.TOP, Gravity.CENTER,Gravity.CENTER_VERTICAL有效考廉,也就是說只有靠上對齊或者靠中間對齊有效.
setIndexArray(String[] letterArray)     設(shè)置 indexList
setIndexList(List<String> indexList)    設(shè)置 indexList
setLineSpacing(int lineSpacing) 設(shè)置字體上下間距值
setOnLetterChangeListener(OnLetterChangeListener onLetterChangeListener)    設(shè)置字母索引變化監(jiān)聽器
setTextColor(int textColor) 設(shè)置字體顏色 textColor
setTextSize(int textSize)   設(shè)置字體大小秘豹,如果字體大小和原來的相同,或者字體大小小于0昌粤,設(shè)置不生效.

自定義屬性表

android:textColor   字體顏色
android:textSize    字體大小
android:background  背景
android:gravity     字母索引重心(實(shí)際效果只有靠頂部對齊或者居中有效)
android:lineSpacingExtra    字母索引文字上下間距
indexArray          字母索引數(shù)組

SuperEditText

API文檔

addTextChangedListener(TextWatcher watcher) 添加文本變化監(jiān)聽器
getText()   獲取當(dāng)前文本
setClearIcon(Drawable drawable) 設(shè)置清除按鈕圖標(biāo)
setClearIcon(int id)    設(shè)置清除按鈕圖標(biāo)
setFocusChangeListener(View.OnFocusChangeListener l)    設(shè)置焦點(diǎn)變化監(jiān)聽器
setHint(int id) 設(shè)置提示文本
setHint(String hint)    設(shè)置提示文本
setKeyListener(KeyListener keyListener) 設(shè)置按鍵監(jiān)聽器
setSelection(int index) 設(shè)置光標(biāo)位置
setText(int id) 設(shè)置文本
setText(String text)    設(shè)置文本

自定義屬性表

    <declare-styleable name="SuperEditText">
        <attr name="android:text"/>
        <attr name="android:hint"/>
        <attr name="android:inputType"/>
        <attr name="android:enabled"/>
        <attr name="android:background"/>
        <attr name="android:digits"/>
        <attr name="android:maxLength"/>
        <attr name="android:textColor"/>
        <attr name="android:textColorHint"/>
        <attr name="textPaddingLeft" format="dimension"/>
        <attr name="textPaddingRight" format="dimension"/>
        <attr name="textPaddingTop" format="dimension"/>
        <attr name="textPaddingBottom" format="dimension"/>
        <attr name="textPadding" format="dimension"/>
        <attr name="filterChinese" format="boolean"/>
        <attr name="switchShowPassword" format="boolean"/>
        <attr name="clearIcon" format="reference"/>
        <attr name="showClearIcon" format="boolean"/>
        <attr name="textBackground" format="reference"/>
    </declare-styleable>

ClearableEditText

API 文檔

getClearTextDrawable() 獲取清除Drawable
isShowClearDrawableNoFocus() 沒有焦點(diǎn)時(shí)是否顯示清除Drawable
setClearTextDrawable(Drawable clearTextDrawable) 設(shè)置清除Drawable
setClearTextDrawable(int drawableId) 設(shè)置清除Drawable
setShowClearDrawableNoFocus(boolean showClearDrawableNoFocus) 設(shè)置沒有焦點(diǎn)時(shí)是否顯示清除Drawable

自定義屬性表

<declare-styleable name="ClearableEditText">
    <attr name="showClearDrawableNoFocus" format="boolean"/>    是否在沒有焦點(diǎn)時(shí)顯示Drawable
</declare-styleable>

<h3 id="PasswordEditText">PasswordEditText</h3>

API 文檔

getHidePasswordDrawable() 獲取隱藏密碼Drawable
getShowPasswordDrawable() 獲取顯示密碼Drawable
isPasswordInputType(int inputType) 判斷輸入類型是不是密碼.
isShowDrawableNoFocus() 獲取是否在沒有焦點(diǎn)時(shí)顯示Drawable.
setClickMode(boolean clickMode) 設(shè)置點(diǎn)擊顯示/隱藏Drawable模式
setHidePasswordDrawable(Drawable hidePasswordDrawable) 設(shè)置隱藏密碼Drawable
setHidePasswordDrawable(int hidePasswordDrawableId) 設(shè)置隱藏密碼Drawable
setShowDrawableNoFocus(boolean showDrawableNoFocus) 設(shè)置是否在沒有焦點(diǎn)時(shí)顯示Drawable
setShowPasswordDrawable(android.graphics.drawable.Drawable showPasswordDrawable) 設(shè)置顯示密碼Drawable
setShowPasswordDrawable(int showPasswordDrawableId) 設(shè)置顯示密碼Drawable

自定義屬性表

    <declare-styleable name="PasswordEditText">
        <attr name="showPasswordDrawable" format="reference"/>  顯示密碼Drawable
        <attr name="hidePasswordDrawable" format="reference"/>  隱藏密碼Drawable
        <attr name="showDrawableWhenEmptyText" format="boolean"/> 當(dāng)文本為空時(shí)是否顯示Drawable
        <attr name="clickMode" format="boolean"/>   點(diǎn)擊模式既绕,true:點(diǎn)擊顯示啄刹,再次點(diǎn)擊隱藏密碼;false:按下顯示凄贩,抬起隱藏密碼
        <attr name="showDrawableNoFocus" format="boolean"/> 當(dāng)沒有焦點(diǎn)時(shí)是否顯示Drawable
    </declare-styleable>

ChangeLog

  • 0.1.0

    • NumberPickerView
    • QuickIndexView
    • SuperEditText
    • SingleTextView
  • 0.2.0

    • ClearableEditText
    • PasswordEditText

TODO

  1. SuperEditText自定義屬性過多誓军,需要優(yōu)化和重新設(shè)計(jì)
  2. 加入更多自定義View
  3. 自定義TabLayout
  4. 完善測試用例(歡迎熟練Espresso等測試的大神提意見或者推薦資料)

想要更多自定義控件請到Github提Issue或者Pull Request吧!

都看到這兒了疲扎,那就請點(diǎn)個(gè)Star吧昵时!非常感謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末评肆,一起剝皮案震驚了整個(gè)濱河市债查,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓜挽,老刑警劉巖盹廷,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異久橙,居然都是意外死亡俄占,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門淆衷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缸榄,“玉大人,你說我怎么就攤上這事祝拯∩醮” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵佳头,是天一觀的道長鹰贵。 經(jīng)常有香客問我,道長康嘉,這世上最難降的妖魔是什么碉输? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮亭珍,結(jié)果婚禮上敷钾,老公的妹妹穿的比我還像新娘。我一直安慰自己肄梨,他們只是感情好阻荒,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著众羡,像睡著了一般财松。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天辆毡,我揣著相機(jī)與錄音菜秦,去河邊找鬼。 笑死舶掖,一個(gè)胖子當(dāng)著我的面吹牛球昨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播眨攘,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼主慰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鲫售?” 一聲冷哼從身側(cè)響起共螺,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎情竹,沒想到半個(gè)月后藐不,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秦效,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年雏蛮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阱州。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挑秉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出苔货,到底是詐尸還是另有隱情犀概,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布夜惭,位于F島的核電站姻灶,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏滥嘴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一至耻、第九天 我趴在偏房一處隱蔽的房頂上張望若皱。 院中可真熱鬧,春花似錦尘颓、人聲如沸走触。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽互广。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惫皱,已是汗流浹背像樊。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旅敷,地道東北人生棍。 一個(gè)月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像媳谁,于是被迫代替她去往敵國和親涂滴。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345