Android: Select first item by default in ListView in Master Detail template

Mokkapps picture Mokkapps · Jan 19, 2014 · Viewed 8.5k times · Source

I program a RSS reader with Master Detail flow with a list view on the left, and a detail view on the right.

When the screen is created the right side is empty and no item on the left is selected. How can I load the first item by default?

I found this post which is similar to my problem: Select the first item by default in a Master Detail flow

The code in my ListFragment looks like this:

@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // Set a listener to be invoked when the list should be refreshed.
        listView = (PullToRefreshListView) getListView();

        listView.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh() {
                //refresh list
                refresh_list();
            }
        });

        listView.setVerticalFadingEdgeEnabled(true);

        // Set custom list adapter to the ListView
        adapter = new CustomListAdapter(getActivity(), feed);
        listView.setAdapter(adapter);

        //create button, on click go to website
        final Button btnAddMore = new Button(getActivity());
        btnAddMore.setText(R.string.button_text_end_list);
        btnAddMore.setBackgroundColor(getResources().getColor(R.color.white));
        btnAddMore.setOnClickListener(new OnClickListener() {
               @Override
               public void onClick(View v) {
                    // go to website on click
                    String url = "http://www.test.de";
                    Intent web = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                    startActivity(web);
               }
              });
        //add button at the end of the listview
        listView.addFooterView(btnAddMore);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // Restore the previously serialized activated item position.
        if (savedInstanceState != null
                && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
            setActivatedPosition(savedInstanceState
                    .getInt(STATE_ACTIVATED_POSITION));
        }

        //select the first item in the listview by default
        listView.requestFocusFromTouch();
        listView.setSelection(0);
        listView.performItemClick(listView
                .getAdapter().getView(0, view, null), 0, 0);
    }

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

    Log.d(TAG, "Hallo in ItemListFragment");

    // show ActionBar
    setHasOptionsMenu(true);

    // get reference to activity
    myApp = getActivity().getApplication();

    // check if intent from ItemListActivity is null
    Bundle be = getActivity().getIntent().getExtras();
    if (be == null) {
        // if null read local feed
        feed = ReadFeed(fileName);
        Log.d(TAG, "Lese Feed lokal :" + feed);
    } else {
        // else get extras from the intent
        feed = (RSSFeed) getActivity().getIntent().getExtras().get("feed");
        Log.d(TAG,
                "Intent von ItemListActivity an ItemListFragment vorhanden");
    }
}

But I receive this error:

01-19 06:39:14.723: E/AndroidRuntime(1921): Caused by: java.lang.NullPointerException
01-19 06:39:14.723: E/AndroidRuntime(1921):     at ItemListFragment.onViewCreated(ItemListFragment.java:185)

in the line

listView.requestFocusFromTouch();

Please help me!

CustomListAdapter

public class CustomListAdapter extends BaseAdapter {

    private LayoutInflater layoutInflater;
    public ImageLoader imageLoader;
    public RSSFeed _feed;
    public Date pDate;

    public CustomListAdapter(Activity activity, RSSFeed feed) {

        _feed = feed;

        layoutInflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        imageLoader = new ImageLoader(activity.getApplicationContext());
    }

    public void setNewFeed(RSSFeed feed) {
        // set new Feed list, after refresh
        _feed = feed;
    }

    @Override
    public int getCount() {
        // Set the total list item count
        return _feed.getItemCount();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        // Inflate the item layout and set the views
        View listItem = convertView;
        int pos = position;
        if (listItem == null) {
            listItem = layoutInflater.inflate(R.layout.list_item, null);
        }

        // Initialize the views in the layout
        ImageView iv = (ImageView) listItem.findViewById(R.id.thumb);
        TextView tvTitle = (TextView) listItem.findViewById(R.id.title);
        TextView tvDate = (TextView) listItem.findViewById(R.id.date);
        TextView comment_bubble = (TextView) listItem.findViewById(R.id.comment_bubble);

        // Set the views in the layout
        imageLoader.DisplayImage(_feed.getItem(pos).getImage(), iv);
        tvTitle.setText(_feed.getItem(pos).getTitle());

        // calculate the time difference to the actual system time
        String pubDate = _feed.getItem(pos).getDate();
        SimpleDateFormat df = new SimpleDateFormat(
                "EEE, dd MMM yyyy HH:mm:ss",Locale.ENGLISH);
        try {
            try {
                pDate = df.parse(pubDate);
            } catch (java.text.ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            pubDate = "Vor "
                    + DateUtils.getDateDifference(pDate);
        } catch (ParseException e) {
            Log.e("DATE PARSING", "Error parsing date..");

        }
        //set time difference
        tvDate.setText(pubDate);

        //set comment in bubble
        comment_bubble.setText(_feed.getItem(pos).getComment());

        return listItem;
    }
}

Answer

Gopal Gopi picture Gopal Gopi · Jan 19, 2014

for Fragments, onViewCreated() will be called prior to onActivityCreated() and here you are initializing ListView in onActivityCreated() and using it onViewCreated() which leads to NullPointerException (as ListView is still not initialized). Instead you can initialize it on onViewCreated() and use in onActivityCreated()...

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    listView = (PullToRefreshListView) getListView();

    listView.setOnRefreshListener(new OnRefreshListener() {
        @Override
        public void onRefresh() {
            //refresh list
            refresh_list();
        }
    });

    listView.setVerticalFadingEdgeEnabled(true);

    // Set custom list adapter to the ListView
    adapter = new CustomListAdapter(getActivity(), feed);
    listView.setAdapter(adapter);
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            // handle List item click here...
        }
    });
    ListAdapter adapter = listView.getAdapter();
    listView.performItemClick(listView.getChildAt(0), 0, adapter.getItemId(0)); // this will call OnItemClickListener
        ......
}