自定義DrawerLayout(封裝DrawerLayout和material-menu)

引言

本文通過自定義布局將DrawerLayoutmaterial-menu封裝起來,使在項(xiàng)目中使用更方便。這里面用到了DrawerLayout菜秦、material-menu异袄、Toolbar,可以參考一些博文了解:

創(chuàng)建自定義view

由于向Toolbar或ListView這樣的部件將會在不同的Activity中多次出現(xiàn)冤灾,為了提高代碼的重用率前域,這里將它們單獨(dú)放到部件文件中,用到時用include引用(當(dāng)然也可以在BaseActivity中部署韵吨,然后讓用到的都繼承BaseActivity)匿垄。這里創(chuàng)建一個MaterialDrawerLayout布局組件來進(jìn)行封裝。

自定義Toolbar

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.v7.widget.Toolbar>

自定義FrameLayout

<?xml version="1.0" encoding="utf-8"?>
<!--DrawerLayout 下面的Fragment-->
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

自定義Listview

<?xml version="1.0" encoding="utf-8"?>
<!-- 側(cè)滑欄 -->
<ListView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/listView_drawer"
    android:layout_width="200dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="@color/white"
    android:choiceMode="singleChoice"
    android:divider="@color/item_normal_divider"
    android:dividerHeight="0.4px" />

為導(dǎo)航欄的Item創(chuàng)建布局

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:textColor="@color/drawer_item"
    android:background="?android:attr/activatedBackgroundIndicator"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"/>

創(chuàng)建MaterialDrawerLayout布局

通過創(chuàng)建布局類的方式來創(chuàng)建自定義布局归粉,這里創(chuàng)建一個MaterialDrawerLayout布局類椿疗,使他繼承DrawerLayout,這這個類中主要完成DrawerLayoutToolbar的綁定工作糠悼、對Toolbar的導(dǎo)航按鈕的監(jiān)聽(導(dǎo)航抽屜的打開個關(guān)閉事件監(jiān)聽)以及對導(dǎo)航抽屜中的Item的點(diǎn)擊事件的監(jiān)聽和處理届榄。

創(chuàng)建構(gòu)造函數(shù)

這里實(shí)現(xiàn)了三個構(gòu)造函數(shù),其主要作用就是將該布局的父Activity的上下文環(huán)境Context傳進(jìn)來倔喂。

public MaterialDrawerLayout(Context context) {
        this(context, null);
    }

    public MaterialDrawerLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MaterialDrawerLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
    }

初始化ListView

<string-array name="drawer_menu">
        <item>Menu 1</item>
        <item>Menu 2</item>
        <item>Menu 3</item>
        <item>Menu 4</item>
</string-array>

這里使用strings.xml中的string數(shù)組資源做數(shù)據(jù)铝条。

    /**
     * 初始化側(cè)欄標(biāo)簽,并且為ListView Item的點(diǎn)擊事件設(shè)置監(jiān)聽器
     */
    private void initDrawerList(){

        mDrawerListView = (ListView)findViewById(R.id.listView_drawer);
        // 從strings.xml中獲取數(shù)據(jù)
        String [] items = getResources().getStringArray(R.array.drawer_menu);

        // 生成適配器
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                mContext, R.layout.drawer_list_item, items);

        // 為ListView設(shè)置適配器
        mDrawerListView.setAdapter(adapter);

        // 為ListView Item設(shè)置監(jiān)聽器
        mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                selectItem(position);
            }
        });
    }

/**
     * 對導(dǎo)航抽屜列表?xiàng)l目點(diǎn)擊的處理
     * @param position
     */
    private void selectItem(int position){
        // add your code
        this.closeDrawer(mDrawerListView);
    }

這里順便為DrawerLayout的ListView的Item設(shè)置了監(jiān)聽器,以及點(diǎn)擊處理席噩。

綁定toolbar

/**
     * 將DrawerLayout和Toolbar綁定
     * @param toolbar
     */
    public void bindToolbar(Toolbar toolbar){

        // 設(shè)置toolbar左上角的導(dǎo)航按鈕圖標(biāo)
        mMaterialMenuDrawable = new MaterialMenuDrawable(
                mContext, Color.WHITE, MaterialMenuDrawable.Stroke.THIN);
        toolbar.setNavigationIcon(mMaterialMenuDrawable);

        // 初始化導(dǎo)航抽屜列表
        initDrawerList();

        // 為導(dǎo)航抽屜的打開關(guān)閉事件設(shè)置監(jiān)聽
        setListener(toolbar);
    }

