2017-01-17 12 views
9

Tôi có một màn hình ưu tiên sử dụng một 'bố trí tùy chỉnh':Preference Screen Tuỳ chỉnh Layout chỉ làm việc với nhấp chuột thứ hai

android:layout="@layout/currencycodes" 

Vấn đề này là nó không thể giúp hiển bố trí trên nỗ lực đầu tiên. Như bạn thấy từ gif động bên dưới, tôi phải rút lui và thử lại lần thứ hai để bố cục xuất hiện. Bây giờ tại sao vậy?

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> 

Sau đây là cách bố trí tùy chỉnh sử dụng. Nó chứa một 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

xin vui lòng thêm java như cũng –

Trả lời

1

Tôi đã đưa ra giải pháp thay thế. Tôi lưu ý khi lạm phát một cách bố trí trong LayoutInflater.java, một hashmap tĩnh được sử dụng để thu thập quan điểm đối tượng:

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

gì đang xảy ra là nhấp chuột đầu tiên gọi LayoutInflater, nhưng đó nhấp chuột đầu tiên chỉ cho biết thêm quan điểm GridView trong hashmap tĩnh. Bạn sẽ thấy rằng, với nhấp chuột đầu tiên, lệnh, sConstructorMap.get(name), chỉ trả về 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) { 

Trong LayoutInflater, biến, mPrivateFactory, là trong thực tế Hoạt động chính của bạn. Có gridview của tôi sẽ được khởi tạo trong mPrivateFactory.onCreateView(). Tuy nhiên, với cú nhấp chuột đầu tiên, mPrivateFactory.onCreateView() trả về null vì hashmap tĩnh không có dạng xem của GridView .... Đó là thêm dưới đây trong dòng lệnh, onCreateView(parent, name, attrs); nơi nó cuối cùng đã được thêm vào:

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; 
     } 
    } 

Vì vậy, cho đến khi tôi đã đưa ra một giải pháp thanh lịch hơn, tôi chỉ gọi phương thức, onCreateView(parent), gấp đôi so với lần đầu tiên đặc biệt thích được nhấp trên. Cuộc gọi đầu tiên cho biết thêm GridView với hashmap tĩnh, cuộc gọi thứ hai sau đó instantiates xem bố trí (một lần nữa) nhưng, lần này, khởi GridView trong phương pháp Hoạt động của riêng onCreateView của riêng tôi, mPrivateFactory.onCreateView():

protected View onCreateView(ViewGroup parent) { 

View layout = super.onCreateView(parent); 

if(firstCall){ 

    firstCall = false; 

    layout = super.onCreateView(parent); 
} 

return layout; 
} 
1

hãy thử thay đổi tuyên bố if của bạn từ

(!mFragMngr.popBackStackImmediate(fragName, 0) 
       && mFragMngr.findFragmentByTag(fragName) == null) 

để

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

Điều đó chỉ xác định nếu nút Gear Setting đã được nhấn hoặc đoạn đã được hiển thị. Không có gì để làm với vấn đề thẳng thắn. – Drawn

2

Vâng trước hết bạn cần phải hiểu như thế nào PreferenceScreen trình ??

Từ [Tài liệu Android] [1]:

Khi nó xuất hiện bên trong một hệ thống phân cấp ưu tiên, nó được hiển thị và đóng vai trò cửa ngõ vào một màn hình ưu đãi (bằng cách cho thấy một màn hình ưu đãi dưới dạng Hộp thoại hoặc qua số startActivity (android.content.Intent) từ getIntent()). trẻ em của PreferenceScreen này không được hiển thị trong màn hình mà PreferenceScreen này được hiển thị. Thay vào đó, một màn hình riêng biệt sẽ là được hiển thị khi tùy chọn này được nhấp.

nói cách đơn giản,

Khung sở thích handle cho thấy các màn hình khác từ hệ thống phân cấp ưu tiên. Thẻ PreferenceScreen này dùng làm điểm ngắt màn hình (tương tự như ngắt trang trong xử lý văn bản). Giống như các loại tùy chọn khác, chúng tôi gán một khóa ở đây để có thể lưu và khôi phục trạng thái cá thể của nó.

Trong trường hợp của bạn, những gì thực sự xảy ra là "application_preferences" sẽ được sử dụng như thư mục gốc của hệ thống phân cấp và trao cho một màn hình đầu tiên PreferenceActivity.The sẽ hiển thị các sở thích "Url_Setting" và "Codes tệ ". Các "tệ Codes" là "second_preferencescreen" và khi nhấp vào sẽ hiển thị một màn hình của sở thích đó là "Ngoại tệ" (vì nó thích như con của các "second_preferencescreen" tag tức Codes tệ).

Vì vậy, Đó là lý do tại sao nó không hiển thị trên đầu nhấp .... nhưng trên nhấp chuột thứ hai hy vọng bạn có Screen sở thích làm việc như thế nào ...

Nếu bạn vẫn còn có bất kỳ nghi ngờ ... cho tôi biết. .. https://developer.android.com/reference/android/preference/PreferenceScreen.html

+0

Bạn đang đọc tài liệu PreferenceScreen mà không xem xét đến vấn đề cụ thể này. "Vì vậy, đó là lý do tại sao nó không hiển thị trên nhấp chuột đầu tiên ..." - Bạn đã tuyên bố không có gì giải thích lý do tại sao nó không hiển thị trên nhấp chuột đầu tiên. "Mã tiền tệ" không phải là "second_preferencescreen" nhưng thứ ba. Thứ hai là "url_settings", và nó hoạt động tốt. – Drawn

+0

@drawn currency code là màn hình tùy chọn thứ hai. Theo mã của bạn có một khóa ưu tiên khác trong đó là trao đổi tiền tệ, bạn đã đề cập đến.Chỉnh sửa màn hình không ưu tiên của họ Để trao đổi tiền tệ. Tôi đã trích dẫn điều này từ tài liệu để bạn biết tài liệu chính thức nói gì về phân cấp tùy chọn. Nó luôn luôn về hệ thống phân cấp ưu tiên và phân cấp màn hình.Root không được tính là đầu tiên mà là application_preference.given của bạn để hoạt động ưu tiên.Hope u có điểm của tôi. Đó là tất cả về phân cấp tùy chọn. Lập chỉ mục. Nội bộ trong android.Where vấn đề của bạn nằm ở đâu ??? – PN10

+0

URL_settings sẽ hoạt động tốt vì đó là màn hình tùy chọn đầu tiên nhưng mã tiền tệ là màn hình tùy chọn thứ hai có sở thích khác..Đối với màn hình đó.hoàn đổi tiền tệ ... Xem thứ tự màn hình tùy chọn của bạn ... Ở đây ... – PN10

Các vấn đề liên quan