2017-01-17 3 views
9

Ich habe eine Vorliebe Bildschirm ein ‚benutzerdefiniertes Layout‘ mit:Preference Bildschirm benutzerdefiniertes Layout funktioniert nur mit zweitem Klick

android:layout="@layout/currencycodes" 

Dieses Problem ist es, das Layout beim ersten Versuch bringen ausfällt. Wie Sie aus dem animierten gif unten sehen können, muss ich mich zurückziehen und ein zweites Mal versuchen, das Layout zu erstellen. Nun, warum ist das so?

enter image description here

preferences.xml

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:key="application_preferences"> 
    <PreferenceCategory> 
     <PreferenceScreen 
       android:key="url_settings" 
       android:title="@string/url_settings" 
       android:summary="@string/summary_url_settings"> 
     </PreferenceScreen> 

     <PreferenceScreen 
       android:key="currency_codes" 
       android:title="@string/left_handed" 
       android:summary="@string/summary_left_handed"> 
      <Preference 
        android:key="currency_exchanges" 
        android:layout="@layout/currencycodes"/> 
     </PreferenceScreen> 
     <EditTextPreference 
       android:key="url_exchange_rate" 
       android:title="@string/url_exchange_rate_settings" 
       android:summary="@string/summary_url_exchange_rate" 
       android:enabled = "false"/> 
    </PreferenceCategory> 
</PreferenceScreen> 

Was früher folgt, ist die benutzerdefinierte Layout. Es enthält eine GridView.

currencycodes.xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:id="@+id/activity_main" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:focusable="true" 
     android:focusableInTouchMode="true" 
     tools:context=".MainActivity"> 

    <GridView 
      android:layout_width="328dp" 
      android:layout_height="479dp" 
      android:layout_marginTop="16dp" 
      app:layout_constraintTop_toTopOf="parent" android:layout_marginStart="16dp" 
      app:layout_constraintLeft_toLeftOf="parent" android:layout_marginEnd="16dp" 
      app:layout_constraintRight_toRightOf="parent" 
      app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="16dp" 
      android:id="@+id/grdExchanges" android:scrollbars="horizontal|vertical" 
      android:smoothScrollbar="true" tools:textAlignment="center" 
      android:verticalScrollbarPosition="defaultPosition"/> 
</android.support.constraint.ConstraintLayout> 
+0

bitte Java hinzufügen, Nun –

Antwort

1

Ich kam mit einem Workaround. Ich festgestellt, wenn ein Layout in LayoutInflater.java aufbläst, ein statischen hashmap Ansicht Objekte zu sammeln verwendet wird:

private static final HashMap<String, Constructor<? extends View>> sConstructorMap 

Was passiert ist, dass der erste Klick den LayoutInflater ruft, aber der erste Klick fügt nur den gridview Blick in dem statisches hashmap. Sie werden sehen, dass mit dem ersten Klick, der Befehl, sConstructorMap.get(name), kehrt nur null:

