在回收器上使用 findViewById 时获取 NullPointerException片段中的视图



尝试构建一个包含 5 个片段的应用程序。第一个包含回收器视图,每当我切换选项卡时,视图都会被丢弃,每次我在充气机膨胀视图时返回时,同时应用程序尝试获取返回空指针异常的回收器视图的 id。而且这个问题只会变得越来越复杂,我不认为使用正确的方法来做到这一点,因为我也会遇到错误。

如果您有任何具有回收器视图片段的应用程序的简单示例,请删除下面的链接,提前感谢您

主活动.java

class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private FragmentHome fragmentHome = new FragmentHome(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentHome.initGetData();
BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavBar);
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragmentHome).commit();
fragmentHome.initRecyclerView();
bottomNavigationView.setOnNavigationItemSelectedListener(navListener);
bottomNavigationView.setOnNavigationItemReselectedListener(new BottomNavigationView.OnNavigationItemReselectedListener() {
@Override
public void onNavigationItemReselected(@NonNull MenuItem menuItem) {
}
});
}
private BottomNavigationView.OnNavigationItemSelectedListener navListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.home: {
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragmentHome).commit();
fragmentHome.initRecyclerView();
break;
}
}
return true;
}
};
}

碎片主页.java

public class FragmentHome extends Fragment {
private String BASE_URL = "https://www.reddit.com";
// INIT RETROFIT AND CALL ONCE AND FOR ALL
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RedditAPI redditAPI = retrofit.create(RedditAPI.class);

private static final String TAG = "FragmentHome";
private RecyclerView feedRecyclerView;
private List<ChildrenData> childrenData;
private String after;
private String previousAfter = "";
private Boolean isScrolling = false;
private int currentItems;
private int totalItems;
private int scrolledOutItems;
private Context context;
private View inflatingView;

public FragmentHome() {
}
public FragmentHome(Context context) {
this.context = context; //I also get some attribute warning 
here not important right now though.
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
inflatingView =  inflater.inflate(R.layout.fragment_home, container, false);
initRecyclerView();
return inflatingView;
}

public void initGetData() {
Call<FeedData> feedDataCall = redditAPI.getFeed();
feedDataCall.enqueue(new Callback<FeedData>() {
@Override
public void onResponse(Call<FeedData> call, final Response<FeedData> response) {
/*   Log.d(TAG, "onResponse: " + response.body().getData().getChildren().get(0).getDataModel().getTitle());
Log.d(TAG, "onResponse: " + response.body().getData().getChildren());*/
childrenData = response.body().getData().getChildren();
Log.d(TAG, "onResponse:  " + childrenData);
after = response.body().getData().getAfter();
Log.d(TAG, "onResponse: " + after);
}
@Override
public void onFailure(Call<FeedData> call, Throwable t) {
Log.d(TAG, "onFailure: " + t.getMessage());
}
});
}
public void initRecyclerView() {
feedRecyclerView = inflatingView.findViewById(R.id.recyclerView);
final FeedRecyclerViewAdapter feedRecyclerViewAdapter = new FeedRecyclerViewAdapter(childrenData, context);
feedRecyclerView.setAdapter(feedRecyclerViewAdapter);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
feedRecyclerView.setLayoutManager(linearLayoutManager);
feedRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
isScrolling = true;
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
currentItems = linearLayoutManager.getChildCount();
totalItems = linearLayoutManager.getItemCount();
scrolledOutItems = linearLayoutManager.findFirstVisibleItemPosition();
if (isScrolling && (totalItems - 1 == currentItems + scrolledOutItems) && (!previousAfter.equals(after))) {
isScrolling = false;
fetchNewData(after, feedRecyclerViewAdapter);
}
}
});
}

public void fetchNewData(final String after_use, final FeedRecyclerViewAdapter feedRecyclerViewAdapter) {
Call<FeedData> feedDataCall_withAfter = redditAPI.getFeed_withAfter(after_use);
previousAfter = after_use;
feedDataCall_withAfter.clone().enqueue(new Callback<FeedData>() {
@Override
public void onResponse(Call<FeedData> call, Response<FeedData> response) {
Log.d(TAG, "onResponse: " + response.body().toString());
childrenData.addAll(response.body().getData().getChildren());
after = response.body().getData().getAfter();
feedRecyclerViewAdapter.notifyDataSetChanged();
}
@Override
public void onFailure(Call<FeedData> call, Throwable t) {
}
});
Log.d(TAG, "fetchNewData: " + childrenData.size());
}
}

收到错误 我收到以下错误

2019-04-15 13:00:28.449 18359-18359/com.example.recyclerview2 E/Android运行时:致命 异常:主要

进程: com.example.recyclerview2, PID: 18359

java.lang.RuntimeException: 无法启动活动 ComponentInfo{com.example.recyclerview2/com.example.recyclerview2.MainActivity}: java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 android.view.View android.view.View.findViewById(int)

StackTrace2019-04-15 13:57:00.234 5508-5508/com.example.recyclerview2 E/Android运行时:致命 异常:主要 进程: com.example.recyclerview2, PID: 5508 java.lang.RuntimeException: 无法启动活动 ComponentInfo{com.example.recyclerview2/com.example.recyclerview2.MainActivity}: java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'android.view.View android.view.View.findViewById(int)' at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 原因:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'android.view.View android.view.View.findViewById(int)' at com.example.recyclerview2.Fragments.FragmentHome.initRecyclerView(FragmentHome.java:92) at com.example.recyclerview2.MainActivity.onCreate(MainActivity.java:44) at android.app.Activity.performCreate(Activity.java:7136) at android.app.Activity.performCreate(Activity.java:7127) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669)

抱歉,堆栈上的第一篇文章,我不知道如何正确格式化代码。

代码中的问题是你在MainActivityonCreate()方法中调用fragmentHome.initRecyclerView();。此时尚未创建片段视图。这就是为什么你得到NullPointerException从 MainActivity 中删除这一行。

下面的initRecyclerView行似乎有问题

feedRecyclerView = inflatingView.findViewById(R.id.recyclerView);

当该行正在执行时inflatingView它似乎为空。但我不明白为什么。请尝试将上面的行移动到onCreateView()内。希望这可以解决问题。

相关内容

最新更新