AndroidStudio - 碎片中的错误

时间:2015-12-19 05:15:41

标签: android android-fragments android-studio

我试图按照教程实现片段。下面是我的代码..

主要活动

    package example.org.myfragment;

import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{

    private ActionBarDrawerToggle actionBarDrawerToggle;
    private DrawerLayout drawerLayout;
    private ListView navList;
    private FragmentTransaction fragmentTransaction;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
        navList = (ListView) findViewById(R.id.navList);
        ArrayList<String> navArray = new ArrayList<String>();

        navArray.add("Notifications");
        navArray.add("My Profile");
        navArray.add("Home");
        navArray.add("Friends");
        navArray.add("Messages");
        navArray.add("Chat");
        navArray.add("Settings");
        navArray.add("Search");

        navList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_activated_1,navArray);
        navList.setAdapter(adapter);
        navList.setOnItemClickListener(this);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,R.string.opendrawer,R.string.closedrawer);
        drawerLayout.setDrawerListener(actionBarDrawerToggle);

        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayShowHomeEnabled(true);
        actionBar.setDisplayHomeAsUpEnabled(true);
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentTransaction = fragmentManager.beginTransaction();

        loadSelection(0);


        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    private void loadSelection(int i){
        navList.setItemChecked(i, true);

        switch (i){
            case 0:
                Notifications notifications = new Notifications();
                fragmentTransaction.replace(R.id.fragmentHolder,notifications);
                fragmentTransaction.commit();
                break;
            case 1:
                MyProfile myProfile = new MyProfile();
                fragmentTransaction.replace(R.id.fragmentHolder,myProfile);
                fragmentTransaction.commit();
                break;
            case 2:
                Home home = new Home();
                fragmentTransaction.replace(R.id.fragmentHolder,home);
                fragmentTransaction.commit();
                break;
            case 3:
                Friends friends = new Friends();
                fragmentTransaction.replace(R.id.fragmentHolder,friends);
                fragmentTransaction.commit();
                break;
            case 4:
                Messages messages = new Messages();
                fragmentTransaction.replace(R.id.fragmentHolder,messages);
                fragmentTransaction.commit();
                break;
            case 5:

                break;
            case 6:

                break;
            case 7:

                break;
        }

    }

    @Override
    public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
        super.onPostCreate(savedInstanceState, persistentState);
        actionBarDrawerToggle.syncState();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }else if (id==android.R.id.home){
            if(drawerLayout.isDrawerOpen(navList)){
                drawerLayout.closeDrawer(navList);
            }else{
                drawerLayout.openDrawer(navList);
            }
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        loadSelection(position);

        drawerLayout.closeDrawer(navList);
    }
}

activity_main.xml中

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

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/fragmentHolder">

    </FrameLayout>

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#dedede"
        android:layout_gravity="start"
        android:id="@+id/navList">
    </ListView>

</android.support.v4.widget.DrawerLayout>

fragment_notifications.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="example.org.myfragment.Notifications">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/Notifications"
        android:gravity="center|top"/>


</FrameLayout>

的strings.xml

<resources>
    <string name="app_name">MyFragment</string>
    <string name="action_settings">Settings</string>
    <string name="opendrawer">Open</string>
    <string name="closedrawer">Close</string>

    <!-- TODO: Remove or change this placeholder text -->
    <string name="Notifications">Notifications</string>

    <!-- TODO: Remove or change this placeholder text -->
    <string name="MyProfile">MyProfile</string>

    <!-- TODO: Remove or change this placeholder text -->
    <string name="Home">Home</string>

    <!-- TODO: Remove or change this placeholder text -->
    <string name="Friends">Friends</string>

    <!-- TODO: Remove or change this placeholder text -->
    <string name="Messages">Messages</string>

</resources>

logcat的:

12-19 00:33:20.054 2625-2625/? I/art: Not late-enabling -Xcheck:jni (already on)
12-19 00:33:20.054 2625-2625/? I/art: Late-enabling JIT
12-19 00:33:20.058 2625-2625/? I/art: JIT created with code_cache_capacity=2MB compile_threshold=1000
12-19 00:33:20.151 2625-2625/example.org.myfragment W/System: ClassLoader referenced unknown path: /data/app/example.org.myfragment-2/lib/x86
12-19 00:33:20.362 2625-2651/example.org.myfragment D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
12-19 00:33:20.443 2625-2651/example.org.myfragment I/OpenGLRenderer: Initialized EGL, version 1.4
12-19 00:33:20.487 2625-2651/example.org.myfragment W/EGL_emulation: eglSurfaceAttrib not implemented
12-19 00:33:20.487 2625-2651/example.org.myfragment W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xabf3bda0, error=EGL_SUCCESS
12-19 00:33:21.221 2625-2625/example.org.myfragment I/Choreographer: Skipped 42 frames!  The application may be doing too much work on its main thread.
12-19 00:33:33.712 2625-2625/example.org.myfragment D/AndroidRuntime: Shutting down VM
12-19 00:33:33.712 2625-2625/example.org.myfragment E/AndroidRuntime: FATAL EXCEPTION: main
                                                                      Process: example.org.myfragment, PID: 2625
                                                                      java.lang.IllegalStateException: commit already called
                                                                          at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:621)
                                                                          at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:613)
                                                                          at example.org.myfragment.MainActivity.loadSelection(MainActivity.java:89)
                                                                          at example.org.myfragment.MainActivity.onItemClick(MainActivity.java:155)
                                                                          at android.widget.AdapterView.performItemClick(AdapterView.java:310)
                                                                          at android.widget.AbsListView.performItemClick(AbsListView.java:1145)
                                                                          at android.widget.AbsListView$PerformClick.run(AbsListView.java:3042)
                                                                          at android.widget.AbsListView$3.run(AbsListView.java:3879)
                                                                          at android.os.Handler.handleCallback(Handler.java:739)
                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                          at android.os.Looper.loop(Looper.java:148)
                                                                          at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
