12
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

NavigationDrawerとフリックでの表示

Posted at

最近のアプリだと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);
}
12
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?