Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/217.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android getListView()出现片段错误_Java_Android_Android Fragments_Android Studio - Fatal编程技术网

Java Android getListView()出现片段错误

Java Android getListView()出现片段错误,java,android,android-fragments,android-studio,Java,Android,Android Fragments,Android Studio,我的android应用程序一直存在问题,在标签之间滑动时出现以下错误导致程序崩溃: 09-16 16:19:27.142 4750-4750/com.khackett.runmate E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.khackett.runmate, PID: 4750 java.lang.IllegalStateException: Content view not yet created

我的android应用程序一直存在问题,在标签之间滑动时出现以下错误导致程序崩溃:

09-16 16:19:27.142    4750-4750/com.khackett.runmate E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.khackett.runmate, PID: 4750
    java.lang.IllegalStateException: Content view not yet created
            at android.support.v4.app.ListFragment.ensureList(ListFragment.java:328)
            at android.support.v4.app.ListFragment.getListView(ListFragment.java:222)
            at com.khackett.runmate.ui.MyRunsFragment$1.done(MyRunsFragment.java:167)
            at com.khackett.runmate.ui.MyRunsFragment$1.done(MyRunsFragment.java:135)
            at com.parse.ParseTaskUtils$2$1.run(ParseTaskUtils.java:115)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            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:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
这是MyRunsFragment:

public class MyRunsFragment extends ListFragment {

    protected SwipeRefreshLayout mSwipeRefreshLayout;

    // member variable to store the list of routes the user has accepted
    protected List<ParseObject> mAcceptedRoutes;

    private int MY_STATUS_CODE = 1111;

