Funktionen auslagern und "findViewById"

  • Antworten:14
  • Bentwortet
Gelöschter Account
  • Forum-Beiträge: 7

21.08.2012, 09:14:42 via Website

Hi,

ich würde gerne, weil ich in mehreren layouts die selben Funktionen benutze, diese funktion quasi in ein "Modul" auslagern.
Habe dazu mal ein test gemacht in dem ich eine neue java datei angelegt habe und diese dort eingefügt habe, nur beendet sich das programm bei dem eintrag "findViewById"...

ist so ein auslagern überhaupt möglich, wenn ja wie könnte ichs realisieren?

aufrufen der externen funktion:
1funktion_list = new funktion(this);
2funktion_list.addListener_Navi(R.id.button_month);

Funktion:
[code] Context context;

public funktion(Context contextnow) {

context = contextnow;
}

public void addListener_Navi(int now_id) {
Button btn;

final int id_s[] = { R.id.button_year,
R.id.button_month,
R.id.button_week,
R.id.button_day};

final Intent intent_id[] = { new Intent(context, MainActivity_Year.class),
new Intent(context, MainActivity_Month.class),
new Intent(context, MainActivity_Week.class),
new Intent(context, MainActivity_Day.class)};

for (int i = 0; i < id_s.length; i++) {
final int i1 = i;
btn = (Button) findViewById(id_s[i]);
if (now_id == id_s[i]){
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
startActivity(intent_id[i1]);
}
});
}else{
btn.setEnabled(false);
}
}
}[/code]

Logcat:
108-21 07:00:39.705: E/AndroidRuntime(526): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)
208-21 07:00:39.705: E/AndroidRuntime(526): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
308-21 07:00:39.705: E/AndroidRuntime(526): at android.app.ActivityThread.access$2100(ActivityThread.java:116)
408-21 07:00:39.705: E/AndroidRuntime(526): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
508-21 07:00:39.705: E/AndroidRuntime(526): at android.os.Handler.dispatchMessage(Handler.java:99)
608-21 07:00:39.705: E/AndroidRuntime(526): at android.os.Looper.loop(Looper.java:123)
708-21 07:00:39.705: E/AndroidRuntime(526): at android.app.ActivityThread.main(ActivityThread.java:4203)
808-21 07:00:39.705: E/AndroidRuntime(526): at java.lang.reflect.Method.invokeNative(Native Method)
908-21 07:00:39.705: E/AndroidRuntime(526): at java.lang.reflect.Method.invoke(Method.java:521)
1008-21 07:00:39.705: E/AndroidRuntime(526): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
1108-21 07:00:39.705: E/AndroidRuntime(526): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
1208-21 07:00:39.705: E/AndroidRuntime(526): at dalvik.system.NativeStart.main(Native Method)
1308-21 07:00:39.705: E/AndroidRuntime(526): Caused by: java.lang.NullPointerException
1408-21 07:00:39.705: E/AndroidRuntime(526): at android.app.Activity.findViewById(Activity.java:1610)
1508-21 07:00:39.705: E/AndroidRuntime(526): at ....funktion.addListener_Navi(funktion.java:53)
1608-21 07:00:39.705: E/AndroidRuntime(526): at ....MainActivity_Month.onCreate(MainActivity_Month.java:22)
1708-21 07:00:39.705: E/AndroidRuntime(526): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
1808-21 07:00:39.705: E/AndroidRuntime(526): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
1908-21 07:00:39.705: E/AndroidRuntime(526): ... 11 more

— geändert am 21.08.2012, 09:19:01

Antworten
Markus Gu
  • Forum-Beiträge: 2.644

21.08.2012, 11:16:20 via Website

prinzipiell schon möglich, du musst findviewid immer dort aufrufen, wo du setcontentview gesetzt hast.

ich weiß jetzt nicht wo du deine methode ausgelagert hast. deshalb kann ich dir da nichts genaueres sagen

swordiApps Blog - Website

Antworten
Gelöschter Account
  • Forum-Beiträge: 7

21.08.2012, 11:36:40 via Website

hab noch deiner antwort mal was ausprobiert aber will noch nicht so....
1.-4. layout:
[code]
1public class MainActivity_Month extends ListActivity {
2
3 funktion funktion_list;
4
5 @Override
6 public void onCreate(Bundle savedInstanceState) {
7
8 funktion_list = new funktion(this,savedInstanceState);
9 funktion_list.addListener_Navi(R.id.button_month);
10
11
12 addListener_database(8);
13
14 funktion_list.addListener_msql();
15 }}

