2015-04-28 43 views
0

作爲Android主題中的一種新形式,我一直在閱讀和學習課程/教程。我瞭解活動交易,但現在我分成了片段,並嘗試使用谷歌日曆API將簡單的應用程序放在一起。但是,我很難從MainActivity部分抓住「更新片段」。更新活動中的片段文本視圖 - Nullpointerexception

在這一點上,應用程序崩潰,只是我 已經試過剛纔的一切,使這項工作,但沒有成功:(你怎麼去這??

這裏是在MainActivity:

public class MainActivity extends Activity 
    implements NavigationDrawerFragment.NavigationDrawerCallbacks { 

com.google.api.services.calendar.Calendar mService; 

GoogleAccountCredential credential; 
public TextView mStatusText; 
public TextView mEventText; 

final HttpTransport transport = AndroidHttp.newCompatibleTransport(); 
final JsonFactory jsonFactory = GsonFactory.getDefaultInstance(); 


static final int REQUEST_ACCOUNT_PICKER = 1000; 
static final int REQUEST_AUTHORIZATION = 1001; 
static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002; 
private static final String PREF_ACCOUNT_NAME = "accountName"; 
private static final String[] SCOPES = {CalendarScopes.CALENDAR_READONLY}; 

/** 
* Fragment managing the behaviors, interactions and presentation of the navigation drawer. 
*/ 
private NavigationDrawerFragment mNavigationDrawerFragment; 

/** 
* Used to store the last screen title. For use in {@link #restoreActionBar()}. 
*/ 
private CharSequence mTitle; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    mNavigationDrawerFragment = (NavigationDrawerFragment) 
      getFragmentManager().findFragmentById(R.id.navigation_drawer); 
    mTitle = getTitle(); 

    // Set up the drawer. 
    mNavigationDrawerFragment.setUp(
      R.id.navigation_drawer, 
      (DrawerLayout) findViewById(R.id.drawer_layout)); 

    // Initialize credentials and calendar service. 
    SharedPreferences settings = getPreferences(Context.MODE_PRIVATE); 
    credential = GoogleAccountCredential.usingOAuth2(
      getApplicationContext(), Arrays.asList(SCOPES)) 
      .setBackOff(new ExponentialBackOff()) 
      .setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null)); 

    mService = new com.google.api.services.calendar.Calendar.Builder(
      transport, jsonFactory, credential) 
      .setApplicationName("Calendar API Android Quickstart") 
      .build(); 


} 

@Override 
public void onNavigationDrawerItemSelected(int position) { 

    Fragment fragment = null; 

    switch (position) { 
     case 0: 
      fragment = new Noticias_Fragment(); 
      break; 
     case 1: 
      fragment = new Eventos_Fragment(); 

      break; 
     case 2: 
      fragment = new Quienes_Fragment(); 
      break; 
     case 3: 
      fragment = new Contacto_Fragment(); 
      break; 
    } 
    // update the main content by replacing fragments 
    FragmentManager fragmentManager = getFragmentManager(); 
    fragmentManager.beginTransaction() 
      .replace(R.id.container, fragment) 
      .commit(); 
} 


public void onSectionAttached(int number) { 
    switch (number) { 
     case 1: 
      mTitle = getString(R.string.title_section1); 
      break; 
     case 2: 
      mTitle = getString(R.string.title_section2); 
      break; 
     case 3: 
      mTitle = getString(R.string.title_section3); 
      break; 
     case 4: 
      mTitle = getString(R.string.title_section4); 
      break; 

    } 
} 

public void restoreActionBar() { 
    ActionBar actionBar = getActionBar(); 
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 
    actionBar.setDisplayShowTitleEnabled(true); 
    actionBar.setTitle(mTitle); 
} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    if (!mNavigationDrawerFragment.isDrawerOpen()) { 
     // Only show items in the action bar relevant to this screen 
     // if the drawer is not showing. Otherwise, let the drawer 
     // decide what to show in the action bar. 
     getMenuInflater().inflate(R.menu.main, menu); 
     restoreActionBar(); 
     return true; 
    } 
    return super.onCreateOptionsMenu(menu); 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 
    if (id == R.id.action_settings) { 
     return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

/** 
* A placeholder fragment containing a simple view. 
*/ 
public static class PlaceholderFragment extends Fragment { 
    /** 
    * The fragment argument representing the section number for this 
    * fragment. 
    */ 
    private static final String ARG_SECTION_NUMBER = "section_number"; 

    /** 
    * Returns a new instance of this fragment for the given section 
    * number. 
    */ 
    public static PlaceholderFragment newInstance(int sectionNumber) { 
     PlaceholderFragment fragment = new PlaceholderFragment(); 
     Bundle args = new Bundle(); 
     args.putInt(ARG_SECTION_NUMBER, sectionNumber); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    public PlaceholderFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_main, container, false); 
     return rootView; 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 
     ((MainActivity) activity).onSectionAttached(
       getArguments().getInt(ARG_SECTION_NUMBER)); 
    } 
} 