    // Default constructor for MyRunsFragment
    public MyRunsFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_my_runs, container, false);

        // Set SwipeRefreshLayout component
        mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipeRefreshLayout);
        // Set the onRefreshListener
        mSwipeRefreshLayout.setOnRefreshListener(mOnRefreshListener);
        mSwipeRefreshLayout.setColorSchemeResources(
                R.color.swipeRefresh1,
                R.color.swipeRefresh2,
                R.color.swipeRefresh3,
                R.color.swipeRefresh4);

        return rootView;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        // Retrieve the accepted routes from the Parse backend
        retrieveAcceptedRoutes();
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        // create the message object which is set to the message at the current position
        ParseObject route = mAcceptedRoutes.get(position);

        // String messageType = message.getString(ParseConstants.KEY_FILE_TYPE);

        JSONArray parseList = route.getJSONArray(ParseConstants.KEY_LATLNG_POINTS);
        JSONArray parseListBounds = route.getJSONArray(ParseConstants.KEY_LATLNG_BOUNDARY_POINTS);
        String objectId = route.getObjectId();
        String routeName = route.getString(ParseConstants.KEY_ROUTE_NAME);
        // JSONArray ids = route.getJSONArray(ParseConstants.KEY_RECIPIENT_IDS);

        // Start a map activity to display the route
        Intent intent = new Intent(getActivity(), MapsActivityTrackRun.class);
        intent.putExtra("parseLatLngList", parseList.toString());
        intent.putExtra("parseLatLngBoundsList", parseListBounds.toString());
        intent.putExtra("myRunsObjectId", objectId);
        intent.putExtra("myRunsRouteName", routeName);

        // Start the MapsActivityDisplayRoute activity
        startActivityForResult(intent, MY_STATUS_CODE);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

    }

    private void retrieveAcceptedRoutes() {
        // query the routes class/table in parse
        // get messages where the logged in user ID is in the list of the recipient ID's (we only want to retrieve the messages sent to us)
        // querying the message class is similar to how we have been querying users
        ParseQuery<ParseObject> queryRoute = new ParseQuery<ParseObject>(ParseConstants.CLASS_ROUTES);
        // use the 'where' clause to search through the messages to find where our user ID is one of the recipients
        queryRoute.whereEqualTo(ParseConstants.KEY_ACCEPTED_RECIPIENT_IDS, ParseUser.getCurrentUser().getObjectId());
        // order results so that most recent message are at the top of the inbox
        queryRoute.addDescendingOrder(ParseConstants.KEY_CREATED_AT);
        // query is ready - run it
        queryRoute.findInBackground(new FindCallback<ParseObject>() {
            // When the retrieval is done from the Parse query, the done() callback method is called
            @Override
            public void done(List<ParseObject> routes, ParseException e) {
                // dismiss the progress indicator here
                // getActivity().setProgressBarIndeterminateVisibility(false);

                // End refreshing once routes are retrieved
                // done() is called from onResume() and the OnRefreshListener
                // Need to check that its called from the the OnRefreshListener before ending it
                if (mSwipeRefreshLayout.isRefreshing()) {
                    mSwipeRefreshLayout.setRefreshing(false);
                }

                // the list being returned is a list of routes
                if (e == null) {
                    // successful - routes found.  They are stored as a list in messages
                    mAcceptedRoutes = routes;

                    // adapt this data for the list view, showing the senders name

                    // create an array of strings to store the usernames and set the size equal to that of the list returned
                    String[] usernames = new String[mAcceptedRoutes.size()];
                    // enhanced for loop to go through the list of users and create an array of usernames
                    int i = 0;
                    for (ParseObject message : mAcceptedRoutes) {
                        // get the specific key
                        usernames[i] = message.getString(ParseConstants.KEY_SENDER_NAME);
                        i++;
                    }

                    // Create the adapter once and update its state on each refresh
                    if (getListView().getAdapter() == null) {
                        // the above adapter code is now replaced with the following line
                        RouteMessageAdapter adapter = new RouteMessageAdapter(getListView().getContext(), mAcceptedRoutes);

                        // Force a refresh of the list once data has changed
                        adapter.notifyDataSetChanged();

                        // need to call setListAdapter for this activity.  This method is specifically from the ListActivity class
                        setListAdapter(adapter);
                    } else {
                        // refill the adapter
                        // cast it to RouteMessageAdapter
                        ((RouteMessageAdapter) getListView().getAdapter()).refill(mAcceptedRoutes);
                    }
                }
            }
        });
    }

    protected SwipeRefreshLayout.OnRefreshListener mOnRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            // When list is swiped down to refresh, retrieve the users runs from the Parse backend
            retrieveAcceptedRoutes();
        }
    };

}
碎片页雷达:

public class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    // The context to be passed in when the adapter is created.
    private Context mContext;
    // The number of tabs in the layout.
    public static int numberOfTabs = 3;

    /**
     * Default constructor that accepts a FragmentManager parameter to add or remove fragments.
     *
     * @param context         the context from the activity using the adapter.
     * @param fragmentManager the FragmentManager for managing Fragments inside of the TabFragmentContainer.
     */
    public MyFragmentPagerAdapter(Context context, FragmentManager fragmentManager) {
        super(fragmentManager);
        mContext = context;
    }

    /**
     * Method to return the relevant fragment for the selected tab.
     */
    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new MyRunsFragment();
            case 1:
                return new InboxRouteFragment();
            case 2:
                return new FriendsFragment();
        }
        return null;
    }

    /**
     * Method that gets the number of tabs in the layout.
     *
     * @return the number of tabs in the layout.
     */
    @Override
    public int getCount() {
        return numberOfTabs;
    }

    /**
     * Method that returns the title of each tab in the layout.
     */
    @Override
    public CharSequence getPageTitle(int position) {
        Locale locale = Locale.getDefault();
        switch (position) {
            case 0:
                return mContext.getString(R.string.title_section1).toUpperCase(locale);
            case 1:
                return mContext.getString(R.string.title_section2).toUpperCase(locale);
            case 2:
                return mContext.getString(R.string.title_section3).toUpperCase(locale);
        }
        return null;
    }
}
包含ViewPager小部件的tab_layout_fragment_容器文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/ColorPrimaryPurple"
        app:tabGravity="fill"
        app:tabIndicatorColor="@color/ColorPrimaryPurple"
        app:tabMode="fixed"
        app:tabSelectedTextColor="@color/textColorPrimary"
        app:tabTextColor="@color/pressedPurpleButton">
    </android.support.design.widget.TabLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v4.view.ViewPager>

