Как реализовать навигационный ящик с детальными деталями фрагментов

Я получил образец навигационного ящика с этого сайта: 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.**********;
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 ********** 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()
 .obtain**********(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 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) {
 ***************().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 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 position ) to this intent */
 intent.putExtra("position", position);
 /** Starting the activity by passing the implicit intent */
 startActivity(intent); 
 }
 }
}
</navdraweritem></navdraweritem>

CountryListFragment как 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);
 }
}
</string></string>

расположение макета в макете папок

><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">
 > </listview></framelayout></android.support.v4.widget.drawerlayout>

layout main в папке 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">
 ></listview></framelayout></framelayout></android.support.v4.widget.drawerlayout>
1 ответ

Я тоже был смущен этим. Я установил навигационный ящик для навигации между основными разделами моего приложения. Затем я хотел, чтобы один из этих основных разделов был настроен как Мастер/Деталь. Я знал, что это возможно, поскольку это в основном то, что Gmail, но с трудом помещало то, что я уже построил вместе с тем, что выплескивает Eclipse при создании Master/Detail Activity.

Я не мог просто запустить ItemListFragment (Master/Detail) из MainActivity (Navigation Drawer), потому что ItemListFragment хочет присоединяться к ItemListActivity, а не к MainActivity, а фрагмент не может иметь двух действий.

Наконец-то я нашел учебное пособие, в котором использовались две идеи дизайна: http://blog.evizija.si/android-layout/

Я только что последовал их примеру и заработал свой UI примерно через 5 минут. Это действительно невероятно просто. Вы делаете MasterActivity более похожим на сгенерированную ItemListActivity (т.е. Реализуете TaskListFragment.Callbacks, копируете по методу onItemSelected и патрон onCreate), и все готово!

Я надеюсь, что это поможет решить вашу проблему! Счастливое кодирование!

ОБНОВЛЕНИЕ. Разработайте шаги, связанные с этим (информация из ссылки), на основе отзывов в комментариях по улучшению моего ответа.

(1) Сделайте свою работу и фрагменты ящика, позвоните им MainActivity и некоторые фрагменты, которые нам здесь не нужны. Лично я создавал бы пустой Фрагмент, например, ItemFragement, чтобы быть владельцем места для Мастера/Детали, пока я получаю Ящик и работаю. Затем, как только ящик работает по желанию, возьмите Мастер/Деталь и соедините их.

(2) Используйте мастер IDE (я запускаю Eclipse), чтобы сделать действия и фрагменты потока master/detail. Я буду ссылаться на них по умолчанию: ItemListActivity, ItemListFragement, ItemDetailActivity, ItemDetailFragment.

(3) Если вы раньше использовали Master/Detail, вы знаете, что большая часть вашей логики входит в фрагмент. Это все еще верно при объединении Master/Detail с ящиком. Обратите внимание: на данный момент нет никакой связи между нашим MainActivity и нашим потоком Master/Detail, а позже может быть недоступен в пользовательском интерфейсе.

(4) Ключевые понятия:. Чтобы соединить ящик со списком, наша MainActivity станет хостинговой операцией для ItemListFragment (а не текущей ItemListActivity). Чтобы сделать эту работу, мы просто скопируем некоторые магию мастера/детали, созданную мастером FROM ItemListActivity INTO MainActivity.

(5) В частности:

(5A) MainActivity реализует ItemListFragment.Callbacks(или EmployeeListFragment.Callbacks, AlbumListFragment.Callbacks, что бы вы ни указали) и реализовать метод onItemSelected

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

(5B) Скопируйте часть кода из onCreate в ItemListActivity и вставьте его в onCreate in MainActivity. Эта часть:

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) Также скопируйте onItemSelected метод из ItemListActivity и вставьте его в MainActivity. У вас уже будет метод onItemSelected, если вы сказали Eclipse "добавить нереализованные методы" в ответ на ошибку, которая была бы поднята после шага 5A. Если вы этого не сделаете, скопируйте весь метод. (этот шаг редактируется в ответ на вопрос в комментариях) Код:

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. Если у вас уже есть запуск Фрагмента заполнителя (например, ItemFragement, предложенный на шаге 1), это всего лишь вопрос замены ItemFragment на ItemListFragment в методе onNavigationDrawerItemSelected.

Надеюсь, что это ясно. Если нет, исходная ссылка может лучше объяснить работу, чем я. Просто перейдите на дно, где блоггер говорит о добавлении активности списка в свою работу с ящиком.

приветствий.

UPDATE:

После того как я попрошу сделать это модератором, я отмечу этот и другой аналогичный вопрос (как дубликаты).

Эти вопросы: https://stackoverflow.com/questions/25403377/combine-navigation-drawer-and-master-detail-layout Навигационный ящик и основной/подробный поток

licensed under cc by-sa 3.0 with attribution.