Frage

Ich verwende eine benutzerdefinierte Titelansicht in meiner Anwendung für jede Tätigkeit. In einer der Aktivitäten, die auf Tastenklicks muss ich die individuelle Titelansicht ändern. Jetzt funktioniert das jedes Mal gut, wenn ich einen Anruf zu setFeatureInt machen.

Aber wenn ich alle Elemente in dem benutzerdefinierten Titel zu aktualisieren versuchen (sagen sie den Text einer Schaltfläche ändern oder eine Textansicht auf dem Titel), wird das Update nicht statt.

Debuggen durch den Code zeigt, dass die Textansicht und Schaltfläche Instanzen nicht null sind, und ich kann auch die individuelle Titelleiste sehen. Aber der Text auf der Textansicht oder die Schaltfläche wird nicht aktualisiert. Hat jemand dieses Problem konfrontiert? Wie kann ich es beheben?

Danke.

Bearbeiten

Hier ist, was ich versuchte. Gelangt beim Aufruf postInvalidate nicht aktualisiert, auch.

    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.text_title);

    TextView databar = (TextView) findViewById(R.id.title_text);
    databar.setText("Some Text");
    databar.postInvalidate();

    Button leftButton = (Button) findViewById(R.id.left_btn);
    leftButton.setOnClickListener(mLeftListener);
    leftButton.setText("Left Btn");
    leftButton.postInvalidate();

    Button rightBtn = (Button) findViewById(R.id.right_btn);
    rightBtn.setOnClickListener(mRightListener);
    rightBtn.postInvalidate();
War es hilfreich?

Lösung

Das Problem ist, dass die einzige Window Implementierung ( PhoneWindow ) verwendet eine LayoutInflater in seiner setFeatureInt Methode und instanziiert das neue Layout mit inflate und attachToRoot=true. Folglich wird, wenn Sie setFeatureInt nennen, die neuen Layouts sind nicht ersetzt und angebracht in den internen Titelbehälter und somit auf dem jeweils anderen gezogen.

Sie können dies umgehen, indem Sie die folgende Hilfsmethode statt setFeatureInt verwenden. Der Helfer entfernt einfach alle Ansichten aus den internen Titel Containern vor der neue benutzerdefinierten Titel-Funktion festgelegt ist:


private void setCustomTitleFeatureInt(int value) {
    try {
        // retrieve value for com.android.internal.R.id.title_container(=0x1020149)
        int titleContainerId = (Integer) Class.forName(
            "com.android.internal.R$id").getField("title_container").get(null);

        // remove all views from titleContainer
        ((ViewGroup) getWindow().findViewById(titleContainerId)).removeAllViews();

        // add new custom title view 
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, value);

    } catch(Exception ex) {
        // whatever you want to do here..
    }
}

Ich bin mir nicht sicher, ob das aktuelle setFeatureInt Verhalten bestimmt ist, aber es ist sicherlich nicht die eine oder andere dokumentiert, weshalb ich dies auf die Android-Entwickler nehmen werde;)

Bearbeiten

Wie in den Kommentaren darauf hingewiesen, die zuvor genannte Problemumgehung ist nicht ideal. Statt konstant auf dem com.android.internal.R.id.title_container verlassen können Sie einfach verbirgt der alte Brauch Titel, wenn Sie einen neuen festlegen.

Nehmen wir an, Sie haben zwei benutzerdefinierte Titellayouts:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/custom_title_1" ...

und

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/custom_title_2" ...

und Sie wollen custom_title_1 mit custom_title_2 zu ersetzen, Sie ehemalige und setFeatureInt verwenden verstecken könnte hinzufügen dieser:

findViewById(R.id.custom_title_1).setVisibility(View.GONE);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_2);

Andere Tipps

Der richtige Weg, dies zu tun, ist wie folgt:

requestWindowFeature( Window.FEATURE_CUSTOM_TITLE );
setContentView( R.layout.my_layout );
getWindow().setFeatureInt( Window.FEATURE_CUSTOM_TITLE, R.layout.my_custom_title );
super.onCreate( savedInstanceState );

Bitte beachten Sie, dass die Reihenfolge dieser Aussagen sehr wichtig ist.

Wenn Sie super.onCreate () vor allen anderen Aussagen nennen Sie eine leere Titelleiste erhalten, die der Hack der Titelleiste id Auffinden und Entfernen alle Ansichten von ihm zu beheben, aber wird nicht empfohlen.

Rufst du ungültig oder postInvalidate die Ansicht neu zu zeichnen, nachdem Sie den Text zu aktualisieren? Wenn es sich um eine benutzerdefinierte Ansicht ist, können Sie einen Haltepunkt in der Auslosung Code setzen, um sicherzustellen, dass es immer genannt?

Wenn Sie auf dem UI-Thread sind, können Sie rufen ‚ungültig‘, wenn Sie es nicht sind, müssen Sie ‚postInvalidate‘ nennen oder die Sicht wird sich nicht neu gezeichnet werden.

Just my 2c Wert:

Wenn in einem MapActivity arbeiten, die Beantragung eines benutzerdefinierten Titel in keinem Titel überhaupt geführt gezeigt wird.

Zum Glück, alles, was ich tun wollte, war anders den Titeltext zu setzen, und ich erkannte bald, dass setTitle nur anrufen () innerhalb von onCreate () arbeitete für mich (ich es nannte, nachdem ich setContentView genannt ())

Sorry, aber ich habe jetzt keine Zeit, dies zu debuggen mehr und herauszufinden, warum das, was ich tat, hat nicht funktioniert, und warum ändert es machte es funktionieren. Wie gesagt, dachte nur, das jemand aus auf dem Weg helfen könnte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top