У меня есть операция основного ящика, которая загружает мои фрагменты, когда выбран элемент ящика. Фрагмент, который является laoded, содержит табуст, который содержит несколько фрагментов, поэтому вы можете переключаться на вкладки.
Перед вкладками у меня был фрагмент с кучей бутов, который при щелчке заменил текущий фрагмент новым фрагментом. У всех фрагментов есть списки в них, и когда вы нажимаете элемент, замените текущий фрагмент списка другим фрагментом.
Моя проблема в том, что я поместил все свои фрагменты в табуст, который ArticleOnSelected больше не работает, и принудительно закрывает мое приложение, когда элемент действительно выбран из списка. Вот пример одной из ошибок FC:
03-02 16:40:34.121 9066-9066/com.beerportfolio.beerportfoliopro E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalArgumentException: No view found for id 0x7f09008c (com.beerportfolio.beerportfoliopro:id/main) for fragment BreweryPage2{41ba3478 #2 id=0x7f09008c}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:919)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:5789)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:843)
at dalvik.system.NativeStart.main(Native Method)
Я вижу, что проблема связана с представлением, и я думаю, что он не может получить доступ к основному кадру из макета, который содержит все фрагменты с ящиком навигации.
Мой класс MainDrawer2 - это то, что открывается первым, и где загружается ящик и фрагменты. Код:
public class MainDrawer2 extends FragmentActivity
{
private static final String EXTRA_NAV_ITEM = "extraNavItem";
private static final String STATE_CURRENT_NAV = "stateCurrentNav";
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private NavDrawerListAdapter mDrawerAdapter;
private ListView mDrawerList;
private CharSequence mTitle;
private CharSequence mDrawerTitle;
private MainNavItem mCurrentNavItem;
public static Intent createLaunchFragmentIntent(Context context, MainNavItem navItem)
{
return new Intent(context, MainDrawer2.class)
.putExtra(EXTRA_NAV_ITEM, navItem.ordinal());
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
mTitle = mDrawerTitle = getTitle();
mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
mDrawerList = (ListView)findViewById(R.id.drawer);
getActionBar().setDisplayHomeAsUpEnabled(true);
enableHomeButtonIfRequired();
mDrawerAdapter = new NavDrawerListAdapter(getApplicationContext());
mDrawerList.setAdapter(mDrawerAdapter);
mDrawerList.setOnItemClickListener(new ListView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
displayNavFragment((MainNavItem)parent.getItemAtPosition(position));
}
});
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer, R.string.app_name, R.string.app_name)
{
public void onDrawerClosed(View view)
{
getActionBar().setTitle(mTitle);
invalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView)
{
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if(getIntent().hasExtra(EXTRA_NAV_ITEM)){
MainNavItem navItem = MainNavItem.values()
[getIntent().getIntExtra(EXTRA_NAV_ITEM,
MainNavItem.STATISTICS.ordinal())];
displayNavFragment(navItem);
}
else if(savedInstanceState != null){
mCurrentNavItem = MainNavItem.values()
[savedInstanceState.getInt(STATE_CURRENT_NAV)];
setCurrentNavItem(mCurrentNavItem);
}
else{
displayNavFragment(MainNavItem.STATISTICS);
}
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private void enableHomeButtonIfRequired()
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){
getActionBar().setHomeButtonEnabled(true);
}
}
@Override
public void setTitle(CharSequence title)
{
mTitle = title;
getActionBar().setTitle(mTitle);
}
@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 toggles
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putInt(STATE_CURRENT_NAV, mCurrentNavItem.ordinal());
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/*
@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);
}
*/
private void displayNavFragment(MainNavItem navItem)
{
if(navItem == mCurrentNavItem){
return;
}
Fragment fragment = Fragment.instantiate(this,
navItem.getFragClass().getName());
if(fragment != null){
getSupportFragmentManager().beginTransaction()
.replace(R.id.main, fragment)
.commit();
setCurrentNavItem(navItem);
}
}
private void setCurrentNavItem(MainNavItem navItem)
{
int position = navItem.ordinal();
// If navItem is in DrawerAdapter
if(position >= 0 && position < mDrawerAdapter.getCount()){
mDrawerList.setItemChecked(position, true);
}
else{
// navItem not in DrawerAdapter, de-select current item
if(mCurrentNavItem != null){
mDrawerList.setItemChecked(mCurrentNavItem.ordinal(), false);
}
}
mDrawerLayout.closeDrawer(mDrawerList);
setTitle(navItem.getTitleResId());
mCurrentNavItem = navItem;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
if(mDrawerLayout.isDrawerOpen(mDrawerList)) {
mDrawerLayout.closeDrawer(mDrawerList);
}
else {
mDrawerLayout.openDrawer(mDrawerList);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void goToSearch(MenuItem item){
//go to search page
Fragment Fragment_one;
FragmentManager man= getSupportFragmentManager();
FragmentTransaction tran = man.beginTransaction();
Fragment_one = new Search();
tran.replace(R.id.main, Fragment_one);//tran.
tran.addToBackStack(null);
tran.commit();
}
}
Загруженный фрагмент по умолчанию - это фрагмент, который содержит мой табуст и создает вкладки:
public class StatisticsTab extends Fragment {
private FragmentTabHost mTabHost;
//Mandatory Constructor
public StatisticsTab() {
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tabs,container, false);
mTabHost = (FragmentTabHost)rootView.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("Basic").setIndicator("Basic"),
StatisticsPage.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Brewery").setIndicator("Brewery"),
BreweryStatistics.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Style").setIndicator("Style"),
StyleStatistics.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Taste").setIndicator("Taste"),
TasteStatisticsPage.class, null);
return rootView;
}
}
Если я нажму на элемент на моей вкладке и выведу список, вот так:
Это дает мне ФК, который я написал выше. Код для этого фрагмента:
public class BreweryStatistics extends Fragment implements GetBreweryStatisticsJSON.OnArticleSelectedListener {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.brewery_statistics_layout, container, false);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
String userName = prefs.getString("userName", null);
String userID = prefs.getString("userID", null);
String url = "myURL";
//async task to get beer taste tag percents
GetBreweryStatisticsJSON task = new GetBreweryStatisticsJSON(getActivity());
task.setOnArticleSelectedListener(this);
task.execute(url);
// Inflate the layout for this fragment
return v;
}
@Override
public void onArticleSelected(String bID){
//code to execute on click
Fragment Fragment_one;
FragmentManager man= getFragmentManager();
FragmentTransaction tran = man.beginTransaction();
Fragment_one = new BreweryPage2();
final Bundle bundle = new Bundle();
bundle.putString("breweryIDSent", bID);
Fragment_one.setArguments(bundle);
tran.replace(R.id.main, Fragment_one);//tran.
tran.addToBackStack(null);
tran.commit();
}
}
И когда выполняется это onArticleSelected, он не загружает новый фрагмент. Теоретически, что должно произойти, Фрагмент, содержащий tabhost StatisticsTab
, должен быть заменен новым фрагментом в OnArticleSelected