Probleme mit dem Löschen von Tabs ( TabHost updaten)

  • Antworten:13
  • Bentwortet
dreadkopp
  • Forum-Beiträge: 23

08.09.2014, 17:14:29 via Website

Aloha Community,

ich versuche für eine App Tabbing zu realisieren.

das ganze soll funktionieren wie folgt:

Ich habe eine bestehende App. Dessen MainActivity soll in Tab1 dargestellt werden und wie bisher funktionieren, wobei alle neuen Activities in dem Tab dargestellt werden.

Ich möchte nun die Möglichkeit haben, einen neuen Tab zu öffnen, in welcher wieder die originale MainActivity geöffnet wird. Hier soll sich die Activity nun auch wieder in dem Tab so verhalten, als gäbe es keinen Tab.

Ich hoffe, ihr versteht, was ich meine.

Bisher bin ich noch nicht weit gekommen:

Ich habe eine DemoApp gefunden, welche mir dynamisch neue Tabs erzeugt und ein wenig editiert.

Was mir fehlt:

*TabAdd-Button soll neben der ActionBar liegen
*Tabs müssen zu schließen sein (bestenfalls mit einem Button im Tab)
*Im Tab soll die ehemalige MainActivity laufen.

meine bisherige MainActivity:

<code>

package com.example.app.test;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AnalogClock;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TabHost;

public class MainActivity extends Activity {

private int counter = 0;

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);

final TabHost tabs=(TabHost)findViewById(R.id.tabhost);


tabs.setup();



TabHost.TabSpec spec=tabs.newTabSpec("buttontab");
spec.setContent(R.id.buttontab);
spec.setIndicator("Button");
tabs.addTab(spec);



Button btn=(Button)tabs.getCurrentView().findViewById(R.id.buttontab);



btn.setOnClickListener(new View.OnClickListener() {
  public void onClick(final View view) {
    TabHost.TabSpec spec=tabs.newTabSpec("tag1");

    spec.setContent(new TabHost.TabContentFactory() {
      public View createTabContent(String tag) {
          //instead of AnalogClock run the TabActivity
          return (new AnalogClock(MainActivity.this));
          // ????  but TabActivity is a activity not a view... 
          //return (new MainActivity(MainActivity.this));
      }
    });
    incCounter();
    int counter = getCounter();

    spec.setIndicator("Tab "+counter); //$NON-NLS-1$
    tabs.addTab(spec);
  }
});

}

public void newTab (View view) {
Intent intent = new Intent(this, TabActivity.class);
startActivity(intent);
}

public void incCounter(){
this.counter++;

}
public int getCounter(){
return this.counter;
}
public void decCounter(){
this.counter--;
}

}

</code>

das Layout:

<code>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TabHost android:id="@+id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="62px">

   <TableLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <TableRow
            android:id="@+id/tableRow1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
             <Button
    android:id="@+id/buttontab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button" />


        </TableRow>

        <TableRow
            android:id="@+id/tableRow2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
             <Button
    android:id="@+id/buttonrmtab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button" />
        </TableRow>


    </TableLayout>

</FrameLayout>

</TabHost>
</LinearLayout>

</code>

Kann mir jemand ein gutes Tutorial dazu geben, oder mir anderweitig unter die Arme greifen? Ich hänge da seit einigen Tagen dran, bin aber außer Abstürzen und Frustration noch zu nicht viel gekommen.

Grüße!

— geändert am 09.09.2014, 14:56:39

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

08.09.2014, 17:39:09 via Website

Hallo dreadkopp,

Herzlich willkommen bei uns im Forum :)

Bitte beachte, dass Threads mit nicht aussagekräftigem Titel bei uns üblicherweise den Regeln entsprechend entfernt werden. Ich bitte dich daher, deinen Threadtitel spätestens innerhalb der nächsten 24 Stunden noch etwas aussagekräftiger zu gestalten (Hierfür einfach unter deinem ersten Beitrag auf 'bearbeiten' klicken, dann kannst du oben noch mal den Titel anpassen)

Danke :)

------------------------------------------

Nun zu deinem Problem:

*TabAdd-Button soll neben der ActionBar liegen

Was meinst du mit neben der Action Bar?
In der Action Bar als Item ist wesentlich einfacher.
Dafür musst du das Item nur in der menu.xml hinzufügen.
Über einen Menuinflater kannst du das dann in der Bar anzeigen lassen.
Per Code auch deine Aktion bei click festlegen.
Ich denke da hilt dir das weiter.

*Tabs müssen zu schließen sein (bestenfalls mit einem Button im Tab)

