I have two fragments and a main activity. The first fragment, FriendsFragment (extends ListFragment) is displayed on the screen and when the user clicks an item, the main Activity replaces the FriendsFragment with FeedFragment, then calls a method from FeedFragment to update the textView.
I'm getting an error that the textView object in the FeedFragment class is null even though I instantiate using the findViewById method.
I have looked at related questions and have tried the solutions but nothing is working. I've tried doing getView().findViewById(R.id.feed_view), getActivity().findViewById(R.id.feed_view), and I've tried putting these in onActivityCreated() and onCreateView()
The only thing that worked is writing this code in onActivityCreated():
text = getView().findViewById(R.id.feed_view);
text.setText("some string");
but this is not what I want
FeedFragments.java
public class FeedFragment extends Fragment {
private static String TAG = "Feed Fragment";
private TextView text;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
Log.i(TAG, "Entered FeedFragment.java onActivityCreated()");
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Log.i(TAG, "Entered FeedFragment.java onCreateView()");
View v = inflater.inflate(R.layout.fragment_feed, container,false);;
text = v.findViewById(R.id.feed_view);
return v;
}
public void updateDisplay(int position)
{
Log.i(TAG, "FeedFragment.java: updateDisplay()");
text.setText(position);
}
MainActivity.java
// previously declared feedFragment: feedFragment = new FeedFragment();
public void onItemSelected(int position)
{
Log.i(TAG, "Entered onItemSelected(" + position + ")");
fragManager = getFragmentManager();
FragmentTransaction fragTransaction = fragManager.beginTransaction();
fragTransaction.replace(R.id.fragment_container, feedFragment, "feed_fragment");
fragTransaction.addToBackStack(null);
fragTransaction.commit();
feedFragment.updateDisplay(position);
}
fragment_feed.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/feed_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/greeting" />
</ScrollView>
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
onViewcreated() is being called after updateDisplay() because the system doesn't run it right away.
you need to pass a value to the feedFragment on it's creation and store it in a bundle and retrieve it after the fragment internal code is run by the system.
the way you solve it is like this:
when you instantiate feedFragment you do it like this:
feedFragment = FeedFragment.newInstance(position)
and inside FeedFragment class you should have a static code:
private static final String ARG_PARAM1 = "param1";
public static FeedFragment newInstance(int param1) {
FeedFragment fragment = new FeedFragment();
Bundle args = new Bundle();
args.putInt(ARG_PARAM1, param1);
fragment.setArguments(args);
return fragment;
}
and non static code:
private int mParam1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getInt(ARG_PARAM1);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Log.i(TAG, "Entered FeedFragment.java onCreateView()");
View v = inflater.inflate(R.layout.fragment_feed, container,false);;
text = v.findViewById(R.id.feed_view);
text.setText(String.valueOf(mParam1));
return v;
}
I wrapped mParam1 in String.valueOf() because when you pass integer to setText it thinks you try to use a Strings.xml resource instead of the number you chose.
also I used very generic variable names. please change them to something meaningful so that your code makes sense.
I'm try to set the action for ImageButton. When the DialgoFragment is called and is shown on screen, I want to preess the button and get an action. When I put my action inside that onClick in the code below it didn't work. I'm sure that's not the right way of doing it.
I'm using this class as fragment:
public class GeneralDialogFragment extends DialogFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout to use as dialog or embedded fragment
View v = inflater.inflate(R.layout.activity_dialog, container, false);
ImageButton mImageButton = (ImageButton) v.findViewById(R.id.image_button);
mImageButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
String name = "";
SharedPreferences prefs = getActivity().getSharedPreferences("MY_PREFS_NAME", Context.MODE_PRIVATE);
String yourmessage = prefs.getString("msg", null);
if (yourmessage != null) {
name = prefs.getString("msg", "No name defined");//"No name defined" is the default value.
}
ScrollTextView txt = (ScrollTextView) v.findViewById(R.id.scroll_text);
txt.setText(name);
txt.setTextSize(220);
txt.startScroll();
}
});
return v;
}
And in this activity_dialog layout I have an ImageButton:
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/image_button"
android:src="#drawable/ic_image_500px"/>
Edited: Now the action is in the class above. The error actually is in the action. I have the MainActivity where I press this send button:
public void send(View view){
EditText mEditText = (EditText)findViewById(R.id.text_msg);
String MESSAGE = mEditText.getText().toString();
SharedPreferences.Editor editor = getSharedPreferences("MY_PREFS_NAME", MODE_PRIVATE).edit();
editor.putString("msg", MESSAGE );
editor.commit();
Intent intent = new Intent(this, MessageActivity.class );
startActivity(intent);
}
It calls the MessageActivity where I call the GeneralDialogFragment class which shows the ImageButton with this code:
DialogFragment mDialog = new GeneralDialogFragment();
mDialog.show(getSupportFragmentManager(), "Dialog TAG");
Because of v which you've added it before, it's working without any errors:
View v = inflater.inflate(R.layout.activity_dialog, container, false);
ImageButton mImageButton = (ImageButton) v.findViewById(R.id.image_button);
I've been trying to change my textViews text in a fragmentActivity based on whether or not user has clicked the button in the first main activity. I have 2 xml files and 2 .java files and the code at the moment crashes when the app starts.
This is the button code
public void getNum(View view) {
buttonCheck = 1;
}
And this is the code from FragmentTab
public class FragmentTab extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_layout, container, false);
TextView tv = (TextView) v.findViewById(R.id.text);
tv.setText("nothing has been input yet");
if (FirstActivity.buttonCheck == 1){
tv = (TextView) v.findViewById(R.id.text);
tv.setText("value");}
FirstActivity.buttonCheck = 0;
return v;
}
The first error i get from my code from logcat is: "java.lang.NullPointerException
at com.ezentertainment.dietabialkowa.FragmentTab.onCreateView(FragmentTab.java:23)" and line 23 is tv.setText("nothing has been input yet");
any help at all is greatly appreciated, I have been fighting with this issue for quite some time now..
tl;dr how to change fragment value based upon input from mainActivity?
edit: here is the fragment_layout.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#eaecee">
<TextView
android:id="#+id/textResult"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="value"
android:textAppearance="?android:attr/textAppearanceMedium" />
Your textview id is
android:id="#+id/textResult"
So, that's why you're getting a null pointer exception.
Also, it's probably a good idea to do a null check when finding a view by ID, just in case something isn't instantiated yet, so it doesn't kill your app. Something like:
TextView tv = (TextView) v.findViewById(R.id.textResult);
if (tv != null){
tv.setText("nothing has been input yet");
} else {
// log something if you want.
}
How about using setArguement:
In Activity:
Bundle bundle = new Bundle();
bundle.putString("email", email);
FragmentA fragment = new FragmentA();
fragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction().add(container, fragment, tag).addToBackStack(tag).commit(); //please input container and tag yourself
In FragmentA:
String email;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle arguments = getArguments();
if (arguments != null)
email = bundle.getString("email");
...
}
This is the error i get:
03-11 08:27:48.513: E/AndroidRuntime(23647): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.plan.yeahimin/com.plan.yeahimin.PlanDetailsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.Serializable android.os.Bundle.getSerializable(java.lang.String)' on a null object reference
I understand its due to a variable having a null value but I can't workout why. It looks like it's 'EXTRA_NEW_PLAN' in the getSerializable() method in the DetailsFragment but other than that I don't know. I'm new to Android so forgive me if it's obvious but any help would be greatly appreciated.
Here is my code for the ListFragment;
public class PlanListFragment extends ListFragment {
public final static String TAG = "com.plan.yeahimin.PlanListFragment";
public final static String EXTRA_NEW_PLAN = "com.plan.yeahimin.plan_id";
private Button mAddPlan;
private ArrayList<Plan> mPlansList;
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.empty_view_or_list_view, parent, false);
ListView view = (ListView) v.findViewById(android.R.id.list);
view.setEmptyView(v.findViewById(android.R.id.empty));
mAddPlan = (Button) v.findViewById(R.id.add_a_plan);
mAddPlan.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.d(TAG, "add plan clicked");
Plan plan = new Plan();
Log.d(TAG, "new plan created");
PlanArrayList.get(getActivity()).addPlans(plan);
Log.d(TAG, "plan added to mPlansList");
Intent i = new Intent(getActivity(), PlanDetailsActivity.class);
i.putExtra(PlanDetailsFragment.EXTRA_NEW_PLAN, plan.getId());
startActivity(i);
return;
}
});
return v;
}
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
mPlansList = PlanArrayList.get(getActivity()).getPlans();
//ArrayList<Plan> mPlansList = new ArrayList<Plan>();
PlanArrayAdapter paa = new PlanArrayAdapter(mPlansList);
setListAdapter(paa);
}
public class PlanArrayAdapter extends ArrayAdapter<Plan>{
public PlanArrayAdapter(ArrayList<Plan> planList){
super(getActivity(), 0, planList);
}
public View getView(int position, View convertView, ViewGroup parent){
// Get the plan item for this position
Plan plan = getItem(position);
//If layout doesnt exist, inflate one
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.plan_list_fragment, parent, false);
}
TextView planTitle = (TextView) convertView.findViewById(R.id.plan_title);
planTitle.setText(plan.getTitle());
TextView planDate = (TextView) convertView.findViewById(R.id.plan_date);
planDate.setText(plan.getDate().toString());
return convertView;
}
}
}
and here is my code for the DetailsFragment which opens from add button;
public class PlanDetailsFragment extends Fragment {
private static final String TAG = "com.plan.yeahimin.PlanDetailsFragment";
public static final String EXTRA_NEW_PLAN = "com.plan.yeahimin.plan_id";
private EditText mTitleField;
private Button mDateButton;
private Button mTimeButton;
private EditText mLocationField;
private EditText mAttendeesField;
private EditText mDescriptionField;
private Plan mPlan;
private ArrayList<Plan> mPlansList;
public static PlanDetailsFragment newInstance(UUID planId){
Bundle args = new Bundle();
args.putSerializable(EXTRA_NEW_PLAN, planId);
PlanDetailsFragment f = new PlanDetailsFragment();
f.setArguments(args);
Log.d(TAG, "newInstance created");
return f;
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
UUID planId = (UUID)getArguments().getSerializable(EXTRA_NEW_PLAN);
mPlan = PlanArrayList.get(getActivity()).getPlan(planId);
}
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.plan_details_fragment, parent, false);
mTitleField = (EditText)v.findViewById(R.id.plan_title);
mLocationField = (EditText)v.findViewById(R.id.plan_location);
mAttendeesField = (EditText)v.findViewById(R.id.plan_attendees);
mDescriptionField = (EditText)v.findViewById(R.id.plan_description);
mDateButton = (Button)v.findViewById(R.id.plan_date);
mTimeButton = (Button)v.findViewById(R.id.plan_time);
return v;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
inflater.inflate(R.menu.main_to_do, menu);
}
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case R.id.save_button:
Log.d(TAG, "save button pressed");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
I think you cannot send any arguments to your Fragment with .newInstance(), because this method does not accept any parameters according to the documentation. So even if you have overloaded .newInstance(UUID), the system calls .newInstance() (if calls at all, I have some doubts). Also please be aware that you put the parameter to Intent with .putExtra(), but do not recall it from the Intent.
In fact the right way to send arguments to a Fragment is as follows:
In the caller (usually it is an Activity, but maybe with another Fragment, like in your example, it would also work, I cannot say for sure):
PlanDetailsFragment fragment = new PlanDetailsFragment();
Bundle args = new Bundle();
args.putSerializable(PlanDetailsFragment.TAG_NEW_PLAN, plan.getID());
fragment.setArguments(args);
getFragmentManager().beginTransaction().add(fragment, TAG_DETAILS_FRAGMENT).commit();
In the fragment:
Bundle args = getArguments();
UUID planID = (UUID) args.getSerializable(TAG_NEW_PLAN);
It is not a ready-to-use code, you should adapt it to your classes and variables names, to where your tags are places, etc. The calls of Activity methods may also require some change if you prefer to work from another fragment. It is just an overall description.
My answer applies to the situation when both fragments are inside one activity. Your using of Intents make me have doubts in this, but I do not fully understand it.
You sent the arguments to an Activity(PlanDetailsActivity).
You should send the arguments to a Fragment through newInstance() method.
In your PlainDetailsActivity, you should create the fragment instance like:
UUID uuid = getIntent().getSerializableExtra(PlanDetailsFragment.EXTRA_NEW_PLAN);
PlanDetailsFragment f = PlanDetailsFragment.newInstance(uuid);
I have a FragmentActivity using a ViewPager to serve several fragments. Each is a ListFragment with the following layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp">
<ListView android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<EditText android:id="#+id/entertext"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
When starting the activity, the soft keyboard shows. To remedy this, I did the following inside the fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Save the container view so we can access the window token
viewContainer = container;
//get the input method manager service
imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
. . .
}
#Override
public void onStart() {
super.onStart();
//Hide the soft keyboard
imm.hideSoftInputFromWindow(viewContainer.getWindowToken(), 0);
}
I save the incoming ViewGroup container parameter from onCreateView as a way to access the window token for the main activity. This runs without error, but the keyboard doesn't get hidden from the call to hideSoftInputFromWindow in onStart.
Originally, I tried using the inflated layout instead of container, i.e:
imm.hideSoftInputFromWindow(myInflatedLayout.getWindowToken(), 0);
but this threw a NullPointerException, presumably because the fragment itself isn't an activity and doesn't have a unique window token?
Is there a way to hide the soft keyboard from within a fragment, or should I create a method in the FragmentActivity and call it from within the fragment?
As long as your Fragment creates a View, you can use the IBinder (window token) from that view after it has been attached. For example, you can override onActivityCreated in your Fragment:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
}
Nothing but the following line of code worked for me:
getActivity().getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
If you add the following attribute to your activity's manifest definition, it will completely suppress the keyboard from popping when your activity opens. Hopefully this helps:
(Add to your Activity's manifest definition):
android:windowSoftInputMode="stateHidden"
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_my, container,
false);
someClass.onCreate(rootView);
return rootView;
}
Keep an instance of my root view in my class
View view;
public void onCreate(View rootView) {
view = rootView;
Use the view to hide the keyboard
public void removePhoneKeypad() {
InputMethodManager inputManager = (InputMethodManager) view
.getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
IBinder binder = view.getWindowToken();
inputManager.hideSoftInputFromWindow(binder,
InputMethodManager.HIDE_NOT_ALWAYS);
}
Exception for DialogFragment though, focus of the embedded Dialog must be hidden, instead only the first EditText within the embedded Dialog
this.getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
This code works for fragments:
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Use this static method, from anywhere (Activity / Fragment) you like.
public static void hideKeyboard(Activity activity) {
try{
InputMethodManager inputManager = (InputMethodManager) activity
.getSystemService(Context.INPUT_METHOD_SERVICE);
View currentFocusedView = activity.getCurrentFocus();
if (currentFocusedView != null) {
inputManager.hideSoftInputFromWindow(currentFocusedView.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}catch (Exception e){
e.printStackTrace();
}
}
If you want to use for fragment just call hideKeyboard(((Activity) getActivity())).
Solution that worked for me in fragments:
fun hideKeyboard(){
val imm = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view?.windowToken, 0)
}
and in an activity:
fun hideKeyboard(){
val inputManager: InputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputManager.hideSoftInputFromWindow(currentFocus?.windowToken, InputMethodManager.SHOW_FORCED)
}
this will be work in my case when in tabs i switch from one fragment to another fragments
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
try {
InputMethodManager mImm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
mImm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
mImm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
} catch (Exception e) {
Log.e(TAG, "setUserVisibleHint: ", e);
}
}
}
Nothing of this worked on API27. I had to add this in the container of the layout, for me it was a ConstraintLayout:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:focusedByDefault="true">
//Your layout
</android.support.constraint.ConstraintLayout>
This worked for me in Kotlin class
fun hideKeyboard(activity: Activity) {
try {
val inputManager = activity
.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
val currentFocusedView = activity.currentFocus
if (currentFocusedView != null) {
inputManager.hideSoftInputFromWindow(currentFocusedView.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
In Kotlin:
(activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(view?.windowToken,0)
Use this code in any fragment button listener:
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(getActivity().INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
Kotlin code
val imm = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(requireActivity().currentFocus?.windowToken, 0)
Just add this line in you code:
getActivity().getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Use this:
Button loginBtn = view.findViewById(R.id.loginBtn);
loginBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(getActivity().INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
});
IN BEGINNING
in fragment, below code(use in onActivityCreated) force to hide keyboard in beginning:
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Objects.requireNonNull(getActivity()).getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
}
DURING FRAGMENT (if need)
and also if you have edittext or sth different needs keyboard, and wanna hide the keyboard when pressing outside the keyboard(in my case I have LinearLayout class in xml), first initialize the layout:
LinearLayout linearLayout;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.<your fragment xml>, container, false);
linearLayout= view.findViewById(R.id.linearLayout);
...
return view;
}
then, you need to below code(use in onViewCreated):
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view12) {
try {
InputMethodManager inputMethodManager = (InputMethodManager) Objects.requireNonNull(VideoFragment.this.getActivity()).getSystemService(INPUT_METHOD_SERVICE);
assert inputMethodManager != null;
inputMethodManager.hideSoftInputFromWindow(VideoFragment.this.getActivity().getCurrentFocus().getWindowToken(), 0);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
You can use two ways:
You can create a method inside fragment, but first you must create a View attribute and put the inflater result inside it before it returns in onCreateView:
1° Open your Fragment class. Create attribute
private View view;
2° assign the 'view' attribute the inflater in onCreateView
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.your_activity_main, container, false);
return view;
}
3° create the method 'hideKeyboard'
public void hideKeyboard(Activity activity) {
try{
InputMethodManager inputManager = (InputMethodManager) activity
.getSystemService(view.getContext().INPUT_METHOD_SERVICE);
View currentFocusedView = activity.getCurrentFocus();
if (currentFocusedView != null) {
inputManager.hideSoftInputFromWindow(currentFocusedView.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}catch (Exception e){
e.printStackTrace();
}
}
5° Now just call the method
hideKeyboard(getActivity());
If that doesn't solve your problem, you can try passing the MainActivity class as an object to close the keyboard inside the Frament class
1° In YourClassActivity that you instantiated Fragment, create the method 'hideKeyboard'
public class YourClassActivity extends AppCompatActivity {
public static void hideKeyboard(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
//Find the currently focused view, so we can grab the correct window token from it.
View view = activity.getCurrentFocus();
//If no view currently has focus, create a new one, just so we can grab a window token from it
if (view == null) {
view = new View(activity);
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
2° Implement the 'Serializable' interface in your Activity that instantiates the Fragment
public class YourClassActivity extends AppCompatActivity implements Serializable {
...
}
3° When you instantiate the Frament in the Activity, you must pass the arguments to that Fragment, which will be the Activity class itself
Bundle bundle = new Bundle();
bundle.putSerializable("activity", this);
YourClassFragment fragment = new YourClassFragment();
fragment.setArguments(bundle);
4° Now let's go to your Fragment class. Create attribute view and activity.
private View view;
private Activity activity;
5° Assign the 'view' attribute the inflater in onCreateView. Here you will retrieve the Activity object that was passed as a parameter of this Fragment
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.your_activity_main, container, false);
activity = (Activity) getArguments().getSerializable("obj");
return view;
}
6° Now just call the method
hideKeyboard(activity);
I did all steps but there is something missing I hide the keyboard in fragments with that method
fun hideKeyBoard(view: View) {
val inputManager =
requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputManager.hideSoftInputFromWindow(
view.windowToken,
SOFT_INPUT_STATE_ALWAYS_HIDDEN
)
}
but still when I open the fragment the keyboard open also after a lot of search I found the problem I must put those code in my xml layout root
android:focusable="true"
android:focusableInTouchMode="true"
Note: If you delete above method and just put the attributes in root layout, it will work fine.