处理方向变化

时间:2015-06-04 01:32:43

标签: android android-orientation onconfigurationchanged

我一直在为课程开发一个项目,我已经达到了一点,经过谷歌搜索仍无法找到解决方案。

这是我得到的错误

06-04 15:07:55.398    3480-3480/com.example.chema.agenda E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.chema.agenda, PID: 3480
java.lang.NullPointerException
        at com.example.chema.agenda.MainActivity_detalleFragment.onActivityCreated(MainActivity_detalleFragment.java:50)
        at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1797)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:979)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
        at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:458)
        at android.os.Handler.handleCallback(Handler.java:808)
        at android.os.Handler.dispatchMessage(Handler.java:103)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:5296)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
        at dalvik.system.NativeStart.main(Native Method)

当我从横向旋转到肖像时,这是我收到错误的类。

public class MainActivity_detalleFragment extends Fragment {

public MainActivity_detalleFragment() {
}


public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // retain this fragment

}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    ViewGroup root = (ViewGroup) inflater
            .inflate(R.layout.fragment_detalle, null);


    return root;

}
public void onActivityCreated(Bundle savedInstanceState){
    super.onActivityCreated(savedInstanceState);
    TextView campoTexto = (TextView)getActivity().findViewById(R.id.textViewNombre);
    TextView campoTexto2 = (TextView)getActivity().findViewById(R.id.textView8);
    ImageView im = (ImageView)getActivity().findViewById(R.id.imageView);
    im.setImageBitmap(MainActivity.getContacto().getImagen());
    campoTexto.setText(MainActivity.getContacto().getName() +" "+  MainActivity.getContacto().getApellidos());
    campoTexto2.setText(MainActivity.getContacto().getPhoneNumber());


}

}

正好在这条车道上 的 im.setImageBitmap(MainActivity.getContacto()getImagen());

这是我的主要活动

public class MainActivity extends ActionBarActivity implements FragmentListar.OnItemClickedListener{
private DrawerLayout desplegable;
private ActionBarDrawerToggle toggle;
Integer[] imgid = {
        R.mipmap.create_contact,
        R.mipmap.delete_action_bar,
        R.mipmap.edit_contact
};
public ListView opciones;
private boolean dosFragmentos;
static Contact contacto;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    String[] valores = getResources().getStringArray(R.array.despl);
    CustomListAdapter adapter = new CustomListAdapter(this, valores, imgid);
    desplegable = (DrawerLayout) findViewById(R.id.drawer_layout);
    opciones = (ListView) findViewById(R.id.left_drawer);
    opciones.setAdapter(adapter);

    toggle = new ActionBarDrawerToggle(this, desplegable, R.mipmap.white_background,
            R.string.drawer_open, R.string.drawer_close);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);

    FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
    tx.replace(R.id.content_frame, Fragment.instantiate(MainActivity.this, "com.example.chema.agenda.FragmentListar"));
    tx.commit();

    opciones.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            TextView c = (TextView) view.findViewById(R.id.item);
            String item = c.getText().toString();
            if (item.equals("Crear")) {
                desplegable.setDrawerListener(new DrawerLayout.SimpleDrawerListener() {
                    @Override
                    public void onDrawerClosed(View drawerView) {
                        super.onDrawerClosed(drawerView);
                        if(getResources().getConfiguration().orientation== Configuration.ORIENTATION_LANDSCAPE){
                            FragmentManager fragMgr = getSupportFragmentManager();
                            Fragment currentFragment = fragMgr.findFragmentById(R.id.content_frame2);
                            FragmentTransaction fragTrans = fragMgr.beginTransaction();
                            fragTrans.remove(currentFragment);

                            FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
                            tx.replace(R.id.content_frame_landscape, Fragment.instantiate(MainActivity.this, "com.example.chema.agenda.CountFragment"));
                            tx.commit();
                        }else {
                            FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
                            tx.replace(R.id.content_frame, Fragment.instantiate(MainActivity.this, "com.example.chema.agenda.CountFragment"));
                            tx.commit();
                        }
                    }
                });
                desplegable.closeDrawer(opciones);
            }
            if (item.equals("Borrar")) {
                desplegable.setDrawerListener(new DrawerLayout.SimpleDrawerListener() {
                    @Override
                    public void onDrawerClosed(View drawerView) {
                        super.onDrawerClosed(drawerView);
                        FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
                        tx.replace(R.id.content_frame, Fragment.instantiate(MainActivity.this, "com.example.chema.agenda.FragmentDelete"));
                        tx.commit();
                    }
                });
                desplegable.closeDrawer(opciones);
            }
        }
    });



}

public void onBackPressed() {
    Log.d("CDA", "onBackPressed Called");
    Intent setIntent = new Intent(this, MainActivity.class);

    startActivity(setIntent);
}