</LinearLayout>

我在这里遵循了其他答案,并将
getListView()
功能添加到
onViewCreated()
方法中,但问题仍然存在。。。有人能指出我可能出错的地方吗?

onViewCreated
onCreateView
之后立即调用,但是缺少
super.onViewCreated
调用,这可能是问题的根本原因

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState); // add this line back in
    // Retrieve the accepted routes from the Parse backend
    retrieveAcceptedRoutes();
}

删除所有这些导入:

import com.yourName.runmate.R;
然后重新同步gradle并重建项目

另请参见此处:

编辑

你的第一个明显错误是

mFragmentManager = getSupportFragmentManager();
应该是:

mFragmentManager = getFragmentManager();
或者将您的主要活动更改为:

MainActivity扩展FragmentActivity
以使用支持片段管理器


您的问题中有很多不必要的代码,可以删除大多数注释并导入用于此问题的代码

我想到的是,没有活动,正在使用。ListFragment需要附加到某个活动,或者您正试图在创建该活动之前调用该活动视图

java.lang.IllegalStateException: Content view not yet created
            at android.support.v4.app.ListFragment.ensureList(ListFragment.java:328)
            at android.support.v4.app.ListFragment.getListView(ListFragment.java:222)
如果您使用的是Main,那么从我看到的情况来看,您没有很好地将它们组合在一起

首先:

从onCreate和onCreateView中取出所有内容(对于所有片段),视图充气器除外

将所有额外代码放入onViewCreated或onActivityCreated中。这样就不能在空视图上调用任何方法,因为这些方法是在创建空视图后调用的

java.lang.IllegalStateException: Content view not yet created
            at android.support.v4.app.ListFragment.ensureList(ListFragment.java:328)
            at android.support.v4.app.ListFragment.getListView(ListFragment.java:222)
第二,你需要整理你的活动和你想要达到的目标

您需要一个页面查看器和碎片列表。pageviewer需要与活动或活动片段相关联,而不是与片段相关联。否则,没有可将pageviewer页面附加到的视图

使用FragmentActivity而不是片段。成为运行ListFragment的活动

public class TabFragmentContainer extends FragmentActivity {

    MyPageAdapter pageAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tab_layout_fragment_container); // change to view layout.

        // Instantiate the adapter that will return a fragment for each of the three sections of the main activity
        myFragmentPagerAdapter = new MyFragmentPagerAdapter(getFragmentManager(), getFragments());

        tabLayout = (TabLayout) view.findViewById(R.id.tabs);

         // Set up the ViewPager with the sections adapter.
        viewPager = (ViewPager) view.findViewById(R.id.viewpager);
                // Set up the adapter for the ViewPager
        viewPager.setAdapter(myFragmentPagerAdapter);

    }
}
我建议将其放入您的ListFragment中,以确保创建您的活动。您将需要从onCreate方法中移动大部分代码,并将它们放在onViewCreated或onActivityCreated中

@Override
public void onActivityCreated(Bundle savedInstanceState) {
  super.onActivityCreated(savedInstanceState);
  ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(), R.layout.my_listview)layout, android.R.layout.simple_list_item_1);

  setListAdapter(adapter);
  getListView().setOnItemClickListener(this);
}
此代码只是一个指南,您需要对其进行调整

让我知道这是否有帮助

这些问答都很好


基于以下事实,同样的原则也适用于viewpager片段:

  • 引发异常是因为当
    done()
    调用
    getListView()
    时,还没有根视图
  • retrieveacceptedrootes()
    所做的查询获得响应时,将调用
    done()
  • retrieveAcceptedRootes
    在多个位置被调用,包括
    OnRefreshListener
    mOnRefreshListener
    ,它在
    onCreateView()
    之前注册为刷新侦听器
