自定義控件筆記1

自定義控件:用系統(tǒng)自帶控件重新組合或者自定義類繼承View或者自定義類繼承ViewGroup,實(shí)現(xiàn)特定的UI效果。

重點(diǎn):
a.View和ViewGroup的區(qū)別
b.Android中事件的傳遞
c.View的原理

事例一:優(yōu)酷菜單


youku1.png

由于這里是以中心為旋轉(zhuǎn)點(diǎn)片效,所以pivotXValue就是view.getWidth()/2红伦,pivotYValue就是view.getHeight()

class Tools {

    /**
     * 隱藏
     * @param view
     */
    public static void hideView(View view) {

       hideView(view,0);
    }

    /**
     * 顯示
     * @param view
     */
    public static void showView(View view) {

       showView(view,0);
    }

    /**
     * 有延遲時(shí)間的隱藏
     * @param view
     * @param startOffset
     */
    public static void hideView(View view, int startOffset) {
        /**
         * fromDegrees 從哪個(gè)角度 toDegrees 到哪個(gè)角度  水平線為x軸
         * pivotXValue  pivotYValue 是相對(duì)于x y坐標(biāo)的位置 控件的左上角的坐標(biāo)為(0,0) 右下角為(1,1)
         * 由于這里是以中心為旋轉(zhuǎn)點(diǎn),所以pivotXValue就是view.getWidth()/2淀衣,pivotYValue就是view.getHeight()
         *
         */
        RotateAnimation animation = new RotateAnimation(0,180,view.getWidth()/2,view.getHeight());
        //設(shè)置動(dòng)畫的速度
        animation.setDuration(500);
        //設(shè)置動(dòng)畫結(jié)束后停留在改變后的位置
        animation.setFillAfter(true);
        //設(shè)置延遲動(dòng)畫時(shí)間
        animation.setStartOffset(startOffset);
        view.startAnimation(animation);
    }

    /**
     * 有延遲時(shí)間的顯示
     * @param view
     * @param startOffset
     */
    public static void showView(View view, int startOffset) {

        RotateAnimation animation = new RotateAnimation(180,360,view.getWidth()/2,view.getHeight());
        //設(shè)置動(dòng)畫的速度
        animation.setDuration(500);
        //設(shè)置動(dòng)畫結(jié)束后停留在改變后的位置
        animation.setFillAfter(true);
        //設(shè)置延遲動(dòng)畫時(shí)間
        animation.setStartOffset(startOffset);
        view.startAnimation(animation);
    }
}

問題:如果此時(shí)隱藏掉所有的菜單昙读,點(diǎn)擊一級(jí)菜單會(huì)出現(xiàn)bug,因?yàn)榧词惯@個(gè)視圖已經(jīng)旋轉(zhuǎn)過去膨桥,但是它的屬性還在蛮浑,所以可以點(diǎn)擊。


youku2.png

如果直接修改成以下代碼會(huì)無效

 /**
     * 有延遲時(shí)間的隱藏
     * @param view
     * @param startOffset
     */
    public static void hideView(View view, int startOffset) {
        /**
         * fromDegrees 從哪個(gè)角度 toDegrees 到哪個(gè)角度  水平線為x軸
         * pivotXValue  pivotYValue 是相對(duì)于x y坐標(biāo)的位置 控件的左上角的坐標(biāo)為(0,0) 右下角為(1,1)
         * 由于這里是以中心為旋轉(zhuǎn)點(diǎn)只嚣,所以pivotXValue就是view.getWidth()/2沮稚,pivotYValue就是view.getHeight()
         *
         */
        RotateAnimation animation = new RotateAnimation(0,180,view.getWidth()/2,view.getHeight());
        //設(shè)置動(dòng)畫的速度
        animation.setDuration(500);
        //設(shè)置動(dòng)畫結(jié)束后停留在改變后的位置
        animation.setFillAfter(true);
        //設(shè)置延遲動(dòng)畫時(shí)間
        animation.setStartOffset(startOffset);
        view.startAnimation(animation);
        view.setEnabled(false);
    }

    /**
     * 有延遲時(shí)間的顯示
     * @param view
     * @param startOffset
     */
    public static void showView(View view, int startOffset) {

        RotateAnimation animation = new RotateAnimation(180,360,view.getWidth()/2,view.getHeight());
        //設(shè)置動(dòng)畫的速度
        animation.setDuration(500);
        //設(shè)置動(dòng)畫結(jié)束后停留在改變后的位置
        animation.setFillAfter(true);
        //設(shè)置延遲動(dòng)畫時(shí)間
        animation.setStartOffset(startOffset);
        view.startAnimation(animation);
        view.setEnabled(true);
    }

