Android的 - 接头类别preferenceActivity用preferenceFragment [英] Android - Headers categories in PreferenceActivity with PreferenceFragment
问题描述
我想显示preference屏幕就像一个在Android设置应用程序:用头,preferenceActivity,preferenceFragment和头文件类别
我wan't在平板电脑这样的结果:
而这一次在智能手机上:
它的工作原理,如果我只使用基本的头,但如果我尝试添加的类别,它适用于智能手机和崩溃的平板电脑,在那里我得到的异常显示java.lang.NullPointerException:姓名== NULL
致命异常:主要
java.lang.RuntimeException的:无法启动的活动ComponentInfo{fr.ifremer.testandroid/fr.ifremer.testandroid.models.$p$pferences.Main$p$pferenceActivity}:显示java.lang.NullPointerException:姓名== NULL
在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2110)
在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
在android.app.ActivityThread.access $ 700(ActivityThread.java:140)
在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1237)
在android.os.Handler.dispatchMessage(Handler.java:99)
在android.os.Looper.loop(Looper.java:137)
在android.app.ActivityThread.main(ActivityThread.java:4921)
在java.lang.reflect.Method.invokeNative(本机方法)
在java.lang.reflect.Method.invoke(Method.java:511)
在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1038)
在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
在dalvik.system.NativeStart.main(本机方法)
致:显示java.lang.NullPointerException:姓名== NULL
在java.lang.VMClassLoader.findLoadedClass(本机方法)
在java.lang.ClassLoader.findLoadedClass(ClassLoader.java:354)
在java.lang.ClassLoader.loadClass(ClassLoader.java:491)
在java.lang.ClassLoader.loadClass(ClassLoader.java:461)
在android.app.Fragment.instantiate(Fragment.java:574)
在安卓preference preferenceActivity.switchToHeaderInner(preferenceActivity.java:1222)。
。在安卓preference preferenceActivity.switchToHeader(preferenceActivity.java:1255)
在安卓preference preferenceActivity.onCreate(preferenceActivity.java:630)。
在fr.ifremer.testandroid.models.$p$pferences.Main$p$pferenceActivity.onCreate(Main$p$pferenceActivity.java:19)
在android.app.Activity.performCreate(Activity.java:5206)
在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2074)
... 11更多
贝娄是code所涉及的组件。我从Android设置应用程序的源得到了他们大部分。
你知道吗?
在此先感谢
主要preferenceActivity:
公共类主要preferenceActivity扩展preferenceActivity {
私有静态列表<头> _headers;
@覆盖
公共无效onBuildHeaders(名单<头>头){
_headers =头;
loadHeadersFromResource(R.xml preference_headers,头);
}
@覆盖
公共无效setListAdapter(ListAdapter适配器){
如果(适配器== NULL){
super.setListAdapter(空);
} 其他 {
super.setListAdapter(新HeaderAdapter(这一点,_headers));
}
}
}
preferencesFragment:
公共类preferencesFragment扩展preferenceFragment {
@覆盖
公共无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
字符串设置= getArguments()的getString(设置)。
如果(settings.equals(假摔)){
加preferencesFromResource(R.xml preference_dive_tile。);
}
否则如果(settings.equals(MAP)){
加preferencesFromResource(R.xml preference_map_tile。);
}
}
}
preference_headers.xml:
< XML版本=1.0编码=UTF-8&GT?;
< preference报头的xmlns:机器人=http://schemas.android.com/apk/res/android>
<头
机器人:ID =@ + ID / header_section_1
机器人:标题=第1/>
<头
机器人:片段=。fr.ifremer.testandroid.models preferences preferencesFragment。
机器人:总结=DIVE摘要
机器人:标题=潜水冠军>
<额外
机器人:名称=设置
机器人:值=DIVE/>
< /头>
<头
机器人:片段=。fr.ifremer.testandroid.models preferences preferencesFragment。
机器人:总结=MAP摘要
机器人:标题=地图标题>
<额外
机器人:名称=设置
机器人:值=地图/>
< /头>
< / preference报头>
最后但并非最不重要的,HeaderAdapter:
公共类HeaderAdapter扩展ArrayAdapter<头> {
静态最终诠释HEADER_TYPE_CATEGORY = 0;
静态最终诠释HEADER_TYPE_NORMAL = 1;
私有静态最终诠释HEADER_TYPE_COUNT = HEADER_TYPE_NORMAL + 1;
私人LayoutInflater mInflater;
私有静态类HeaderViewHolder {
ImageView的图标;
TextView的称号;
TextView的总结;
}
公共HeaderAdapter(上下文的背景下,名单,其中,头>对象){
超(背景下,0,对象);
mInflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
静态INT getHeaderType(头球冲顶){
如果(header.fragment == NULL和放大器;&安培; header.intent == NULL)返回HEADER_TYPE_CATEGORY;
否则返回HEADER_TYPE_NORMAL;
}
@覆盖
公众诠释getItemViewType(INT位置){
标题标题=的getItem(位置);
返回getHeaderType(头);
}
@覆盖
公共布尔areAllItemsEnabled(){返回false; / *因为类* /}
@覆盖
公共布尔的IsEnabled(INT位置){返回getItemViewType(位置)= HEADER_TYPE_CATEGORY!; }
@覆盖
公众诠释getViewTypeCount(){返回HEADER_TYPE_COUNT; }
@覆盖
公共布尔hasStableIds(){返回true; }
@覆盖
公共查看getView(INT位置,查看convertView,ViewGroup中父){
HeaderViewHolder持有人;
标题标题=的getItem(位置);
INT headerType = getHeaderType(头);
查看查看= NULL;
如果(convertView == NULL){
持有人=新HeaderViewHolder();
开关(headerType){
案例HEADER_TYPE_CATEGORY:
鉴于=新的TextView(的getContext(),空,android.R.attr.listSeparatorTextViewStyle);
holder.title =(TextView的)观点;
打破;
案例HEADER_TYPE_NORMAL:
鉴于= mInflater.inflate(R.layout preference_header_item,父母,假的。);
holder.icon =(ImageView的)view.findViewById(R.id.icon);
holder.title =(TextView中)view.findViewById(R.id.title);
holder.summary =(TextView中)view.findViewById(R.id.summary);
打破;
}
view.setTag(保持器);
}
其他 {
鉴于= convertView;
支架=(HeaderViewHolder)view.getTag();
}
//所有的视场必须在每次更新,因为视图可以回收
开关(headerType){
案例HEADER_TYPE_CATEGORY:
holder.title.setText(header.getTitle(的getContext()getResources())。);
打破;
案例HEADER_TYPE_NORMAL:
holder.icon.setImageResource(header.iconRes);
holder.title.setText(header.getTitle(的getContext()getResources())。);
的CharSequence摘要= header.getSummary(的getContext()getResources());
如果(!TextUtils.isEmpty(摘要)){
holder.summary.setVisibility(View.VISIBLE);
holder.summary.setText(摘要);
}
其他 {
holder.summary.setVisibility(View.GONE);
}
打破;
}
返回查看;
}
}
也许第一个标题是默认选择的菜单。如果是这样,它应该有片段属性来显示它的右侧。
I would like to display a preference screen like the one in the Android settings app : using headers, PreferenceActivity, PreferenceFragment and headers categories.
I wan't this result on a tablet :
And this one on a smartphone :
It works if I just use the basic headers, but if I try to add categories, it works on the smartphone, and crash on the tablet, where I get the exception "java.lang.NullPointerException: name == null" :
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{fr.ifremer.testandroid/fr.ifremer.testandroid.models.preferences.MainPreferenceActivity}: java.lang.NullPointerException: name == null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2110)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
at android.app.ActivityThread.access$700(ActivityThread.java:140)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4921)
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:1038)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
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:574)
at android.preference.PreferenceActivity.switchToHeaderInner(PreferenceActivity.java:1222)
at android.preference.PreferenceActivity.switchToHeader(PreferenceActivity.java:1255)
at android.preference.PreferenceActivity.onCreate(PreferenceActivity.java:630)
at fr.ifremer.testandroid.models.preferences.MainPreferenceActivity.onCreate(MainPreferenceActivity.java:19)
at android.app.Activity.performCreate(Activity.java:5206)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2074)
... 11 more
Bellow are the pieces of code involved. I got them mostly from the Android settings app source.
Any idea ?
Thanks in advance
MainPreferenceActivity :
public class MainPreferenceActivity extends PreferenceActivity {
private static List<Header> _headers;
@Override
public void onBuildHeaders(List<Header> headers) {
_headers = headers;
loadHeadersFromResource(R.xml.preference_headers, headers);
}
@Override
public void setListAdapter(ListAdapter adapter) {
if (adapter == null) {
super.setListAdapter(null);
} else {
super.setListAdapter(new HeaderAdapter(this, _headers));
}
}
}
PreferencesFragment :
public class PreferencesFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String settings = getArguments().getString("settings");
if (settings.equals("DIVE")) {
addPreferencesFromResource(R.xml.preference_dive_tile);
}
else if (settings.equals("MAP")) {
addPreferencesFromResource(R.xml.preference_map_tile);
}
}
}
preference_headers.xml :
<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android" >
<header
android:id="@+id/header_section_1"
android:title="Section 1" />
<header
android:fragment="fr.ifremer.testandroid.models.preferences.PreferencesFragment"
android:summary="DIVE summary"
android:title="DIVE title" >
<extra
android:name="settings"
android:value="DIVE" />
</header>
<header
android:fragment="fr.ifremer.testandroid.models.preferences.PreferencesFragment"
android:summary="MAP summary"
android:title="MAP title" >
<extra
android:name="settings"
android:value="MAP" />
</header>
</preference-headers>
Last but not least, HeaderAdapter :
public class HeaderAdapter extends ArrayAdapter<Header> {
static final int HEADER_TYPE_CATEGORY = 0;
static final int HEADER_TYPE_NORMAL = 1;
private static final int HEADER_TYPE_COUNT = HEADER_TYPE_NORMAL + 1;
private LayoutInflater mInflater;
private static class HeaderViewHolder {
ImageView icon;
TextView title;
TextView summary;
}
public HeaderAdapter(Context context, List<Header> objects) {
super(context, 0, objects);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
static int getHeaderType(Header header) {
if (header.fragment == null && header.intent == null) return HEADER_TYPE_CATEGORY;
else return HEADER_TYPE_NORMAL;
}
@Override
public int getItemViewType(int position) {
Header header = getItem(position);
return getHeaderType(header);
}
@Override
public boolean areAllItemsEnabled() { return false; /* because of categories */ }
@Override
public boolean isEnabled(int position) { return getItemViewType(position) != HEADER_TYPE_CATEGORY; }
@Override
public int getViewTypeCount() { return HEADER_TYPE_COUNT; }
@Override
public boolean hasStableIds() { return true; }
@Override
public View getView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
Header header = getItem(position);
int headerType = getHeaderType(header);
View view = null;
if (convertView == null) {
holder = new HeaderViewHolder();
switch (headerType) {
case HEADER_TYPE_CATEGORY:
view = new TextView(getContext(), null, android.R.attr.listSeparatorTextViewStyle);
holder.title = (TextView) view;
break;
case HEADER_TYPE_NORMAL:
view = mInflater.inflate(R.layout.preference_header_item, parent, false);
holder.icon = (ImageView) view.findViewById(R.id.icon);
holder.title = (TextView) view.findViewById(R.id.title);
holder.summary = (TextView) view.findViewById(R.id.summary);
break;
}
view.setTag(holder);
}
else {
view = convertView;
holder = (HeaderViewHolder) view.getTag();
}
// All view fields must be updated every time, because the view may be recycled
switch (headerType) {
case HEADER_TYPE_CATEGORY :
holder.title.setText(header.getTitle(getContext().getResources()));
break;
case HEADER_TYPE_NORMAL :
holder.icon.setImageResource(header.iconRes);
holder.title.setText(header.getTitle(getContext().getResources()));
CharSequence summary = header.getSummary(getContext().getResources());
if (!TextUtils.isEmpty(summary)) {
holder.summary.setVisibility(View.VISIBLE);
holder.summary.setText(summary);
}
else {
holder.summary.setVisibility(View.GONE);
}
break;
}
return view;
}
}
Maybe first header is default selected menu. If so, it should have fragment attribute to show it right side.
这篇关于Android的 - 接头类别preferenceActivity用preferenceFragment的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!