2016-10-31 2 views
0

Ich habe einige Schwierigkeiten mit Ansichten in einer Methode von einer anderen Klasse aufgerufen, um ordnungsgemäß zu funktionieren.Android Studio - Verwenden von Methoden aus externen Klassen mit Ansichten

Meine App enthält eine Erlebnisleiste in der Hauptaktivität (Overlay genannt), die den Fortschritt des Benutzers anhand einer Fortschrittsleiste verfolgt. Was ich tun möchte, ist eine separate Methode in einer anderen Klasse, die jeden Code verarbeitet, der sich auf die Experience-Leiste bezieht.

Ich habe bereits eine Instanz für die Klasse erstellt und die Methode wird korrekt aufgerufen, aber bestimmte android/view bezogene Stücke führen zu einem krassen. System.out.println wird Text im Debugger anzeigen, die Verwendung von Toast und anderen Ansichten jedoch nicht. Hier sind die zwei Klassendateien und der damit verbundene Fehler.


public class OverlayActivity extends AppCompatActivity 
    implements NavigationView.OnNavigationItemSelectedListener { 

NavigationView navigationView = null; 
Toolbar toolbar = null; 
int level = 0; 
int addXP = 110; 
ProgressBar experienceBar; 
Button buttonXP; 
TextView experienceLevel; 
ExperienceManager exp; 

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

    //Set the Overlay Fragment 

    OverlayFragment fragment = new OverlayFragment(); 
    android.support.v4.app.FragmentTransaction fragmentTransaction = 
      getSupportFragmentManager().beginTransaction(); 
    fragmentTransaction.replace(R.id.fragment_container, fragment); 
    fragmentTransaction.commit(); 

    toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
    fab.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Snackbar.make(view, "Hay! Don't touch me!", Snackbar.LENGTH_LONG) 
        .setAction("Action", null).show(); 
     } 
    }); 

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
      this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); 
    drawer.setDrawerListener(toggle); 
    toggle.syncState(); 

    navigationView = (NavigationView) findViewById(R.id.nav_view); 
    navigationView.setNavigationItemSelectedListener(this); 

    experienceBar = (ProgressBar) findViewById(R.id.experienceBar); 
    experienceBar.setProgress(12); 

    experienceLevel = (TextView) findViewById(R.id.ds_appBar_level); 

    buttonXP = (Button) findViewById(R.id.buttonXP); 
    buttonXP.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View View) { 
      exp = new ExperienceManager(); 
      exp.addExperience(level, addXP); 
     } 
    }); 
} 

public class ExperienceManager extends AppCompatActivity { 

ProgressBar experienceBar; 

public int addExperience(int level, int addXP) { 
    experienceBar = (ProgressBar) findViewById(R.id.experienceBar); 

    int addLevel = 0; 
    while (addXP >= experienceBar.getMax()) { 
     addXP -= experienceBar.getMax(); 
     addLevel += 1; 
    } 
    if (addXP >= experienceBar.getMax()-experienceBar.getProgress()) { 

     experienceBar.setProgress(experienceBar.getProgress() + addXP - experienceBar.getMax()); 
     addLevel += 1; 
    } else { 
     experienceBar.setProgress(experienceBar.getProgress() + addXP); 
    } 
    if (addLevel >= 1) { 
     level += addLevel; 
     Toast toast = Toast.makeText(getBaseContext(), "Level up!", Toast.LENGTH_SHORT); 
     toast.show(); 
     //experienceLevel.setText("Level " + level); 
    } 
    return level; 
} 

E/AndroidRuntime: FATAL EXCEPTION: main 
       Process: com.teamcirelios.deepstone, PID: 4138 
       java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference 
        at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java:116) 
        at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java:147) 
        at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:27) 
        at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:50) 
        at android.support.v7.app.AppCompatDelegateImplV23.<init>(AppCompatDelegateImplV23.java:29) 
        at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:199) 
        at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:181) 
        at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:521) 
        at android.support.v7.app.AppCompatActivity.findViewById(AppCompatActivity.java:190) 
        at com.teamcirelios.deepstone.ExperienceManager.addExperience(ExperienceManager.java:15) 
        at com.teamcirelios.deepstone.OverlayActivity$2.onClick(OverlayActivity.java:77) 
        at android.view.View.performClick(View.java:5697) 
        at android.widget.TextView.performClick(TextView.java:10826) 
        at android.view.View$PerformClick.run(View.java:22526) 
        at android.os.Handler.handleCallback(Handler.java:739) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:158) 
        at android.app.ActivityThread.main(ActivityThread.java:7225) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 

