简体   繁体   中英

Fragment Rotation

I have the following piece of code which retrieve some weather data from the openweathermap api. The AsyncTask class is used for that purpose.

public class ForecastFragment extends Fragment {
String imageUrl;
ListView listView;
List<WeatherForecastData> WeatherForecastDataList;
String IMG_URL = "http://api.openweathermap.org/img/w/";
Fragment fragment;

public ForecastFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    //Inflate xml view and convert it to a View object
    View rootView = inflater.inflate(R.layout.fragment_forecast, container, false);

    //Initialise ListView.
    listView = (ListView) rootView.findViewById(R.id.listView);
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String temp = WeatherForecastDataList.get(position).getWeatherTemperature();

            Toast.makeText(getActivity(), temp + "° C"+" Have a nice day", Toast.LENGTH_SHORT).show();
        }
    });
    return rootView;
}

//Now we are ready for further processing
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    setRetainInstance(true);
    if (savedInstanceState == null) {
        if(isOnline()) {
            requestData("http://api.openweathermap.org/data/2.5/forecast/daily?lat=50.09&lon=14.42&cnt=9&&units=metric&mode=json");
        }else{
            Toast.makeText(getActivity(),"There is no internet connection",Toast.LENGTH_SHORT).show();
        }
    }

}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putString("ImageURL", imageUrl);
    super.onSaveInstanceState(savedInstanceState);
}

//We create a MyTask object,and execute the async. thread with the specified url which is shown just above.
private void requestData(String uri) {
    MyTask task = new MyTask();
    task.execute(uri);
}

//AsyncTask that will do the asynchronous threading. It displays the weather's icon,description
//and temperature in the main thread via the OnPostExecute(...) method.
private class MyTask extends AsyncTask<String, String, List<WeatherForecastData>> {

    @Override
    protected void onPreExecute() {
        //Used to initialise Views such as Progress Bars which are not needed for this
        //project.
    }

    @Override
    protected List<WeatherForecastData> doInBackground(String... params) {
        //Read the url,specify the METHOD GET, and store it in content.
        String content = HttpManager.getData(params[0]);
        //JSON parsing of the openweather api's response. It is not hard,but I had to use the
        //debugger quite a lot to make sure that I deserialise the correct JSON values into Strings.
        WeatherForecastDataList = WeatherJSONParser.parseFeed(content);
        //Fetching the url image
        for (WeatherForecastData d : WeatherForecastDataList) {
            try {
                imageUrl = IMG_URL + d.getPhoto();
                InputStream in = (InputStream) new URL(imageUrl).getContent();
                Bitmap bitmap = BitmapFactory.decodeStream(in);
                //Is it deprecated?
                d.setBitmap(bitmap);
                in.close();
            } catch (Exception e) {
                e.printStackTrace();

            }
        }
        return WeatherForecastDataList;
    }

    //WeatherForecastData is the Object that contains all that instances we want to display.
    @Override
    protected void onPostExecute(List<WeatherForecastData> result) {

        if (result == null) {
            Toast.makeText(getActivity(), "There is some wrong,and data can not be displayed", Toast.LENGTH_LONG).show();
            return;
        }
        WeatherForecastDataList = result;
        //Display the ListView.
        WeatherAdapter adapter = new WeatherAdapter(getActivity(), R.layout.weather_row, WeatherForecastDataList);
        listView.setAdapter(adapter);
    }

}

protected boolean isOnline() {
    ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnectedOrConnecting()) {
        return true;
    } else {
        return false;
    }
}
}

My question is how to make my async task class to work when phone rotates.In other words,I don't want my Fragment to be killed,but storing the weather get I get. I saw other questions here too,but I am confused in this part. Thank you.

Making config changes in the manifest is not the recommended way to save the instance of the fragment.

Instead, you should save the instance of the fragment in container activity's onSaveInstanceState() overriden method. Below is a small snippet that will help you:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState,"fragmentInstanceSaved",getSupportFragmentManager().findFragmentById(R.id.fragment_container));
}

Now, in your container activity's onCreate method check if bundle is null or not:

    if(savedInstanceState!=null){
            Fragment fragment = getSupportFragmentManager().getFragment(savedInstanceState,"fragmentInstanceSaved");
            //recreate your preserved fragment here
        }else{
            //goto ur default activity or fragment....
}

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