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;
}
}
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;
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.
I want to open a fragment from my activity, but when I do both the Activity layout and fragment layout is inflated, I only want the fragment layout to display. Why is this?
Activity Code:
public class Login extends Activity {
public static String res="";
private EditText login_username,login_pass;
private TextView test_login;
private SharedPreferences sp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
Button btn_login = (Button) findViewById(R.id.btnLogin);
btn_login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
login(login_username.getText().toString(),login_pass.getText().toString());
}
});
private void login(final String user,String pass){
new Login_Server("http://192.168.1.100/test/index.php/client_users/Login",user,pass).execute();
final ProgressDialog pd=new ProgressDialog(Login.this);
pd.setMessage("Please Wait...");
pd.show();
final Timer tm=new Timer();
tm.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (res.equals("login")) {
Index index = new Index();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(android.R.id.content, index); // give your fragment container id in first parameter
transaction.addToBackStack(null); // if written, this transaction will be added to backstack
transaction.commit();
tm.cancel();
res = "";
}
}
});
}
}, 1, 1500);
}
Fragment code:
public class Index extends Fragment implements View.OnClickListener {
private Button Index,Share;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.index, container, false);
Index=(Button)rootview.findViewById(R.id.index_page);
Share=(Button)rootview.findViewById(R.id.share_page);
btn_click();
return rootview;
}
public void btn_click(){
Index.setOnClickListener(this);
Share.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.share_page:
Share share_page = new Share();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(android.R.id.content, share_page); // give your fragment container id in first parameter
transaction.addToBackStack(null); // if written, this transaction will be added to backstack
transaction.commit();
break;
}
}
}
xml layout fragment:
<LinearLayout
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:weightSum="100">
<include layout="#layout/main_index"></include>
<include layout="#layout/bottom_menu"></include>
</LinearLayout>
On your login activity
setContentView(R.layout.login);
inflates the activity layout
and on your fragment
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.index, container, false);
Index=(Button)rootview.findViewById(R.id.index_page);
Share=(Button)rootview.findViewById(R.id.share_page);
btn_click();
return rootview;
}
inflates the fragment's layout
therefor you inflate 2 layouts
anyway if u wish to use the fragment layout allover the activity screen
u should change the activity layout to host a container with an ID
like in your code on the activity u have this line:
transaction.replace(android.R.id.content, index);
you should just have a view on the activity layout with the id=content and make it match_parent on height and width
this one should be the parent of all the other childs on the layout
that way the fragment will cover all of the activity layout when u replace the container
gl..
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;
}
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());