Ebenso ein ähnlicher Fehler ergibt sich, wenn eine Schaltfläche klicken in einem Fragment zu registrieren versuchen. Die Experience-Leiste selbst wird mit der Aktion "Overlay" angezeigt. Damit die App jedoch wie beabsichtigt funktioniert, müsste sie eine Eingabe zum Aufrufen dieser Klasse von einer Schaltfläche (oder genauer gesagt einer Checkbox) innerhalb eines Fragments erhalten.

Die einzige Lösung, die ich funktionierend sehen könnte, würde sein, experienceBar.getMax() und ähnliches zu nehmen und sie als Parameter einzuschließen. Allerdings müsste ich sowohl das Level als auch das aktuelle xp zurückgeben, was meiner Kenntnis nach nicht möglich ist.

Um alles zusammenzufassen, habe ich drei Hauptfragen.

  • Was ist die nicht technische Erklärung für diesen Fehler?
  • Was ist der beste (und relativ einfache) Weg, um den Code zu reparieren, um die gewünschte Funktion zu erreichen?
  • Wie kann ich Ereignisse in einem Fragment registrieren?

Vielen Dank!

Antwort

0

Zunächst sollte Ihre Dienstklasse, d. H. Experience Manager, AppCompatActivity nicht erweitern ... Ihre Dienstklasse ist keine Aktivität! PS Sie können ViewById Ihre Fortschrittsleiste nicht in der Experience Manager-Klasse finden, da diese ProgressBar nicht Teil Ihrer ExperienceManager-Aktivität ist. Sie ist Teil Ihrer OverlayActivity.

Wenn Sie eine statische Hilfsmethode zum Hinzufügen von Erfahrung und Verwaltung erstellen möchten, sollten Sie Ihren Code auf diese Weise schreiben.

public class ExperienceManager{ 

public static int addExperience(ProgressBar experienceBar, int level, int addXP){ 

    int addLevel = 0; 
    while (addXP >= experienceBar.getMax()) { 
     addXP -= experienceBar.getMax(); 
     addLevel += 1; 
    } 
    if (addXP >= experienceBar.getMax()-experienceBar.getProgress()) { 

     experienceBar.setProgress(experienceBar.getProgress() + addXP - experienceBar.getMax()); 
     addLevel += 1; 
    } else { 
     experienceBar.setProgress(experienceBar.getProgress() + addXP); 
    } 
    if (addLevel >= 1) { 
     level += addLevel; 
     Toast toast = Toast.makeText(getBaseContext(), "Level up!", Toast.LENGTH_SHORT); 
     toast.show(); 
     //experienceLevel.setText("Level " + level); 
    } 
    return level; 
} 
} 

Und Sie können diese Methode auf diese Weise nennen:

buttonXP.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View View) { 
      // Calling the static utility method over here... 
      ExperienceManager.addExperience(experienceBar, level, addXP); 

     } 
}); 

Das ist alles, was Sie tun müssen, um :)

Ich empfehle vertraut Praktiken mit Java Design Patterns und beste Programmierung würde immer, bevor Sie versuchen Android.

+0

Wenn diese Antwort Ihnen geholfen hat, bitte upvote und markieren Sie diese Antwort als richtig :). (Pfeil nach oben und Häkchen neben Antwort) – oathkeeper

+0

Das funktioniert, danke! Der ExperienceManager erweitert AppCompatActivity war eine Teständerung basierend auf einer Antwort, die ich heute gefunden habe, und wurde einfach nicht zurück geändert. Guter Fang! Soweit es das Projekt betrifft, ist es eine App für die Congressional App Challenge, die selbst für "neuere" Programmierer wie mich entwickelt wurde, die nur etwa einen Monat lang Programmiererfahrung haben. Danke für Ihre Hilfe! –

Verwandte Themen