public final View createView(String name, String prefix, AttributeSet attrs) 
     throws ClassNotFoundException, InflateException { 

    Constructor<? extends View> constructor = sConstructorMap.get(name); 

    Class<? extends View> clazz = null; 

     try { 

      if (constructor == null) { 

Im LayoutInflater, die Variable, mPrivateFactory, ist in der Tat Ihre Haupttätigkeit. Dort wird meine Gridview in mPrivateFactory.onCreateView() initialisiert. Mit dem ersten Klick gibt mPrivateFactory.onCreateView() jedoch null zurück, da das statische hashmap die Ansicht der Gridview noch nicht hat. Es ist weiter unten in der Befehlszeile, onCreateView(parent, name, attrs); wo es schließlich hinzugefügt:

if (view == null && mPrivateFactory != null) { 
     view = mPrivateFactory.onCreateView(parent, name, context, attrs); 
    } 

    if (view == null) { 
     final Object lastContext = mConstructorArgs[0]; 
     mConstructorArgs[0] = context; 
     try { 
      if (-1 == name.indexOf('.')) { 
       view = onCreateView(parent, name, attrs); <-- ADD TO STATIC HASHMAP 
      } else { 
       view = createView(name, null, attrs); 
      } 
     } finally { 
      mConstructorArgs[0] = lastContext; 
     } 
    } 

Also, bis ich mit einer eleganteren Lösung kam, nenne ich nur die Methode, onCreateView(parent), zweimal das erste Mal, dass besonders bevorzugt angeklickt wird auf. Der erste Aufruf fügt der gridview zum statischen hashmap, der zweite Anruf instanziiert dann die Layout-Ansicht (wieder), aber dieses Mal initialisiert die gridview in meiner eigenen Aktivität eigener onCreateView Methode, mPrivateFactory.onCreateView():

protected View onCreateView(ViewGroup parent) { 

View layout = super.onCreateView(parent); 

if(firstCall){ 

    firstCall = false; 

    layout = super.onCreateView(parent); 
} 

return layout; 
} 
1

versuchen, von

Ihre if Anweisung Ändern
(!mFragMngr.popBackStackImmediate(fragName, 0) 
       && mFragMngr.findFragmentByTag(fragName) == null) 

zu

(mFragMngr.findFragmentByTag(fragName) == null) 
+0

Das bestimmt nur, ob der Einstellungsschaltknopf bereits gedrückt wurde oder das Fragment bereits angezeigt wird. Nichts mit dem Thema zu tun. – Drawn

2

Nun zunächst einmal, Sie verstehen müssen, wie PreferenceScreen Works ??

Aus [Android Dokumentation] [1]:

Wenn es erscheint, in einer anderen Präferenzhierarchie wird gezeigt und dient als Gateway zu einem anderen Bildschirm von Präferenzen (entweder durch anderen Bildschirm von Präferenzen zeigen als Dialog oder über eine startActivity (android.content.Intent) von der getIntent()). Die Kinder dieses PreferenceScreen werden auf dem Bildschirm NICHT angezeigt. Dieser PreferenceScreen wird angezeigt. Stattdessen wird ein separater Bildschirm angezeigt, wenn diese Einstellung angeklickt wird.

In einfachen Worten, Griffe

Die Präferenz Rahmen diese Bildschirme aus der Präferenzhierarchie zeigt. Dieses PreferenceScreen-Tag dient als Bildschirmunterbrechung (ähnlich wie Seitenumbruch in der Textverarbeitung). Wie bei anderen Voreinstellungstypen weisen wir hier einen Schlüssel zu, damit der Instanzstatus gespeichert und wiederhergestellt werden kann.

In Ihrem Fall, was tatsächlich geschieht „application_preferences“ wird als die Wurzel der Hierarchie und da auf einen PreferenceActivity.The ersten Bildschirm verwendet werden Präferenzen zeigen „Url_Setting“ und "Währung Codes ". Die „Währung Codes“ ist die „second_preferencescreen“ und wenn darauf geklickt wird ein weiterer Bildschirm von Präferenzen, die sowohl „Geldwechsel“ (wie es Präferenzen als Kinder der „second_preferencescreen“ Tag dh Währung Codes ist).

Also, das, warum es nicht zuerst zeigt auf klicken .... aber auf den zweiten Klick hoffen, dass Sie bekam wie Präferenz Bildschirm funktioniert ...

Wenn Sie noch irgendwelche Zweifel haben ... lassen Sie mich wissen. .. https://developer.android.com/reference/android/preference/PreferenceScreen.html

+0

Sie rezitieren die PreferenceScreen-Dokumentation ohne Rücksicht auf dieses spezielle Problem. "Also, warum erscheint es nicht beim ersten Klick ..." - Sie haben nichts angegeben, was erklärt, warum es beim ersten Klick nicht angezeigt wird. Die "Währungscodes" sind nicht die "zweite_Voransicht", sondern die dritte. Die zweite ist "url_settings", und es funktioniert gut. – Drawn

+0

@drawn Währung Code ist zweite Präferenz Bildschirm.Gemäß Ihrem Code, der eine andere Präferenz-Taste hat, die Währung Exchange ist, haben Sie erwähnt.Vorschlagen Sie nicht Präferenz Bildschirm für den Währungsumtausch. Ich habe dies aus der Dokumentation zitiert, damit Sie wissen, was offizielle Dokumente über die Präferenzhierarchie aussagen. .Es geht immer um die Präferenzhierarchie & Bildschirm.Root-Hierarchie wird nicht als erste gezählt, die Ihre Anwendung_Preference.Given auf Präferenz Aktivität ist.Hier hast du meinen Punkt.Es geht alles um Präferenzhierarchie. Indizierung. Intern in Android. Wo liegt dein Problem ??? – PN10

+0

URL_settings funktioniert gut, da es der erste Einstellungsbildschirm ist, aber Währungscodes sind zweite Präferenz-Bildschirm, die eine andere Präferenz haben..Für diese screen.iecurrency Austausch ... Siehe die Reihenfolge Ihrer Präferenz Bildschirm ... Hier ... – PN10

Verwandte Themen