【发布时间】:2015-02-24 22:37:06
【问题描述】:
我正在尝试使用 ListFragment 在我的主要活动中显示一个列表。该列表由我使用自定义对象的自定义 ArrayAdapter 填充。我无法将此列表显示在应用程序中。当我调试时,它没有显示任何错误,但应用程序立即崩溃。
这是我的片段
编辑:我尝试了几个响应并将问题缩小到 ListViewFragment 中的 momentObjectListView.setAdapter(momentObjectAdapter)。我找不到 momentObjectAdapter 为 null 的原因,所以它必须是 momentObjectListView 但是我找不到问题的根源。任何帮助将非常感激。我的activity_main.xml、片段、主要活动和适配器代码都包括在内。
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.access$800(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.access$800(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.access$800(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>
【问题讨论】:
-
代码对我来说看起来不错。需要 Logcat 消息,只需复制/粘贴,让它看起来不错。我会检查的。
-
@TheOriginalAndroid 刚刚添加了 logcat 消息,谢谢。
-
好的,我发布了答案。
-
我认为您的列表不在您正在膨胀的 XML 文件中,而是在
main_activity -
@jmalatras,也许我知道您遇到的问题,请在“object momentObjectListView is null”上搜索我的答案。我希望你能继续你的项目。
标签: android listview android-fragments android-listview android-arrayadapter