我想将屏幕内容作为字符串发布到其他社交应用程序(电子邮件,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>
答案 0 :(得分:0)
您在forecastAdapter
最初迭代项目后,通过AsyncTask填充onCreateView
。
我建议您在notifyDataSetChanged
中添加项目后,在适配器上调用onPostExecute
。然后可能在那时迭代集合。
您当前的方法存在缺点。想象一下,您导航到此片段,启动AsyncTask
,然后在onPostExecute
之前离开它。您的适配器将不存在,但AsyncTask
将尝试更新它。