0

我是新开发的android应用程序,请原谅我可能犯的任何愚蠢错误。在问题: 我正在做一个应用程序,其主要活动布局屏幕包含一些东西,并有一个导航抽屉接线。现在我试图使用导航抽屉中的条目来调用各种片段,并显示它们我的主要活动。但是,当我运行我的代码片段时,我得到一个活动被毁坏错误我附上了我的代码以供参考。我认为问题出在我对容器所做的一切。为了让片段覆盖我的主要活动的整个屏幕,我给了片段容器作为根布局,因为我不确定如何去做这件事。它处理项目的点击从导航抽屉主要活动的绘图片段

class DrawerItemClickListener extends FragmentActivity implements ListView.OnItemClickListener { 
@Override 
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
    selectItem(position); 
} 

private void selectItem(int position) { 
    Fragment mFragment = null; 
    switch(position) { 
     case 0: 
      mFragment = new AnnouncementFragment(); 
      Bundle args = new Bundle(); 
      args.putInt(null, position); 
      break; 
     case 1: 
      break; 
     case 2: 
      break; 
     case 3: 
      break; 
     default: 
      break; 
    } 
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction().replace(R.id.drawer_layout, mFragment); 
    transaction.commit(); 
    transaction.addToBackStack(null); 
} 

代码片段主要活动的

public class AnnouncementFragment extends Fragment { 
@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.fragment_announcement, container, false); 
} 

XML布局

代码

<android.support.v4.widget.DrawerLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/drawer_layout" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 

<RelativeLayout 
    android:id = "@+id/main_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/screen_login" 
     android:gravity="center" 
     android:textColor="@android:color/holo_blue_light" 
     android:id="@+id/login_tv" 
     android:layout_alignParentTop="true" 
     android:layout_marginTop="105dp" 
     android:layout_alignParentEnd="true" 
     android:layout_alignParentStart="true" 
     android:textSize="40sp" /> 

    <EditText 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/username_et" 
     android:layout_below="@id/login_tv" 
     android:layout_alignParentStart="true" 
     android:layout_marginTop="45dp" 
     android:layout_alignParentEnd="true" 
     android:hint="@string/username"/> 

    <EditText 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:inputType="textPassword" 
     android:ems="10" 
     android:id="@+id/editText2" 
     android:layout_below="@id/username_et" 
     android:layout_alignParentStart="true" 
     android:layout_marginTop="30dp" 
     android:layout_alignParentEnd="true" 
     android:hint="@string/password" /> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/login" 
     android:id="@+id/login_btn" 
     android:layout_below="@+id/editText2" 
     android:layout_centerHorizontal="true" 
     android:layout_marginTop="25dp" /> 

</RelativeLayout> 

<ListView 
    android:id="@+id/drawer_list" 
    android:layout_width="200dp" 
    android:layout_height="match_parent" 
    android:layout_gravity="start" 
    android:background="#ffeeeeee"/> 

错误

java.lang.IllegalStateException: Activity has been destroyed 
                   at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1399) 
                   at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:637) 
                   at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:616) 
                   at com.it.learnera.DrawerItemClickListener.selectItem(DrawerItemClickListener.java:40) 
                   at com.it.learnera.DrawerItemClickListener.onItemClick(DrawerItemClickListener.java:19) 

我想知道我怎样才能使在主活动布局中的片段平局,而不会造成一片混乱

欢呼和预先感谢

回答

0
FragmentTransaction transaction = getSupportFragmentManager() 
       .beginTransaction() 
       .replace(R.id.drawer_layout, mFragment); // < - first problem (see ad. 1) 
       .commit() // <- third problem (see ad. 3) 

     // second problem (see ad. 2) 
     mFragment = new AnnouncementFragment(); 
     Bundle args = new Bundle(); 
     args.putInt(null, position); 

广告1.您更换,而不是它的容器

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"> 
<!-- The main content view --> 
<FrameLayout 
    android:id="@+id/content_frame" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 
<!-- The navigation drawer --> 
<ListView android:id="@+id/left_drawer" 
    android:layout_width="240dp" 
    android:layout_height="match_parent" 
    android:layout_gravity="start" 
    android:choiceMode="singleChoice" 
    android:divider="@android:color/transparent" 
    android:dividerHeight="0dp" 
    android:background="#111"/> 

drawer_layou - 这是一个视图瓦特HICH认为:

  • 的FrameLayout/id为 - > content_frame

     (container capable to hold "only" one element: fragment/view) 
    
  • 的ListView/id为 - > left_drawer

     (list view for example with menu entries ) 
    

桑尼欧需要更换content_frame

enter image description here

PS以便更好地查看交易的目的,你应该把它在一个声明 - 在 “链/序列”