因?yàn)閭鬟M(jìn)來的view是RelativeLayout,而RelativeLayout是繼承ViewGroup的册舞,即使其設(shè)置了Enabled蕴掏,也只是對(duì)他自身有效,但是他里面的子view依然可以被點(diǎn)擊调鲸。

解決辦法:
1.將View改為ViewGroup盛杰,循環(huán)出其子View,并且對(duì)每個(gè)子View設(shè)置Enabled藐石。
2.通過屬性動(dòng)畫解決

方法1:

/**
     * 有延遲時(shí)間的隱藏
     * @param view
     * @param startOffset
     */
    public static void hideView(ViewGroup view, int startOffset) {
        /**
         * fromDegrees 從哪個(gè)角度 toDegrees 到哪個(gè)角度  水平線為x軸
         * pivotXValue  pivotYValue 是相對(duì)于x y坐標(biāo)的位置 控件的左上角的坐標(biāo)為(0,0) 右下角為(1,1)
         * 由于這里是以中心為旋轉(zhuǎn)點(diǎn)即供,所以pivotXValue就是view.getWidth()/2,pivotYValue就是view.getHeight()
         *
         */
        RotateAnimation animation = new RotateAnimation(0,180,view.getWidth()/2,view.getHeight());
        //設(shè)置動(dòng)畫的速度
        animation.setDuration(500);
        //設(shè)置動(dòng)畫結(jié)束后停留在改變后的位置
        animation.setFillAfter(true);
        //設(shè)置延遲動(dòng)畫時(shí)間
        animation.setStartOffset(startOffset);
        view.startAnimation(animation);
        for (int i = 0;i<view.getChildCount();i++){
            View child = view.getChildAt(i);
            child.setEnabled(false);
        }

    }

    /**
     * 有延遲時(shí)間的顯示
     * @param view
     * @param startOffset
     */
    public static void showView(ViewGroup view, int startOffset) {

        RotateAnimation animation = new RotateAnimation(180,360,view.getWidth()/2,view.getHeight());
        //設(shè)置動(dòng)畫的速度
        animation.setDuration(500);
        //設(shè)置動(dòng)畫結(jié)束后停留在改變后的位置
        animation.setFillAfter(true);
        //設(shè)置延遲動(dòng)畫時(shí)間
        animation.setStartOffset(startOffset);
        view.startAnimation(animation);
        for (int i = 0;i<view.getChildCount();i++){
            View child = view.getChildAt(i);
            child.setEnabled(true);
        }

    }

android包含三種動(dòng)畫:View Animation(補(bǔ)間)贯钩、Drawable Animation(幀動(dòng)畫)募狂、property Animation(屬性動(dòng)畫)

View Animation:
基于View的漸變動(dòng)畫办素,只改變了View的繪制效果角雷,而實(shí)際屬性未變,比如動(dòng)畫移動(dòng)一個(gè)按鈕的位置性穿,但按鈕的實(shí)際點(diǎn)擊位置未變勺三。在代碼中定義動(dòng)畫,可以參考AnimationSet類和Animation子類需曾,而如使用Xml吗坚,可以在res/anim/文件夾中定義Xml。(事例一則是View Animation)

Drawable Animation:加載一系列的Drawable資源來創(chuàng)建動(dòng)畫呆万,這種傳統(tǒng)動(dòng)畫某種程度上就是創(chuàng)建不同圖片序列商源,順序播放。在代碼中定義使用AnimationDawable類谋减;XMl文件更簡單的組成動(dòng)畫幀牡彻,在res/drawable文件夾,使用<animation-list>采用<item>來定義不同的幀出爹。

property Animation:動(dòng)畫的對(duì)象除了是view對(duì)象庄吼,還可以是Object對(duì)象缎除,動(dòng)畫之后,Object對(duì)象的屬性值被實(shí)實(shí)在在的改變总寻。view屬性改變器罐,view能自動(dòng)調(diào)用invalidate來刷新。

方法2:

