我有一个使用'自定义布局'的首选项屏幕:
android:layout="@layout/currencycodes"
此问题是无法在第一次尝试时调出布局。 正如您从下面的动画GIF看到的那样,我必须撤退并再次尝试再次进行布局。那为什么呢?
的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 :(得分:2)
首先,您需要了解PreferenceScreen的工作原理吗?
来自[Android文档] [1]:
当它出现在另一个首选项层次结构中时,会显示和 作为另一个偏好屏幕的门户(通过 显示另一个偏好屏幕作为对话框或通过 来自getIntent()的startActivity(android.content.Intent)。该 此PreferenceScreen的子项不会显示在屏幕中 此首选项屏幕显示在。相反,将显示一个单独的屏幕 单击此首选项时显示。
简单来说,
首选项框架处理从首选项层次结构中显示这些其他屏幕。 此PreferenceScreen标记用作屏幕中断(类似于文字处理中的分页符)。与其他首选项类型相似,我们在此处分配一个键,以便它能够保存和恢复其实例状态。
在您的情况下,实际发生的是&#34; application_preferences &#34;将用作层次结构的根并提供给PreferenceActivity。第一个屏幕将显示首选项&#34; Url_Setting &#34;和&#34; 货币代码&#34;。 &#34; 货币代码&#34;是&#34; second_preferencescreen &#34;点击后会显示另一个首选项屏幕,即&#34; 货币兑换&#34; (因为它喜欢&#34; second_preferencescreen &#34;标记的子项,即货币代码)。
所以,这就是为什么它没有在第一次点击时显示....但是第二次点击希望你得到 偏好屏如何运作......
如果您还有任何疑问......请告诉我...... https://developer.android.com/reference/android/preference/PreferenceScreen.html
答案 1 :(得分:1)
尝试从
更改if
声明
(!mFragMngr.popBackStackImmediate(fragName, 0)
&& mFragMngr.findFragmentByTag(fragName) == null)
到
(mFragMngr.findFragmentByTag(fragName) == null)
答案 2 :(得分:1)
我想出了一个解决方法。我注意到在LayoutInflater.java中扩展布局时,会使用静态hashmap来收集视图对象:
private static final HashMap<String, Constructor<? extends View>> sConstructorMap
发生的事情是第一次单击调用LayoutInflater,但第一次单击只会在静态hashmap中添加gridview视图。您将看到,第一次单击时,命令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,因为静态hashmap还没有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,第二个调用然后再次实例化布局视图,但这次,在我自己的Activity自己的onCreateView方法mPrivateFactory.onCreateView()
中初始化gridview:
protected View onCreateView(ViewGroup parent) {
View layout = super.onCreateView(parent);
if(firstCall){
firstCall = false;
layout = super.onCreateView(parent);
}
return layout;
}