FragmentTransaction transaction = getSupportFragmentManager() 
       .beginTransaction() 
       .replace(R.id.frame_layout, mFragment) 
       .addToBackStack(null) // add to manager " will remember this fragment - for navigation purpose" 
       .commit() // commit mean do everything from top to bottom on next pass 

广告2.你也需要把ARGS在片段:

 mFragment = new AnnouncementFragment(); 
     Bundle args = new Bundle(); 
     args.putInt(null, position); 
     mFragment.setArguments(args) 

ad 3。当活动的onSaveInstanceState是后

你调用commit

注: 片段事务才能创建/提交的活动节省的状态之前。

如果尝试后提交事务:

  • Activity.onSaveInstanceState()

和之前的以下

  • Activity.onStart()
  • Activity.onResume()

你会得到一个错误。这是因为框架负责保存当前片段的状态,并且如果在保存状态后进行更改,则会丢失它们。 FragmentTransaction与FragmentTransaction.commit致力于

后()定于进程的主线程异步执行

如果您想要立即执行任何这样的未决操作,您可以调用此函数(仅限于主线程)来执行此操作。请注意,所有回调和其他相关行为都将在此调用中完成,因此请注意这是从哪里调用的。

boolean executePendingTransactions();

  • 如果有任何待执行的事务要执行,则返回true。

BTW看看这个文档是指的是延伸FragmentActivity:

https://developer.android.com/reference/android/support/v4/app/FragmentActivity.html

我不知道你定位的API,但你也可以检查这个错误:

http://johnfeng.github.io/blog/2015/05/31/fragment-activity-has-been-destoryed-problem/

(儿童片段的状态未被重置的问题)

嗨,欣赏详细的解释,但它不工作 - Prejith P

与本文有关国家损失,这是我想与您问题相关

http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html

所以你可以尝试拨打而不是commit()(但这不是解决方案):

commitAllowingStateLoss() 

嗨,我刚才自己修好了。我改变了我的导航抽屉的实现,它刚开始工作。我不知道它是怎么固定的,这就是为什么我没有张贴在这里的答案 - Prejith P

是 - 这个问题是你实现你已经尝试过的活动实例后,调用commit()被摧毁什么是堆栈跟踪表明

java.lang.IllegalStateException: Activity has been destroyed 
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1399) 
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:637) 
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:616) 
at com.it.learnera.DrawerItemClickListener.selectItem(DrawerItemClickListener.java:40) 
at com.it.learnera.DrawerItemClickListener.onItemClick(DrawerItemClickListener.java:19) 
               ` 

当你调用commit()你应该确保说:

  • 活动连接
  • 活动是可见的(之前的onSaveInstanceState)
+0

您好,感谢回答。你说的话很有道理,但我仍然像以前一样得到同样的错误。我在我的布局中添加了content_frame,然后用它替换了这个片段容器 –

+0

嗨,欣赏详细的解释,但它不起作用 –

+0

@PrejithP - 查看最后一个链接 – ceph3us

0

的问题是,你打电话transaction.addToBackStack(null);您提交更换后。我建议你做如下:

getSupportFragmentManager().beginTransaction() 
.replace(R.id.drawer_layout, mFragment).addToBackStack(null).apply(); 
+0

嗨,你好吗?用.apply()意味着什么? –

+0

感到困惑,只是使用.commit() –

+0

仍然给我以前的错误 –

0

u需要一个片段片段通信

class DetailActivity extends 

AppCompatActivity implements BioDetailClickView { 
@Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.activity_detail); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    toolbar.setNavigationIcon(R.drawable.navigation); 
    setSupportActionBar(toolbar); 
    FragmentManager fm = getSupportFragmentManager(); 
    Fragment fragment = fm.findFragmentById(R.id.fragment_container); 

    if (fragment == null) { 
     fragment = new Fragment1(); 
     fm.beginTransaction() 
       .add(R.id.fragment_container, fragment) 
       .commit(); 
    } 

} 

public void fragment_transaction(Fragment fragment){ 
    FragmentManager fragmentManager = getSupportFragmentManager(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
    fragmentTransaction.replace(R.id.fragment_container, fragment); 
    fragmentTransaction.addToBackStack(null); 
    fragmentTransaction.commit(); 
} 


@Override 
public void onClickFragmentQuick() { 

    Fragment frag= new Fragment1(); 
    fragment_transaction(frag); 
} 

@Override 
public void onClickFragment2() { 

    Fragment fragment =new Fragment2(); 
    fragment_transaction(fragment); 

} 

@Override 
public void onClickFragment3() { 

    Fragment fragment =new Fragment3(); 
    fragment_transaction(fragment); 

} 

    public interface BioDetailClickView { 
    void onClickFragment1(); 
    void onClickFragment2(); 
    void onClickFragment3(); 


} 
相关问题