高級UI-DrawerLayout側滑

側滑的方案有很多種,早期的開源SliddingMenu,以及後來的DrawerLayout以及NavigationView等都可實現側滑效果,這裏介紹的是DrawerLayout,下一節將介紹NavigationView

原理

DrawerLayout位於v4包,爲了做到最低限度的兼容,使得更低版本的Android也可以使用這個側滑效果
其就是一個自定義的容器,繼承自ViewGroup
在解析DrawerLayout佈局的時候,根據android:layout_gravity="start"標籤確定主佈局和側滑佈局
例如下面的佈局,就直接呈現出一個側滑菜單

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--內容部分-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/holo_green_light"
            android:text="內容部分" />
    </LinearLayout>
    <!--側滑菜單部分-->
    <LinearLayout
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_blue_light"
            android:text="item 1" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_orange_light"
            android:text="item 2" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_light"
            android:text="item 3" />
    </LinearLayout>
</android.support.v4.widget.DrawerLayout>

直接運行,效果圖如下
DrawerLayout側滑-實現

使用Toolbar

因爲要使用Toolbar,就要去掉其ActionBar,故直接修改style文件

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

更改佈局,使其符合MD標準

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/tool_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary" />

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!--內容部分-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/holo_green_light"
                android:text="內容部分" />
        </LinearLayout>
        <!--側滑菜單部分-->
        <LinearLayout
            android:layout_width="200dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:background="@color/colorPrimary"
            android:orientation="vertical"
            android:paddingTop="50dp">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_blue_light"
                android:text="item 1" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_orange_light"
                android:text="item 2" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/holo_red_light"
                android:text="item 3" />
        </LinearLayout>
    </android.support.v4.widget.DrawerLayout>
</LinearLayout>

在活動處設置Toolbar

public class MainActivity extends AppCompatActivity {

    private Toolbar toolbar;
    private DrawerLayout drawerLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = findViewById(R.id.tool_bar);
        //將ActionBar替換成Toolbar
        setSupportActionBar(toolbar);
        drawerLayout = findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this,
                drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close);
        //同步狀態
        drawerToggle.syncState();
        //給側滑控件設置監聽
        drawerLayout.setDrawerListener(drawerToggle);
    }
}

至此便完成了側滑功能的實現,其效果圖如下
DrawerLayout側滑-toolbar

實現右側滑入,這個其實很簡單,將之前設置的android:layout_gravity="start"更改爲android:layout_gravity="end"便實現右側滑入,同時還可以實現左右都可以滑入

實現類似QQ的效果

在監聽的狀態裏面設置即可

public class MainActivity extends AppCompatActivity {

    private Toolbar toolbar;
    private DrawerLayout drawerLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = findViewById(R.id.tool_bar);
        //將ActionBar替換成Toolbar
        setSupportActionBar(toolbar);
        drawerLayout = findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this,
                drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close);
        //同步狀態
        drawerToggle.syncState();
        //給側滑控件設置監聽
        //drawerLayout.setDrawerListener(drawerToggle);
        drawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerSlide(@NonNull View view, float slideOffset) {
                //滑動過程中回調,其中slideOffset的值爲 0~1
                View content = drawerLayout.getChildAt(0);
                View menu = view;
                float scale = 1 - slideOffset;//1~0
                float leftScale = (float) (1f - 0.3 * scale);//1~0.7
                //float rightScale = (float) (0.7f + 0.3 * scale);//0.7~1
                menu.setScaleX(leftScale);//1~0.7
                menu.setScaleY(leftScale);//1~0.7
                //content.setScaleX(rightScale);
                //content.setScaleY(rightScale);
                content.setTranslationX(menu.getMeasuredWidth() * (1 - scale));//0~width
            }

            @Override
            public void onDrawerOpened(@NonNull View view) {
                //打開時回調

            }

            @Override
            public void onDrawerClosed(@NonNull View view) {
                //關閉時回調

            }

            @Override
            public void onDrawerStateChanged(int i) {
                //狀態改變時回調

            }
        });
    }
}

效果圖如下
DrawerLayout側滑-仿QQ側滑

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章