2017-01-17 41 views
9

工作我有使用“自定义布局”偏好屏幕:偏好屏幕自定义布局仅与第二点击

android:layout="@layout/currencycodes" 

这个问题是它不能带来了布局上的首次尝试。 正如您从下面的动画gif中看到的那样,我必须撤退并再次尝试布局才能出现。那为什么呢?

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> 

以下是使用自定义布局。它包含一个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

请添加Java作为以及 –

回答

1

我想出了一个解决方法。我注意到在充气一个LayoutInflater.java布局时,静态HashMap的是用来收集视图对象:

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

发生了什么事是第一次点击调用LayoutInflater,但第一次点击只增加gridview的视图中静态hashmap。你会发现,与第一次点击,命令,sConstructorMap.get(name),只返回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) { 

在LayoutInflater,变量,mPrivateFactory,其实是你的主要活动。这是我的gridview将在mPrivateFactory.onCreateView()初始化。但是,通过第一次单击,mPrivateFactory.onCreateView()返回null,因为静态哈希映射没有gridview的视图....但是。这是下面将进一步在命令行中,onCreateView(parent, name, attrs);在那里最后补充说:

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

所以直到我想出了一个更好的解决方案,我只是调用该方法,onCreateView(parent),两次第一次,特别优选点击上。第一次调用添加GridView控件的静态HashMap中,第二个电话,然后实例化布局来看(再次),但是,这一次,在我自己的活动自己的onCreateView方法初始化GridView控件,mPrivateFactory.onCreateView()

protected View onCreateView(ViewGroup parent) { 

View layout = super.onCreateView(parent); 

if(firstCall){ 

    firstCall = false; 

    layout = super.onCreateView(parent); 
} 

return layout; 
} 
1

尝试从

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

改变你if声明

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

这仅仅决定了设定档位按钮是否已被按下或片段已被显示。坦率地说,这个问题没有任何关系。 – Drawn

2

那么首先你需要了解如何PreferenceScreen作品?

从[Android文档] [1]:

当它出现另一个偏好层级内时,它被示出和 用作网关偏好的另一屏幕(或者通过 表示偏好的另一个屏幕作为对话或通过getIntent()中的 startActivity(android.content.Intent))。这PreferenceScreen的 孩子在 这PreferenceScreen在显示屏幕没有显示,而是被点击此偏好时,一个单独的屏幕上会显示 。

简单的话,

偏好框架处理显示了从首层级这些其他屏幕。 此PreferenceScreen标记用作屏幕中断(类似于文字处理中的分页符)。与其他首选项类型一样,我们在此处指定一个键,以便能够保存和恢复其实例状态。

对你来说,什么是真正发生的是“application_preferences”将被用作层次结构的根,并给一个PreferenceActivity.The第一屏将显示首选项“Url_Setting”和“货币代码 ”。该“货币代码”是“second_preferencescreen”,并点击将显示首选项的另一个屏幕,这是“外币兑换”的时候(因为它的喜好为“second_preferencescreen”标签即货币代码的孩子)。

所以,这就是为什么它没有出现在第一次点击....但在第二次点击希望你有 偏好屏幕是如何工作的?

如果您还有任何疑问...让我知道。 .. https://developer.android.com/reference/android/preference/PreferenceScreen.html

+0

您在背诵PreferenceScreen文档时并未考虑到此特定问题。 “那么,为什么它没有显示在第一次点击...” - 你没有说明什么解释了为什么它没有显示在第一次点击。 “货币代码”不是“second_preferencescreen”,而是第三个。第二个是“url_settings”,它工作正常。 – Drawn

+0

@退出的货币代码是第二优先屏幕。根据您的代码,其中有另一个优先键,它是货币兑换看到你已经提到。优先其非优先屏幕对于货币兑换。我从文档中引用了这一点,以便了解官方文档对偏好等级的说明。 。它总是关于偏好层次和屏幕。根目录层次结构不被视为第一个,它是您的应用程序偏好。喜欢偏好活动。希望您明白我的观点。这都是关于偏好层次结构。索引。内部在android.Where你的问题在于? – PN10

+0

URL_settings将正常工作,因为它是第一优先选择屏幕,但货币代码是第二优先选择屏幕,它具有另一个优先选项。对于那个screen.iecurrency交换...请参阅您的首选项屏幕的顺序...这里... – PN10