0
0

More than 3 years have passed since last update.

【Android】NavigationViewを使わないで、スライドするメニューをつくる

Posted at

スライドするメニューはDialogFragmentで作成しました。
Activityの上に、DialogFragmentが被さるイメージです。

アニメーションの作成

左から右へスライドするアニメーション(res/anim/slide_in.xml)

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="250"
        android:fromXDelta="-100%"
        android:toXDelta="0%" />

    <alpha
        android:duration="250"
        android:fromAlpha="0.8"
        android:toAlpha="1.0" />
</set>

右から左へスライドするアニメーション(res/anim/slide_out.xml)

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="250"
        android:fromXDelta="0%"
        android:toXDelta="-100%" />

    <alpha
        android:duration="250"
        android:fromAlpha="1.0"
        android:toAlpha="0.2" />
</set>

themes.xmlに、作成したアニメーションのstyleを定義

<resources xmlns:tools="http://schemas.android.com/tools">
    ....
    <style name="SlideInMenuAnimation">
        <item name="android:windowEnterAnimation">@anim/slide_in</item>
        <item name="android:windowExitAnimation">@anim/slide_out</item>
    </style>
    ....
</resources>

スライドするメニューの作成

レイアウト

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/slide_menu"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    tools:context=".SlideInMenuFragment">

    <LinearLayout
        android:id="@+id/menu_area"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- ActionBarと同じ高さのスペースの余白 -->
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/design_default_color_primary"
            android:minHeight="?android:attr/actionBarSize" />

        <!-- メニュー部分 -->
        <ListView
            android:id="@+id/menu_list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</FrameLayout>

DialogFragmentの実装

public class SlideInMenuFragment extends DialogFragment {

    public SlideInMenuFragment() {
        // Required empty public constructor
    }

    public static SlideInMenuFragment newInstance() {
        SlideInMenuFragment fragment = new SlideInMenuFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        Dialog dialog = new Dialog(getActivity());
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.fragment_slide_in_menu);

        // 全画面表示のDialogで、左寄せに配置する
        Window window = dialog.getWindow();
        window.getAttributes().windowAnimations = R.style.SlideInMenuAnimation;
        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        window.setGravity(Gravity.TOP | Gravity.START);
        window.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);

        // LayoutのルートViewを設定
        FrameLayout rootView = dialog.findViewById(R.id.slide_menu);
        onViewCreated(rootView, savedInstanceState);
        return dialog;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        String[] menuArray = {"メニュー", "メニュー", "メニュー"};
        // メニューの内容を設定する
        ListView menu = view.findViewById(R.id.menu_list);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, menuArray);
        menu.setAdapter(adapter);
    }
}

MainActivityで呼ぶ

public class MainActivity extends AppCompatActivity {

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

        // ActionBarの左端にボタンを設定する
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
            // ↓アイコンは標準のソートアイコン使ってますが、≡ に変えたらいい感じになります。
            actionBar.setHomeAsUpIndicator(android.R.drawable.ic_menu_sort_by_size);
        }
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        int id = item.getItemId();
        if (id == android.R.id.home) {
            // メニュー表示
            FragmentManager fragmentManager = getSupportFragmentManager();
            SlideInMenuFragment fragment = SlideInMenuFragment.newInstance();
            fragment.show(fragmentManager, fragment.getClass().getSimpleName());
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

}

結果

アクションバーの左にあるアイコンをクリックすると、
image.png
 ↓
image.png
メニューが開きます。背景の透明部分をタップすると、メニューが閉じます。

注意

この実装だとジェスチャー操作して、メニューがピロピロと出てこないです。
自前でメニューを色々する必要があったのでこの方法を実装しましたが、
やっぱりNavigationView 使った方がいいです。

0
0
1

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
0
0