為導(dǎo)航按鈕設(shè)置監(jiān)聽

/**
     * 為toolbar上的導(dǎo)航按鈕設(shè)置監(jiān)聽
     * @param toolbar
     */
    private void setListener(Toolbar toolbar){
        mDarwerToggle = new ActionBarDrawerToggle(
                (Activity) mContext, this, toolbar, R.string.drawer_open, R.string.drawer_close){
            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                isDrawerOpened = false;
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                isDrawerOpened = true;
            }

            public void onDrawerStateChanged(int newState) {
                if(newState == DrawerLayout.STATE_IDLE){
                    if (isDrawerOpened){
                        mMaterialMenuDrawable.setIconState(MaterialMenuDrawable.IconState.ARROW);
                    }else{
                        mMaterialMenuDrawable.setIconState(MaterialMenuDrawable.IconState.BURGER);
                    }
                }
            }

            public void onDrawerSlide(View drawerView, float slideOffset) {
                mMaterialMenuDrawable.setTransformationOffset(
                        MaterialMenuDrawable.AnimationState.BURGER_ARROW,
                        isDrawerOpened ? 2 - slideOffset : slideOffset);
            }
        };


        this.setDrawerListener(mDarwerToggle);
    }

將自定義MaterialDrawerLayout應(yīng)用到Activity中

首先隱藏項(xiàng)目的ActionBar班缰,以便引入toolbar,參考Toolbar的簡單使用悼枢。在activity_main.xml中引入toolbar以及materialdrawerlayout布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <!--Toolbar-->
    <include layout="@layout/toolbar" />

    <!--DrawerLayout-->
    <com.example.customedrawerlayout.MaterialDrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!--FragmentContent-->
        <include layout="@layout/framelayout" />
        <!--ListView-->
        <include layout="@layout/listview_drawer" />

    </com.example.customedrawerlayout.MaterialDrawerLayout>
</LinearLayout>

MainActivity中為toolbar做些設(shè)置埠忘,然后調(diào)用MaterialDrawerLayoutbindToolbar(),如下所示:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mDrawerLayout = (MaterialDrawerLayout)findViewById(R.id.drawer_layout);
        mToolbar = (Toolbar)findViewById(R.id.toolbar);

        // 將toolbar設(shè)為標(biāo)題欄
        setSupportActionBar(mToolbar);

        // 設(shè)置返回鍵可用
        getSupportActionBar().setHomeButtonEnabled(true);

        // 在Toolbar做最左邊加上導(dǎo)航按鈕
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);



        mDrawerLayout.bindToolbar(mToolbar);
    }

當(dāng)然最終要的一點(diǎn)是,不要忘了引入相應(yīng)的依賴莹妒。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末假丧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子动羽,更是在濱河造成了極大的恐慌包帚,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件运吓,死亡現(xiàn)場離奇詭異渴邦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)拘哨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門谋梭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人倦青,你說我怎么就攤上這事瓮床。” “怎么了产镐?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵隘庄,是天一觀的道長。 經(jīng)常有香客問我癣亚,道長丑掺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任述雾,我火速辦了婚禮街州,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘玻孟。我一直安慰自己唆缴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布黍翎。 她就那樣靜靜地躺著面徽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪玩敏。 梳的紋絲不亂的頭發(fā)上斗忌,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天质礼,我揣著相機(jī)與錄音旺聚,去河邊找鬼。 笑死眶蕉,一個胖子當(dāng)著我的面吹牛砰粹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼碱璃,長吁一口氣:“原來是場噩夢啊……” “哼弄痹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嵌器,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肛真,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后爽航,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚓让,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年讥珍,在試婚紗的時候發(fā)現(xiàn)自己被綠了历极。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡衷佃,死狀恐怖趟卸,靈堂內(nèi)的尸體忽然破棺而出啊鸭,到底是詐尸還是另有隱情凉夯,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布物喷,位于F島的核電站惯悠,受9級特大地震影響右蕊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吮螺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一饶囚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鸠补,春花似錦萝风、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泉蝌,卻和暖如春歇万,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背勋陪。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工贪磺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诅愚。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓寒锚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子刹前,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354

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