通过代码动态创建表格时遭遇java.lang.NullPointerException错误求助
问题分析与修复方案
Hey there, let's figure out why you're hitting that error when trying to add rows to your table! The main issue here is how you're handling the TableRow and Button instances—using global static variables is causing context mismatches and potential null pointer exceptions. Let's break this down and fix it step by step.
What's Going Wrong?
- Global Static Controls: You initialized
trandbas static variables inMainActivity, then tried to reuse them intab2. Static variables stick around across your app lifecycle and can cause context leaks, plus they're tied toMainActivity's context instead of the tab2 fragment's context. - Uninitialized Static Variable in tab2: You declared another static
TableRow trintab2but never assigned it a value—this would throw aNullPointerExceptionwhen you calltr.setLayoutParams(). - Deprecated Layout Constant:
FILL_PARENTis outdated; you should useMATCH_PARENTinstead for modern Android compatibility.
Fixed Code
First, update MainActivity.java to remove the unnecessary static variables:
package com.coreclue.random5; import android.support.design.widget.TabLayout; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; public class MainActivity extends AppCompatActivity{ private SectionsPagerAdapter mSectionsPagerAdapter; private ViewPager mViewPager; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); mViewPager = (ViewPager) findViewById(R.id.container); mViewPager.setAdapter(mSectionsPagerAdapter); TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager)); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view){ Snackbar.make(view, "test test test 123", Snackbar.LENGTH_LONG).setAction("Action", null).show(); } }); } @Override public boolean onCreateOptionsMenu(Menu menu){ getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item){ int id = item.getItemId(); if(id == R.id.action_settings){ return true; } return super.onOptionsItemSelected(item); } public static class PlaceholderFragment extends Fragment{ private static final String ARG_SECTION_NUMBER = "section_number"; public static PlaceholderFragment newInstance(int sectionNumber){ PlaceholderFragment fragment = new PlaceholderFragment(); Bundle args = new Bundle(); args.putInt(ARG_SECTION_NUMBER, sectionNumber); fragment.setArguments(args); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ View tabView1 = inflater.inflate(R.layout.tab1, container, false); View tabView2 = inflater.inflate(R.layout.tab2, container, false); View tabView3 = inflater.inflate(R.layout.tab3, container, false); if(getArguments().getInt(ARG_SECTION_NUMBER) == 1){ tab1 obj = new tab1(); obj.main(tabView1); return tabView1; } else if(getArguments().getInt(ARG_SECTION_NUMBER) == 2){ tab2 obj = new tab2(); obj.main(tabView2); return tabView2; } else if(getArguments().getInt(ARG_SECTION_NUMBER) == 3){ return tabView3; } else{ return tabView1; } } } public class SectionsPagerAdapter extends FragmentPagerAdapter{ public SectionsPagerAdapter(FragmentManager fm){ super(fm); } @Override public Fragment getItem(int position){ return PlaceholderFragment.newInstance(position + 1); } @Override public int getCount(){ return 3; } } }
Next, update tab2.java to create controls locally using the fragment's context:
package com.coreclue.random5; import android.view.View; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; import android.widget.Button; public class tab2{ public void main(View rootView){ final TextView line1 = rootView.findViewById(R.id.line1); line1.setText("aa"); TableLayout tl = (TableLayout) rootView.findViewById(R.id.table123); // Create TableRow and Button using the current view's context TableRow tr = new TableRow(rootView.getContext()); tr.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)); Button b = new Button(rootView.getContext()); b.setText("Dynamic Button"); b.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)); tr.addView(b); tl.addView(tr, new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT)); } }
Why This Works
- Local Control Creation: By making
TableRowandButtonlocal to themainmethod, you ensure each instance is tied to the tab2 fragment's context, avoiding leaks and conflicts. - No Static Variables: Removing static references eliminates null pointer risks and lifecycle issues.
- Updated Layout Constant:
MATCH_PARENTis the modern replacement forFILL_PARENT, keeping your code compatible with newer Android versions.
Give this a try—it should resolve the error you're seeing!
内容的提问来源于stack exchange,提问作者c31e
相关产品推荐
相关产品推荐

