加载完成后的ListView侦听器?

时间:2015-09-16 17:24:28

标签: listview android-fragments android-intent shareactionprovider

我想将屏幕内容作为字符串发布到其他社交应用程序(电子邮件,watsapp等)。屏幕基本上显示7天天气预报列表。在onCreateView中,我尝试将ArrayAdapter的内容捕获到String(forecastStr),但它在其中获取null。我该如何处理?

  

这是我的代码(Java类:ForecastFragment):

public class ForecastFragment extends Fragment {
    private ArrayAdapter<String> forecastAdapter;
    private static final String LOG_TAG =ForecastFragment.class.getSimpleName();
    private static final String FORECAST_SHARE_HASHTAG = "#HowzTheWeather";
    private String forecastStr;
    public ForecastFragment() {
        setHasOptionsMenu(true);
    }
    @Override
    public void  onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
forecastAdapter = new ArrayAdapter<String>(getActivity(), R.layout.list_item_forecast,R.id.list_item_forecast_textview,new ArrayList<String>());
        View rootView = inflater.inflate(R.layout.fragment_main,container,false);
        ListView listView = (ListView) rootView.findViewById(R.id.list_view_forecast);
        listView.setAdapter(forecastAdapter);
        for ( int i=0;i<forecastAdapter.getCount();i++){
            forecastStr=forecastAdapter.getItem(i);
            Log.v(LOG_TAG, "Value of forecastStr is "+forecastStr);
        }


        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String forecast = forecastAdapter.getItem(position);
                Intent intent = new Intent(getActivity(), DetailActivity.class).putExtra(Intent.EXTRA_TEXT, forecast);
                startActivity(intent);
            }
        });
        return rootView;
    }
    @Override
    public void onCreateOptionsMenu(Menu menu,MenuInflater inflater ) {
        // Inflate the menu; this adds items to the action bar if it is present.
       inflater.inflate(R.menu.forecast_fragment, menu);
        MenuItem menuItem = menu.findItem(R.id.action_share);
        ShareActionProvider shareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(menuItem);
        if (shareActionProvider != null ) {
            shareActionProvider.setShareIntent(createShareForecastIntent());
        } else {
            Log.d(LOG_TAG, "Share Action Provider is null?");
        }
    }
    private Intent createShareForecastIntent() {
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        shareIntent.setType("text/plain");
        Log.i(LOG_TAG, "value of String forecastStr " + forecastStr);

        shareIntent.putExtra(Intent.EXTRA_TEXT, forecastStr +
                FORECAST_SHARE_HASHTAG);
        return shareIntent;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item){
        int id = item.getItemId();
        if(id==R.id.action_refresh){
            updateWeather();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void updateWeather(){
        FetchWeatherTask weatherTask = new FetchWeatherTask();
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
        String location = prefs.getString(getString(R.string.pref_location_key),getString(R.string.pref_location_default));
        weatherTask.execute(location);
    }

    @Override
    public void onStart(){
        super.onStart();
        updateWeather();
    }    
    public class FetchWeatherTask extends AsyncTask<String,Void,String[]>{
        private final String LOG_TAG=FetchWeatherTask.class.getSimpleName();

        public String[] getWeatherDataFromJSONStr(String forecastJsonStr, int numDays) throws JSONException{
            final String OEM_LIST= "list";
            final String OEM_WEATHER="weather";
            final String OEM_TEMPRATURE ="temp";
            final String OEM_MAX ="max";
            final String OEM_MIN ="min";
            final String OEM_DATETIME ="dt";
            final String OEM_DESCRIPTION = "main";

            JSONObject forecastJson = new JSONObject(forecastJsonStr);
            JSONArray forecastListArray = forecastJson.getJSONArray(OEM_LIST);

            String[] resultsStrs = new String[numDays];
            for (int i=0;i<forecastListArray.length();i++ ){
                String day;
                String description;
                String highAndLow;

                JSONObject  dayForeCast = forecastListArray.getJSONObject(i);
                long dateTime = dayForeCast.getLong(OEM_DATETIME);
                day=getReadableDateString(dateTime);
                JSONObject weatherObject = dayForeCast.getJSONArray(OEM_WEATHER).getJSONObject(0);
                description = weatherObject.getString(OEM_DESCRIPTION);

                JSONObject tempratureObject =  dayForeCast.getJSONObject(OEM_TEMPRATURE);
                double high = tempratureObject.getDouble(OEM_MAX);
                double low = tempratureObject.getDouble(OEM_MIN);
                highAndLow = formatHighAndLow(high,low);
                resultsStrs[i] = day + " - " + description + " - " + highAndLow;
            }    
            return resultsStrs;
        }
        private String formatHighAndLow(double high, double low) {
            SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
            String unitType = sharedPrefs.getString
                    (getString(R.string.pref_units_key), getString(R.string.pref_units_metric));

            if(unitType.equals(getString(R.string.pref_units_imperial))){
                high=(high*1.8)+32;
                low=(low*1.8)+32;
            }else if (!unitType.equals(getString(R.string.pref_units_metric))){
                Log.d(LOG_TAG,"Unit Type not found "+unitType);
            }

            long roundedHigh= Math.round(high);
            long roundedLow= Math.round(low);

            String highLowStr = roundedHigh + "/" + roundedLow ;
            return  highLowStr;
        }


        private String getReadableDateString(long dateTime) {
            Date date = new Date(dateTime*1000);
            SimpleDateFormat format = new SimpleDateFormat("E,MMM d");

            return format.format(date).toString();

        }


        @Override
        protected String[] doInBackground(String... params){
            if (params.length==0){
                return null;
            }
            HttpURLConnection urlConnection =null;
            BufferedReader reader = null;
            String forecastJSONstr=null;
            String format="json";
            String units="metric";
            int numDays=7;


            try{
                final String FORECST_BASE_URL="http://openweathermap.org/data/2.5/forecast/daily/?";
                final String QUERY_PARM="q";
                final String FORMAT_PARAM="mode";
                final String UNITS_PARAM="units";
                final String DAYS_PARAM="cnt";
                //http://openweathermap.org/data/2.5/forecast/daily/?q=14623&mode=json&units=metric&cnt=7"

                Uri builtUri=Uri.parse(FORECST_BASE_URL).buildUpon()
                        .appendQueryParameter(QUERY_PARM,params[0])
                        .appendQueryParameter(FORMAT_PARAM,format)
                        .appendQueryParameter(UNITS_PARAM,units)
                        .appendQueryParameter(DAYS_PARAM,Integer.toString(numDays)).build();


                URL url = new URL(builtUri.toString());
                Log.i(LOG_TAG,"Uri is: "+url.toString());
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.connect();

                InputStream inputStream = urlConnection.getInputStream();
                if (inputStream == null) {
                    return  null;
                }
                reader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                StringBuffer buffer=new StringBuffer();
                while ((line=reader.readLine())!=null ){
                    buffer.append(line+"\n");
                }
                if(buffer.length()==0)
                {
                    return null;
                }
                forecastJSONstr=buffer.toString();
                Log.v(LOG_TAG,"ForeCast JSON String is : "+forecastJSONstr);

            } catch (java.io.IOException e) {
                Log.e(LOG_TAG,"Error",e );
                return  null;
            } finally {
                if(urlConnection!=null){
                    urlConnection.disconnect();
                }
                if(reader!=null){
                    try {
                        reader.close();
                    } catch (IOException e) {
                        Log.e(LOG_TAG,"Error closing stream",e);
                    }
                }

            }
            try {
                return  getWeatherDataFromJSONStr(forecastJSONstr,numDays);

            }catch (JSONException e){
                Log.e(LOG_TAG,e.getMessage(),e);
                e.printStackTrace();
            }
            return null;
        }
        @Override
        protected void onPostExecute(String[] result){
            if(result !=null){
                forecastAdapter.clear();
                for (String dayForecastStr : result){
                    forecastAdapter.addAll(dayForecastStr);
                }
            }
        }
    }
}
  

forecast_fragment.xml

<?xml version="1.0" encoding="utf-8"?>

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
        <item android:id="@+id/action_refresh"
            android:title="@string/action_refresh"
            app:showAsAction="never" />

    <item android:id="@+id/action_share"
        android:title="@string/action_share"
        app:showAsAction="always"
        app:actionProviderClass="android.support.v7.widget.ShareActionProvider" />
</menu>

1 个答案:

答案 0 :(得分:0)

您在forecastAdapter最初迭代项目后,通过AsyncTask填充onCreateView

我建议您在notifyDataSetChanged中添加项目后,在适配器上调用onPostExecute。然后可能在那时迭代集合。

您当前的方法存在缺点。想象一下,您导航到此片段,启动AsyncTask,然后在onPostExecute之前离开它。您的适配器将不存在,但AsyncTask将尝试更新它。