I am having issues trying to restore state of Android Spinners in my application. Currently there are multiple Spinners in my Activity's ListView header that depend on one another, as the selection of one Spinner loads data for the subsequent Spinner.
The problem I am experiencing is, restoring state doesn't seem to work when I manually set selections on the Spinners. I have tried in both onRestoreInstanceState and onResume. It appears setting the selections is asynchronous when looking at the LogCat output. How can I reliably restore state of these Spinners when I have to wait for one to be selected before the other can populated and then set?
EDIT: Added code
Activity's onCreate():
mSecondSpinner = mMyListHeader.findViewById(R.id.second_spinner);
mSecondSpinnerArrayAdapter = new SecondArrayAdapter(MyActivity.this, R.layout.second_spinner_item, new ArrayList<MySecondDto>());
mSecondSpinner.setAdapter(mSecondSpinnerArrayAdapter);
mSecondSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
MySecondDto selectedMySecondDto = (MySecondDto) parent.getItemAtPosition(position);
List<MyThirdDto> myThirdDtos = selectedMySecondDto.getMyThirdDtos();
// Load third spinner with dtos....
}
#Override
public void onNothingSelected(AdapterView<?> parent) {}}
);
mFirstSpinner = mMyListHeader.findViewById(R.id.first_spinner);
mFirstSpinnerAdapter= new FirstArrayAdapter(MyActivity.this, R.layout.first_spinner, mResponse.getAllDtos());
mFirstSpinner.setAdapter(mFirstSpinnerArrayAdapter);
mFirstSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mSecondSpinner.setAdapter(null);
MyFirstDto selectedMyFirstDto = (MyFirstDto ) parent.getItemAtPosition(position);
List<MySecondDto> mySecondDtos = selectedMyFirstDto .getMySecondDtos();
mSecondSpinnerArrayAdapter.clearAndReplaceAll(mySecondDtos);
mSecondSpinner.setAdapter(mSecondSpinnerArrayAdapter);
// If there is only one second dto, disable the spinner
if (mySecondDtos== null || mySecondDtos.size() <= 1)
{
disableSpinner(mSecondSpinner);
}
else
{
// Enable second spinner, select the hint element
enableSpinner(mSecondSpinner);
mSecondSpinner.setSelection(mSecondSpinnerArrayAdapter .getHintIndex());
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {}
});
Activity's onRestoreInstanceState():
mFirstSpinner.setSelection(mFirstAdapterPosition);
mFirstSpinnerArrayAdapter.notifyDataSetChanged();
mSecondSpinner.setSelection(mSecondAdapterPosition);
mSecondSpinnerArrayAdapter.notifyDataSetChanged();
Have u tried this
mySpinner.post(new Runnable() { #Override public void run() { mySpinner.setSelection(position); } });
This might work for you.
There could be a bug in it somewhere, so be careful.
I have a similar situation to you but I had 3 spinners and they get populated depending on the selection of the previous one.
The idea is to store the Indexes/Positions of the Spinners in IndexVariables.
Theses Variables have default value of -1.
Store current values in onSaveInstanceState,
Restore values in onActivityCreated.
In onItemSelected check if selected Item = null, check if the IndexVariable was set (i.e. !-= -1)
If so use it to set Spinner then set IndexVariable back to -1;
Here's the class
(I used NothingSelectedSpinnerAdapter from How to make an Android Spinner with initial text "Select One".
Not really important but just giving a shout out to the guy/girl where I got that code.)
public class SpinnerTestFragment extends Fragment {
private MainActivity activity;
private static final String SELECTED_THEME_IDX_STORAGE_KEY = "mSelectedTheme_IDX_StorageKey";
private static final String SELECTED_AIM_IDX_STORAGE_KEY = "mSelectedAim_IDX_StorageKey";
private static final String SELECTED_GOAL_IDX_STORAGE_KEY = "mSelectedGoal_IDX_StorageKey";
private static String TAG = "SpinnerTestFragment";
private Spinner spnrThemes;
private Spinner spnrAims;
private Spinner spnrGoals;
private String mSelectedTheme;
private String mSelectedAim;
private String mSelectedGoal;
private int mSelectedAimIdx = -1;
private int mSelectedThemeIdx = -1;
private int mSelectedGoalIdx = -1;
//----------------------------------------------------------------------------------------//
public SpinnerTestFragment() {
}//ctor
//----------------------------------------------------------------------------------------//
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
activity = (MainActivity) getActivity();
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_photo, container, false);
spnrThemes = view.findViewById(R.id.spnrThemes);
spnrAims = view.findViewById(R.id.spnrAims);
spnrGoals = view.findViewById(R.id.spnrGoals);
setSpinner(spnrThemes, "Select Theme", ThemesAimsGoals.getThemes());
spnrThemes.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Object selectedItem = parent.getItemAtPosition(position);
if (selectedItem != null) {
mSelectedTheme = selectedItem.toString();
setSpinner(spnrAims, "Select Aim", ThemesAimsGoals.getAims(mSelectedTheme));
} else if(mSelectedThemeIdx != -1){
selectedItem = parent.getItemAtPosition(mSelectedThemeIdx);
mSelectedTheme = selectedItem.toString();
setSpinner(spnrAims, "Select Aim", ThemesAimsGoals.getAims(mSelectedTheme));
parent.setSelection(mSelectedThemeIdx);
mSelectedThemeIdx = -1;
}//Else
}//onItemSelected
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
spnrAims.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Object selectedItem = parent.getItemAtPosition(position);
if (selectedItem != null) {
mSelectedAim = selectedItem.toString();
setSpinner(spnrGoals, "Select Goal", ThemesAimsGoals.getGoals(mSelectedTheme, mSelectedAim));
} else if(mSelectedAimIdx != -1){
selectedItem = parent.getItemAtPosition(mSelectedAimIdx);
mSelectedAim = selectedItem.toString();
setSpinner(spnrGoals, "Select Goal", ThemesAimsGoals.getGoals(mSelectedTheme, mSelectedAim));
parent.setSelection(mSelectedAimIdx);
mSelectedAimIdx = -1;
}//Else
}//onItemSelected
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
spnrGoals.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Object selectedItem = parent.getItemAtPosition(position);
if (selectedItem != null) {
mSelectedGoal = selectedItem.toString();
}else if(mSelectedGoalIdx != -1){
selectedItem = parent.getItemAtPosition(mSelectedGoalIdx);
mSelectedGoal = selectedItem.toString();
parent.setSelection(mSelectedGoalIdx);
mSelectedGoalIdx = -1;
}//Else
}//onItemSelected
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
return view;
}//onCreateView
//----------------------------------------------------------------------------------------//
/**
* Populate Spinner
* #param spnr Spinner to populate
* #param prompt What to show at the start
* #param array Items in the spinner
*/
private void setSpinner(Spinner spnr, String prompt, String[] array) {
spnr.setPrompt(prompt);
ArrayAdapter<CharSequence> adapter = new ArrayAdapter(activity, android.R.layout.simple_spinner_item, array);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spnr.setAdapter(
new NothingSelectedSpinnerAdapter(
adapter,
R.layout.contact_spinner_row_nothing_selected,
activity,
prompt));
}//setSpinner
//----------------------------------------------------------------------------------------//
/**
* Some lifecycle callbacks so that the image can survive orientation chang
*
* #param outState current state of fragment
*/
#Override
public void onSaveInstanceState(Bundle outState) {
Log.d(TAG, "onSaveInstanceState");
super.onSaveInstanceState(outState);
outState.putInt(SELECTED_THEME_IDX_STORAGE_KEY, spnrThemes.getSelectedItemPosition());
outState.putInt(SELECTED_AIM_IDX_STORAGE_KEY, spnrAims.getSelectedItemPosition());
outState.putInt(SELECTED_GOAL_IDX_STORAGE_KEY, spnrGoals.getSelectedItemPosition());
}//onSaveInstanceState
//----------------------------------------------------------------------------------------//
/**
* Rebuilds the Activity/Fragment in the image of the last one.
*
* #param savedInstanceState Info from last session or rotation
*/
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(TAG, "onActivityCreated");
if (savedInstanceState == null)
return;
mSelectedThemeIdx = savedInstanceState.getInt(SELECTED_THEME_IDX_STORAGE_KEY);
mSelectedAimIdx = savedInstanceState.getInt(SELECTED_AIM_IDX_STORAGE_KEY);
mSelectedGoalIdx = savedInstanceState.getInt(SELECTED_GOAL_IDX_STORAGE_KEY);
}//onActivityCreated
}//Cls
Related
I have an activity Advanced Research, with a spinner that contains all category from my db. When i create the activity, this spinner call onSetItemListener in loop. Why?
I try to use onTouchListener but not working, maybe i fail something.
if(risultato.getCategoria().getSottocategorie().toArray() != null && risultato.getCategoria().getSottocategorie().toArray().length != 0){
adapterSpinnerCategoria = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, risultato.getCategoria().getSottocategorie().toArray());
}else{
adapterSpinnerCategoria = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, categoriaVuota);
}
spinnerCategoria.setAdapter(adapterSpinnerCategoria);
public void spinnerChange(AdapterView<?> parent){
if(!parent.getSelectedItem().toString().equals("Sottocategorie vuote")) {
ricercaAvanzata.setCategoria((Categoria) parent.getSelectedItem());
setArticoli();
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
spinnerChange(parent);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
return;
}
public void setListener() {
spinnerCategoria.setOnItemSelectedListener(this);
}
public class ActivityRicercaAvanzata extends AppCompatActivity implements AdapterView.OnItemSelectedListener { .... }
I expect that when i click on spinner call onItemSelected not before
i am using Spinner for Country Selection for User Registration.
please vote my answer.
Spinner spcountry;
String country;
//in onCreare
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
spcountry = (Spinner) findViewById(R.id.country);
final String[] countryNames = getResources().getStringArray(R.array.countries_array);
ArrayAdapter aa = new ArrayAdapter(this, android.R.layout.simple_spinner_item, countryNames);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//Setting the ArrayAdapter data on the Spinner
spcountry.setAdapter(aa);
spcountry.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Log.v("item", (String) parent.getItemAtPosition(position));
if (position == 0) {
return;
} else
country = countryNames[position];
//Toast.makeText(getBaseContext(),country,Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// TODO Auto-generated method stub
}
});
}
From what I can see, you are extending AdapterView.OnItemSelectedListener.
You cannot extend it since OnItemSelectedListener is an interface, not a class.
What you actually should be doing is, implementing it instead, like so:
MyActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
}
Then you can set the OnItemSelectedListener on the Spinner,
spinnerCategoria.setOnItemSelectedListener(this);
And the final step would be to write the implementation for the overridden methods,
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
//Your implementation here
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
//Your implementation here
}
Ok, mark as solved thx. I create a new List and i convert my set into list. After this operation i add a null element at first position, and when i'm call onItemSelected, i do
if(position != 0)then
//do something
Activity start always at position 0 then must wait my click and my choice. Thx all for help me.
I have a spinner(dynamic) which contains a list of IDs' and each ID has a product value. When I click on a particular ID, the value needs to be changed associated with that ID.
I have a listView which contains a table. The table consists of product names, product price and product information. When I change the ID, the table information(listview) changes but not the product value (this is a textview and not part of listview).
I'm passing the product value using an intent from a different class. How do I make it such that when I change an item in the spinner, the product value gets changed?
/**
* Listener for flight leg selection of spinner
*/
private OnItemSelectedListener onFlightLegSelectedListener = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
new ShowSalesReportAsyncTask(flightLegMap.get(flightLegs.get(position)), position).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// Do nothing
}
};
This is my onCreate where I am getting the product value.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sales_report);
salesReportListView = (ListView) findViewById(R.id.sales_report_listview);
spinnerFlightLegs = (Spinner) findViewById(R.id.flight_legs);
noTransactionsWarning = (TextView) findViewById(R.id.no_transactions_warning);
totalValueNetAmount = (TextView) findViewById(R.id.total_currency_net_value);
String salesRevenue = TOTAL_VALUE;
Bundle extras = getIntent().getExtras();
if (extras != null) {
salesRevenue = extras.getString(TOTAL_VALUE);
}
totalValueNetAmount.setText(salesRevenue);
flightLegMap = getAllFlightLegs();
if (!flightLegMap.isEmpty()) {
setFlightLegSpinner();
btnShare.setEnabled(true);
} else {
btnShare.setEnabled(false);
}
spinnerFlightLegs.setOnItemSelectedListener(onFlightLegSelectedListener);
salesReportListAdapter = new SalesReportListAdapter(this);
salesReportListView.setAdapter(salesReportListAdapter);
This is the Async task that I use to populate the view with data.
private class ShowSalesReportAsyncTask extends AsyncTask> {
private String flightLeg;
private int position;
public ShowSalesReportAsyncTask(String flightLeg, int position) {
this.flightLeg = flightLeg;
this.position = position;
}
#Override
protected List<Purchase> doInBackground(Void... params) {
List<Purchase> rows = new ArrayList<Purchase>();
PurchaseDao purchaseDao = new PurchaseDao(flightLeg, MIUtils.getShardDatabaseIndexMap());
LOG.debug(TAG + "Getting report for : {}", flightLeg);
// double netTotal = SalesUtil.calculateFlightTransactionTotal(purchaseDao, refundDao,());
return purchaseDao.getSuccessfulTransactions();
}
#Override
protected void onPostExecute(List<Purchase> result) {
super.onPostExecute(result);
if (!result.isEmpty()) {
noTransactionsWarning.setVisibility(View.GONE);
} else {
noTransactionsWarning.setVisibility(View.VISIBLE);
}
salesReportListAdapter.setRowsAndFlightDetails(result, flightLegMap.get(flightLegs.get(position)),
spinnerFlightLegs.getSelectedItem().toString());
totalValueNetAmount.setText((int) netTotal);
}
}
The item that needs to be changed is "EUR". SPINNER TABLE IMAGE
Add the code to register the listener in the onStart() method of the activity. This should work.
This should better answer your question - How to keep onItemSelected from firing off on a newly instantiated Spinner?
We have a list view fragment that contains a listview, edit text(for search) and check box(Select All). As mentioned we are using Edit Text for searching the values from the list view.
Problem:
We have list view displaying 10 items( list view sorted alphabetically).
When we type 'W' in the edit text we are displayed with two values i.e. WF and WH.
The selection is made for WF(first item displayed).
After clearing the characters in the edit text, we are now displayed with the complete list of the list view.
But the selection is now made for first item in the list AHMD. (we intended to select WF)
Basically, the positions of the data in the list view is not getting refreshed after we have performed search.
code:
public static class ListViewFragment extends Fragment {
private ListView myListView;
private EditText editsearch;
private CheckBox selectAll;
private String SELECTED_FILTER;
private ArrayList<String> SelectedFilter1;
private ArrayList<String> checkekprev=new ArrayList<String>();
private ArrayList<String> CheckedFitlers=new ArrayList<String>();
ArrayAdapter<String> adapter_list;
OnCheckedItemsLister onCheckedItemsLister;
public ListViewFragment() {
// Empty constructor required for fragment subclasses
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
onCheckedItemsLister = (OnCheckedItemsLister) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement onSomeEventListener");
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
SelectedFilter1=getArguments().getStringArrayList("ArrayList");
SELECTED_FILTER=getArguments().getString("SELECTED_FILTER");
checkekprev=getArguments().getStringArrayList("checkedprevlist");
if(checkekprev.size()==SelectedFilter1.size())
selectAll.setChecked(true);
else
selectAll.setChecked(false);
adapter_list = new ArrayAdapter<String>(this.getActivity(),
android.R.layout.simple_list_item_multiple_choice,SelectedFilter1);
adapter_list.notifyDataSetChanged();
myListView.setAdapter(adapter_list);
myListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
myListView.setTextFilterEnabled(true);
try{
if(checkekprev.isEmpty()==false){
Log.i("Adapter set", "Yes");
for(int j=0;j<checkekprev.size();j++){
Log.i("Adapter set", "Yes:"+j);
int pos=adapter_list.getPosition(checkekprev.get(j));
Log.i("Adapter set", "Pos:"+pos);
myListView.setItemChecked(pos,true);
}
}
}catch(NullPointerException e){
Log.i("Null set", "Yes");
}
editsearch.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
String text = editsearch.getText().toString().toLowerCase(Locale.getDefault());
adapter_list.getFilter().filter(text);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
});
selectAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
Log.i("CheckBOX","Is Checked:"+isChecked);
if(isChecked)
{
for ( int i=0; i< myListView.getCount(); i++ )
myListView.setItemChecked(i, true);
}else
{
for ( int i=0; i< myListView.getCount(); i++ )
myListView.setItemChecked(i, false);
}
SparseBooleanArray checked = myListView.getCheckedItemPositions();
CheckedFitlers.clear();
for(int i=0;i<=checked.size();i++){
if (checked.get(i)){
CheckedFitlers.add(SelectedFilter1.get(i));
}
}
onCheckedItemsLister.someEvent(CheckedFitlers,SELECTED_FILTER);
}
}
);
myListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id){
setItemChecked(position);
onCheckedItemsLister.someEvent(CheckedFitlers,SELECTED_FILTER);
}
});
}
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if(savedInstanceState!=null){
checkekprev=savedInstanceState.getStringArrayList("Checked_Values");
}
}
public void setItemChecked(int position){
//if(SelectedFilter1.get(position).)
//int len = myListView.getCount();
SparseBooleanArray checked = myListView.getCheckedItemPositions();
for(int i=0;i<=checked.size();i++){
Log.i("Check Sparse Array","Check Sparse Array: "+checked.get(i));
}
//for (int i = 0; i < len; i++){
Log.i("SelectedFilter1.get(position)","SelectedFilter1.get(position):::"+SelectedFilter1.get(position));
Log.i("checked.get(position))","checked.get(position)):::"+checked.get(position));
for (int i=0; i<CheckedFitlers.size();i++){
Log.i("CheckedFitlers","CheckedFitlers:::" + CheckedFitlers.get(i));
}
for (int i=0; i<checkekprev.size();i++){
Log.i("checkekprev","checkekprev:::" + checkekprev.get(i));
}
Log.i("CheckedFitlers","CheckedFitlers:::" + CheckedFitlers.size());
Log.i("checkekprev","checkekprev:::" + checkekprev.size());
if(CheckedFitlers.size() == 0 && checkekprev.size() != 0){
CheckedFitlers = checkekprev;
}
Log.i("CheckedFitlers","CheckedFitlers:::" + CheckedFitlers.size());
if (checked.get(position)) {
Log.i("Adding","Adding::"+checked.get(position));
CheckedFitlers.add(SelectedFilter1.get(position));
for(int i=0;i<checkekprev.size();i++){
//Log.i("Checked Filters FOr loop","Checked Filters:"+CheckedFitlers.get(i));
}
} else
{
Log.i("Removing","Removing::"+checked.get(position)+":"+SelectedFilter1.get(position));
CheckedFitlers.remove(SelectedFilter1.get(position));
for(int i=0;i<checkekprev.size();i++){
//Log.i("Checked Filters for loop","Checked Filters:"+CheckedFitlers.get(i));
}
}
Log.i("CheckedFitlers","CheckedFitlers:::" + CheckedFitlers.size());
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_list_view, container, false);
myListView=(ListView) rootView.findViewById(R.id.listView_brand);
editsearch = (EditText) rootView.findViewById(R.id.search);
selectAll=(CheckBox) rootView.findViewById(R.id.checkBox1);
selectAll.setFocusable(false);
return rootView;
}
public void onSaveInstanceState(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
Log.i("savedInstanceState in listfragment","savedInstanceState in listfragment");
//onCheckedItemsLister.someEvent(CheckedFitlers,SELECTED_FILTER);
onCheckedItemsLister.getSelectedFilter(SELECTED_FILTER);
}
}
When you typed 'W' in the edit text we are displayed with two values i.e. WF and WH. The selection is made for WF(first item displayed).
But you have performed action for first row of a listview, Now the checkbox of listview is checked and when clearing the characters in the edit text, your are seeing the complete list of the list view with first box checked. which is correct.
If you want to avoid this issues, Create custom adapter and override getfilter method.
Otherwise, Create your own logic and call listView.setItemChecked( stored positions, true/false); in ontextchanged.
In this example, let's say that the activity labels and listview items have equal values. There are 10 items from WF to WZ. (I sampled with 4 items) When "WZ" is typed in the edittext, the "WZ" item is displayed on the first line of the listview. When the first line is clicked, it is desirable to calling the "WZ" activity, not the "WF" activity. I've created the following little code for it, and it works fine.
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String v1 = getString(R.string.title_activity_wf).toString();
String v2 = getString(R.string.title_activity_wh).toString();
String v3 = getString(R.string.title_activity_wm).toString();
String v4 = getString(R.string.title_activity_wt).toString();
.
.
.
.
.
.
String selectedFromList = (String) (listView.getItemAtPosition(position));
if (selectedFromList.equalsIgnoreCase(v1)) {
startActivity(new Intent(getApplicationContext(), Wf.class));
} else if (selectedFromList.equalsIgnoreCase(v2)) {
startActivity(new Intent(getApplicationContext(), Wh.class));
} else if (selectedFromList.equalsIgnoreCase(v3)) {
startActivity(new Intent(getApplicationContext(), Wm.class));
} else if (selectedFromList.equalsIgnoreCase(v4)) {
startActivity(new Intent(getApplicationContext(), Wt.class));
}
});
I want to programmatically (re)highlight selected list item after screen rotation.
public class MyListFragment extends ListFragment {
private static final String tag = MyListFragment.class.getName();
private static final String indexTag = "index";
private int index = -1;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
if (savedInstanceState != null) {
index = savedInstanceState.getInt(indexTag, -1);
Log.d(tag, "Restored index " + index + " from saved instance state.");
}
}
#Override
public void onResume() {
super.onResume();
if (index >= 0) {
showDetails(index);
}
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
showDetails(position);
}
private void showDetails(int index) {
this.index = index;
getListView().setItemChecked(index, true);
// update details panel
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(indexTag, index);
}
}
I use CheckedTextView as item view in my custom adapter:
public class MyListAdapter extends BaseAdapter {
private static final String tag = MyListAdapter.class.getName();
#Override
public CheckedTextView getView(int position, View convertView, ViewGroup parent) {
if (convertView == null || !(convertView instanceof CheckedTextView)) {
final LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.simple_list_item_single_choice, parent, false);
}
((CheckedTextView)convertView).setText("test");
return (CheckedTextView)convertView;
}
}
After screen rotation showDetails() is called and details panel updates but setItemChecked()does nothing and the item is still not highlighted. Also I noticed that when item it clicked by touch event setItemChecked() is not needed and the row highlights anyway.
So how can I programmatically check the item during onResume stage?
put showIndex(index) in your onActivityCreate() because on screen rotation Android destroys current activity and create another one saving current state through Bundle savedInstanceState
I solved the problem. I forgot that I'm setting list adapter through AsyncTask on my activity so when showDetails() is called during onResume stage my fragment still has empty list.
So I removed onResume method from my fragment, made showDetails() public and call it from my activity after setting the adapter:
public void onListLoadDone(...) {
final MyListAdapter adapter = new MyListAdapter(...);
myListFragment.setListAdapter(adapter);
myListFragment.showDetails();
}
I have a spinner which starts a second activity on a value change. This works good.
After a return everything works fine too. But if I rotate now the mobile the OnItemSelectedListener is called! Why? The spinner should be on position -1. Which means that the callback will not be called.
How does android know which spinner item is selected? I tried to prevend to restore this information by sending the base class the a null value for the savedInstanceState.
Here is some code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
setContentView(R.layout.menu);
String db=MyDatabase.getData();
if(db == null)
db="";
Spinner spinner=(Spinner)findViewById(R.id.spinner);
MyAdapter adapter=new MyAdapter(this, db, "ID", "Name");
spinner.setAdapter(adapter);
adapter.setHint(spinner, "Please select...");
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id2) {
int id=((SpinnerItem)parent.getAdapter().getItem(position)).getId();
Intent intent=new Intent();
intent.setClass(MainMenu.this, Other.class);
intent.putExtra("id", id);
startActivity(intent);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
}
Here is my adapter:
public class MyAdapter extends ArrayAdapter<SpinnerItem> {
private final Context context;
private String hint;
public MyAdapter(Context context, String input, String key, String value) {
super(context, android.R.layout.simple_spinner_item, create(input, key, value));
this.context=context;
}
private static SpinnerItem[] create(String input, String key, String value) {
Vector<SpinnerItem> list=new Vector<SpinnerItem>();
// fill the list
return list.toArray(new SpinnerItem[] {});
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// show the hint
if(position == -1) {
TextView tv=new TextView(context);
tv.setTextColor(Color.DKGRAY);
tv.setText(hint);
return tv;
}
return super.getView(position, convertView, parent);
}
public void setHint(Spinner spinner, String hint) {
if(spinner.getAdapter() == null) {
throw new IllegalStateException("Set your adapter first!");
}
this.hint=hint;
try {
final Method m=AdapterView.class.getDeclaredMethod("setNextSelectedPositionInt", int.class);
m.setAccessible(true);
m.invoke(spinner, -1);
final Method n=AdapterView.class.getDeclaredMethod("setSelectedPositionInt", int.class);
n.setAccessible(true);
n.invoke(spinner, -1);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
}
When you rotate your device your Activity gets restarted or recreated add this line to your AndroidManifest file in activity tag to avoid it.
android:configChanges="keyboardHidden|orientation"
When you change the orientation the onCreate() of Activity get Called.
and by default as the behaviour of the spinner the method onItemSelectedListener() get called of the spinner when ever the activity gets created.
So this is happening to you in this case
Solution for such issue is given here StackOverflow Question's Link check how he handled the issue by taking two counters checkBoxCounter and checkBoxInitialized and try to implement same in your case.