简体   繁体   中英

Handling orientation changes with dynamic spinners

I have searched the web and keep trying for 5 hours but I couldn't find a way to solve the problem. I want to keep the state of my spinners after orientation changes.

I have 2 spinners which are created dynamically. They get their items by http request and the first spinner changes the items in the second one by setOnItemSelectedListener() method. I read the Strings into Global Lists.

public class Global {
    public static String userName;
    public static String userType;
    public static String serverIp;
    public static int spinnerLeaguePos=0;
    public static int spinnerMatchPos=0;
    public static List<String> leagues;
    public static List<String> matches;
}

My first problem was preventing the activity from restart.

android:configChanges="orientation|keyboardHidden"

I have made this change in my manifest file to handle orientation changes by myself and avoid activity from restart.

I have found a way for handling orientation changes on internet but it doesn't worked for me. I'm getting null pointer exception when I change the orientation.

07-05 12:41:08.119: E/AndroidRuntime(26388): FATAL EXCEPTION: main
07-05 12:41:08.119: E/AndroidRuntime(26388): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.MatchSelectionActivity}: java.lang.NullPointerException
07-05 12:41:08.119: E/AndroidRuntime(26388):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3351)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at android.app.ActivityThread.access$700(ActivityThread.java:123)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1151)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at android.os.Handler.dispatchMessage(Handler.java:99)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at android.os.Looper.loop(Looper.java:137)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at android.app.ActivityThread.main(ActivityThread.java:4424)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at java.lang.reflect.Method.invokeNative(Native Method)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at java.lang.reflect.Method.invoke(Method.java:511)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at dalvik.system.NativeStart.main(Native Method)
07-05 12:41:08.119: E/AndroidRuntime(26388): Caused by: java.lang.NullPointerException
07-05 12:41:08.119: E/AndroidRuntime(26388):    at com.example.MatchSelectionActivity.setLeagues(MatchSelectionActivity.java:90)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at com.example.MatchSelectionActivity.onCreate(MatchSelectionActivity.java:47)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at android.app.Activity.performCreate(Activity.java:4465)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
07-05 12:41:08.119: E/AndroidRuntime(26388):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
07-05 12:41:08.119: E/AndroidRuntime(26388):    ... 12 more

This is what I have done so far. I don't even sure about to way I'm trying to do it. So any more appropriate way for doing this will be appreciated.

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    spinnerLeague = (Spinner) findViewById(R.id.spinner_league);
    spinnerMatch = (Spinner) findViewById(R.id.spinner_match);

    if (savedInstanceState != null) {
        setLeagues();
        setMatches();
        spinnerLeague.setSelection(Global.spinnerLeaguePos);
        spinnerMatch.setSelection(Global.spinnerMatchPos);
    }
    else{
        Global.leagues = new ArrayList<String>();
        Global.matches = new ArrayList<String>();

        Global.leagues.add(getString(R.string.league_select));
        Global.matches.add(getString(R.string.match_select));

        GetLeagues task = new GetLeagues();
        String requestString = "http://" + Global.serverIp + ":8080/server/GetCurrentLeagues";
        task.execute(new String[] { requestString });
    }

    setContentView(R.layout.match_selection_layout);

}

public class GetLeagues extends AsyncTask<String, Void, String[]> {
    @Override
    protected String[] doInBackground(String... urls) {
        //this part works properly, and reads the leagues into Global.leagues List
    }

    @Override
    protected void onPostExecute(String[] result) {
        setLeagues();
    }
}
public class GetMatches extends AsyncTask<String, Void, String[]> {
    @Override
    protected String[] doInBackground(String... urls) {
        //this part works properly, and reads the matches into Global.matches List
    }

    @Override
    protected void onPostExecute(String[] result) {
        setMatches();
    }
}

 public void setLeagues() {

    spinnerLeague = (Spinner) findViewById(R.id.spinner_league);
    ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, Global.leagues);
    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinnerLeague.setAdapter(dataAdapter);

    spinnerLeague.setOnItemSelectedListener(new OnItemSelectedListener() {

        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

            spinnerLeague = (Spinner) findViewById(R.id.spinner_league);

            if(position!=0){
                spinnerMatch.setEnabled(true);
                Global.spinnerLeaguePos=position;

                GetMatches task = new GetMatches();
                String requestString = "http://" + Global.serverIp +":8080/server/GetCurrentMatches/"+Global.spinnerLeaguePos;
                task.execute(new String[] { requestString });
            }
            else{
                setMatches();
                spinnerMatch.setEnabled(false);
                Global.spinnerLeaguePos=position;
            }

        }

        public void onNothingSelected(AdapterView<?> parent) {
            // TODO Auto-generated method stub

        }
    });
  }

    public void setMatches() {

    spinnerMatch = (Spinner) findViewById(R.id.spinner_match);
    ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, Global.matches);
    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinnerMatch.setAdapter(dataAdapter);


    spinnerMatch.setOnItemSelectedListener(new OnItemSelectedListener() {

        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            Global.spinnerMatchPos=position;
        }

        public void onNothingSelected(AdapterView<?> parent) {
            // TODO Auto-generated method stub

        }
    });
  }

You need to call setContentView(R.layout.match_selection_layout) before calling findViewById . Otherwise, findViewById will return null (since the parent View has not yet been inflated/attached to the screen).

Also you should not use configChanges as a bandaid to fix your activity. There are many ways an Activity can be restarted; for example, if the user changed the device's language setting from English to Spanish (this would cause the entire Activity to be destroyed and created). Always make sure orientation changes work correctly... don't just give up on them and simply override onConfigurationChanged .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM