6

Ich habe die Probe Navigationsleiste von dieser Seite erhalten: http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/Wie Navigationsleiste mit Fragmenten implementieren Master Detail

und das Master-Detail von hier: http://wptrafficanalyzer.in/blog/itemclick-handler-for-listfragment-in-android/

der Fehler LogCat oncreateview (inflac .. ..) die Ansicht nicht

mich geschaffen werden, ich habe versucht, dass

//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, -1), true, "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);   
     } 
    } 
} 

die CountryListFragment als 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, int position, long id) {  

     /** Invokes the implementation of the method istFragmentItemClick   in  the hosting activity */ 
     ifaceItemClickListener.onListFragmentItemClick(position); 

    } 

} 

Layout Haupt in Ordner-Layout

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

Layout Haupt im Ordner Layout-Land

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

Antwort

11

Ich wurde von diesem auch verwirrt. Ich habe die Navigationsleiste eingerichtet, um zwischen den Hauptbereichen meiner App zu navigieren. Dann wollte ich einen dieser Hauptabschnitte als Master/Detail einrichten. Ich wusste, dass es möglich war, da dies im Grunde das ist, was Google Mail ist, aber es hat mir schwer gefallen, das, was ich bereits aufgebaut hatte, mit dem zu kombinieren, was Eclipse ausspuckt, wenn er eine Master/Detail-Aktivität generiert.

Ich konnte nicht einfach die ItemListFragment (Master/Detail) aus dem MainActivity (Navigation Drawer) starten, weil ItemListFragment an ItemListActivity, nicht MainActivity anhängen will, und ein Fragment kann nicht zwei Aktivitäten haben.

Schließlich fand ich ein Tutorial darauf, dass tatsächlich die beiden Design-Ideen zusammen verwendet: http://blog.evizija.si/android-layout/

Ich folgte einfach ihrem Beispiel und meine UI bekam in ca. 5 Minuten wie gewünscht arbeiten. Es ist wirklich unglaublich einfach. Sie lassen MasterActivity ein wenig mehr wie die generierte ItemListActivity aussehen (dh implementieren Sie TaskListFragment.Callbacks, kopieren Sie die onItemSelected Methode und ein Chuck von onCreate) und Sie sind fertig!

Ich hoffe, das hilft Ihr Problem zu lösen! Glückliche Kodierung!


UPDATE: Ausarbeitung über die Schritte (info von link), basierend auf dem Feedback in den Kommentaren auf meine Antwort zu verbessern.

(1) Machen Sie Ihre Schublade Aktivität und Fragmente, nennen wir sie MainActivity und einige Fragmente, die uns hier nicht interessieren. Persönlich würde ich ein leeres Fragment, wie zum Beispiel ItemFragement, erstellen, um ein Platzhalter für den Master/Detail zu sein, während ich das Drawer in Gang setze. Sobald die Schublade wie gewünscht funktioniert, musst du den Master/Detail angehen und verbinden.

(2) Verwenden Sie den IDE-Assistenten (Ich führe Eclipse), um die Aktivitäten und Fragmente von Master/Detail fließen zu lassen. Ich werde auf sie anhand ihrer Standardnamen verweisen: ItemListActivity, ItemListFragement, ItemDetailActivity, ItemDetailFragment.

(3) Wenn Sie Master/Detail zuvor verwendet haben, wissen Sie, dass die meisten Ihrer Logik in das Fragment gehen. Dies trifft immer noch zu, wenn Master/Detail mit Schublade kombiniert wird.Beachten Sie, dass zu diesem Zeitpunkt keine Verbindung zwischen unserer MainActivity und unserem Master/Detail-Flow besteht und dass der spätere möglicherweise nicht einmal in der Benutzeroberfläche verfügbar ist.

(4) Schlüsselkonzept: Um die Schublade mit der Liste zu verbinden, unsere MainActivity wird die Hosting-Aktivität für ItemListFragment (anstelle der aktuellen ItemListActivity) sein. Um dies zu erreichen, kopieren wir einfach einige der Master/Detail-Zauber, die vom Assistenten erstellt wurden FROM ItemListActivity INTO MainActivity.

(5) Im Einzelnen:

(5A) MainActivity implementiert ItemListFragment.Callbacks (oder EmployeeListFragment.Callbacks, AlbumListFragment.Callbacks, was auch immer Sie Listing) und implementieren onItemSelected Methode

public class MainActivity extends Activity 
          implements OnItemClickListener, ItemListFragment.Callbacks { 

(5B) Kopieren Sie einen Teil des Codes von onCreate in ItemListActivity und fügen Sie ihn in MainActivity in onCreate ein. Dieser Teil:

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) Methode Kopie onItemSelected Auch aus ItemListActivity und in MainActivity einfügen. Sie verfügen bereits über eine onItemSelected-Methode, wenn Sie Eclipse in Reaktion auf den Fehler, der nach Schritt 5A ausgelöst wurde, angewiesen haben, "nicht implementierte Methoden hinzuzufügen". Wenn nicht, kopieren Sie die gesamte Methode. (dieser Schritt als Antwort auf eine Frage bearbeitet in den Kommentaren) Code:

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) Dann ist der letzte Schritt MainActivity (der Schublade) offen ItemListFragment haben. Wenn Sie bereits einen Platzhalter-Fragment-Start haben (wie in Schritt 1 vorgeschlagenes ItemFragment), müssen Sie nur ItemFragment durch ItemListFragment in der onNavigationDrawerItemSelected-Methode ersetzen.

Hoffe, das ist klar. Wenn nicht, könnte der ursprüngliche Link eine bessere Erklärung liefern als ich. Überfliegen Sie einfach den unteren Rand, wo der Blogger davon spricht, die Aktivität der Liste in ihre Schubladenaktivität einzubinden.

Prost.


UPDATE:

Nach fragen ist, um von einem Moderator zu tun, ich bin das Markieren dieses und andere ähnliche Frage (als Duplikate).

Diese Fragen stellen:
https://stackoverflow.com/questions/25403377/combine-navigation-drawer-and-master-detail-layout
Navigation Drawer and master/detail flow


+1

Es ist hilfreich, um die tatsächlichen Code-Beispiele zu geben, die auf Blogs seit Links gearbeitet, kann usw. tot wird nach einer Weile – aarosil

+0

MainActivity eine Nav Drawer Aktivität ist, Es hat also keine OnSelectedItem-Methode. Also, wo geht dieser Code hin? Geht es in onNavigationDrawerItemSelected? Weil das falsch aussieht. –

+0

@RayKiddy es geht in OnItemSelected. Sie müssen diese Methode hinzufügen, nachdem Sie angegeben haben, dass MainActivity ItemListFragment.Callbacks implementiert, Schritt 5A. Ich habe diese Erklärung auch meiner Antwort für die Nachwelt hinzugefügt. –