在 Fragment 中使用 setAdapter 引用空对象

Null object reference with setAdapter in Fragment

当我在 Fragment 的 onCreateView 方法中使用 setAdapter 来回收视图时,我得到了一个异常空对象引用。请告诉我我做错了什么或我该怎么做?我使用 getActivity() 而不是 "this".

我需要创建 TabbedActivity。我可以在没有片段的情况下执行此操作吗?

One.java

public class One extends Fragment {


@BindView(R.id.recycler_view)
RecyclerView recyclerView;

@BindView(R.id.button2)
Button button;

private WebSitesViewModel mWebSitesViewModel;

int i = 0;

MyRecViewAdapter adapter;

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

    ButterKnife.bind(getActivity());

    String url = getActivity().getIntent().getStringExtra(Intent.EXTRA_TEXT);
    if (url != null) {
        if (isNetworkConnected(getActivity())) {
            One.JsoupAsyncTask jsoupAsyncTask = new One.JsoupAsyncTask(this);
            jsoupAsyncTask.execute(url);
            Toast.makeText(getActivity(), R.string.bookmarks_added, Toast.LENGTH_LONG).show();

        } else {
            Toast.makeText(getActivity(), "Network not connected!", Toast.LENGTH_LONG).show();
        }
    }

    mWebSitesViewModel = ViewModelProviders.of(this).get(WebSitesViewModel.class);

    adapter = new MyRecViewAdapter(getActivity(), mWebSitesViewModel );
    recyclerView.setAdapter(adapter);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    mWebSitesViewModel.getAllWebSites().observe(this, new Observer<List<WebSites>>() {
        @Override
        public void onChanged(@Nullable final List<WebSites> webSites) {
            // Update the cached copy of the words in the adapter.

            adapter.setWebSites(webSites);
        }
    });

    initSwipe();

    return inflater.inflate(R.layout.fragment_container, container,  false);
}




public static boolean isNetworkConnected(Context c) {
    ConnectivityManager connectivityManager
            = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}


private static class JsoupAsyncTask extends AsyncTask<String, Void, Void> {


    private final WeakReference<One> activityWeakReference;

    JsoupAsyncTask(One context) {
        activityWeakReference = new WeakReference<>(context);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(String... url) {

        try {
            Document document = Jsoup.connect(url[0]).get();
            Element img = document.select("img").first();
            String imgSrc = img.absUrl("src");

            addData(document.title(), url[0], imgSrc);


        } catch (IOException e ) {
            e.printStackTrace();
        }

        return null;
    }

    private void addData(String head, String url, String imgSrc) {

        WebSites webSites = new WebSites(head, url, imgSrc, 0);
        activityWeakReference.get().mWebSitesViewModel.insert(webSites);

    }

}


private void initSwipe() {

    ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | RIGHT) {
        @Override
        public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            return makeMovementFlags(0, RIGHT);
        }

        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            return false;
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            final int position = viewHolder.getAdapterPosition();
            if (direction == RIGHT) {

                mWebSitesViewModel.delete(adapter.getmWebSites().get(position));
                adapter.notifyItemRemoved(position);

            }
        }

    };

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
    itemTouchHelper.attachToRecyclerView(recyclerView);
}

}

fragment_container.xml

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/all"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="dev.zca.mybookmarks.selectfragment.ContainerActivity$PlaceholderFragment">

<TextView
    android:id="@+id/section_label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="aassqs"
 />
</android.support.constraint.ConstraintLayout>

异常

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setAdapter(android.support.v7.widget.RecyclerView$Adapter)' on a null object reference
                                                                         at dev.zca.mybookmarks.selectfragment.One.onCreateView(One.java:77)

使用片段时,您需要以不同的方式绑定视图。而不是使用:

ButterKnife.bind(getActivity());

您需要先膨胀视图,然后将其输入 Butterknife:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_container, container,  false);
    ButterKnife.bind(this, view);

    ...

    return view;
}

Non-Activity Binding 下的 Butterknife homepage 上有一个示例。

你应该在其他任何事情之前而不是之后膨胀你的片段视图。另外,您的 ButterKnife 绑定方法是完全错误的。

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

    // BEFORE EVERYTHING ELSE
    View view = inflater.inflate(R.layout.fragment_container, container,  false);

    ButterKnife.bind(this, view);

    ...

    // RETURN IT AT THE END OF METHOD
    return view;
}