Majid Rostamian
Majid Rostamian

Reputation: 74

findViewByID not work in tab layout

i use tab layout matching this tutorial:

tab layout tutorial androidhive

It works fine, but when I add a button to fragment_one.xml , i cant use setOnClickListener for this button Because findViewById not work in MainActivity.java

the MainActivity bellow code:

public class MainActivity extends AppCompatActivity {
Button button;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(viewPager);

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);

    button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
           Snackbar.make(view, "Replace with your own action",Snackbar.LENGTH_LONG).setAction("Action", null).show();
        }
    });
}

the app stopped with this error: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener' on a null object reference

Where should the button be defined and setOnClickListener?

Upvotes: 0

Views: 2128

Answers (2)

Tal Barda
Tal Barda

Reputation: 4287

Even though a fragment is hosted by an activity, it has its own layout (which is contained in the activity's layout) and therefore you'll have to define the fragment's view in its java class.

In most cases, a fragment would have its own Java class for you to manage and manipulate it, so in your case, it should look like this:

public class OneFragment extends Fragment{

    public OneFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_one, container, false);
        Button button=view.findViewById(R.id.myButtonInFragment);
        return view;
    }

}

If you'd like to access this button from its parent activity, you can achieve it by making the button public:

public class OneFragment extends Fragment{

   public Button button;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_one, container, false);
        button=view.findViewById(R.id.myButtonInFragment);
        return view;
    }
}

and then, access it using the fragment's instance in your activity:

OneFragment myFragment=new OneFragment();

After you have attached the fragment to the activity, you can use:

myFragment.button.setClickEnabled(false);

However, accessing fragment's children outside of the fragment is not recommended, and you should avoid it if you can.

Upvotes: 2

Raj
Raj

Reputation: 3001

public class MainActivity extends AppCompatActivity {
    Button button;
    Fragment fragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fragment = new Fragment();


        View view = fragment.getView();
        if (view !=null) {
             view.findViewById(R.id.button);

        }
    }
}

Upvotes: 0

Related Questions