public void ButtonOnClick(View v) { 
    switch (v.getId()) { 
     case R.id.imageButton: //botón Mail 
      Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); 
      emailIntent.setType("text/plain"); 
      emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"[email protected]"}); 
      emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Motivo"); 
      emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Escribe tu texto a enviar"); 
      startActivity(Intent.createChooser(emailIntent, "Elije tu gestor de correo...")); 
      break; 
     case R.id.imageButton2: //botón Página 
      Intent intent2 = new Intent(Intent.ACTION_VIEW); 
      intent2.setData(Uri.parse("http://www.lapaginadelfreshxalapa.com")); 
      startActivity(intent2); 
      break; 
     case R.id.imageButton3: //botón FB 
      Intent intent3 = new Intent(Intent.ACTION_VIEW); 
      intent3.setData(Uri.parse("http://www.facebook.com/freshxalapa")); 
      startActivity(intent3); 
      break; 
     case R.id.imageButton4: //botón TW 
      Intent intent4 = new Intent(Intent.ACTION_VIEW); 
      intent4.setData(Uri.parse("http://www.twitter.com/freshxalapa")); 
      startActivity(intent4); 
      break; 

    } 
} 

/** 
* Called whenever this activity is pushed to the foreground, such as after 
* a call to onCreate(). 
*/ 

@Override 
protected void onResume() { 
    super.onResume(); 
    if (isGooglePlayServicesAvailable()) { 
     refreshEventList(); 
    } else { 

     mStatusText.setText("Google Play Services required: " + 
       "after installing, close and relaunch this app."); 
    } 
} 

/** 
* Called when an activity launched here (specifically, AccountPicker 
* and authorization) exits, giving you the requestCode you started it with, 
* the resultCode it returned, and any additional data from it. 
* @param requestCode code indicating which activity result is incoming. 
* @param resultCode code indicating the result of the incoming 
*  activity result. 
* @param data Intent (containing result data) returned by incoming 
*  activity result. 
*/ 
@Override 
protected void onActivityResult(
     int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    switch(requestCode) { 
     case REQUEST_GOOGLE_PLAY_SERVICES: 
      if (resultCode == RESULT_OK) { 
       refreshEventList(); 
      } else { 
       isGooglePlayServicesAvailable(); 
      } 
      break; 
     case REQUEST_ACCOUNT_PICKER: 
      if (resultCode == RESULT_OK && data != null && 
        data.getExtras() != null) { 
       String accountName = 
         data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); 
       if (accountName != null) { 
        credential.setSelectedAccountName(accountName); 
        SharedPreferences settings = 
          getPreferences(Context.MODE_PRIVATE); 
        SharedPreferences.Editor editor = settings.edit(); 
        editor.putString(PREF_ACCOUNT_NAME, accountName); 
        editor.commit(); 
        refreshEventList(); 
       } 
      } else if (resultCode == RESULT_CANCELED) { 
       mStatusText.setText("Account unspecified."); 
      } 
      break; 
     case REQUEST_AUTHORIZATION: 
      if (resultCode == RESULT_OK) { 
       refreshEventList(); 
      } else { 
       chooseAccount(); 
      } 
      break; 
    } 

    super.onActivityResult(requestCode, resultCode, data); 
} 

/** 
* Attempt to get a list of calendar events to display. If the email 
* address isn't known yet, then call chooseAccount() method so the user 
* can pick an account. 
*/ 
private void refreshEventList() { 
    if (credential.getSelectedAccountName() == null) { 
     chooseAccount(); 
    } else { 
     if (isDeviceOnline()) { 
      new EventsFetchTask(this).execute(); 
     } else { 
      mStatusText.setText("No network connection available."); 
     } 
    } 
} 

/** 
* Clear any existing events from the list display and update the header 
* message; called from background threads and async tasks that need to 
* update the UI (in the UI thread). 
*/ 
public void clearEvents() { 
    runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      mStatusText.setText("Retrieving events…"); 
      mEventText.setText(""); 
     } 
    }); 
} 

/** 
* Fill the event display with the given List of strings; called from 
* background threads and async tasks that need to update the UI (in the 
* UI thread). 
* @param eventStrings a List of Strings to populate the event display with. 
*/ 
public void updateEventList(final List<String> eventStrings) { 
    runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      if (eventStrings == null) { 
       mStatusText.setText("Error retrieving events!"); 
      } else if (eventStrings.size() == 0) { 
       mStatusText.setText("No upcoming events found."); 
      } else { 
       mStatusText.setText("Your upcoming events retrieved using" + 
         " the Google Calendar API:"); 
       mEventText.setText(TextUtils.join("\n\n", eventStrings)); 
      } 
     } 
    }); 
} 

/** 
* Show a status message in the list header TextView; called from background 
* threads and async tasks that need to update the UI (in the UI thread). 
* @param message a String to display in the UI header TextView. 
*/ 
public void updateStatus(final String message) { 
    runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      mStatusText.setText(message); 
     } 
    }); 
} 