Funktionen-java:
[code]
public class funktion extends Activity{

Context context;

public funktion(Context contextnow,Bundle nowsavedInstanceState) {
super.onCreate(nowsavedInstanceState);

context = contextnow;
}

public void addListener_Navi(int now_id) {
Button btn;

final int id_s[] = { R.id.button_year,
R.id.button_month,
R.id.button_week,
R.id.button_day};

final int lay_id_s[] = {R.layout.activity_year,
R.layout.activity_month,
R.layout.activity_week,
R.layout.activity_day};

final Intent intent_id[] = { new Intent(context, MainActivity_Year.class),
new Intent(context, MainActivity_Month.class),
new Intent(context, MainActivity_Week.class),
new Intent(context, MainActivity_Day.class)};

for (int i = 0; i < id_s.length; i++) {
if (now_id == id_s[i]){
setContentView(lay_id_s[i]);
}
}

for (int i = 0; i < id_s.length; i++) {
final int i1 = i;
if (now_id == id_s[i]){
btn = (Button) findViewById(id_s[i]);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
startActivity(intent_id[i1]);
}
});
}else{
btn = (Button) findViewById(id_s[i]);
btn.setEnabled(false);
}
}
}}
[/code][/code]

Antworten
Markus Gu
  • Forum-Beiträge: 2.644

21.08.2012, 11:40:23 via Website

das ist alles etwas wirr was du da machst :)

du hast deine buttons ja in deinem xml layout

dann musst du auch als erstes setContentView aufrufen und das Layout setzen. sonst wirst du keinerlei Erfolg mit findViewById haben.

nochmal die Grundlagen durchlesen.

swordiApps Blog - Website

Antworten
Gelöschter Account
  • Forum-Beiträge: 7

21.08.2012, 11:56:24 via Website

Also wirr find ichs auch aber sonst habe ich nichst gefunden wie ich es anders Lösen kann.
Mein Ziel ist einfach das ich 4 unterschiedliche "Seiten" habe oben eine kleine Navigation die natürlich bei allen 4 gleich aussehen nur halt ein eintrag davon nicht anwählbar (verständtlicherweise die wo man drauf ist).
Grundidee die ich bei den Code hatte , war halt soballt eine Klasse aufgerufen wird , dass meine Funktion aufgerufen wird


(
1funktion_list = new funktion(this,savedInstanceState);
29 funktion_list.addListener_Navi(R.id.button_month);
)


, die dann erst das aktuelle layout Läd


([code]for (int i = 0; i < id_s.length; i++) {
if (now_id == id_s[i]){
setContentView(lay_id_s[i]);
}
}[/code])


und dann der navi sagt welchen Button er Deaktivieren


([code]btn = (Button) findViewById(id_s[i]);
btn.setEnabled(false);[/code])


soll und die anderen ein OnClick


([code]btn = (Button) findViewById(id_s[i]);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
startActivity(intent_id[i1]);
}
});[/code])


zuweisen.

Im Prinzip habe ich das programm danach geschreiben nur Java will es bestimmt anders haben....

— geändert am 21.08.2012, 11:58:13

Antworten
Andreas Weichert
  • Forum-Beiträge: 287

21.08.2012, 19:06:50 via Website

Code wiederzuverwenden ist ja immer eine gute Idee. Ich mag auch nicht immer wieder dasselbe schreiben. Ich verstehe allerdings nicht was Du vor hast.
Könntes Du vereinfacht nur das Prinzip darlegen und die Begriffe Layout, Activity und Funktion besser trennen.
Zeige nur einfache Quelltext die nur die Struktur zeigen. Formatierung durch Einrückungen würden den Code besser lesbar machen.

Ansonsten würde ich Vererbung vorschlagen. Eine Basis-Activity die deine gemeinsam verwendeten Funktionen beinhaltet.

Antworten
Gelöschter Account
  • Forum-Beiträge: 7

22.08.2012, 06:41:01 via Website

Andreas Weichert
Code wiederzuverwenden ist ja immer eine gute Idee. Ich mag auch nicht immer wieder dasselbe schreiben. Ich verstehe allerdings nicht was Du vor hast.
Könntes Du vereinfacht nur das Prinzip darlegen und die Begriffe Layout, Activity und Funktion besser trennen.

Wie schon gesagt, habe 5 layouts , davon haben 4 eine eigene Activity und die 5. ist die navigation , diese ich in den 4 layouts include.
In der "AndroidManifest.xml" habe ich alle 4 ActivitysFestgelegt und eine davon das diese Starten soll.
Diese eine Activity wird dann aufgerufen, im "oncreate" wird sofort meine Funktions-Klasse gestartet , alles übergeben (Context contextnow,Bundle nowsavedInstanceState) und danach meine navigations-Funktion aufgerufen.
So und da hänge ich dan auch schon... wie kann ich in meiner Navigations-Funktion (die in der Funktions-Klasse befindet) das Layout setzen und darauf zugreifen?

