【问题标题】:App crashes when trying to open a fragment with listview尝试使用列表视图打开片段时应用程序崩溃
【发布时间】:2014-11-06 17:40:21
【问题描述】:

当我尝试打开由列表视图组成的片段时,我的应用程序崩溃了。

场景:

  1. 第一次打开fragmentA,listview不显示。

  2. 单击fragmentA 上的按钮(转到fragmentB)。

  3. 在 fragmentB 上单击返回按钮,在 fragmentA 上显示列表视图。

  4. 退出应用,再次尝试打开fragmentA,应用崩溃。

我的片段类:

public class FamilyTreeFragment extends Fragment {

// Declare Variables
ListView listview;
List<ParseObject> ob;
ProgressDialog mProgressDialog;
FamilyTreeListViewAdapter adapter;
private List<FamilyTree> familytreelist = null;
View rootView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_familytree, container, false);

    new RemoteDataTask().execute();
    // Locate the listview in listview_main.xml
    listview = (ListView) rootView.findViewById(R.id.list);
    // Pass the results into ListViewAdapter.java
    // adapter = new FamilyTreeListViewAdapter(getActivity(), familytreelist);
    // Binds the Adapter to the ListView
    // listview.setAdapter(adapter);
    // Close the progressdialog
    mProgressDialog.dismiss();

    // btn_add
    Button btn_add = (Button) rootView.findViewById(R.id.btn_add);
    btn_add.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            // Toast.makeText(SuggestionsFragment.this.getActivity(),
            // "You have selected Parks.", Toast.LENGTH_SHORT).show();
            getFragmentManager().beginTransaction().replace(R.id.container, new FamilyTreeFragment2()).addToBackStack(null).commit();
        }
    });

    return rootView;
}

// RemoteDataTask AsyncTask
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Create a progressdialog
        mProgressDialog = new ProgressDialog(getActivity());
        // Set progressdialog title
        mProgressDialog.setTitle("");
        // Set progressdialog message
        mProgressDialog.setMessage("Loading...");
        mProgressDialog.setIndeterminate(false);
        // Show progressdialog
        mProgressDialog.show();

    }

    protected Void doInBackground(Void... arg0) {
        // Create the array
        familytreelist = new ArrayList<FamilyTree>();
        try {
            // Locate the class table named "Country" in Parse.com
            ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("FamilyTree");
            // Locate the column named "ranknum" in Parse.com and order list
            // by ascending
            query.orderByAscending("createdAt");
            ob = query.find();
            for (ParseObject familytree : ob) {
                // Locate images in flag column
                ParseFile image = (ParseFile) familytree.get("image");

                FamilyTree tree = new FamilyTree();
                tree.setName((String) familytree.get("name"));
                tree.setRelation((String) familytree.get("relation"));
                tree.setImage(image.getUrl());
                familytreelist.add(tree);
            }
        } catch (ParseException e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    protected void onPostExecute(Void result) {

        // Locate the listview in listview_main.xml
        listview = (ListView) rootView.findViewById(R.id.list);
        // Pass the results into ListViewAdapter.java
        adapter = new FamilyTreeListViewAdapter(getActivity(), familytreelist);
        // Binds the Adapter to the ListView
        listview.setAdapter(adapter);
        // Close the progressdialog
        // mProgressDialog.dismiss();
    }
}

}

XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/familytreecontainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.parcel.FamilyTreeFragment$PlaceholderFragment" >

<ListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="407dp"
    android:layout_weight="2.86" >
</ListView>

<Button
    android:id="@+id/btn_add"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Add" />

Logcat:

11-06 17:01:06.500: E/AndroidRuntime(22072): FATAL EXCEPTION: main
11-06 17:01:06.500: E/AndroidRuntime(22072): Process: com.example.parcel, PID: 22072
11-06 17:01:06.500: E/AndroidRuntime(22072): java.lang.NullPointerException
11-06 17:01:06.500: E/AndroidRuntime(22072):    at  com.example.parcel.FamilyTreeFragment$RemoteDataTask.onPostExecute(FamilyTreeFragment.java:111)
11-06 17:01:06.500: E/AndroidRuntime(22072):    at com.example.parcel.FamilyTreeFragment$RemoteDataTask.onPostExecute(FamilyTreeFragment.java:1)
11-06 17:01:06.500: E/AndroidRuntime(22072):    at android.os.AsyncTask.finish(AsyncTask.java:632)
11-06 17:01:06.500: E/AndroidRuntime(22072):    at android.os.AsyncTask.access$600(AsyncTask.java:177)
11-06 17:01:06.500: E/AndroidRuntime(22072):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
11-06 17:01:06.500: E/AndroidRuntime(22072):    at android.os.Handler.dispatchMessage(Handler.java:102)
11-06 17:01:06.500: E/AndroidRuntime(22072):    at android.os.Looper.loop(Looper.java:157)
11-06 17:01:06.500: E/AndroidRuntime(22072):    at android.app.ActivityThread.main(ActivityThread.java:5867)
11-06 17:01:06.500: E/AndroidRuntime(22072):    at java.lang.reflect.Method.invokeNative(Native Method)
11-06 17:01:06.500: E/AndroidRuntime(22072):    at java.lang.reflect.Method.invoke(Method.java:515)
11-06 17:01:06.500: E/AndroidRuntime(22072):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
11-06 17:01:06.500: E/AndroidRuntime(22072):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)
11-06 17:01:06.500: E/AndroidRuntime(22072):    at dalvik.system.NativeStart.main(Native Method)