public void OnItemClicked(int id) {
    DatabaseHandler d1 = new DatabaseHandler(this.getApplicationContext());
    contacto = d1.getContact(id);


    FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
    if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
        tx.replace(R.id.content_frame2, Fragment.instantiate(MainActivity.this, "com.example.chema.agenda.MainActivity_detalleFragment"));
        tx.commit();
    }

    else {
        if ((getResources().getConfiguration().screenLayout &
                Configuration.SCREENLAYOUT_SIZE_MASK) ==
                Configuration.SCREENLAYOUT_SIZE_LARGE) {
            tx.replace(R.id.content_frame2, Fragment.instantiate(MainActivity.this, "com.example.chema.agenda.MainActivity_detalleFragment"));
            tx.commit();

        } else {
            tx.replace(R.id.content_frame, Fragment.instantiate(MainActivity.this, "com.example.chema.agenda.MainActivity_detalleFragment"));
            tx.commit();
        }
    }

}

@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();
    if (toggle.onOptionsItemSelected(item)) {

    }
    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    toggle.syncState();
}

public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    toggle.onConfigurationChanged(newConfig);


    // Checks the orientation of the screen

}
static public Contact getContacto(){
    return contacto;
}

我的FragmentListar类:

public class FragmentListar extends ListFragment {

private List<Contact> c1;
OnItemClickedListener mListener = sDummyCallbacks;

private static OnItemClickedListener sDummyCallbacks = new OnItemClickedListener() {
    @Override
    public void OnItemClicked(int id) {
    }
};

public FragmentListar() {
    c1 = null;
}


public interface OnItemClickedListener {
    public void OnItemClicked(int id);
}

public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnItemClickedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement OnItemClickedListener");
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);

    DatabaseHandler d1 = new DatabaseHandler(getActivity().getApplicationContext());
    this.c1 = d1.getAllContacts();

    d1.close();

    // Estable cemos el Adapter a la Lista del Fragment
    setListAdapter(new ContactListAdapter(getActivity(),
            c1));
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    // TODO Auto-generated method stub
    super.onListItemClick(l, v, position, id);

    // Mostramos un mensaje con el elemento pulsado


    mListener.OnItemClicked(c1.get(position).getID());

}

我真的不知道为什么MainActivity在轮换时重新启动时会调用MainActivity_detalleFragment。它应该是FragmentListar中的一个名为。

将contacto修复为非静态

public void OnItemClicked(int id) {

    Bundle bundle = new Bundle();
    bundle.putString("id", Integer.toString(id));
    // set Fragmentclass Arguments
    MainActivity_detalleFragment fragobj = new MainActivity_detalleFragment();
    fragobj.setArguments(bundle);

    FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
    if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
        tx.replace(R.id.content_frame2, Fragment.instantiate(MainActivity.this, "com.example.chema.agenda.MainActivity_detalleFragment"));
        tx.commit();
    }

    else {
        if ((getResources().getConfiguration().screenLayout &
                Configuration.SCREENLAYOUT_SIZE_MASK) ==
                Configuration.SCREENLAYOUT_SIZE_LARGE) {
            tx.replace(R.id.content_frame2, Fragment.instantiate(MainActivity.this, "com.example.chema.agenda.MainActivity_detalleFragment"));
            tx.commit();

        } else {
            tx.replace(R.id.content_frame, Fragment.instantiate(MainActivity.this, "com.example.chema.agenda.MainActivity_detalleFragment"));
            tx.commit();
        }
    }

}

1 个答案:

答案 0 :(得分:0)

永远不要使用静态方法从活动中检索信息!

这里发生的是,当您单击列表中的项目时,将填充contacto。在旋转屏幕后,该变量及其指向的任何内容都不会保留在屏幕方向上,因此它将为Null,因此为NullPointerException。

老实说你的代码存在一些问题,但问题是关于NPE,所以我会专注于那个。

快速解决此问题的方法是检查getContacto()是否返回Null。还要使MainActivity.getContacto()成为非静态方法(getActivity()。getContacto())。

你需要深入研究的是为什么细节片段完全保留,因为布局可能不包含细节片段而是列表片段,对吗?

您需要考虑的是使用我对问题的评论中提到的Loader。 Loader结果会在方向更改中保留,您根本不会遇到此问题。如果你不必在每次换向后重新加载,它显然会更有效率。

还要考虑您需要在活动中检索联系人的原因。据我所知,你可以在详细信息片段中看到它,为什么不把这段代码移到你的片段中呢?

DatabaseHandler d1 = new DatabaseHandler(this.getApplicationContext());
contacto = d1.getContact(id);

当然片段需要知道id,但这是一件好事,因为那是细节片段应该具有的真实信息。