Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select first item in ListView with Cursor Loader

I have an android app that (on tablets) uses the master-detail flow to show a list of forecasts on the left and detailed information on the right. I want to be able to select the first item when the application loads.

I have code in the onLoadFinished method that sets the selected index. I implemented this because sometimes the user would select an item, and if they changed the orientation it would be off screen. I used this following method to ensure that once it loads the proper item is selected again:

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    mForecastAdapter.swapCursor(data);

    // If we have a selected index - select it.
    if(mSelectedIndex != ListView.INVALID_POSITION) {
        mForecastListView.setSelection(mSelectedIndex);
    }
}

I tried adding an else statement that checked if a tablet was being used, to select the first item. The code was executed, but it seemed to happen before the listview actually loaded and the item was not selected. Where should I put the code to select the first item, upon app opening?

EDIT Here is a method that I have tried, to no luck:

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    mForecastAdapter.swapCursor(data);

    // If we have a selected index - select it.
    if(mSelectedIndex != ListView.INVALID_POSITION) {
        mForecastListView.setSelection(mSelectedIndex);
    } else if(mForecastAdapter.IsTwoPane()){
        mForecastListView.setSelection(0);
    }
}
like image 678
AdamMc331 Avatar asked Oct 17 '14 00:10

AdamMc331


3 Answers

I would do the following, I've done it for listviews in general, should work with Cursors too.

In your adapter, create a field for selected position

public int selectedPos = 0;//use setter/getter eventually

Now make sure that the OnItemClickListener/OnItemSelectedListener for your listView does the following:

<YOUR_ADAPTER_INSTANCE>.selectedPos = positionSelected;

Finally, in getView() for your adapter, do the following:

if(position == selectedPos) {
   //do what you want to show selection
} else {
   //do what you want for default state of the list items
}

This will ensure that when the list is being shown for the first time, selectedPos will be 0, and as such the first position will be selected according to above.

If you want to persist your user's selection through orientationChange and the likes, you'll just need to make sure that once you are 'restored' you pass on the information to the adapter.

like image 83
Hahn Avatar answered Nov 16 '22 14:11

Hahn


If you are trying to restore the listview due to configuration change, maybe saving the state would help? For example:

private Parcelable mForceastListViewSavedState;
private int mForecastListViewPositionSavedState;
private static final String sForecastListViewSavedStateKey = "ForecastListViewSavedState";
private static final String sForecastListViewPositionSavedState = "ForecastListViewPositionSavedState";

@Override
public void onSaveInstanceState(Bundle outState) {
    if(mForecastListView != null){
        outState.putParcelable(sForecastListViewSavedStateKey, mForecastListView.onSaveInstanceState());
        outState.putInt(sForecastListViewPositionSavedState, mForecastListView.getFirstVisiblePosition());
    }
    super.onSaveInstanceState(outState);
}

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

    //Restore InstanceState
    if (savedInstanceState != null){
        mForceastListViewSavedState = savedInstanceState.getParcelable(sForecastListViewSavedStateKey);
        mForecastListViewPositionSavedState = savedInstanceState.getInt(sForecastListViewPositionSavedState);
    }
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    mForecastAdapter.swapCursor(data);

    //Restore ListView State
    if (mForceastListViewSavedState != null){
        mForecastListView.onRestoreInstanceState(mForceastListViewSavedState);
        mForecastListView.setSelection(mForecastListViewPositionSavedState);
    }
}
like image 22
Eric Avatar answered Nov 16 '22 15:11

Eric


I solve the problem ,though this question is out of date. my solution is:

@Override
public void onLoadFinished(Loader<Cursor> cursorLoader,Cursor cursor){

    mForecastAdapter.swapCursor(cursor);
    if(mPositon!=ListView.INVALID_POSITION){
        mListView.smoothScrollToPosition(mPositon);
    }else if(mTwoPane){
        {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    mListView.performItemClick(mListView, 0, mListView.getAdapter().getItemId(0));                        }
            });
        }
    }
}
like image 1
LiLin Avatar answered Nov 16 '22 14:11

LiLin