Search code examples
javaandroidbottom-sheetandroid-bottomsheetdialog

how to settext button in bottom sheet dialog fragment?


i have one class for bottomsheetdialog fragment.I looked at many places but I'm confused.i want to change text of button in bottom sheet.i get this error 'android.view.View android.view.View.findViewById(int)' on a null object reference. here are my codes;

 public class MainActivity extends AppCompatActivity {

    @Override
     protected void onCreate(final Bundle savedInstanceState) {

       bottomSheetFragment=new BottomSheetFragment();
       View viewDialog=bottomSheetFragment.getView();
       assert viewDialog != null;
       MaterialButton btn_titresim=viewDialog.findViewById(R.id.btn_titresim);
       btn_titresim.setText("text");
     }
 }

Another class for BottomSheetDialogFragment

public class BottomSheetFragment extends BottomSheetDialogFragment {
public BottomSheetFragment() {}

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

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    Objects.requireNonNull(getDialog()).setOnShowListener(dialog -> {

        BottomSheetDialog d = (BottomSheetDialog) dialog;
        View bottomSheetInternal = 
            d.findViewById(com.google.android.material.R.id.design_bottom_sheet);
        assert bottomSheetInternal != null;
        BottomSheetBehavior.from(bottomSheetInternal).setState(BottomSheetBehavior.STATE_EXPANDED);
    });
    return inflater.inflate(R.layout.layout_popup, container, false);
}

}


Solution

  • You can solve this by having a listener interface in your fragment that returns the BottomSheet fragment's View back to your activity, so you can then access the BottomSheetDialogFragmentunderlying views normally by findViewById() method.

    Here I decided to use the Singleton pattern for the BottomSheetDialogFragment to set a listener instance from the activity.

    So in your fragment add a listener; it's named below FragmentListener, call the listener callback in onCreateView() or in onViewCreated()

    public class BottomSheetFragment extends BottomSheetDialogFragment {
    
        public BottomSheetFragment() {}
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        interface FragmentListener {
            void getView(View view);
        }
    
        static FragmentListener mFragmentListener;
    
        public static BottomSheetFragment newInstance(FragmentListener listener) {
            mFragmentListener = listener;
            return new BottomSheetFragment();
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            Objects.requireNonNull(getDialog()).setOnShowListener(dialog -> {
    
                BottomSheetDialog d = (BottomSheetDialog) dialog;
                View bottomSheetInternal = 
                    d.findViewById(com.google.android.material.R.id.design_bottom_sheet);
                assert bottomSheetInternal != null;
                BottomSheetBehavior.from(bottomSheetInternal).setState(BottomSheetBehavior.STATE_EXPANDED);
            });
    
            View view = inflater.inflate(R.layout.layout_popup, container, false);
    
            // Trigger the listener callback to return the view back to the activity
            // mFragmentListener.getView(view);  // Not working in all devices
    
            return inflater.inflate(R.layout.layout_popup, container, false);
        }
    
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            // Trigger the listener callback to return the view back to the activity
            mFragmentListener.getView(view);
        }
    
    }
    

    implement the listener by your activity, and change the text in your callback, and instantiate the BottomSheetDialogFragment using the singleton pattern instead.

     public class MainActivity extends AppCompatActivity implements BottomSheetFragment.FragmentListener {
    
        @Override
         protected void onCreate(final Bundle savedInstanceState)  {
    
           bottomSheetFragment = BottomSheetFragment.newInstance(this);
    
         }
    
        @Override
        public void getView(View view) {
            // Setting the text
            ((MaterialButton) view.findViewById(R.id.btn_titresim)).setText("text");
        }
    
     }
    

    Wish that solves your problem