/**
     * 有延遲時(shí)間的隱藏
     * @param view
     * @param startOffset
     */
    public static void hideView(ViewGroup view, int startOffset) {


        //使用屬性動(dòng)畫
        //第一個(gè)參數(shù)是作用的對(duì)象渐行,第二個(gè)參數(shù)是要改變的屬性名轰坊,小寫
        //例子 view.setRotation();
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view,"rotation",0,180);
        //設(shè)置動(dòng)畫的速度
        objectAnimator.setDuration(500);
        //設(shè)置延遲時(shí)間
        objectAnimator.setStartDelay(startOffset);
        //設(shè)置旋轉(zhuǎn)中心
        view.setPivotX(view.getWidth()/2);
        view.setPivotY(view.getHeight());
        objectAnimator.start();

    }

    /**
     * 有延遲時(shí)間的顯示
     * @param view
     * @param startOffset
     */
    public static void showView(ViewGroup view, int startOffset) {


        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view,"rotation",180,360);
        //設(shè)置動(dòng)畫的速度
        objectAnimator.setDuration(500);
        //設(shè)置延遲時(shí)間
        objectAnimator.setStartDelay(startOffset);
        //設(shè)置旋轉(zhuǎn)中心
        view.setPivotX(view.getWidth()/2);
        view.setPivotY(view.getHeight());
        objectAnimator.start();

    }

更簡單的寫法:

/**
     * 有延遲時(shí)間的隱藏
     * @param view
     * @param startOffset
     */
    public static void hideView(ViewGroup view, int startOffset) {

        OtherFunction(view,startOffset);

    }

    /**
     * 有延遲時(shí)間的顯示
     * @param view
     * @param startOffset
     */
    public static void showView(ViewGroup view, int startOffset) {

        OtherFunction(view,startOffset);
    }

    private static void OtherFunction(ViewGroup view, int startOffset) {
        //另一種寫法
        view.setPivotX(view.getWidth()/2);
        view.setPivotY(view.getHeight());
        view.animate()
                .rotationBy(180)    //旋轉(zhuǎn)角度
                .setDuration(500)
                .setStartDelay(startOffset)
                .start();
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市祟印,隨后出現(xiàn)的幾起案子衰倦,更是在濱河造成了極大的恐慌,老刑警劉巖旁理,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件樊零,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡孽文,警方通過查閱死者的電腦和手機(jī)驻襟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芋哭,“玉大人沉衣,你說我怎么就攤上這事〖跷” “怎么了豌习?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拔疚。 經(jīng)常有香客問我肥隆,道長,這世上最難降的妖魔是什么稚失? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任栋艳,我火速辦了婚禮,結(jié)果婚禮上句各,老公的妹妹穿的比我還像新娘吸占。我一直安慰自己,他們只是感情好凿宾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布矾屯。 她就那樣靜靜地躺著,像睡著了一般初厚。 火紅的嫁衣襯著肌膚如雪件蚕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音骤坐,去河邊找鬼绪杏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛纽绍,可吹牛的內(nèi)容都是我干的蕾久。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拌夏,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼僧著!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起障簿,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤盹愚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后站故,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體皆怕,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年西篓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了愈腾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岂津,死狀恐怖虱黄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吮成,我是刑警寧澤橱乱,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站粱甫,受9級(jí)特大地震影響泳叠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜魔种,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一析二、第九天 我趴在偏房一處隱蔽的房頂上張望粉洼。 院中可真熱鬧节预,春花似錦、人聲如沸属韧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宵喂。三九已至糠赦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拙泽。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國打工淌山, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人顾瞻。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓泼疑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親荷荤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子退渗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,980評(píng)論 3 119
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,110評(píng)論 25 707
  • 本筆記的原文本鏈接 Property Animation Overview 屬性動(dòng)畫總覽 The property...
    Jaesoon閱讀 1,101評(píng)論 2 3
  • 一年又一年,時(shí)間飛速流逝古毛。轉(zhuǎn)身回望翻翩,世間萬物早已改變,不變的是……老友依然在身邊稻薇。雖然各自忙碌体斩,平常大多都是通訊聯(lián)...
    42b0cde219b9閱讀 262評(píng)論 0 0
  • 自古以來,鳳族和凰族生生世世相依相偎颖低。俗稱不可分離絮吵。 可是,天有不測(cè)風(fēng)云忱屑。只因凰族大臣想叛亂蹬敲,使得鳳族凰族人心惶惶...
    南城北戲閱讀 135評(píng)論 1 0