ich erstelle eine App welche zukünftig einige Activities besitzen soll.
Da in den Activities immer wieder die selben grafischen Elemente bearbeitet werden sollen möchte ich die Bearbeitung als Methoden in eine extra Klasse auslagern.
Bis jetzt ist es mir noch nicht gelungen und ich weiß nicht, woran es liegt.
So sieht es bis jetzt aus…
MainActivity:```public class MainActivity extends Activity {
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
public class Gui {
public void resetUnit(View view) {
view.btnTurntable.setBackgroundResource(R.drawable.unit_toggle_button);
view.btnSupply.setBackgroundResource(R.drawable.unit_toggle_button);
view.btnDoser.setBackgroundResource(R.drawable.unit_toggle_button);
view.btnCovering.setBackgroundResource(R.drawable.unit_toggle_button);
}
}```
Warum kann ich nicht mit dem Object gui meine Buttons bearbeiten?
Wie muss ich das anstellen, damit es geht?
Herzliche Grüße! ;)
Frank
Finde das ganze eher konzeptionell fraglich und verstehe auch nicht welchen Vorteil Du Dir dadurch erhoffst…
Warum kann die Methode resetUnit nicht eine Methode der Activity sein?
Zum Problem: Die Variablen sind nur lokal innerhalb der onCreate deklariert. Um in der anderen Klasse darauf zugreifen zu können müssten diese als Instanzvariable und public definiert sein.
den erhofften Vorteil habe ich doch oben beschrieben und mein Beispiel ist nur ein kleines, um das Problem zu verdeutlichen. Ich möchte in den einzelnen Activities nicht die kompletten Methoden kopieren und reinsetzen und langen (und dann auch unübersichtlicheren) Quellcode erzeugen.
Die ToggleButtons sind alle als public angelegt (vor der ersten Methode) wie z.B. ToggleButton btnDoser;
Wie meinst du das, dass die Buttons als Instanzvariable angelegt sein müssen? Ist btnDoser nicht schon eine Instanzvariable?
*** Edit ***
Um das gesagte zu untermauern…
hier nochmal die MainActivity:
Dieser Code sieht doch schon anders aus als der erste, bei diesem müsstest du auch darauf zugreifen dürfen. Was ist denn das Problem? Was erwartest du und was passiert?
Warum sollte man Methoden zur Manipulation von Komponenten in einer andere Klasse auslagern und nicht in der Klasse vornehmen, in der die Komponenten deklariert sind? Ich sehe da die Gefahr, dass man irgendwann den Überblick verliert.
Zu Deinem Code. resetUnit erwartet eine View. Du übergibst aber eine Activity. Das müsste Dir aber die IDE bereits per Fehlermeldung verraten, dass das nicht geht.
Die Methode muss als Parameter eine Activity übernehmen können und dann darf es auch nicht eine allgemeine Activity sein, sondern es muss ich um genau die Activity handeln in der die Instanzvariablen deklariert sind.
Also entweder resetUnit(MainActivity activity) oder resetUnit(Activity activity) und dann in der Methode activity zu einer MainActivity casten.
natürlich, ich übergebe die MainActivity und will sie in der als View entgegennehmen.
Das geht natürlich nicht, da hast du Recht
und deshalb bekomme ich die Fehlermeldung “btnTurntable cannot be resolved or is not a field”.
Starten konnte ich daher auch nie, da der Fehler schon die ganze Zeit angezeigt wird.
Der Vorschlag: resetUnit(Activity activity) funktioniert leider nicht, selbe Fehlermeldung wie oben “btnTurnTable cannot be…”.
Der Vorschlag: resetUnit(MainActivity activity) funktioniert sehr schön! Löst aber leider nicht meine Problemstellung. Martin, du hast ja gefragt…[QUOTE=_Michael;62747]Warum sollte man Methoden zur Manipulation von Komponenten in einer andere Klasse auslagern und nicht in der Klasse vornehmen, in der die Komponenten deklariert sind? Ich sehe da die Gefahr, dass man irgendwann den Überblick verliert.[/QUOTE]
Nun ja, ich erhoffe mir, dass bei der Erstellung der folgenden 20 Activitys,
bei denen ein Teil (30 bis 70%) der Steuerung / Methoden identisch sind,
jeweils 300 Zeilen Quelltext sparen kann und statt dessen nur die Methoden der Klasse Gui aufrufen muss.
Außerdem erhöht es die Wartbarkeit, da ggf. nur an einer Stelle geschraubt werden muss.
Hat noch jemand eine Idee zur Lösung des Problems?
Du greifst auf konkrete Instanzvariable der Klasse MainActivity zu, da bleibt dir nichts anders übrig.
Hier wäre wie gesagt ein Cast auf MainActivity notwendig. Die Variante macht aber nicht viel Sinn bzw. hat keine Vorteile.
[QUOTE=frankmehlhop;62757]Nun ja, ich erhoffe mir, dass bei der Erstellung der folgenden 20 Activitys,
bei denen ein Teil (30 bis 70%) der Steuerung / Methoden identisch sind[/QUOTE]
20 Activties für eine App ist schon recht viel, kann man die Anzahl nicht reduzieren? Unabhängig von der Anzahl solltest Du mal darüber nachdenken ob/was die Activties gemeinsam haben. Wenn Du 20 spezifische individuelle Activities hast bräuchtest Du mit Deiner Vorgehensweise auch 20 resetUnit Methoden und hast damit eigentlich nur Code verschoben.
Wenn in den Activties ein Teil identisch ist, kann man diesen Teil nicht in einer eigenen View definieren, die man in den Activities verwendet? Oder evtl. kann man eine (abstrakte) Activty definieren, die diese gemeinsamen Funktionen implementiert und von der alle anderen Activities erben…
Diese resetUnit-Methoden sind für jede Aktivity identisch.
Sonst macht das Auslagern wirklich keinen Sinn.
Entsprechend ist auch ein großer Teil der Oberfläche identisch,
was ich mit dem xml gut auslagern /inkludieren lässt.
Das mit der abstrakten Activity könnte gehen…
Ich schaue es mir mal an.
Aber wenn sonst noch jemanden was dazu einfällt,
bitte mitteilen!
Da in den Activities immer wieder die selben grafischen Elemente bearbeitet werden sollen möchte ich die Bearbeitung als Methoden in eine extra Klasse auslagern.
Das hört sich nach einem verqueren Versuch an Fragments neu zu erfinden. Der erste Satz in der Doku zu den Fragments lautet:
A Fragment represents a behavior or a portion of user interface in an Activity. […]
Das Wiederverwenden von Views und dazugehörigen Logik macht Sinn. Das Entkoppeln der logisch gekoppelten Views und Logik allerdings nicht. Schau dir die Fragments mal an, hört sich danach an als wäre das genau was du suchst.
Funktioniert sehr gut!
Für diejenigen, die hierherkommen und eine ähnliche Lösung suchen hier der Code:
MainActivity.java:
import android.os.Bundle;
import android.app.Activity;
abstract class MainActivity extends Activity {
public String wort;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public String getWort() {
return wort;
}
public void setWort(String wort) {
this.wort = wort;
}
}```
Zwei.java:```package com.mehlhop.astrakteactivity;
import android.os.Bundle;
import android.widget.TextView;
public class Zwei extends MainActivity {
private TextView txv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zwei);
txv = (TextView) findViewById(R.id.txv);
setWort("Guten Morgen!");
txv.setText(getWort());
}
}```
mit dem Design:
[XML]<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Zwei" >
<TextView
android:id="@+id/txv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
[/XML]
und der Änderung im Manifest:
[XML]...
<activity
android:name="com.mehlhop.astrakteactivity.MainActivity"
android:label="@string/app_name" >
</activity>
<activity
android:name="com.mehlhop.astrakteactivity.Zwei"
android:label="@string/title_activity_zwei" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter> >
</activity>
...[/XML]
FREU!
*** Edit ***
[QUOTE=schlingel]Schau dir die Fragments mal an, hört sich danach an als wäre das genau was du suchst.[/QUOTE]
Danke Schlingel,
das werde ich mir anschauen! ;)
(Die Fragments sind mir gerade gestern das erste mal begegnet,
im Zusammenhang mit Tablets..)
Für diejenigen, die hierherkommen und eine ähnliche Lösung suchen hier der Code
Vererbung als Code Sharing ist architektonisch die schlechteste Variante um die Funktionalität auf mehr als eine Klasse mit einer Code-Basis zu verteilen. extends/implements sollte immer nur verwendet werden wenn es tatsächlich eine IS-A Verbindung gibt.
Glaube jetzt eine ungefähre Ahnung zu haben was Du vorhast. Du meinst mit “die selben” tatsächlich die selben Komponenten. Heißt ein Teil deines Layouts bleibt immer gleich und der Rest wird immer ausgetauscht. In dem Fall muss ich meinem Vorposter zustimmen. Hier ist Vererbung keine gute Lösung. Mit Fragments scheint so etwas realisierbar.
Irgendwie passt der neue Code nicht zu dem bisherigen. In dem Beispiel macht es keinen Sinn bzw. es wird nicht deutlich warum MainActivitity eine Activity sein muss und “Zwei” von ersterer erben sollte. Komposition wäre hier genau das richtige.