/** 
* Starts an activity in Google Play Services so the user can pick an 
* account. 
*/ 
private void chooseAccount() { 
    startActivityForResult(
      credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER); 
} 

/** 
* Checks whether the device currently has a network connection. 
* @return true if the device has a network connection, false otherwise. 
*/ 
private boolean isDeviceOnline() { 
    ConnectivityManager connMgr = 
      (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); 
    return (networkInfo != null && networkInfo.isConnected()); 
} 

/** 
* Check that Google Play services APK is installed and up to date. Will 
* launch an error dialog for the user to update Google Play Services if 
* possible. 
* @return true if Google Play Services is available and up to 
*  date on this device; false otherwise. 
*/ 
private boolean isGooglePlayServicesAvailable() { 
    final int connectionStatusCode = 
      GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); 
    if (GooglePlayServicesUtil.isUserRecoverableError(connectionStatusCode)) { 
     showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode); 
     return false; 
    } else if (connectionStatusCode != ConnectionResult.SUCCESS) { 
     return false; 
    } 
    return true; 
} 

/** 
* Display an error dialog showing that Google Play Services is missing 
* or out of date. 
* @param connectionStatusCode code describing the presence (or lack of) 
*  Google Play Services on this device. 
*/ 
void showGooglePlayServicesAvailabilityErrorDialog(
     final int connectionStatusCode) { 
    runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      Dialog dialog = GooglePlayServicesUtil.getErrorDialog(
        connectionStatusCode, 
        MainActivity.this, 
        REQUEST_GOOGLE_PLAY_SERVICES); 
      dialog.show(); 
     } 
    }); 
} 
} 

而這裏的片段:

import android.app.Fragment; 
import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

public class Eventos_Fragment extends Fragment { 
View rootView; 

/** 
* A Calendar service object used to query or modify calendars via the 
* Calendar API. Note: Do not confuse this class with the 
* com.google.api.services.calendar.model.Calendar class. 
*/ 


TextView mStatusText; 
TextView mEventText; 



@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 


    rootView = inflater.inflate(R.layout.fragment_evento, container, false); 
    //Set up event text views for Google API 

    return rootView; 
} 

public void changeStatusText(){ 
    //this textview should be bound in the fragment onCreate as a member variable 
    mStatusText = (TextView) rootView.findViewById(R.id.status_text_view); 
    mStatusText.setText("Estatus"); 
} 

public void changeEventText(){ 
    //this textview should be bound in the fragment onCreate as a member variable 
    mEventText = (TextView) rootView.findViewById(R.id.event_text_view); 
    mEventText.setText("Evento"); 
} 

} 

日誌:

04-28 18:38:46.751 1557-1557/mx.com.origamilab.fresh E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    Process: mx.com.origamilab.fresh, PID: 1557 
    java.lang.RuntimeException: Unable to resume activity {mx.com.origamilab.fresh/mx.com.origamilab.fresh.MainActivity}: java.lang.NullPointerException 
      at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2774) 
      at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2803) 
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2238) 
      at android.app.ActivityThread.access$800(ActivityThread.java:135) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:136) 
      at android.app.ActivityThread.main(ActivityThread.java:5001) 
      at java.lang.reflect.Method.invokeNative(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:515) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
      at dalvik.system.NativeStart.main(Native Method) 
    Caused by: java.lang.NullPointerException 
      at mx.com.origamilab.fresh.MainActivity.onResume(MainActivity.java:258) 
      at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1192) 
      at android.app.Activity.performResume(Activity.java:5310) 
      at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2764) 
            at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2803) 
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2238) 
            at android.app.ActivityThread.access$800(ActivityThread.java:135) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
            at android.os.Handler.dispatchMessage(Handler.java:102) 
            at android.os.Looper.loop(Looper.java:136) 
            at android.app.ActivityThread.main(ActivityThread.java:5001) 
            at java.lang.reflect.Method.invokeNative(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:515) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
            at dalvik.system.NativeStart.main(Native Method) 
+1

你的stacktrace表示它是#258處的NullPointerException,我認爲mStatusText爲null。你可以移動mStatusText =(TextView)rootView.findViewById(R.id.status_text_view);在onCreateView() – Prakash

+0

只供您參考:CodePath有非常好的Android教程在這裏https://guides.codepath.com/android#fragments – Prakash

+0

謝謝,做到了這一點,並試用了它,但它拋出了一個java.lang.NullPointerException MainActivity.onResume –

回答

0

試試這個

更換

FragmentManager fragmentManager = getFragmentManager(); 
fragmentManager.beginTransaction() 
     .replace(R.id.container, fragment) 
     .commit(); 

android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager(); 
      fragmentManager.beginTransaction() 
        .replace(R.id.container, fragment).commit(); 
+0

試過了,對於這個,它告訴我它無法解析方法getSupportFragmentManager:/ –

0

mStatusText永遠不會初始化爲您的MainActivity什麼。這就是爲什麼你會得到一個NullPointerException。

您需要使用findViewById對其進行初始化。也許你的onResume()實現的第一件事。