1

So I have a ListView within a fragment, when the screen rotates the data within that ListView disappears.

Any ideas as to why the ListView might do this? Here is some of my code for the fragment class.

    package com.example.ioiocontroller;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

public class digitalFragment extends Fragment {
    ArrayList<digitalControlObject> digitalList;
    ListView digitalListView;
    View digitalFragmentView;
    Button addDigital;
    Button removeDigital;
    MyAdapter adapter;

    public digitalFragment() {
        // TODO Auto-generated constructor stub
    }

    public View onCreateView(LayoutInflater viewInflation, ViewGroup container,
            Bundle SavedInstantState) {
        digitalList = new ArrayList<digitalControlObject>();
        digitalFragmentView = viewInflation.inflate(
                R.layout.digitalfragment_page, container, false);

        addDigital = (Button) digitalFragmentView
                .findViewById(R.id.digitalAddition);
        removeDigital = (Button) digitalFragmentView
                .findViewById(R.id.digitalRemoval);
        digitalListView = (ListView) digitalFragmentView
                .findViewById(R.id.digitalListView);
        adapter = new MyAdapter(getActivity(), R.id.digitalListView, digitalList);
        digitalListView.setAdapter(adapter);

        // ADDITION CLICK METHOD FOR DIGITAL IO
        addDigital.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                digitalList.add(new digitalControlObject(0,true,true,0));

                adapter.notifyDataSetChanged();
                // create and pass the digitalControlObject to the main activity

            }
        });

        // REMOVAL CLICK METHOD FOR DIGITAL IO
        removeDigital.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

            }
        });

        return digitalFragmentView;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        adapter = new MyAdapter(getActivity(), R.id.digitalListView, digitalList);
        digitalListView.setAdapter(adapter);
        adapter.notifyDataSetChanged();

    }

    public ListView getDigitalListView() {
        return digitalListView;
    }

    public void setDigitalListView(ListView digitalListView) {
        this.digitalListView = digitalListView;
    }

    public View getDigitalFragmentView() {
        return digitalFragmentView;
    }

    public void setDigitalFragmentView(View digitalFragmentView) {
        this.digitalFragmentView = digitalFragmentView;
    }
//////////////////////////////////////////////////////////////////////////////////
    public class MyAdapter extends ArrayAdapter<digitalControlObject> {

        private Context context;

        public MyAdapter (Context context, int textViewResourceId, List<digitalControlObject> items) {
            super(context, textViewResourceId, items);
            this.context = context;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView;
            if (view == null) {
                LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = inflater.inflate(R.layout.digitallistview_layout, null);
            }

            digitalControlObject item = getItem(position);
            if (item != null) {
                TextView itemCol1View = (TextView) view.findViewById(R.id.digcol1);
                TextView itemCol2View = (TextView) view.findViewById(R.id.digcol2);
                TextView itemCol3View = (TextView) view.findViewById(R.id.digcol3);
                //TextView itemCol4View = (TextView) view.findViewById(R.id.digcol4);
                if (itemCol1View != null) {
                    itemCol1View.setText(String.valueOf(item.getPin()));
                }
                if (itemCol2View != null && item.getPinMode()) {
                    itemCol2View.setText("Output");
                }else{
                    itemCol2View.setText("Input");
                }
                if (itemCol3View != null && item.getPowerState()) {
                    itemCol3View.setText("On");
                }else{
                    itemCol3View.setText("Off");
                }
             }

            return view;
        }
    }

}

EDIT:

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

        // Get a layout inflater (inflater from getActivity() or
        // getSupportActivity() works as well)
        LayoutInflater inflater = (LayoutInflater) getActivity()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View newView = inflater.inflate(R.layout.digitalfragment_page, null);
        // This just inflates the view but doesn't add it to any thing.
        // You need to add it to the root view of the fragment
        ViewGroup rootView = (ViewGroup) getView();
        // Remove all the existing views from the root view.
        // This is also a good place to recycle any resources you won't need
        // anymore
        rootView.removeAllViews();
        rootView.addView(newView);
        // Voila, you have the new view setup
    }
Timothy Frisch
  • 2,995
  • 2
  • 30
  • 64

2 Answers2

3

When rotating screen, Android recreates your fragment, so you have to save its state. In your case save digitalList list elements in onSaveInstanceState() method and add them to the adapter during onCreate(Bundle savedInstanceState). Here is a good example: https://stackoverflow.com/a/16819087/1018109

Community
  • 1
  • 1
pelotasplus
  • 9,852
  • 1
  • 35
  • 37
2

From here:

In some special cases, you may want to bypass restarting of your activity based on one or more types of configuration changes. This is done with the android:configChanges attribute in its manifest. For any types of configuration changes you say that you handle there, you will receive a call to your current activity's onConfigurationChanged(Configuration) method instead of being restarted. If a configuration change involves any that you do not handle, however, the activity will still be restarted and onConfigurationChanged(Configuration) will not be called.

Meaning that you need to modify your Android Manifest for the onConfigurationChanged to be called.

EDIT:
See here:

Add something like this to your Activity in the manifest:

android:configChanges="orientation"
Merlevede
  • 8,140
  • 1
  • 24
  • 39