側滑的方案有很多種,早期的開源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>
直接運行,效果圖如下
使用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);
}
}
至此便完成了側滑功能的實現,其效果圖如下
實現右側滑入,這個其實很簡單,將之前設置的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) {
//狀態改變時回調
}
});
}
}
效果圖如下