在 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;
}
当我在 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;
}