Andreas Weichert
Zeige nur einfache Quelltext die nur die Struktur zeigen. Formatierung durch Einrückungen würden den Code besser lesbar machen.

Ich füge 1:1 den Code von Eclipse hierrein, nur die foren-Software haut mir aber die "Einrückungen" wieder raus und öffters nimmt er "(code)(/code)" nicht an....

Andreas Weichert
Ansonsten würde ich Vererbung vorschlagen. Eine Basis-Activity die deine gemeinsam verwendeten Funktionen beinhaltet.

mit "Vererbung" verstehe ich jetzt das ich statt "extends Activity" -> "extends meineklasse" benutzen soll, was ich wiederum nicht nutzen kann weil ich noch andere Klassen verweden muss...

Antworten
Andreas Weichert
  • Forum-Beiträge: 287

22.08.2012, 09:53:00 via Website

Dennis R.

Wie schon gesagt, habe 5 layouts , davon haben 4 eine eigene Activity und die 5. ist die navigation , diese ich in den 4 layouts include.
In der "AndroidManifest.xml" habe ich alle 4 ActivitysFestgelegt und eine davon das diese Starten soll.
Diese eine Activity wird dann aufgerufen, im "oncreate" wird sofort meine Funktions-Klasse gestartet , alles übergeben (Context contextnow,Bundle nowsavedInstanceState) und danach meine navigations-Funktion aufgerufen.
So und da hänge ich dan auch schon... wie kann ich in meiner Navigations-Funktion (die in der Funktions-Klasse befindet) das Layout setzen und darauf zugreifen?
Wußte nicht, dass man Layouts includieren kann. Bin noch nicht lange bei Android.
Wie ichs verstanden haben:
Du hast 4 Activities mit 4 Layouts. Die Layouts habe absolut identische Teillayouts (Navigation) für die Du natürlich auch identischen Code brauchst.
Diesen identischen Code hast Du in mehrere Klassen ausgelagert. (ev. Designfehler)
In diesen Klassen willst Du z.B. auf die Controls zugreifen. Übergebe doch einfach die Activity diesen Klassen.
1class Navigation
2{
3 void Init(Activity A) { Button b = (Button) A.findViewById(R......); etc. }
4}
Die Codeformatierung funktioniert ja wirklich nicht !!!!

Dennis R.

mit "Vererbung" verstehe ich jetzt das ich statt "extends Activity" -> "extends meineklasse" benutzen soll, was ich wiederum nicht nutzen kann weil ich noch andere Klassen verweden muss...
Besser noch:
Da Du gewissermaßten eine Vererbungstruktur der Layout hast solltes Du dieselbe Vererbungsstruktur auch für die Activitys verwenden.
D.h. die Navigation komplette in eine BasisActivity integrieren.
Entweder bettest du deine fertigen Klassen darin ein oder schreibst den code direkt darin.
Eingebetteten Klassen habe den Parentcontext somit Zugriff auf die Activity

1class NaviActivity extends Activity
2{
3 void InitNavi() { findViewById, .............. setOnClickListener etc. ....... }
4}
5class Activity1 extends NaviActivity
6{
7 onCreate(....)
8 {
9 setContentView(R.......)
10 InitNavi(); // allg. Navi code
11 //Weiterer spezifischer Code........
12 }
13}

Habe ich es richtig verstanden?

Antworten
Gelöschter Account
  • Forum-Beiträge: 7

23.08.2012, 08:17:59 via Website

So, habe dein Tipp mit
1class Navigation
2{
3 void Init(Activity A) { Button b = (Button) A.findViewById(R......); etc. }
4}
mal befolgt , warum ich net selbst drauf gekommen bin ist fraglich nur habe jetzt noch probleme mit den OnClick Event und startActivity...

wie folgt habe ich es im mom stehen (in der Funktions.class):
[code] nowActivity.findViewById(id_s[i]).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
nowActivity.startActivity(new Intent(nowActivity, MainActivity_Day.class));
}
});[/code]
in den Button Springt er rein nur die Aktivity will nicht Starten bzw Beendet meine App...