Das ist nicht so einfach, da müsstest du dir eine eigene Tab Logik aufbauen.
Alternative: Schließen mit langem click über einen LongCklick listener
Bitte beachte dass es zur TabHost variante schon bessere möglichkeiten gibt, Tabs in android zu erstellen:
http://maxalley.wordpress.com/2013/05/18/android-creating-a-tab-layout-with-fragmenttabhost-and-fragments/

*Im Tab soll die ehemalige MainActivity laufen.

Die MainActtivity selber wirst du da nicht reinbekommen.
Dafür musst du deine Activity zu einem Fragment umschreien.
Dabei schränkt sich aber die funktion in keinster Weise ein.
http://developer.android.com/guide/components/fragments.html

LG Pascal

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
dreadkopp
  • Forum-Beiträge: 23

08.09.2014, 17:45:11 via Website

dankeschön!

das meine MainActivity dann nicht mehr MainActivity ist, ist mir klar :P

meine Tabs sind dann folglich Fragmente der MainActivity, diese Fragmente können jedoch wiederrum auch Activities starten?

Schließen durch LongClick wäre jetzt erstmal kein Problem, jedoch habe ich nur addTab gefunden, jedoch nix á la removeTab.

vielen dank für den wordpresslink, ich hoffe, dass hilft mir weiter!

dass ich den Add-Button in die ActionBar legen kann, war mir nicht bewusst, die ganze Andorid-Developerrei ist neu für mich ;)

Grüße

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

08.09.2014, 18:20:29 via Website

Ja die Fragmente können auch Activities starten, diese sind dann aber ohne TabLayout.
Hier wie man Tabs entfernt:
http://stackoverflow.com/questions/3299845/how-to-remove-tab-from-tabhost

PS: Ändere deinen Threadtitiel sonst [lies meinen voherigen Post]

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
dreadkopp
  • Forum-Beiträge: 23

08.09.2014, 21:16:22 via Website

Vielen vielen Dank!

Bin nun denke ich schon ein gutes Stück weiter.

Ich kann Tabs erstellen und löschen.

Ein Problem bleibt: Erstelle ich beispielsweise 4 Tabs, lösche dann Tab2 und Tab3, und wechsele dann zu Tab 4, schmiert mir die App ab.

Hat jemand eine Idee, was ich da vergessen habe?

public void removeTab(int index) {

     decCounter();

     mTabHost.getTabWidget().removeView(mTabHost.getTabWidget().getChildTabViewAt(index));

     mTabHost.setCurrentTab(index - 1);

     mTabHost.requestLayout();

     mTabHost.invalidate();

}

und die ganze app findet man hier: ...oder auch nicht, da bin ich zu neu...

Dickes Dankeschön schonmal!!!!

Grüße!

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

08.09.2014, 21:21:47 via Website

Was ist denn die Exception?
Müsste im logCat der rote Text sein.

Ist eigentlich klar:

Wenn du Tab 2 entfernst, ist der Current Tab 1 da nach deiner Rechung index-1.
Wenn du aber Tab 3 zusetzlich entfernst dann -> index-1 = 2
Fehler: Tab 2 Existiert nicht mehr.

Bevor du den CurrentTab setzt musst du noch prüfen, ob der Tab auch wirklich existiert.

Edit: PS: Du hast deinen Title immernoch nicht geändert. Sonst wird der morgen gelöscht trotz hilfe..

— geändert am 08.09.2014, 21:25:20

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
dreadkopp
  • Forum-Beiträge: 23

08.09.2014, 22:16:07 via Website

hmmm da hast du recht, das verursacht aber nicht den fehler.

habe den Testfall jetzt umgesetzt. zumindest kann ich jetzt nix mehr killen, was nicht da ist und springe auch auf keinen verbotenen Zustand (dachte ich)

lösche ich meine Tabs "von hinten" weg funktioniert alles wunderbar.

lösche ich meine Tabs "von vorn" weg, stürzt mir das ganze beim löschen des vorletzten Tabs ab.

zudem kann ich nach dem Löschen "von vorn" die bestehen Tabs nur bedingt anwählen. Hier gibt's auch öfter einen Absturz.

ich kriege in beiden Fälle eine NullPointerException für FocusCurrentTab().

Ich vermute, dass der TabHost nicht korrekt updatet nach den Änderungen, sodass Tabs noch dargestellt werden, obwohl ihr Index ein anderer sein müsste. Kann ich das irgendwie erzwingen? TabHost.notify/notifyAll() führt nur zum Absturz.

hier der Code + Apk:

Edit by Pascal P.: Direkte Links zu Filehostern sind nicht erlaubt

