2014-01-20 3 views
0

사용자 정의 Android 환경 설정 화면을 작성하고 있는데 헤더가 조각을 가지고 있지 않을 때 조각이 예상되는 b/c가 충돌합니다. - 주어진 섹션 세트의 제목 인 헤더 만 갖고 싶습니다. . 검색을 시도했지만 아무 쓸모가 없으므로 미안합니다.조각이없는 기본 설정 헤더?

<preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> 
    <header android:id="@+id/headerStaffGeneral" android:title="@string/staff_general" /> <!-- This causes a crash as name == null --> 
    <header 
     android:id="@+id/headerSettings" 
     android:fragment="com.example.ex.prefs.SettingsPreferencesFragment" 
     android:title="@string/staff_manager_settings" 
     android:icon="@drawable/ic_action_settings" 
     /> 
</preference-headers> 

다른 코드를 포함해야하는 경우

pref_headers.xml

, 나는 그를 포함 할 수 있습니다,하지만 난 뭔가와 충돌 HEADER 태그를 교체해야하는 경우 내 질문의 본질이다.

UPDATE : 첫 번째 HEADER 태그가 pref_headers.xml 파일에서 제거 된 경우

LogCat Output

FATAL EXCEPTION: main 
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ex/com.example.ex.prefs.PrefsActivity}: java.lang.NullPointerException: name == null 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2245) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2295) 
at android.app.ActivityThread.access$700(ActivityThread.java:150) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:175) 
at android.app.ActivityThread.main(ActivityThread.java:5279) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:511) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 
at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.NullPointerException: name == null 
at java.lang.VMClassLoader.findLoadedClass(Native Method) 
at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:354) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:491) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:461) 
at android.app.Fragment.instantiate(Fragment.java:582) 
at android.preference.PreferenceActivity.switchToHeaderInner(PreferenceActivity.java:1245) 
at android.preference.PreferenceActivity.switchToHeader(PreferenceActivity.java:1278) 
at android.preference.PreferenceActivity.onCreate(PreferenceActivity.java:647) 
at android.app.Activity.performCreate(Activity.java:5283) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209) 
... 11 more 

PrefsActivity.java

package com.example.ex.prefs; 

import java.util.ArrayList; 
import java.util.List; 

import android.preference.PreferenceActivity; 
import android.widget.ListAdapter; 

import com.example.ex.R; 

public class PrefsActivity extends PreferenceActivity { 

    private List<Header> mHeaders; 

    protected void onResume() { 
    super.onResume(); 

    setTitle(R.string.staff_manager_settings); 

    if (getListAdapter() instanceof PrefsHeaderAdapter) 
     ((PrefsHeaderAdapter) getListAdapter()).resume(); 
    } 

    protected void onPause() { 
    super.onPause(); 
    if (getListAdapter() instanceof PrefsHeaderAdapter) 
     ((PrefsHeaderAdapter) getListAdapter()).pause(); 
    } 

    public void onBuildHeaders(List<Header> target) { 
    // Called when the settings screen is up for the first time 
    // we load the headers from our xml description 

    loadHeadersFromResource(R.xml.pref_headers, target); 

    mHeaders = target; 
    } 

    public void setListAdapter(ListAdapter adapter) { 
    int i, count; 

    if (mHeaders == null) { 
     mHeaders = new ArrayList<Header>(); 
     // When the saved state provides the list of headers, 
     // onBuildHeaders is not called 
     // so we build it from the adapter given, then use our own adapter 

     count = adapter.getCount(); 
     for (i = 0; i < count; ++i) 
     mHeaders.add((Header) adapter.getItem(i)); 
    } 

    super.setListAdapter(new PrefsHeaderAdapter(this, mHeaders)); 
    } 

} 

이 오류가 표시되지 않습니다.

+0

분명히 활동이 첫 번째 헤더의 존재하지 않는 "단편"을로드하려고합니다. 'PrefsHeaderAdapter'에서'@Override public boolean isEnabled (int position) {리턴 위치! = 0; }' – ozbek

+0

그건 작동하지 않았지만 tx. –

답변

1

기본 설정 헤더의 XML이 정확했으며 android:id 속성은 필요하지 않았습니다 (단, 결코 해가되지는 않음). 2 가지를 추가해야했습니다 : setListAdapteronGetInitialHeader. 여기

는 3 개 파일에 대한 최종 코드 :

prefs_headers.xml

<?xml version="1.0" encoding="utf-8"?> 
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> 
    <header android:title="@string/staff_general"/> 
    <header 
    android:id="@+id/headerSettings" 
    android:fragment="com.example.ex.prefs.SettingsPreferencesFragment" 
    android:icon="@drawable/ic_action_settings" 
    android:title="@string/staff_manager_settings"/> 
    <header 
    android:id="@+id/headerHistory" 
    android:fragment="com.example.ex.prefs.HistoryPreferencesFragment" 
    android:icon="@drawable/ic_action_event" 
    android:title="@string/staff_manager_history"/> 
    <header android:title="@string/staff_special" /> 
    <header 
    android:id="@+id/headerNetwork" 
    android:fragment="com.example.ex.prefs.NetworkPreferencesFragment" 
    android:icon="@drawable/ic_action_cloud" 
    android:title="@string/staff_manager_network"/> 
    <header 
    android:id="@+id/headerPrinter" 
    android:fragment="com.example.ex.prefs.PrinterPreferencesFragment" 
    android:icon="@drawable/ic_action_star" 
    android:title="@string/staff_manager_star_printer"/> 
</preference-headers> 

PrefsActivity.java

package com.example.ex.prefs; 

import java.util.List; 

import android.preference.PreferenceActivity; 
import android.preference.PreferenceActivity.Header; 
import android.util.Log; 
import android.widget.ListAdapter; 

import com.example.ex.R; 

public class PrefsActivity extends PreferenceActivity { 
    private static List<Header> _headers; 

    @Override 
    public void setListAdapter(ListAdapter adapter) { 
     if (adapter == null) { 
      super.setListAdapter(null); 
     } else { 
      super.setListAdapter(new PrefsHeaderAdapter(this, _headers)); 
     } 
    } 

    @Override 
    public void onBuildHeaders(List<Header> target) { 
    _headers = target; 
    loadHeadersFromResource(R.xml.pref_headers, target); 
    } 
    @Override 
    public Header onGetInitialHeader() { 
    super.onResume(); 
    if (PrefsActivity._headers != null) { 
     for (int i = 0; i < PrefsActivity._headers.size(); i++) { 
     Header h = PrefsActivity._headers.get(i); 
     if (PrefsHeaderAdapter.getHeaderType(h) != PrefsHeaderAdapter.HEADER_TYPE_CATEGORY) { 
      return h; 
     } 
     } 
    } 
    return null; 
    } 
} 

PrefsHeaderAdapter.java 패키지 com.example.ex.prefs; 열쇠는 첫 번째 헤더 B 아니라는 것을 확인하기 위해 onGetInitialHeader을 무시했다

import java.util.List; 

import android.content.Context; 
import android.preference.PreferenceActivity.Header; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.ImageView; 
import android.widget.TextView; 

import com.example.ex.R; 

public class PrefsHeaderAdapter extends ArrayAdapter<Header> { 

    static final int   HEADER_TYPE_CATEGORY = 0; 
    static final int   HEADER_TYPE_NORMAL = 1; 

    private LayoutInflater  mInflater; 

    public PrefsHeaderAdapter(Context context, List<Header> objects) { 
    super(context, 0, objects); 
    mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
    Header header = getItem(position); 
    int headerType = getHeaderType(header); 
    View view = null; 

    switch (headerType) { 
     case HEADER_TYPE_CATEGORY: 
     view = mInflater.inflate(android.R.layout.preference_category, parent, false); 
     ((TextView) view.findViewById(android.R.id.title)).setText(header.getTitle(getContext().getResources())); 
     break; 
     case HEADER_TYPE_NORMAL: 
     view = mInflater.inflate(R.layout.preference_header_item, parent, false); 
     ((ImageView) view.findViewById(android.R.id.icon)).setImageResource(header.iconRes); 
     ((TextView) view.findViewById(android.R.id.title)).setText(header.getTitle(getContext().getResources())); 
     ((TextView) view.findViewById(android.R.id.summary)).setText(header.getSummary(getContext().getResources())); 
     break; 
    } 

    return view; 
    } 

    @Override 
    public boolean isEnabled(int position) { 
    return getItemViewType(position) != HEADER_TYPE_CATEGORY; 
    } 
    @Override 
    public boolean areAllItemsEnabled() { 
    return false; 
    } 
    @Override 
    public int getViewTypeCount() { 
    return 2; 
    } 
    @Override 
    public boolean hasStableIds() { 
    return true; 
    } 

    public static int getHeaderType(Header header) { 
    if ((header.fragment == null) && (header.intent == null)) { 
     return HEADER_TYPE_CATEGORY; 
    } else { 
     return HEADER_TYPE_NORMAL; 
    } 
    } 
} 

/C Android - Headers categories in PreferenceActivity with PreferenceFragment의 정보에 따르면, 안드로이드는 조각 내 카테고리 헤더이고 가정 기본적으로 첫 번째로드 , 그러나 그것이 아니기 때문에, 그것은 추락했다. 이 ListAdapter는 목록의 특성을 관리하고 헤더 유형을 결정하는 데 사용됩니다. 해답을 하드 코딩하지 않고 헤더 유형을 안정적으로 결정하는 데 필요합니다.

나는 이것으로 다른 사람들에게 도움이되기를 바랍니다.

1

아마도 android:id 값이 필요하지만 작동해야합니다.

<preference-headers 
     xmlns:android="http://schemas.android.com/apk/res/android"> 


    <!-- WIRELESS and NETWORKS --> 
    <header android:id="@+id/wireless_section" 
     android:title="@string/header_category_wireless_networks" /> 

    <!-- Wifi --> 
    <header 
     android:id="@+id/wifi_settings" 
     android:fragment="com.android.settings.wifi.WifiSettings" 
     android:title="@string/wifi_settings_title" 
     android:icon="@drawable/ic_settings_wireless" /> 

... 

그래서, 그들은 제목 목록에서 섹션 헤더에 대한 android:fragment없이 <header>을 사용하는 것으로 나타납니다 당신이 설정 응용 프로그램의 기본 헤더를 보면, 당신은 물건처럼 참조하십시오.

+0

지금 사용해보기. 감사! –

+0

여전히 ID가 추가되어 충돌이 발생합니다. 지금 LogCat을 얻으려고하지만 너무 빨리 사라집니다. 잠시 후에 질문을 업데이트 할 것입니다. –

+0

LogCat 및 PrefsActivity.java로 업데이트 된 질문 - 도움이됩니까? 이 문제를 해결하기 위해 모든 코드를 제공해 드리게되어 기쁩니다. –