http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/
以及来自这里的主要细节:
http://wptrafficanalyzer.in/blog/itemclick-handler-for-listfragment-in-android/
错误LogCat oncreateview(inflac ….)视图
无法创建
我,我尝试过
//the main activiry as Activity: package in.wptrafficanalyzer.listfragmentitemclick; import in.wptrafficanalyzer.listfragmentitemclick.adapter.NavDrawerListAdapter; import in.wptrafficanalyzer.listfragmentitemclick.model.NavDrawerItem; import java.util.ArrayList; import in.wptrafficanalyzer.listfragmentitemclick.R; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.app.ListFragment; import android.content.Intent; import android.content.res.Configuration; import android.content.res.TypedArray; import android.os.Bundle; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; public class MainActivity extends Activity implements CountryListFragment.ListFragmentItemClickListener { private DrawerLayout mDrawerLayout; private ListView mDrawerList; private ActionBarDrawerToggle mDrawerToggle; // nav drawer title private CharSequence mDrawerTitle; // used to store app title private CharSequence mTitle; // slide menu items private String[] navMenuTitles; private TypedArray navMenuIcons; private ArrayList<NavDrawerItem> navDrawerItems; private NavDrawerListAdapter adapter; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTitle = mDrawerTitle = getTitle(); // load slide menu items navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items); // nav drawer icons from resources navMenuIcons = getResources() .obtainTypedArray(R.array.nav_drawer_icons); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList = (ListView) findViewById(R.id.list_slidermenu); navDrawerItems = new ArrayList<NavDrawerItem>(); // adding nav drawer items to array // Home navDrawerItems.add(new NavDrawerItem(navMenuTitles[0],navMenuIcons.getResourceId(0,-1))); // Find People navDrawerItems.add(new NavDrawerItem(navMenuTitles[1],navMenuIcons.getResourceId(1,-1))); // Photos navDrawerItems.add(new NavDrawerItem(navMenuTitles[2],navMenuIcons.getResourceId(2,-1))); // Communities,Will add a counter here navDrawerItems.add(new NavDrawerItem(navMenuTitles[3],navMenuIcons.getResourceId(3,-1),true,"22")); // Pages navDrawerItems.add(new NavDrawerItem(navMenuTitles[4],navMenuIcons.getResourceId(4,-1))); // What's hot,We will add a counter here navDrawerItems.add(new NavDrawerItem(navMenuTitles[5],navMenuIcons.getResourceId(5,"50+")); // Recycle the typed array navMenuIcons.recycle(); mDrawerList.setOnItemClickListener(new SlideMenuClickListener()); // setting the nav drawer list adapter adapter = new NavDrawerListAdapter(getApplicationContext(),navDrawerItems); mDrawerList.setAdapter(adapter); // enabling action bar app icon and behaving it as toggle button getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true); mDrawerToggle = new ActionBarDrawerToggle(this,mDrawerLayout,R.drawable.ic_drawer,//nav menu toggle icon R.string.app_name,// nav drawer open - description for accessibility R.string.app_name // nav drawer close - description for accessibility ) { public void onDrawerClosed(View view) { getActionBar().setTitle(mTitle); // calling onPrepareOptionsMenu() to show action bar icons invalidateOptionsMenu(); } public void onDrawerOpened(View drawerView) { getActionBar().setTitle(mDrawerTitle); // calling onPrepareOptionsMenu() to hide action bar icons invalidateOptionsMenu(); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); if (savedInstanceState == null) { // on first time display view for first nav item displayView(0); } } /** * Slide menu item click listener * */ private class SlideMenuClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent,View view,int position,long id) { // display view for selected nav drawer item displayView(position); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main,menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // toggle nav drawer on selecting action bar app icon/title if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } // Handle action bar actions click switch (item.getItemId()) { case R.id.action_settings: return true; default: return super.onOptionsItemSelected(item); } } /*** * Called when invalidateOptionsMenu() is triggered */ @Override public boolean onPrepareOptionsMenu(Menu menu) { // if nav drawer is opened,hide the action items boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); menu.findItem(R.id.action_settings).setVisible(!drawerOpen); return super.onPrepareOptionsMenu(menu); } /** * Diplaying fragment view for selected nav drawer list item * */ private void displayView(int position) { // update the main content by replacing fragments ListFragment fragment = null; switch (position) { case 0: //fragment = new HomeFragment(); break; case 1: fragment = new CountryListFragment(); break; case 2: //fragment = new PhotosFragment(); break; case 3: // fragment = new CommunityFragment(); break; case 4: //fragment = new PagesFragment(); break; case 5: //fragment = new WhatsHotFragment(); break; default: break; } if (fragment != null) { FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.country_list_fragment,fragment).commit(); // update selected item and title,then close the drawer mDrawerList.setItemChecked(position,true); mDrawerList.setSelection(position); setTitle(navMenuTitles[position]); mDrawerLayout.closeDrawer(mDrawerList); } else { // error in creating fragment Log.e("MainActivity","Error in creating fragment"); } } @Override public void setTitle(CharSequence title) { mTitle = title; getActionBar().setTitle(mTitle); } /** * When using the ActionBarDrawerToggle,you must call it during * onPostCreate() and onConfigurationChanged()... */ @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); // Pass any configuration change to the drawer toggls mDrawerToggle.onConfigurationChanged(newConfig); } /** Called when the activity is first created. */ @Override public void onListFragmentItemClick(int position) { /** Getting the orientation ( Landscape or Portrait ) of the screen */ int orientation = getResources().getConfiguration().orientation; /** Landscape Mode */ if(orientation == Configuration.ORIENTATION_LANDSCAPE ){ /** Getting the fragment manager for fragment related operations */ FragmentManager fragmentManager = getFragmentManager(); /** Getting the fragmenttransaction object,which can be used to add,remove or replace a fragment */ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); /** Getting the existing detailed fragment object,if it already exists. * The fragment object is retrieved by its tag name * */ Fragment prevFrag = fragmentManager.findFragmentByTag("in.wptrafficanalyzer.country.details"); /** Remove the existing detailed fragment object if it exists */ if(prevFrag!=null) fragmentTransaction.remove(prevFrag); /** Instantiating the fragment CountryDetailsFragment */ CountryDetailsFragment fragment = new CountryDetailsFragment(); /** Creating a bundle object to pass the data(the clicked item's position) from the activity to the fragment */ Bundle b = new Bundle(); /** Setting the data to the bundle object */ b.putInt("position",position); /** Setting the bundle object to the fragment */ fragment.setArguments(b); /** Adding the fragment to the fragment transaction */ fragmentTransaction.add(R.id.detail_fragment_container,fragment,"in.wptrafficanalyzer.country.details"); /** Adding this transaction to backstack */ fragmentTransaction.addToBackStack(null); /** Making this transaction in effect */ fragmentTransaction.commit(); }else{ /** Portrait Mode or Square mode */ /** Creating an intent object to start the CountryDetailsActivity */ Intent intent = new Intent("in.wptrafficanalyzer.CountryDetailsActivity"); /** Setting data ( the clicked item's position ) to this intent */ intent.putExtra("position",position); /** Starting the activity by passing the implicit intent */ startActivity(intent); } } }
CountryListFragment as listfragment:
package in.wptrafficanalyzer.listfragmentitemclick; import android.app.Activity; import android.app.ListFragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; public class CountryListFragment extends ListFragment{ /** List of countries to be displayed in the ListFragment */ ListFragmentItemClickListener ifaceItemClickListener; /** An interface for defining the callback method */ public interface ListFragmentItemClickListener { /** This method will be invoked when an item in the ListFragment is clicked */ void onListFragmentItemClick(int position); } /** A callback function,executed when this fragment is attached to an activity */ @Override public void onAttach(Activity activity) { super.onAttach(activity); try{ /** This statement ensures that the hosting activity implements ListFragmentItemClickListener */ ifaceItemClickListener = (ListFragmentItemClickListener) activity; }catch(Exception e){ Toast.makeText(activity.getBaseContext(),"Exception",Toast.LENGTH_SHORT).show(); } } @Override public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) { /** Data source for the ListFragment */ ArrayAdapter<String> adapter = new ArrayAdapter<String>(inflater.getContext(),android.R.layout.simple_list_item_1,Country.name); /** Setting the data source to the ListFragment */ setListAdapter(adapter); return super.onCreateView(inflater,container,savedInstanceState); } @Override public void onListItemClick(ListView l,View v,long id) { /** Invokes the implementation of the method istFragmentItemClick in the hosting activity */ ifaceItemClickListener.onListFragmentItemClick(position); } }
布局主要在文件夹布局中
><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/country_list_fragment" android:layout_width="fill_parent" android:layout_height="wrap_content" android:name="in.wptrafficanalyzer.listfragmentitemclick.CountryListFragment" /> <!-- Listview to display slider menu --> <ListView android:id="@+id/list_slidermenu" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:choiceMode="singleChoice" android:divider="@color/list_divider" android:dividerHeight="1dp" android:listSelector="@drawable/list_selector" android:background="@color/list_background"/> > </android.support.v4.widget.DrawerLayout>
布局主要在文件夹布局 – 土地
><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/country_list_fragment" android:layout_width="200dp" android:layout_height="wrap_content" android:name="in.wptrafficanalyzer.listfragmentitemclick.CountryListFragment" /> <FrameLayout android:id="@+id/detail_fragment_container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_gravity="center" /> <!-- Listview to display slider menu --> <ListView android:id="@+id/list_slidermenu" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:choiceMode="singleChoice" android:divider="@color/list_divider" android:dividerHeight="1dp" android:listSelector="@drawable/list_selector" android:background="@color/list_background"/> ></android.support.v4.widget.DrawerLayout>
解决方法
我无法从MainActivity(导航抽屉)中启动ItemListFragment(主/细节),因为ItemListFragment想要附加到ItemListActivity,而不是MainActivity,并且片段不能有两个Activity.
我终于找到了一个实际使用这两个设计思想的教程:
http://blog.evizija.si/android-layout/
我只是按照他们的例子,让我的UI在大约5分钟内按照需要工作.它实际上非常简单.你使MasterActivity看起来更像生成的ItemListActivity(即实现TaskListFragment.Callbacks,复制onItemSelected方法,以及onCreate的一个chuck)你已经完成了!
我希望这有助于解决您的问题!快乐的编码!
更新:基于对改进我的答案的评论中的反馈,阐述所涉及的步骤(来自链接的信息).
(1)让你的抽屉活动和碎片,让我们称之为MainActivity和我们在此不关心的一些片段.就个人而言,我会创建一个空的片段,例如ItemFragement,作为Master / Detail的占位符,同时让Drawer启动并运行.然后,一旦抽屉按照需要工作,解决主/细节并链接它们.
(2)使用IDE向导(我正在运行Eclipse)来创建主/详细信息流的活动和片段.我将通过它们的默认名称来引用它们:ItemListActivity,ItemListFragement,ItemDetailActivity,ItemDetailFragment.
(3)如果您之前使用过Master / Detail,那么您知道大部分逻辑都会进入片段.将Master / Detail与Drawer结合使用时仍然如此.注意,此时我们的MainActivity和Master / Detail流程之间没有任何关联,后者甚至可能无法在UI中访问.
(4)关键概念:要将抽屉与列表连接起来,我们的MainActivity将成为ItemListFragment的托管活动(而不是当前的ItemListActivity).为了完成这项工作,我们只需复制一些由向导FROM ItemListActivity INTO MainActivity创建的Master / Detail魔法.
(5)具体:
(5A)MainActivity实现ItemListFragment.Callbacks(或EmployeeListFragment.Callbacks,AlbumListFragment.Callbacks,无论你列出什么)并实现onItemSelected方法
public class MainActivity extends Activity implements OnItemClickListener,ItemListFragment.Callbacks {
(5B)从ItemListActivity中复制onCreate的部分代码,并将其粘贴到MainActivity中的onCreate.这部分:
if (findViewById(R.id.item_detail_container) != null) { // The detail container view will be present only in the // large-screen layouts (res/values-large and // res/values-sw600dp). If this view is present,then the // activity should be in two-pane mode. mTwoPane = true; // In two-pane mode,list items should be given the // 'activated' state when touched. ((ItemListFragment) getFragmentManager() .findFragmentById(R.id.item_list)) .setActivateOnItemClick(true); }
(5C)同样从ItemListActivity复制onItemSelected方法并将其粘贴到MainActivity中.如果你告诉Eclipse“添加未实现的方法”以响应在步骤5A之后引发的错误,那么你已经有了一个onItemSelected方法.如果不这样做,请复制整个方法. (此步骤针对评论中的问题进行了编辑)代码:
if (mTwoPane) { // In two-pane mode,show the detail view in this activity by // adding or replacing the detail fragment using a // fragment transaction. Bundle arguments = new Bundle(); arguments.putString(ItemDetailFragment.ARG_ITEM_ID,id); ItemDetailFragment fragment = new ItemDetailFragment(); fragment.setArguments(arguments); getFragmentManager().beginTransaction() .replace(R.id.item_detail_container,fragment) .commit(); } else { // In single-pane mode,simply start the detail activity // for the selected item ID. Intent detailIntent = new Intent(this,ItemDetailActivity.class); detailIntent.putExtra(ItemDetailFragment.ARG_ITEM_ID,id); startActivity(detailIntent); }
(6)然后最后一步是让MainActivity(抽屉)打开ItemListFragment.如果您已经启动了占位符Fragment(如步骤1中建议的ItemFragement),则只需在onNavigationDrawerItemSelected方法中用ItemListFragment替换ItemFragment即可.
希望很清楚.如果没有,原始链接可能比我更好地解释.只是浏览一下博客谈论将列表活动添加到抽屉活动的底部.
干杯.
更新:
在被主持人要求这样做之后,我正在标记这个和另一个类似的问题(重复).
那些问题:
https://stackoverflow.com/questions/25403377/combine-navigation-drawer-and-master-detail-layout
Navigation Drawer and master/detail flow