…在存在根视图之前,可以调用
getListView()

    // Set SwipeRefreshLayout component 
    mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipeRefreshLayout);
    // Set the onRefreshListener 
    mSwipeRefreshLayout.setOnRefreshListener(mOnRefreshListener);
    mSwipeRefreshLayout.setColorSchemeResources(
            R.color.swipeRefresh1,
            R.color.swipeRefresh2,
            R.color.swipeRefresh3,
            R.color.swipeRefresh4);
尝试将这3条语句从
onCreateView()
移动到
onViewCreated()
,这样只有在存在根视图时才能调用刷新侦听器

    // Set SwipeRefreshLayout component 
    mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipeRefreshLayout);
    // Set the onRefreshListener 
    mSwipeRefreshLayout.setOnRefreshListener(mOnRefreshListener);
    mSwipeRefreshLayout.setColorSchemeResources(
            R.color.swipeRefresh1,
            R.color.swipeRefresh2,
            R.color.swipeRefresh3,
            R.color.swipeRefresh4);
尝试声明:

viewPager = (ViewPager) view.findViewById(R.id.viewpager); 
viewPager.setAdapter(myFragmentPagerAdapter);  
myFragmentPagerAdapter = new MyFragmentPagerAdapter(getActivity(), getChildFragmentManager());
之前:

    tabLayout = (TabLayout) view.findViewById(R.id.tabs);
    tabLayout.post(new Runnable() {
            @Override
            public void run() {
                tabLayout.setupWithViewPager(viewPager);
                viewPager.setCurrentItem(1, false);
                // tabLayout.getTabAt(1).select();
            }
        });

        // Return the created View
        return view;

我又读了一遍你的问题,然后我猜:

  • 当后台任务继续运行时,ListFragment将被销毁。因此,当它完成时,您的回调将更新不再活动的ListView

  • 实际上,
    viewPager.setOffscreenPageLimit(3)可能会起作用,但这不是一个好的做法。它强制您的ViewPager在内存中创建和存储更多不必要的片段。这就是为什么我反对这个答案。你可以不这样做就解决这个问题

你应该做什么:以下两种练习中的一种可以,或者两者都可以:

  • 在您的
    onDestroyView
    之前,在您的
    onPause
    或任何生命周期方法中销毁您的任务

  • 排除
    done()
    方法中更新ListView的代码。让它成为一个本地方法,您将仔细检查ListView,在那里,您应该要求更新进程在UI线程上运行,以避免任何线程问题。确保检查您的
    getView()
    是否不为null(但不要检查您的
    getListView()
    ,因为如果getView()返回null,它会引发异常)

我建议您使用这两种方法来确保:视图仍然可用,并且在
不可见的
片段中运行任务时不会浪费资源。不要忘记,默认情况下,一旦片段不可见,它将被视为已被销毁(例如,ViewPager并不总是保留2个片段的引用,但请记住这种情况)


希望有此帮助。

非法状态异常:当
getView()
返回nullgetListView或getView时,将抛出未创建的内容视图。
getListView()
检查
getView()
是否返回null。如果
getView()
返回null,则
尚未创建的内容视图
为空thrown@petey已经具有
android:id=“@android:id/list”
id属性。我将其更改为您的建议,但仍然发生崩溃。如果有任何不同,我将添加xml布局。您能告诉我在哪里创建
视图
对象,该对象在
选项卡FragmentContainer
onCreate()
方法中使用吗?另外,
onCreate()
中的
getFragment()
方法正在生成一个“无法解析方法”—我尝试用替换它
    tabLayout = (TabLayout) view.findViewById(R.id.tabs);
    tabLayout.post(new Runnable() {
            @Override
            public void run() {
                tabLayout.setupWithViewPager(viewPager);
                viewPager.setCurrentItem(1, false);
                // tabLayout.getTabAt(1).select();
            }
        });

        // Return the created View
        return view;