列表视图片段不会显示

时间:2015-02-24 22:37:07

标签: android listview android-fragments android-listview android-arrayadapter

我正在尝试使用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)

MainActivity:

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>

4 个答案:

答案 0 :(得分:0)

在此行中更改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);

答案 1 :(得分:0)

在您的Logcat文件中,它显示

  

android.view.InflateException:二进制XML文件行#9:错误   膨胀类片段

这意味着xml文件不正确。在日志中也更深入,

  

代码MainActivity.onCreate(MainActivity.java:11)   ...

     

引起:java.lang.NullPointerException:尝试调用虚拟   方法&#39;无效   android.widget.ListView.setAdapter(android.widget.ListAdapter)&#39;在...上   null对象引用   com.malatras.moment2.ListViewFragment.onCreateView(ListViewFragment.java:34)   ...

     

ListViewFragment.onCreateView(ListViewFragment.java:34)

还需要加载文件ListViewFragment.java。为了节省时间,也许发布更多文件。

答案 2 :(得分:0)

另一个可能的良好代码更改是从以下位置修改ListViewFragment定义:

public class ListViewFragment extends ListFragment {

为:

public class ListViewFragment extends Fragment implements AbsListView.OnItemClickListener {

OnItemClickListener是可选的。

我之所以这么说是因为MainActivity已经通过ListActivity托管了ListView对象。另一个原因,Android Studio向导生成“to”建议代码。这听起来不错。

另一种方法是将ListActivity从MainActivity中移除到Activity,原因相同。

然而,所有这些建议都可能被认为是代码风格。

答案 3 :(得分:0)

此代码我不喜欢并且与您的方法getMoments不兼容:

for(final MomentObject entry : getMoments()) {
        momentObjectAdapter.add(entry);
    }

现在试试这个来快速修复样本:

List<MomentObject> myMoments = getMoments();
for(final MomentObject entry : myMoments) {

原因是for循环中的getMoments()是动态评估的。我想也是如此,即使你最后宣布它。

在日志中,

  

尝试调用虚方法&#39; void   android.widget.ListView.setAdapter(android.widget.ListAdapter)&#39;在...上   null对象引用

我相信对象momentObjectListView为null。我在 fragment_list_view .xml中找不到用户界面。但是它位于 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需要一个很好的网页来解释布局。