列表视图片段不会显示
List View Fragment Won't Display
我正在尝试使用 ListFragment 在我的主 activity 中显示一个列表。该列表由使用自定义对象的自定义 ArrayAdapter 填充。我无法在应用程序中显示此列表。当我调试时,它没有显示任何错误,但应用程序立即崩溃。
这是我的片段
编辑:我尝试了几种响应,并将问题缩小到 ListViewFragment 中的 momentObjectListView.setAdapter(momentObjectAdapter)。我找不到 momentObjectAdapter 为 null 的原因,所以它必须是 momentObjectListView 但是我找不到问题的根源。任何帮助将非常感激。我的 activity_main.xml、片段、主要 activity 和适配器代码都包含在内。
public class ListViewFragment extends ListFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Activity myAct = getActivity();
View view = inflater.inflate(R.layout.activity_main, container, false);
ListView momentObjectListView = (ListView)view.findViewById(R.id.list_item);
//ListView momentObjectListView = getListView();
MomentObjectAdapter momentObjectAdapter = new MomentObjectAdapter(myAct, R.layout.moment_object_list_item);
//momentObjectListView.setAdapter(momentObjectAdapter);
List<MomentObject> myMoments = getMoments();
for(final MomentObject entry : myMoments) {
momentObjectAdapter.add(entry);
}
//ListViewFragment.this.setListAdapter(momentObjectAdapter);
momentObjectListView.setAdapter(momentObjectAdapter);
return view;
}
private List<MomentObject> getMoments() {
// Let's setup some test data.
// Normally this would come from some asynchronous fetch into a data source
// such as a sqlite database, or an HTTP request
final List<MomentObject> entries = new ArrayList<MomentObject>();
for(int i = 1; i < 50; i++) {
entries.add(
new MomentObject(
"Test Entry " + i,
"Anonymous Author",
new GregorianCalendar(2011, 11, i).getTime(),
R.drawable.photoicon
)
);
}
return entries;
}
}
这是我的 activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:background="#ffffffff">
<fragment android:name="com.malatras.moment2.ListViewFragment"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
如果我需要提供什么来解决这个问题,请告诉我。
LogCat:
e02-24 18:54:29.119 2325-2325/com.malatras.moment2 I/art﹕ Not late-enabling -Xcheck:jni (already on)
02-24 18:54:29.191 2325-2325/com.malatras.moment2 D/AndroidRuntime﹕ Shutting down VM
02-24 18:54:29.191 2325-2325/com.malatras.moment2 E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.malatras.moment2, PID: 2325
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.malatras.moment2/com.malatras.moment2.MainActivity}: android.view.InflateException: Binary XML file line #9: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: android.view.InflateException: Binary XML file line #9: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:377)
at android.app.Activity.setContentView(Activity.java:2144)
at com.malatras.moment2.MainActivity.onCreate(MainActivity.java:11)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.malatras.moment2.ListViewFragment.onCreateView(ListViewFragment.java:34)
at android.app.Fragment.performCreateView(Fragment.java:2053)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:870)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1045)
at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1147)
at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2116)
at android.app.Activity.onCreateView(Activity.java:5282)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:377)
at android.app.Activity.setContentView(Activity.java:2144)
at com.malatras.moment2.MainActivity.onCreate(MainActivity.java:11)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
主要活动:
public class MainActivity extends ListActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MomentObjectAdapter:
public final class MomentObjectAdapter extends ArrayAdapter<MomentObject> {
private final int momentObjectLayoutResource;
public MomentObjectAdapter(final Context context, final int momentObjectLayoutResource) {
super(context, 0);
this.momentObjectLayoutResource = momentObjectLayoutResource;
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
// We need to get the best view (re-used if possible) and then
// retrieve its corresponding ViewHolder, which optimizes lookup efficiency
final View view = getWorkingView(convertView);
final ViewHolder viewHolder = getViewHolder(view);
final MomentObject entry = getItem(position);
// Setting the title view is straightforward
viewHolder.titleView.setText(entry.getTitle());
// Setting the subTitle view requires a tiny bit of formatting
final String formattedSubTitle = String.format("By %s on %s",
entry.getAuthor(),
DateFormat.getDateInstance(DateFormat.SHORT).format(entry.getPostDate())
);
viewHolder.subTitleView.setText(formattedSubTitle);
// Setting image view is also simple
viewHolder.imageView.setImageResource(entry.getIcon());
return view;
}
private View getWorkingView(final View convertView) {
// The workingView is basically just the convertView re-used if possible
// or inflated new if not possible
View workingView = null;
if(null == convertView) {
final Context context = getContext();
final LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
workingView = inflater.inflate(momentObjectLayoutResource, null);
} else {
workingView = convertView;
}
return workingView;
}
private ViewHolder getViewHolder(final View workingView) {
// The viewHolder allows us to avoid re-looking up view references
// Since views are recycled, these references will never change
final Object tag = workingView.getTag();
ViewHolder viewHolder = null;
if(null == tag || !(tag instanceof ViewHolder)) {
viewHolder = new ViewHolder();
viewHolder.titleView = (TextView) workingView.findViewById(R.id.moment_object_title);
viewHolder.subTitleView = (TextView) workingView.findViewById(R.id.moment_object_subtitle);
viewHolder.imageView = (ImageView) workingView.findViewById(R.id.moment_object_icon);
workingView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) tag;
}
return viewHolder;
}
/**
* ViewHolder allows us to avoid re-looking up view references
* Since views are recycled, these references will never change
*/
private static class ViewHolder {
public TextView titleView;
public TextView subTitleView;
public ImageView imageView;
}
}
moment_object_list_item:
<?xml version="1.0" encoding="utf-8"?>
<!-- Layout for individual news entries in a list -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Icon shown next to the title/subtitle -->
<ImageView
android:id="@+id/moment_object_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:padding="3dp" />
<!-- Title of the news entry -->
<TextView
android:id="@+id/moment_object_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/moment_object_icon"
android:layout_alignTop="@id/moment_object_icon"
android:layout_margin="5dp"
android:textSize="14sp"
android:textStyle="bold" />
<!-- Subtitle contains author and date -->
<TextView
android:id="@+id/moment_object_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/moment_object_title"
android:layout_below="@id/moment_object_title"
android:textSize="12sp" />
</RelativeLayout>
在您的 XML 文件中更改此行:android:id="@+id/list"
至:
android:id="@id/android:list
并在 ListViewFragment
中更改为:ListView momentObjectListView =(ListView)view.findViewById(R.id.list)
;
对此:
ListView momentObjectListView = (ListView)view.findViewById(android.R.id.list);
在你的 Logcat 文件中,它说
android.view.InflateException: Binary XML file line #9: Error
inflating class fragment
这意味着 xml 文件不正确。在日志中也更深入,
The code MainActivity.onCreate(MainActivity.java:11)
...
Caused by: java.lang.NullPointerException: Attempt to invoke virtual
method 'void
android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a
null object reference at
com.malatras.moment2.ListViewFragment.onCreateView(ListViewFragment.java:34)
...
ListViewFragment.onCreateView(ListViewFragment.java:34)
也需要加载文件 ListViewFragment.java。为了节省时间,也许post个文件。
另一个可能好的代码更改是修改 ListViewFragment 定义:
public class ListViewFragment extends ListFragment {
至:
public class ListViewFragment extends Fragment implements AbsListView.OnItemClickListener {
OnItemClickListener 是可选的。
我之所以这样说是因为 MainActivity 已经通过 ListActivity 承载了 ListView 对象。另一个原因是,Android Studio 向导会生成 "to" 建议代码。这对我来说听起来不错。
另一种方法是将 ListActivity 从 MainActivity 中删除为仅 Activity,原因相同。
然而,所有这些建议都可以被视为代码风格。
我不喜欢并且与您的方法 getMoments 不兼容的这段代码是:
for(final MomentObject entry : getMoments()) {
momentObjectAdapter.add(entry);
}
现在试试这个快速示例修复:
List<MomentObject> myMoments = getMoments();
for(final MomentObject entry : myMoments) {
原因是 for 循环中的 getMoments() 是动态求值的。我认为是这样,即使你用 final 声明了它。
在日志中,
Attempt to invoke virtual method 'void
android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a
null object reference
我认为对象 momentObjectListView 为空。我在 fragment_list_view.xml 中找不到 UI。但是在 activity_main.xml 中。示例代码:
View view = inflater.inflate(R.layout.activity_main, container, false);
ListView momentObjectListView = (ListView)view.findViewById(R.id.list);
activity_main:
中 ListFragment 的示例布局元素
<fragment android:name="com.malatras.moment2.ListViewFragment"
android:id="@+id/list"
...>
了解基础知识需要一个解释布局的好网页@ Layouts。
我正在尝试使用 ListFragment 在我的主 activity 中显示一个列表。该列表由使用自定义对象的自定义 ArrayAdapter 填充。我无法在应用程序中显示此列表。当我调试时,它没有显示任何错误,但应用程序立即崩溃。
这是我的片段
编辑:我尝试了几种响应,并将问题缩小到 ListViewFragment 中的 momentObjectListView.setAdapter(momentObjectAdapter)。我找不到 momentObjectAdapter 为 null 的原因,所以它必须是 momentObjectListView 但是我找不到问题的根源。任何帮助将非常感激。我的 activity_main.xml、片段、主要 activity 和适配器代码都包含在内。
public class ListViewFragment extends ListFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Activity myAct = getActivity();
View view = inflater.inflate(R.layout.activity_main, container, false);
ListView momentObjectListView = (ListView)view.findViewById(R.id.list_item);
//ListView momentObjectListView = getListView();
MomentObjectAdapter momentObjectAdapter = new MomentObjectAdapter(myAct, R.layout.moment_object_list_item);
//momentObjectListView.setAdapter(momentObjectAdapter);
List<MomentObject> myMoments = getMoments();
for(final MomentObject entry : myMoments) {
momentObjectAdapter.add(entry);
}
//ListViewFragment.this.setListAdapter(momentObjectAdapter);
momentObjectListView.setAdapter(momentObjectAdapter);
return view;
}
private List<MomentObject> getMoments() {
// Let's setup some test data.
// Normally this would come from some asynchronous fetch into a data source
// such as a sqlite database, or an HTTP request
final List<MomentObject> entries = new ArrayList<MomentObject>();
for(int i = 1; i < 50; i++) {
entries.add(
new MomentObject(
"Test Entry " + i,
"Anonymous Author",
new GregorianCalendar(2011, 11, i).getTime(),
R.drawable.photoicon
)
);
}
return entries;
}
}
这是我的 activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:background="#ffffffff">
<fragment android:name="com.malatras.moment2.ListViewFragment"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
如果我需要提供什么来解决这个问题,请告诉我。
LogCat:
e02-24 18:54:29.119 2325-2325/com.malatras.moment2 I/art﹕ Not late-enabling -Xcheck:jni (already on)
02-24 18:54:29.191 2325-2325/com.malatras.moment2 D/AndroidRuntime﹕ Shutting down VM
02-24 18:54:29.191 2325-2325/com.malatras.moment2 E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.malatras.moment2, PID: 2325
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.malatras.moment2/com.malatras.moment2.MainActivity}: android.view.InflateException: Binary XML file line #9: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: android.view.InflateException: Binary XML file line #9: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:377)
at android.app.Activity.setContentView(Activity.java:2144)
at com.malatras.moment2.MainActivity.onCreate(MainActivity.java:11)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.malatras.moment2.ListViewFragment.onCreateView(ListViewFragment.java:34)
at android.app.Fragment.performCreateView(Fragment.java:2053)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:870)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1045)
at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1147)
at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2116)
at android.app.Activity.onCreateView(Activity.java:5282)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:377)
at android.app.Activity.setContentView(Activity.java:2144)
at com.malatras.moment2.MainActivity.onCreate(MainActivity.java:11)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
主要活动:
public class MainActivity extends ListActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MomentObjectAdapter:
public final class MomentObjectAdapter extends ArrayAdapter<MomentObject> {
private final int momentObjectLayoutResource;
public MomentObjectAdapter(final Context context, final int momentObjectLayoutResource) {
super(context, 0);
this.momentObjectLayoutResource = momentObjectLayoutResource;
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
// We need to get the best view (re-used if possible) and then
// retrieve its corresponding ViewHolder, which optimizes lookup efficiency
final View view = getWorkingView(convertView);
final ViewHolder viewHolder = getViewHolder(view);
final MomentObject entry = getItem(position);
// Setting the title view is straightforward
viewHolder.titleView.setText(entry.getTitle());
// Setting the subTitle view requires a tiny bit of formatting
final String formattedSubTitle = String.format("By %s on %s",
entry.getAuthor(),
DateFormat.getDateInstance(DateFormat.SHORT).format(entry.getPostDate())
);
viewHolder.subTitleView.setText(formattedSubTitle);
// Setting image view is also simple
viewHolder.imageView.setImageResource(entry.getIcon());
return view;
}
private View getWorkingView(final View convertView) {
// The workingView is basically just the convertView re-used if possible
// or inflated new if not possible
View workingView = null;
if(null == convertView) {
final Context context = getContext();
final LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
workingView = inflater.inflate(momentObjectLayoutResource, null);
} else {
workingView = convertView;
}
return workingView;
}
private ViewHolder getViewHolder(final View workingView) {
// The viewHolder allows us to avoid re-looking up view references
// Since views are recycled, these references will never change
final Object tag = workingView.getTag();
ViewHolder viewHolder = null;
if(null == tag || !(tag instanceof ViewHolder)) {
viewHolder = new ViewHolder();
viewHolder.titleView = (TextView) workingView.findViewById(R.id.moment_object_title);
viewHolder.subTitleView = (TextView) workingView.findViewById(R.id.moment_object_subtitle);
viewHolder.imageView = (ImageView) workingView.findViewById(R.id.moment_object_icon);
workingView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) tag;
}
return viewHolder;
}
/**
* ViewHolder allows us to avoid re-looking up view references
* Since views are recycled, these references will never change
*/
private static class ViewHolder {
public TextView titleView;
public TextView subTitleView;
public ImageView imageView;
}
}
moment_object_list_item:
<?xml version="1.0" encoding="utf-8"?>
<!-- Layout for individual news entries in a list -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Icon shown next to the title/subtitle -->
<ImageView
android:id="@+id/moment_object_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:padding="3dp" />
<!-- Title of the news entry -->
<TextView
android:id="@+id/moment_object_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/moment_object_icon"
android:layout_alignTop="@id/moment_object_icon"
android:layout_margin="5dp"
android:textSize="14sp"
android:textStyle="bold" />
<!-- Subtitle contains author and date -->
<TextView
android:id="@+id/moment_object_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/moment_object_title"
android:layout_below="@id/moment_object_title"
android:textSize="12sp" />
</RelativeLayout>
在您的 XML 文件中更改此行:android:id="@+id/list"
至:
android:id="@id/android:list
并在 ListViewFragment
中更改为:ListView momentObjectListView =(ListView)view.findViewById(R.id.list)
;
对此:
ListView momentObjectListView = (ListView)view.findViewById(android.R.id.list);
在你的 Logcat 文件中,它说
android.view.InflateException: Binary XML file line #9: Error inflating class fragment
这意味着 xml 文件不正确。在日志中也更深入,
The code MainActivity.onCreate(MainActivity.java:11) ...
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference at com.malatras.moment2.ListViewFragment.onCreateView(ListViewFragment.java:34) ...
ListViewFragment.onCreateView(ListViewFragment.java:34)
也需要加载文件 ListViewFragment.java。为了节省时间,也许post个文件。
另一个可能好的代码更改是修改 ListViewFragment 定义:
public class ListViewFragment extends ListFragment {
至:
public class ListViewFragment extends Fragment implements AbsListView.OnItemClickListener {
OnItemClickListener 是可选的。
我之所以这样说是因为 MainActivity 已经通过 ListActivity 承载了 ListView 对象。另一个原因是,Android Studio 向导会生成 "to" 建议代码。这对我来说听起来不错。
另一种方法是将 ListActivity 从 MainActivity 中删除为仅 Activity,原因相同。
然而,所有这些建议都可以被视为代码风格。
我不喜欢并且与您的方法 getMoments 不兼容的这段代码是:
for(final MomentObject entry : getMoments()) {
momentObjectAdapter.add(entry);
}
现在试试这个快速示例修复:
List<MomentObject> myMoments = getMoments();
for(final MomentObject entry : myMoments) {
原因是 for 循环中的 getMoments() 是动态求值的。我认为是这样,即使你用 final 声明了它。
在日志中,
Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
我认为对象 momentObjectListView 为空。我在 fragment_list_view.xml 中找不到 UI。但是在 activity_main.xml 中。示例代码:
View view = inflater.inflate(R.layout.activity_main, container, false);
ListView momentObjectListView = (ListView)view.findViewById(R.id.list);
activity_main:
中 ListFragment 的示例布局元素 <fragment android:name="com.malatras.moment2.ListViewFragment"
android:id="@+id/list"
...>
了解基础知识需要一个解释布局的好网页@ Layouts。