最近のアプリだとFacebookやGmail、Foursquareなど、フリックすると左側からペロッと出てくるメニュー、ありますね?アレの実装サンプルを探していたら、SupportLibraryにDrawerLayoutというのがありました。これを使えば実装できます。google的にはnavigation drawers
というそうです。
詳細はサンプルソースを診てもらうことにして、要するに
_DrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
_DrawerToggle = new ActionBarDrawerToggle(
this,
_DrawerLayout,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close
) {
@Override
public void onDrawerClosed(View drawerView) {
getActionBar().setTitle(_Title);
invalidateOptionsMenu();
}
@Override
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(_DrawerTitle);
invalidateOptionsMenu();
}
};
_DrawerLayout.setDrawerListener(_DrawerToggle);
こんな感じでフリックで表示するドロワーをDrawerLayout
とし、DrawerListenerにActionBarDrawerToggle
をセットすればActionBar上でうまいことしてくれるということらしいです。
でも、フリックで反応しない
但し、これで実装した場合、フリックでうまく出てきません。というか、正確に言うと左画面端から、画面外→内へのフリックでしか反応しません。これは最近のデカサイズ端末では厳しい。
そうすると画面上、どこでも左→右へのフリックでドロワーを表示したいのが心情ですね。GestureDetectorでフリック操作でもドロワーをオープンします。
private GestureDetector gd;
gd = new GestureDetector(this, new FlingHandler());
private class FlingHandler implements GestureDetector.OnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
float dx = Math.abs(velocityX);
float dy = Math.abs(velocityY);
if(dx > dy && dx > 200) {
if(e1.getX() - e2.getX() < 150) {
//show drawer
_DrawerLayout.openDrawer(_DrawerList);
return true;
}
}
return false;
}
}
フリックの実装だけです。但し、これだけだと画面上のフリックをonTouchEventでは拾えません。子のViewでEventを拾われてしまうのでdispatchTouchEvent
でフックします
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return gd.onTouchEvent(ev) || super.dispatchTouchEvent(ev);
}