Grüße!

— geändert am 09.09.2014, 10:00:50 durch Moderator

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

09.09.2014, 10:32:26 via Website

Hallo dreadkopp,
ich habe deinen Link entfernt, da dirkete Link und Links zu Filehostern nicht erlaubt sind.

LG Pascal

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
dreadkopp
  • Forum-Beiträge: 23

09.09.2014, 11:04:01 via Website

oh, sorry. gibt es eine möglichkeit, Dateien anzuhängen? vielleicht bin ich auch blind. Die CodeFormatierung tuts für mich nicht so richtig.

Neben meinem Problem mit dem TabHost habe ich nun auch noch das Problem, dass Activities, die ich aus einem Tab heraus starte, sich vor die Tabs drängeln und als Vollbild laufen, anstatt im Tab zu bleiben.

Hiermit starte ich die neue Activity in meinem FragmentTab:

public void startActivity(){
    Intent myIntent = new Intent(getActivity(), TestActivity.class);
    myIntent.putExtra("Text", getValue());
    startActivity(myIntent);

getValue liest dabei ein EditText aus.

Grüße!

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

09.09.2014, 11:11:58 via Website

Ja, das mit den Activities habe ich schon erklärt.
Wenn du ein Intent machst, dann kommt die Activity in den Vordergrund und das TabLayout verschwindet.
Du müsstest alle Activities, die im TabLayout angezeigt werden sollen, in Fragments "konvertieren".
Also aus Activity wird Fragment.
Dann funktioniert das.

Nein, es gibt hier keine Dateianhangs Funktion.

Edit: Kannst mir den Filehoster Link per pn schicken, wenn was neues ist, den alten Stand habe ich schon

— geändert am 09.09.2014, 11:17:07

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

09.09.2014, 12:23:48 via Website

Ich habe mir den Code jetzt mal angeschaut.
Ich glaube dass die probleme in der removeTab entstehen.
Wen du nämlich einen Tab entfernst, dann wird der interne index des nächsten Tabs nicht neu erstellt und so entsteht irgendwann eine NullPointerException, da der gespeicherte index nicht mehr Existiert.
Wenn du eine ArrayList aller Tabs macht und damit die Tabs Verwaltest klappt es und gibt keine Fehler mehr.

  ArrayList<TabSpec> TabList = new ArrayList<TabSpec>();
      public void addTab() {

    incCounter();
TabSpec t =     mTabHost.newTabSpec("tab "+counter).setIndicator("Tab "+counter, null);
TabList.add(t);
    mTabHost.addTab(

             t,FragmentTab.class, null);
}

public void removeTab(int index) {

    if(index >=0)
    {
     TabList.remove(index);
     mTabHost.clearAllTabs();

     for(TabSpec t : TabList)
     {
         mTabHost.addTab(t);

     }
     mTabHost.setCurrentTab(0);//Immer aufs erste Elemnt setzen
    }


     else {
         System.out.println("No more Tabs to remove");
     }
     mTabHost.requestLayout();
     mTabHost.invalidate();

}

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
dreadkopp
  • Forum-Beiträge: 23

09.09.2014, 13:56:17 via Website

Vielen Dank! So klappts natürlich!

Jetzt muss ich es nur noch hinbekommen, die bestehende App in die Tabs zu integrieren... das wird vielleicht ne Wurst.

alle Activities zu Fragments konvertieren wird wohl gegen den Baum enden.

Ich habe gelesen, dass der TabHost auch ganze Activities anstelle von Fragments halten kann. führe ich in diesen nun neue Activities aus, bleibe ich in meinem Tab. Da ist nur wieder Fraglich, wie ich die Kommunikation zur Main lösen zwecks Tabs erstellen/löschen... alles nicht so einfach ;)

Nochmal vielen Dank, das hat mich deutlich weiter gebracht!

Grüße!

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

09.09.2014, 14:09:58 via Website

Dann setz deinen Thread doch auf beantwortet:
oben unter "Mehr" findest du diesen Menüpunkt.
LG Pascal

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

09.09.2014, 21:34:11 via Website

Ich habe mir dein Projekt nun nochmal angeschaut und festgestellt, dass du bei denem Vorhaben an Fragments nicht vorbeikommst.
Ich würde es so machen:
http://stackoverflow.com/questions/17227855/tabhost-with-fragments-and-fragmentactivity
[siehe 1. Antwort]

Der Code würde dann in deine addTab Methode hineinkommen.
Natürlich musst du dann deine Activity in ein Fragment umgeschrieben werden.

LG Pascal

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten