I am struggling with following error when I try to invoke fragment layout. Here is the code.
MainActivity;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void showFragOne(View view){
FragmentManager FM = getFragmentManager();
FragmentTransaction FT = FM.beginTransaction();
FT.add(R.layout.frag_one, new FragOne());
FT.commit();
}
}
showFragOne is called when button click on ativity_main layout.
frag_one is layout for FragOne Fragment
Fragment Class;
public class FragOne extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.frag_one, container, false);
return view;
}
}
Please help me in resolving this.
the way you are calling add() is wrong. The first parameter is the id of a ViewGroup that is going to host the fragment, not the layout of the fragment itself. For instance
FT.add(android.R.id.content, new FragOne());
Related
I have image in my fragment. I want click on the picture and... for example change the fragment. I have found the same topic How to setOnclick Listener to button in fragment but ClickListner does not work.
I have tried make the same code in Activity and onClickListner is work, but in the frame it does not work.
Below my code in the Fragment.
public class Fragment2 extends Fragment {
ImageView imageView;
MyListner listner;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View getview = inflater.inflate(R.layout.fragment_2, container, false);
imageView = (ImageView) getview.findViewById(R.id.imageView1);
imageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
listner.callback();
}
});
return inflater.inflate(R.layout.fragment_2, container, false);
}
Below my interface
public interface MyListner {
public void callback();}
Below my MainActivity
public class MainActivity extends AppCompatActivity implements MyListner {
Fragment2 fragment2;
Fragment1 fragment1;
ImageView imageViewMain;
ImageView imageViewFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragment2 = new Fragment2();
setContentView(R.layout.activity_main);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();//начало транзакции объекта
ft.replace(R.id.container, fragment2);
ft.addToBackStack(null);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
#Override
public void callback() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();//начало транзакции объекта
ft.replace(R.id.container, fragment1);
ft.addToBackStack(null);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}}
Please, let me know where is the problem?
It seems you are inflating your fragment's view twice. Instead of this you need to return the view which you have already inflated as a result of your onCreateView inside Fragment2.
Try changing
return inflater.inflate(R.layout.fragment_2, container, false);
to
return getview;
Problem: Having a SwipeView inside a Fragment (So when the Fragment is active you can cycle through some other fargments)
What I tried: I tried implementing it the same way you would implement it normally but in the fragment:
NORMAL WAY:
public class MainActivity extends FragmentActivity {
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewPager);
SwipeAdapter swipeAdapter = new SwipeAdapter(getSupportFragmentManager());
viewPager.setAdapter(swipeAdapter);
}
}
THE WAY I TRIED IT WITH A FRAGMENT:
public class SecondFragment extends Fragment {
ViewPager viewPager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_first, container, false);
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
viewPager = view.findViewById(R.id.VIEWPAGER);
SwipeAdapter swipeAdapter = new SwipeAdapter(getChildFragmentManager());
viewPager.setAdapter(swipeAdapter);
}
}
THE ERROR: It returns a "null object reference" when I try to set the adapter (I'm guessing it has problems with the FragmentManager)
ADAPTER FOR BOTH EXAMPLES:
public class SwipeAdapter extends FragmentStatePagerAdapter {
public SwipeAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new PageFragment();
Bundle bundle = new Bundle();
bundle.putInt("count", position+1);
fragment.setArguments(bundle);
return fragment;
}
#Override
public int getCount() {
return 5;
}
}
In the Main Activity I set up so you can switch fragments with buttons, and what I'm trying to implement in the second fragment is to be able to swipe through fragments with SwipeView
MAIN ACTIVITY CODE:
public class MainActivity extends AppCompatActivity {
Button firstFragment, secondFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
firstFragment = (Button) findViewById(R.id.firstFragment);
secondFragment = findViewById(R.id.secondFragment);
firstFragment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loadFragment(new FirstFragment());
}
});
secondFragment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loadFragment(new SecondFragment());
}
});
}
private void loadFragment(Fragment fragment) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.frameLayout, fragment);
fragmentTransaction.commit();
}
}
I don't know if this is the right way to do it, but if anyone has a way to make this work any help would be appreciated, thanks!
You cannot set the adapter because your view has not been created yet.
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_first, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewPager = view.findViewById(R.id.viewPager) as ViewPager
swipeAdapter = SwipeAdapter(childFragmentManager)
...
}
I tried the code below, but it's not working . program crushed without giving me output. How can i send data from one fragment to another fragment in same activity? First time using fragment `
//first fragment
public class FirstFragment extends Fragment implements View.OnClickListener{
public FirstFragment() {
}
Button btnSend;
EditText etTextContainer;
Bundle b;
SecondFragment fragB;
View v;
FragmentTransaction fragmentTransaction;
Fragment fragment;
SecondFragment mfragment;
String etex;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v= inflater.inflate(R.layout.fragment_first2, container, false);
btnSend=(Button)v.findViewById(R.id.btnSend);
etTextContainer=(EditText)v.findViewById(R.id.etText);
btnSend.setOnClickListener(mClickListener);
return v;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
View.OnClickListener mClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
etex = etTextContainer.getText().toString();
FragmentTransaction transection = getFragmentManager().beginTransaction();
mfragment = new SecondFragment();
//using Bundle to send data
Bundle bundle = new Bundle();
bundle.putString("key", etex);
mfragment.setArguments(bundle); //data being send to SecondFragment
transection.replace(R.id.tvShowTxt, mfragment);
transection.isAddToBackStackAllowed();
transection.addToBackStack(null);
transection.commit();
}
};
#Override
public void onClick(View view) {
}
}
// second fragment
public class SecondFragment extends Fragment {
Bundle b;
TextView tvShowText;
String s;
View v;
public SecondFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v= inflater.inflate(R.layout.fragment_second, container, false);
tvShowText = (TextView) v.findViewById(R.id.tvShowTxt);
Bundle bundle=getArguments();
tvShowText.setText(String.valueOf(bundle.getString("key")));
return v;
}
}`
It is not recommended way
All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.
Suggestion
Take activity instance from onAttach() inside fragment, and then ask Activity to communicate to another fragment.
Ref: Android Documentation
https://developer.android.com/training/basics/fragments/communicating.html#DefineInterface
In FirstFragment create Bundle like this
Bundle bundle = new Bundle();
bundle.putString("key","abc"); // Put anything what you want
SecondFragment fragment2 = new SecondFragment();
fragment2.setArguments(bundle);
getFragmentManager()
.beginTransaction()
.replace(R.id.content, fragment2)
.commit();
In SecondFragment
Bundle bundle = this.getArguments();
if(bundle != null){
// handle your code here.
}
Hope this helps you.
can anyone point me in the right direction and tell me what I'm doing wrong?
I have here a fragment with a button. When the button is pressed, it needs to replace the current fragment and load a new one. I've figured how to go from Fragment to Activity, and Activity to Fragment, just not Fragment to Fragment. I'm aware this question has been asked a few times but I'm just so new I couldn't figure it out myself.
public class FragmentName extends Fragment {
public FragmentName() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_name, container, false);
Button ID = (Button) rootView.findViewById(R.id.buttonID);
ID.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentName NAME = new FragmentName();
fragmentTransaction.replace(R.id.main_container, NAME);
fragmentTransaction.commit();
}
});
return rootView;
}
}
I think you are not initialising the FragmentManager. Without FragmentManager it is not possible to replace,update,create any fragment. Beacuse it is responsible replace or deleting any fragment. Hope this will help.
public class FragmentName extends Fragment {
public FragmentName() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_name, container, false);
Button ID = (Button) rootView.findViewById(R.id.buttonID);
ID.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FragmentName NAME = new FragmentName();
fragmentTransaction.replace(R.id.main_container, NAME);
fragmentTransaction.commit();
}
});
return rootView;
}
}
What I am trying to do is to use only one Activity as a host for many fragments such as the activity will host only one fragment at a time and the fragments should attached to the activity in a certain order.
My Fragment code:
public class FirstFragment extends Fragment{
//some code here to instantiate FirstFragment here.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main, container, false);
Button button = (Button) view.findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity) getActivity()).onFirstFragmentFinished(position);
}
});
return view;
}
// Container Activity must implement this interface
public interface FirstFragmentListener {
public void onFirstFragmentFinished(int position);
}
}
Simply, in each fragment I have a button when pressed it will get the host activity and call the implemented method of FirstFragmentListener interface.
public class MainActivity extends AppCompatActivity implements FirstFragmentListener {
#Override
public void onCreateView(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTra = fragmentManager.beginTransaction();
fragmentTra .replace(R.id.main_layout, new FirstFragment());
fragmentTra.commit();
}
#Override
public void onFirstFragmentFinished(int position)
{
if(position == 1)
{
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTra = fragmentManager.beginTransaction();
fragmentTra .replace(R.id.main_layout, new SecondFragment());
fragmentTra.commit();
}
}
}
When the activity is created, always replace whatever inside this activity with FirstFragment layout.
When the FirstFragment finishes its work and the button on that fragment is pressed, it will call the implemented method of FirstFragment interface on this activity and then check the position for some value, if the condition is correct then go and replace FirstFragment with The SecondFragment instance.
The app is crashing when commit() method is called.
Use of your onFirstFragmentFinished is wrong. Look at official doc:
android-comunication-activity-ffragment
It is prefer to Override onAttach() method.
In Fragment you need View to bind with fragment like this :
public class FirstFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main, container, false);
Button button = (Button) view.findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(position == 1){
SecondFragment secondFrag= new SecondFragment();
getActivity().getFragmentManager().beginTransaction()
.replace(R.id.main_layout, secondFrag)
.addToBackStack(null)
.commit();
}
}
});
return view;
}
}
I look at my stack trace and I found this exception:
com.example.exchange.msbexchange E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.exchange.msbexchange, PID: 17975
java.lang.RuntimeException: com.example.exchange.msbexchange.MainActivity#1e7d93b must implement OnFragmentInteractionListener
at com.example.exchange.msbexchange.CurrencyFragment.onAttach(CurrencyFragment.java:83)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1030)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1259)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1624)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6117)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
It is obviousely because my MainActivity does not implement the interface of the SecondFragment Class. I did not know this is mandatory for the fragments to work. I just need to implement the interface and now it is working.
you need implement your interface FirstFragmentListener in onAttach in fragment
FirstFragmentListener mCallback;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (FirstFragmentListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
then use it as you do on click or what ever you want
Where do you get position variable from? It seems that this variable does not have value...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main, container, false);
Button button = (Button) view.findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity) getActivity()).onFirstFragmentFinished(position);
}
});
return view;
}