我该如何解决这个问题?任何帮助表示赞赏。谢谢。

【问题讨论】:

    标签: android listview android-fragments android-listview


    【解决方案1】:

    试试这个方法,希望能帮助你解决问题。

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

    替换为

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

    错误原因:

    您在类级别有 decalre rootView 但未在 onCreateView() 上初始化,您将 View rootView 作为 onCreateView() 中的局部变量,因此 onPostExecute() rootView 将指向仍未初始化的类级别变量。

    格式良好的代码:

    public class FamilyTreeFragment extends Fragment {
    
        // Declare Variables
        private ListView listview;
        private Button btn_add;
        private FamilyTreeListViewAdapter adapter;
        private List<FamilyTree> familytreelist;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_familytree, container, false);
    
            listview = (ListView) rootView.findViewById(R.id.list);
            btn_add = (Button) rootView.findViewById(R.id.btn_add);
    
            mProgressDialog.dismiss();
            btn_add.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Toast.makeText(SuggestionsFragment.this.getActivity(),
                    // "You have selected Parks.", Toast.LENGTH_SHORT).show();
                    getFragmentManager().beginTransaction().replace(R.id.container, new FamilyTreeFragment2()).addToBackStack(null).commit();
                }
            });
    
            new RemoteDataTask().execute();
            return rootView;
        }
    
        // RemoteDataTask AsyncTask
        private class RemoteDataTask extends AsyncTask<Void, Void, List<FamilyTree>> {
            private ProgressDialog mProgressDialog;
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                // Create a progressdialog
                mProgressDialog = new ProgressDialog(getActivity());
                // Set progressdialog title
                mProgressDialog.setTitle("");
                // Set progressdialog message
                mProgressDialog.setMessage("Loading...");
                mProgressDialog.setIndeterminate(false);
                // Show progressdialog
                mProgressDialog.show();
    
            }
    
            protected List<FamilyTree> doInBackground(Void... arg0) {
                // Create the array
                List<FamilyTree> list = new ArrayList<FamilyTree>();
                try {
                    // Locate the class table named "Country" in Parse.com
                    ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("FamilyTree");
                    // Locate the column named "ranknum" in Parse.com and order list
                    // by ascending
                    query.orderByAscending("createdAt");
                    List<ParseObject> ob = query.find();
                    for (ParseObject familytree : ob) {
                        // Locate images in flag column
                        ParseFile image = (ParseFile) familytree.get("image");
    
                        FamilyTree tree = new FamilyTree();
                        tree.setName((String) familytree.get("name"));
                        tree.setRelation((String) familytree.get("relation"));
                        tree.setImage(image.getUrl());
                        list.add(tree);
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                    Log.e("Error", e.getMessage());
                }
                return list;
            }
    
            protected void onPostExecute(List<FamilyTree> result) {
                super.onPostExecute(result);
    
                if(mProgressDialog!=null && mProgressDialog.isShowing()){
                    mProgressDialog.dismiss();
                }
                if(familytreelist==null){
                    familytreelist = new ArrayList<FamilyTree>();
                }
    
                familytreelist.addAll(result);
    
                // Pass the results into ListViewAdapter.java
                adapter = new FamilyTreeListViewAdapter(getActivity(), familytreelist);
                // Binds the Adapter to the ListView
                listview.setAdapter(adapter);
            }
        }
    
    }
    

    【讨论】:

    • 嗨。我已替换 View rootView = inflater.inflate(R.layout.fragment_familytree, container, false);与 rootView = inflater.inflate(R.layout.fragment_familytree, 容器, false);并删除了 onPostExecute() 声明的列表视图,它可以工作!非常感谢!
    • 如果您要从 onPostExecute() 中删除 listview 初始化,则将 listview 初始化行移到这个 new RemoteDataTask().execute() 之前;行在 onCreateView() 中。
    • 好的。我已经做出了改变。再次感谢。
    • 哦,我现在明白了。进度对话框现在可以正常工作了。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    • 2018-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多