【问题标题】:List View Fragment Won't Display列表视图片段不会显示
【发布时间】: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


【解决方案1】:

我不喜欢且与您的方法 getMoments 不兼容的这段代码是:

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

现在试试这个快速修复示例:

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

原因是 for 循环中的 getMoments() 是动态评估的。我想是的,即使你用 final 声明了它。

在日志中,

尝试调用虚方法'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' 空对象引用

我相信对象 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 需要一个很好的解释布局的网页。

【讨论】:

  • 不幸的是没有运气。
  • fragment_list_view.xml 中有什么我特别应该有的吗?它在片段的代码中被夸大了,但除了空白 FrameLayout 之外我没有任何东西,因为我在代码本身中创建列表。
  • 在这个答案中,我怀疑它是 ListViewFragment.java 第 34 行的代码。这与 momentObjectAdapter 和 MomentObject 有关,我刚刚注意到 MomentObject 类没有发布。
  • jmalatras,我认为此时,您将不得不调试这部分代码。我无法复制发布的代码,并且我一直在查看我看不到的代码。这部分代码是可疑的,因为它比它需要的更复杂并且日志支持它。
  • 我相信对象 momentObjectListView 为空。它找不到 UI 元素。这可以通过在调试器中单步执行代码来轻松检测到。我会更新我的答案。
【解决方案2】:

在您的 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);

【讨论】:

  • 仍然给出相同的结果。
【解决方案3】:

在你的 Logcat 文件中,它说

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

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

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

引起:java.lang.NullPointerException:尝试调用虚拟 方法'无效 android.widget.ListView.setAdapter(android.widget.ListAdapter)' 空对象引用 com.malatras.moment2.ListViewFragment.onCreateView(ListViewFragment.java:34) ...

ListViewFragment.onCreateView(ListViewFragment.java:34)

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

【讨论】:

  • 我发布了自定义适配器以及 MainActivity 和 moment_object_list_item 。我不认为它会是 moment_object_list_item,因为我将它作为主要活动正常工作,但无法使用该位置的列表做我想要的,所以我现在想要它作为一个片段。我认为这是使用 getActivity() 作为上下文参数的事情。我可能是错的,所以请让我知道你在想什么。
  • 日志文件显示 XML 文件第 9 行。对我来说唯一的问题是哪个 xml 文件?由于您没有发布所有相关的布局和代码,因此您必须告诉我。
  • 如果您认为是 Activity,那么您可以通过调试器或如下代码检查它: Activity myAct = getActivity() ,看看它是否有效。
  • 我发布了所有相关的内容,您是否需要一些我缺少的东西?如果 XML 第 9 行有错误,我会认为是 activity_main 文件,因为第 9 行对应于片段的开头。如果活动有问题,那不会反过来阻止 xml 绘制吗?
  • 我认为你的直觉是正确的。我注意到日志文件中的另一行将问题归咎于 MainActivity。我会检查的。
【解决方案4】:

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

public class ListViewFragment extends ListFragment {

到:

public class ListViewFragment extends Fragment implements AbsListView.OnItemClickListener {

OnItemClickListener 是可选的。

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

另一种方法是将 ListActivity 从 MainActivity 中删除为仅 Activity,原因相同。

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

【讨论】:

  • 这些都不行。仍然在 ArrayAdapter 的上下文参数中获取空对象引用,但我不确定它哪里出错了。
  • 很抱歉,不清楚。这更像是编码风格而不是解决方案。我会编辑这个答案。
猜你喜欢
  • 2015-01-28
  • 1970-01-01
  • 2021-09-29
  • 1970-01-01
  • 1970-01-01
  • 2013-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多