指定的子级已有父级异常

时间:2013-07-09 12:27:47

标签: java android tabs android-fragments

我在我的代码中使用Fragments,因为TabActivity已被弃用,但我在Logcat中收到此错误:

07-09 09:19:40.936: E/AndroidRuntime(5935): FATAL EXCEPTION: main
07-09 09:19:40.936: E/AndroidRuntime(5935): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.view.ViewGroup.addViewInner(ViewGroup.java:1976)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.view.ViewGroup.addView(ViewGroup.java:1871)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.view.ViewGroup.addView(ViewGroup.java:1828)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.view.ViewGroup.addView(ViewGroup.java:1808)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.support.v4.app.NoSaveStateFrameLayout.wrap(NoSaveStateFrameLayout.java:40)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:915)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.os.Handler.handleCallback(Handler.java:587)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.os.Handler.dispatchMessage(Handler.java:92)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.os.Looper.loop(Looper.java:130)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at android.app.ActivityThread.main(ActivityThread.java:3691)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at java.lang.reflect.Method.invokeNative(Native Method)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at java.lang.reflect.Method.invoke(Method.java:507)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
07-09 09:19:40.936: E/AndroidRuntime(5935):     at dalvik.system.NativeStart.main(Native Method)

以下是我添加标签的代码:

public class RelatorioPontos extends FragmentActivity {

     private FragmentTabHost mTabHost;
     private String id;

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

            setContentView(R.layout.relatorio_layout);
            mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
            mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);

            id = getIntent().getStringExtra("idPonto");

            Bundle args = new Bundle();
            args.putString("id", id);

            mTabHost.addTab(mTabHost.newTabSpec("dados").setIndicator("Dados"), DadosPonto.class, args);
            mTabHost.addTab(mTabHost.newTabSpec("analises").setIndicator("Análises"), AnalisesPonto.class, args);
            mTabHost.addTab(mTabHost.newTabSpec("multimidia").setIndicator("Multimídia"), ArquivosMultimidia.class, args);
        }


}

以下是第一个标签类:

public class DadosPonto extends Fragment{

    Ponto ponto = new Ponto();
    private String id;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        id = getArguments().getString("id");

        PontoDAO pdao = new PontoDAO(getActivity().getApplicationContext());
        ponto = pdao.retornaPonto(id);
    }

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

        if (container == null) {
            return null;
        }

        View view = inflater.inflate(R.layout.dados_ponto_layout, container, false);

        View idPonto = view.findViewById(R.id.idPonto);
        View idUser = view.findViewById(R.id.idUser);
        View pontoNome = view.findViewById(R.id.nomePonto);
        View dtCampo = view.findViewById(R.id.dtCampo);
        View projeto = view.findViewById(R.id.projeto);
        View UTMEste = view.findViewById(R.id.utmEste);
        View UTMNorte = view.findViewById(R.id.utmNorte);
        View UTMFuso = view.findViewById(R.id.utmFuso);
        View UTMHemisferio = view.findViewById(R.id.utmHemisferio);
        View latDec = view.findViewById(R.id.latDec);
        View longDec = view.findViewById(R.id.longDec);
        View altitude = view.findViewById(R.id.altitude);
        View localidade = view.findViewById(R.id.localidade);
        View outrasUG = view.findViewById(R.id.outrasUG);
        View descPonto = view.findViewById(R.id.descPonto);
        View complemento = view.findViewById(R.id.complemento);
        View equipe = view.findViewById(R.id.equipe);
        View fonteUG = view.findViewById(R.id.fonteUG);

        ((TextView) idPonto).setText("Id do ponto: " + ponto.getIdPonto());
        ((TextView) idUser).setText("Id do usuário: " + ponto.getIdUsuario()+"");
        ((TextView) pontoNome).setText("Nome do ponto: " + ponto.getPontoNome());
        ((TextView) dtCampo).setText("Data do campo: " + ponto.getDtCampo());
        ((TextView) projeto).setText("Projeto: " + ponto.getProjeto()+"");
        ((TextView) UTMEste).setText("UTM Este: " + String.valueOf(ponto.getUTMEste()));
        ((TextView) UTMNorte).setText("UTM Norte: " + String.valueOf(ponto.getUTMNorte()));
        ((TextView) UTMFuso).setText("UTM Fuso: " + ponto.getUTMFuso()+"");
        ((TextView) UTMHemisferio).setText("UTM Hemisfério: " + ponto.getUTMHemisferio());
        ((TextView)latDec).setText("Latitude decimal: " + String.valueOf(ponto.getLatDec()));
        ((TextView)longDec).setText("Longitude decimal: " + String.valueOf(ponto.getLongDec()));
        ((TextView)altitude).setText("Altitude: " + ponto.getAltitude()+"");
        ((TextView)localidade).setText("Localidade: " + ponto.getLocalidade());
        ((TextView)outrasUG).setText("Outras Unidades Geológicas: " + ponto.getOutrasUG());
        ((TextView)descPonto).setText("Descrição do ponto: " + ponto.getDescPonto());
        ((TextView)complemento).setText("Complemento da descrição: " + ponto.getComplement());
        ((TextView)equipe).setText("Equipe: " + ponto.getEquipe());
        ((TextView)fonteUG).setText("Fonte da Unidade Geológica: " + ponto.getFonteUG());

        return view;
    }
}

第二个标签活动:

public class AnalisesPonto extends ListFragment {

    private ArrayList<AnaliseEstrutural> analises;
    AnalisesDAO andao;
    String idPonto;


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

        idPonto = getArguments().getString("id");



        if (container == null) {
            return null;
        }

        View lista = inflater.inflate(R.layout.analises_ponto_layout, container, false);

        //ListView analisesList = (ListView) lista.findViewById(android.R.id.list);
        View analisesList = (ListView) lista.findViewById(android.R.id.list);

        andao = new AnalisesDAO(getActivity().getApplicationContext());
        analises = andao.relatorioAnalises(idPonto);

        AnalisesAdapter analisesAdapter = new AnalisesAdapter(getActivity().getApplicationContext());
        for(int j = 0; j < analises.size(); j++) {
            analisesAdapter.add(analises.get(j));
        }

        return analisesList;
    }       
}

第三类代码与第二类代码相同,所以我不会在这里发布,第一个选项卡效果很好但是当我进入第二个选项卡时,我得到了这个例外。

我怀疑我是如何处理这个例外的?

1 个答案:

答案 0 :(得分:10)

最有可能在发生配置更改时遇到此异常,例如屏幕方向。它抱怨视图仍然附加到先前的视图层次结构,因此您需要将其删除并将其重新附加到当前视图层次结构中。

public class DadosPonto extends Fragment{

    // Keep a reference to the view; 
    private View view;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (view == null) {
            view = inflater.inflate(R.layout.dados_ponto_layout, container, false);
            View idPonto = view.findViewById(R.id.idPonto);
            // .....
        } else {
            // If we are returning from a configuration change:
            // "view" is still attached to the previous view hierarchy
            // so we need to remove it and re-attach it to the current one
            ViewGroup parent = (ViewGroup) view.getParent();
            parent.removeView(view);
        }
        return view;
    }
}