Question

Today I was making a new app when I saw the normal way of constructing activities had changed. I'm trying to fill a listview with data from my database but I cannot get it to work. The rootview is the problem I'm guessing.

Following code is an old activity example that works as it should (I tested it):

public class TrackNewActivity extends Activity {

    List<TrackSave> tracks = new ArrayList<TrackSave>();

    private DatabaseHelper db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_track_save);

        db = new DatabaseHelper(this);
        tracks = db.getAllSavedTracks();
        fillTracks();
    }

    private void fillTracks() {
        TrackAdapter trackAdapter = new TrackAdapter(getApplicationContext(),
                tracks);
        final ListView listView = (ListView) findViewById(R.id.listView);
        listView.setAdapter(trackAdapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parentView, View childView,
                    int position, long id) {
            }
        });
    }
}

Note the setContentView is set to a fragment view I actually want to use. This fragment_track_save.java just contains a Linearlayout with a listview to diplsay the items. Unfortunately following code does not work where I try to get the same as old activity example:

public class TrackSaveActivity extends ActionBarActivity {

    List<TrackSave> tracks = new ArrayList<TrackSave>();

    static View rootView;
    private DatabaseHelper db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_track);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment()).commit();
        }

        db = new DatabaseHelper(this);
        tracks = db.getAllSavedTracks();
        fillTracks();
    }

    private void fillTracks() {
        TrackAdapter trackAdapter = new TrackAdapter(getApplicationContext(),
                tracks);
        final ListView listView = (ListView) rootView
                .findViewById(R.id.listView);
        listView.setAdapter(trackAdapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parentView, View childView,
                    int position, long id) {
            }
        });
    }

    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            rootView = inflater.inflate(R.layout.fragment_track_save,
                    container, false);

            return rootView;
        }
    }
}

The problem here occurs when I try to find the listview. It always refers to a nullpointer exception because it cannot find the listview, that's my guess.

activity_track.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="*.TrackActivity"
    tools:ignore="MergeRootFrame" />

Hopefully I made it clear.

Was it helpful?

Solution

If you want to use a fragment you should have a MainActivity with something like this:

    public class MainActivity extends ActionBarActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            if (savedInstanceState == null) {
                getFragmentManager().beginTransaction()
                        .add(R.id.container, new MyFragment())
                        .commit();
            }
        }
    }

Then, a class for the Fragment, in this case a ListFragment:

    public class MyFragment extends ListFragment {

        public MyFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);

            ArrayList<String> la = new ArrayList<String>();
            la.add("Item1");
            la.add("Item2");

            ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
                    android.R.layout.simple_list_item_1, la);

            setListAdapter(adapter);
            return rootView;
        }

fragment_main Should look something like this:

    <LinearLayout 
        // ....>

        <ListView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </ListView>

    </LinearLayout>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top