12-19 00:33:36.026 2625-2625/? I/Process: Sending signal. PID: 2625 SIG: 9

当我点击任何片段时,应用程序崩溃了.. 第一个片段&#34; Notifications&#34;根本没有出现..

3 个答案:

答案 0 :(得分:1)

尝试做这样的事情::

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{

private ActionBarDrawerToggle actionBarDrawerToggle;
private DrawerLayout drawerLayout;
private ListView navList;
private FragmentTransaction fragmentTransaction;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
    navList = (ListView) findViewById(R.id.navList);
    ArrayList<String> navArray = new ArrayList<String>();

    navArray.add("Notifications");
    navArray.add("My Profile");
    navArray.add("Home");
    navArray.add("Friends");
    navArray.add("Messages");
    navArray.add("Chat");
    navArray.add("Settings");
    navArray.add("Search");

    navList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_activated_1,navArray);
    navList.setAdapter(adapter);
    navList.setOnItemClickListener(this);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,R.string.opendrawer,R.string.closedrawer);
    drawerLayout.setDrawerListener(actionBarDrawerToggle);

    ActionBar actionBar = getSupportActionBar();
    actionBar.setDisplayShowHomeEnabled(true);
    actionBar.setDisplayHomeAsUpEnabled(true);
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentTransaction = fragmentManager.beginTransaction();

   // loadSelection(0);


    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });
}

private void loadSelection(int i){
    navList.setItemChecked(i, true);

    switch (i){
        case 0:
            Notifications notifications = new Notifications();
            fragmentTransaction.replace(R.id.fragmentHolder,notifications).commit();

            break;
        case 1:
            MyProfile myProfile = new MyProfile();
            fragmentTransaction.replace(R.id.fragmentHolder,myProfile).commit();

            break;
        case 2:
            Home home = new Home();
            fragmentTransaction.replace(R.id.fragmentHolder,home).commit();

            break;
        case 3:
            Friends friends = new Friends();
            fragmentTransaction.replace(R.id.fragmentHolder,friends).commit();

            break;
        case 4:
            Messages messages = new Messages();
            fragmentTransaction.replace(R.id.fragmentHolder,messages).commit();

            break;
        case 5:

            break;
        case 6:

            break;
        case 7:

            break;
    }

}

@Override
public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
    super.onPostCreate(savedInstanceState, persistentState);
    actionBarDrawerToggle.syncState();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }else if (id==android.R.id.home){
        if(drawerLayout.isDrawerOpen(navList)){
            drawerLayout.closeDrawer(navList);
        }else{
            drawerLayout.openDrawer(navList);
        }
    }

    return super.onOptionsItemSelected(item);
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    loadSelection(position);

    drawerLayout.closeDrawer(navList);
}

}

答案 1 :(得分:1)

不要全局声明FragmentTransaction个对象。每次单击列表项时,都必须创建FragmentTransaction的新对象。

因此,在切换案例后,在loadSelection方法中定义FragmentTransaction。

private void loadSelection(int i){
        Fragment fragment;

        switch (i){
            case 0:
                fragment = new Notifications();
                break;
            case 1:
                fragment = new MyProfile();
                break;
            ......
        }

        if(fragment != null) {
            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.replace(R.id.fragmentHolder , fragment);
            ft.commit();
        }
}

答案 2 :(得分:1)

每次更改片段

时都需要使用New FragmentTransaction
private void loadSelection(int i){
        navList.setItemChecked(i, true);

        switch (i){
            case 0:

                Notifications notifications = new Notifications();
                getSupportFragmentManager().beginTransaction().replace(R.id.fragmentHolder,notifications).commit();

                break;
            case 1:

                MyProfile myProfile = new MyProfile();
                getSupportFragmentManager().beginTransaction().replace(R.id.fragmentHolder,myProfile).commit();

                break;
            case 2:

                Home home = new Home();
                getSupportFragmentManager().beginTransaction().replace(R.id.fragmentHolder,home).commit();

                break;
            case 3:

                Friends friends = new Friends();
                getSupportFragmentManager().beginTransaction().replace(R.id.fragmentHolder,friends).commit();

                break;
            case 4:
                Messages messages = new Messages();
                getSupportFragmentManager().beginTransaction().replace(R.id.fragmentHolder,messages).commit();

                break;
            case 5:

                break;
            case 6:

                break;
            case 7:

                break;
        }

    }