Navigation Drawer
これはすべてのアクティビティに表示されるはずです。
これに似た多くの質問を見ましたが、MainActivityを他のアクティビティで拡張するような解決策を見つけました。
そのため、メインアクティビティを2番目のアクティビティに拡張しましたが、2番目のアクティビティに引き出しが表示されていません
MainActivity
public class MainActivity extends ActionBarActivity
{
private ListView mDrawerList;
private DrawerLayout mDrawer;
private CustomActionBarDrawerToggle mDrawerToggle;
private String[] menuItems;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
// getSupportActionBar().hide();
setContentView(R.layout.activity_main_drawer);
// enable ActionBar app icon to behave as action to toggle nav drawer
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
// set a custom shadow that overlays the main content when the drawer
// opens
mDrawer.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
_initMenu();
mDrawerToggle = new CustomActionBarDrawerToggle(this, mDrawer);
mDrawer.setDrawerListener(mDrawerToggle);
}
private void _initMenu()
{
NsMenuAdapter mAdapter = new NsMenuAdapter(this);
// Add Header
mAdapter.addHeader(R.string.ns_menu_main_header);
// Add first block
menuItems = getResources().getStringArray(R.array.ns_menu_items);
String[] menuItemsIcon = getResources().getStringArray(R.array.ns_menu_items_icon);
int res = 0;
for (String item : menuItems)
{
int id_title = getResources().getIdentifier(item, "string", this.getPackageName());
int id_icon = getResources().getIdentifier(menuItemsIcon[res], "drawable", this.getPackageName());
NsMenuItemModel mItem = new NsMenuItemModel(id_title, id_icon);
// if (res==1) mItem.counter=12; //it is just an example...
// if (res==3) mItem.counter=3; //it is just an example...
mAdapter.addItem(mItem);
res++;
}
mAdapter.addHeader(R.string.ns_menu_main_header2);
mDrawerList = (ListView) findViewById(R.id.drawer);
if (mDrawerList != null)
mDrawerList.setAdapter(mAdapter);
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
}
@Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.control_menu, menu);
return super.onCreateOptionsMenu(menu);
}
/* Called whenever we call invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu)
{
// If the nav drawer is open, hide action items related to the content
// view
boolean drawerOpen = mDrawer.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_keyboard).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
/*
* The action bar home/up should open or close the drawer.
* ActionBarDrawerToggle will take care of this.
*/
if (mDrawerToggle.onOptionsItemSelected(item))
{
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
private class CustomActionBarDrawerToggle extends ActionBarDrawerToggle
{
public CustomActionBarDrawerToggle(Activity mActivity, DrawerLayout mDrawerLayout)
{
super(mActivity, mDrawerLayout, R.drawable.ic_drawer, R.string.ns_menu_open, R.string.ns_menu_close);
}
@Override
public void onDrawerClosed(View view)
{
getSupportActionBar().setTitle(getString(R.string.ns_menu_close));
supportInvalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
}
@Override
public void onDrawerOpened(View drawerView)
{
getSupportActionBar().setTitle(getString(R.string.ns_menu_open));
supportInvalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
}
}
private class DrawerItemClickListener implements ListView.OnItemClickListener
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Intent intent = new Intent(MainActivity.this, Tutorial.class);
startActivity(intent);
}
}
}
SecondActivity
public class Tutorial extends MainActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.help);
}
}
onCreate
のTutorialActivity
でsetContentView
を呼び出さないで、代わりに次のようにします。
@Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View contentView = inflater.inflate(R.layout.help, null, false);
mDrawer.addView(contentView, 0);
}
mDrawer
をMainActivity
で保護します。およびR.layout.activity_main_drawer
引き出しタグと重力のある要素を左(または右)に保持します。
これが私の実装です。
[〜#〜] first [〜#〜]、これは [〜#〜] post [〜#〜] は概念。
[〜#〜] second [〜#〜]、これは [〜#〜] key [〜#〜] 1。
[〜#〜] finally [〜#〜]、ここにすべての回答の組み合わせが1箇所にあります
基本アクティビティ
これは、他のすべてのアクティビティの基本アクティビティです
要件に基づいて、ActivityやFragmentActivityなどを拡張できます。
Navigation Drawer
ここで一度セットアップします。
public class BaseActivity extends FragmentActivity {
protected DrawerLayout mDrawer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.base_layout);
mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
//This is about creating custom listview for navigate drawer
//Implementation for NavigateDrawer HERE !
ArrayList<DrawerListItem> drawerListItems = new ArrayList<DrawerListItem>();
drawerListItems.add(new DrawerListItem(0,"AIR° DEVICES"));
drawerListItems.add(new DrawerListItem(1,"A/C Device [1]"));
drawerListItems.add(new DrawerListItem(1,"A/C Device [2]"));
drawerListItems.add(new DrawerListItem(1,"A/C Device [3]"));
drawerListItems.add(new DrawerListItem(0,"AIR° FEATURES"));
drawerListItems.add(new DrawerListItem(2,"SLEEP MODE"));
drawerListItems.add(new DrawerListItem(2,"TRACKING MODE"));
drawerListItems.add(new DrawerListItem(2,"SETTINGS"));
DrawerAdapter mDrawerAdapter = new DrawerAdapter(this, R.layout.drawer_list_header, drawerListItems);
ListView mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerList.setAdapter(mDrawerAdapter);
}
}
BASE ACTIVITY XML
このxmlレイアウトはNavigation Drawer
<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.widget.DrawerLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/drawer_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<FrameLayout
Android:id="@+id/content_frame"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
</FrameLayout>
<!-- The navigation drawer -->
<ListView
Android:id="@+id/left_drawer"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_gravity="left"
Android:scrollingCache="false"
Android:background="@drawable/drawer_bg"
Android:divider="@null"
Android:choiceMode="singleChoice"/>
</Android.support.v4.widget.DrawerLayout>
その他すべてのアクティビティ
その他のActivity
は、単にBaseActivity
を拡張し、以下のようにコードを定義します。
Navigation Drawer
は特定のアクティビティに対して表示されます。
mDrawer
はBaseActivity
の形式です。 protected
変数です。
public class Screen1 extends BaseActivity
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//inflate your activity layout here!
View contentView = inflater.inflate(R.layout.screen1, null, false);
mDrawer.addView(contentView, 0);
//Do the rest as you want for each activity
}
スクリーン1 XMLサンプル
アクティビティごとに希望どおりに設計します。もういや Navigation Drawer
レイアウト !
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
</LinearLayout>
[〜#〜] note [〜#〜]
この実装では、Navigation Drawer
はアクションバーにバインドしません。 BaseActivity
でそれを行いたい場合も、このガイドはすべての要件をカバーしているわけではありません。これは単なるサンプルです。
SherlockActivity(またはあなたの場合はActionBarActivity)を拡張するBaseActivityアクティビティを作成しました
public class BaseActivity extends SherlockActivity
次に、次のように、すべてのアクティビティでBaseActivityを拡張します。
public class GlossaryActivity extends BaseActivity
後で、アクティビティレイアウトをアクティビティに対応するレイアウトに置き換える必要があります。BaseActivityで次のようなメソッドを作成しました。
protected void replaceContentLayout(int sourceId, int destinationId) {
View contentLayout = findViewById(destinationId);
ViewGroup parent = (ViewGroup) contentLayout.getParent();
int index = parent.indexOfChild(contentLayout);
parent.removeView(contentLayout);
contentLayout = getLayoutInflater().inflate(sourceId, parent, false);
parent.addView(contentLayout, index);
}
各アクティビティのonCreateメソッドでこのメソッドを呼び出しました。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.replaceContentLayout(R.layout.activity_glossary, super.CONTENT_LAYOUT_ID);
}
super.CONTENT_LAYOUT_ID
はBaseActivityのFrameLayoutで、他のparamは置換したいレイアウトです
Android studio:
ギャラリーから新しいアクティビティ(ナビゲーションドロワーアクティビティ)を作成し、任意の名前を付けます。Android studioがすべてを作成します(後でカスタマイズできるクラスとxmlファイル)
他のアクティビティでは、ナビゲーションドロワーアクティビティを拡張し、これらの他のアクティビティにマニフェストファイル(Android:theme = "@ style/AppTheme.NoActionBar")に「アクションバーがない」ことを確認する必要があります。
次のように他のアクティビティを変更する必要があります。
public class Mainactivity extends NavActivity
{
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//inflate your activity layout here!
View contentView = inflater.inflate(R.layout.activity_main, null, false);
drawer.addView(contentView, 0);
}
注:メインアクティビティは、NavActivityのアクションバーを拡張します。NavActivityには、ナビゲーションドロワーを呼び出す完全に機能するアクションバーがあります。
私はそれがあなたとうまくいくことを願っています
これはハックな方法です。特別な種類のデバッグビルドにのみ使用し、リアルタイムでビューのプロパティを設定します(設計ツール)。
通常どおり子アクティビティを使用できますなしで、さまざまな回答に必要な特別な動作ができるという利点があります。
baseActvityでは、次を追加できます。
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// WARNING: Hacky, use carefully!!!
ViewGroup androidBaseView = (ViewGroup) findViewById(Android.R.id.content);
//this one in what child activity has just set in setContentView()
ViewGroup childContent = (ViewGroup) androidBaseView.getChildAt(0);
View drawerView = LayoutInflater.from(this)
.inflate(R.layout.base_activity_drawer, androidBaseView, false);
FrameLayout frameLayout = (FrameLayout) drawerView.findViewById(R.id.content);
androidBaseView.removeView(childContent);
frameLayout.addView(childContent);
androidBaseView.addView(drawerView);
}
そして、引き出し用のxmlはただ:
<Android.support.v4.widget.DrawerLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/nav_drawer"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true">
<FrameLayout
Android:id="@+id/content"
Android:layout_width="match_parent"
Android:layout_height="match_parent"/>
<LinearLayout
Android:id="@+id/drawer_for_components"
Android:layout_width="240dp"
Android:layout_height="match_parent"
Android:layout_gravity="end"
Android:orientation="vertical"
Android:fitsSystemWindows="true"
/>
</Android.support.v4.widget.DrawerLayout>
派生クラスonCreate
から@Override
を省略しました。
更新:setContentView
を2回呼び出した場合の影響はわかりませんが、問題になる可能性があります。引き出しを設定するコードを分離し、両方のonCreate
メソッドから呼び出します。
私もこの問題を抱えていました。これは私の実装です:
activity_main.xml-CoordinatorLayoutのインデックス1の子はcontent_main.xmlです。これはコードを変更できます。
<Android.support.v4.widget.DrawerLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/drawer_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true"
tools:openDrawer="start">
<Android.support.design.widget.CoordinatorLayout
Android:id="@+id/coordinator"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true">
<Android.support.design.widget.AppBarLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:theme="@style/AppTheme.AppBarOverlay">
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</Android.support.design.widget.AppBarLayout>
**<include layout="@layout/content_main" />**
<Android.support.design.widget.FloatingActionButton
Android:id="@+id/fab"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="bottom|end"
Android:layout_margin="@dimen/fab_margin"
Android:src="@Android:drawable/ic_dialog_email" />
</Android.support.design.widget.CoordinatorLayout>
<Android.support.design.widget.NavigationView
Android:id="@+id/nav_view"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_gravity="start"
Android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</Android.support.v4.widget.DrawerLayout>
他のアクティビティUIを拡張するクラスを作成しました:
public class MyLayoutInflater {
public void inflate(Activity activity, int LayoutResource, Android.app.ActionBar getSupportActionBar, Intent getIntent){
CoordinatorLayout coordinatorLayout = (CoordinatorLayout) activity.findViewById(R.id.coordinator);
Android.view.LayoutInflater inflater = (Android.view.LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View contentView = inflater.inflate(LayoutResource, null, false);
//change i so that it suits the child number in you coordinator layout
int i = 1;
coordinatorLayout.removeViewAt(i);
coordinatorLayout.addView(contentView, i);
getSupportActionBar.setTitle(actionBarTitle);
}
public void inflate(Activity activity, int LayoutResource, Android.support.v7.app.ActionBar getActionBar, String actionBarTitle){
CoordinatorLayout coordinatorLayout = (CoordinatorLayout) activity.findViewById(R.id.coordinator);
Android.view.LayoutInflater inflater = (Android.view.LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View contentView = inflater.inflate(LayoutResource, null, false);
//change i so that it suits the child number in you coordinator layout
int i = 1;
coordinatorLayout.removeViewAt(i);
coordinatorLayout.addView(contentView, i);
getActionBar.setTitle(actionBarTitle);
}
}
他のアクティビティでは、MainActivityを拡張し、このメソッドを呼び出して必要なパラメーターを指定するだけです。
public class AnotherActivity extends MainActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new MyLayoutInflater().inflate(this,R.layout.content_activity_another, getSupportActionBar(), getIntent());
}
}
現在、Single-Activity App Architecture( source )を使用する必要があります。
次に、メインアクティビティにナビゲーションドロワーを追加するだけです