LogCat:
108-23 06:11:04.855: E/AndroidRuntime(216): Uncaught handler: thread main exiting due to uncaught exception
208-23 06:11:04.865: E/AndroidRuntime(216): android.app.SuperNotCalledException: Activity {.../....MainActivity_Day} did not call through to super.onCreate()
308-23 06:11:04.865: E/AndroidRuntime(216): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2366)
408-23 06:11:04.865: E/AndroidRuntime(216): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
508-23 06:11:04.865: E/AndroidRuntime(216): at android.app.ActivityThread.access$2100(ActivityThread.java:116)
608-23 06:11:04.865: E/AndroidRuntime(216): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
708-23 06:11:04.865: E/AndroidRuntime(216): at android.os.Handler.dispatchMessage(Handler.java:99)
808-23 06:11:04.865: E/AndroidRuntime(216): at android.os.Looper.loop(Looper.java:123)
908-23 06:11:04.865: E/AndroidRuntime(216): at android.app.ActivityThread.main(ActivityThread.java:4203)
1008-23 06:11:04.865: E/AndroidRuntime(216): at java.lang.reflect.Method.invokeNative(Native Method)
1108-23 06:11:04.865: E/AndroidRuntime(216): at java.lang.reflect.Method.invoke(Method.java:521)
1208-23 06:11:04.865: E/AndroidRuntime(216): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
1308-23 06:11:04.865: E/AndroidRuntime(216): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
1408-23 06:11:04.865: E/AndroidRuntime(216): at dalvik.system.NativeStart.main(Native Method)

Antworten
André
  • Forum-Beiträge: 77

23.08.2012, 09:06:18 via Website

Und was genau verstehst du nicht bei der Fehlermeldung "Activity {.../....MainActivity_Day} did not call through to super.onCreate()"?

Antworten
Gelöschter Account
  • Forum-Beiträge: 7

23.08.2012, 09:39:21 via Website

schön und gut das er den Befehl nicht finden kann aber wo muss ich ihn hinsetzen wenn ich ihn in meiner Haupt-Klasse schon gesetzt habe?

Antworten
Andreas Weichert
  • Forum-Beiträge: 287

23.08.2012, 10:42:29 via Website

Ich würde erstmal debuggen ober er in MainActivity_Day.OnCreate reinspringt.
Wenn ja durchsteppen und Fehlerzeile finden.

Ev. fehlt super.OnCreate() in MainActivity_Day.OnCreate dann kommt der Fehler wahrscheinlich erst später.

Was mich auch iritiert, "public class funktion extends Activity"
function ist doch selbst keine Activity sondern ein Modul, das eine Activity verwalten.

Wie gesagt Activity-Vererbung ist die Struktur die auf dein Problem passt.
Sag mal nen schlauen Spruch:
"Eine gute Datenstruktur ist der hallbe Algorithmus"
D.h. Wenn Code für einfache Aufgaben kompliziert wird ist die Datenstruktur nicht an das Problem angepasst.

Gelöschter Account

Antworten
André
  • Forum-Beiträge: 77

23.08.2012, 10:43:12 via Website

Hast du im onCreate() deiner Hauptklasse den Aufruf super.onCreate() drin und rufst das auch aus den Subklassen auf? Dann würde es den Fehler nicht geben. Du hast also vermutlich irgendwo vergessen, den Aufruf aufwärts zu propagieren.

— geändert am 23.08.2012, 10:43:52

Antworten
Andreas Weichert
  • Forum-Beiträge: 287

23.08.2012, 10:58:15 via Website

Dennis R.
schön und gut das er den Befehl nicht finden kann aber wo muss ich ihn hinsetzen wenn ich ihn in meiner Haupt-Klasse schon gesetzt habe?

Ich nehme mal an deine Hauptklasse ist function. Das ist wie gesagt eigenltich keine Activity.
Du must in MainActivity_Day.super.onCreate aufrufen.
Oder nowActivity.super.onCreate() - wäre allerding ein wenig schräg platziert.

Antworten
Gelöschter Account
  • Forum-Beiträge: 7

23.08.2012, 10:59:59 via Website

Andreas Weichert
Ich würde erstmal debuggen ober er in MainActivity_Day.OnCreate reinspringt.
Wenn ja durchsteppen und Fehlerzeile finden.

Ev. fehlt super.OnCreate() in MainActivity_Day.OnCreate dann kommt der Fehler wahrscheinlich erst später.
Das wars hatte ich vorher versuchsweise entfernt und nicht mehr drann gedacht und 2. sollte ich genauer lesen was die Fehlermeldung will....

Andreas Weichert
Was mich auch iritiert, "public class funktion extends Activity"
function ist doch selbst keine Activity sondern ein Modul, das eine Activity verwalten.
Das war auch ein versuch gewesen hatte ich aber in laufe meiner Arbeit wieder entfernt gehabt

Danke für die Hilfe und die Gedullt^^

— geändert am 23.08.2012, 11:01:26

Antworten