Hello i am new to fragments.. I have one main activity and two fragments in it. if i enter data in first fragment's editText , it is displayed on second Fragment's TextView.. If i enter the data and press submit button repeatedly, the data is changing in second fragment too.. but when i press back button, the application get closed. I want to display data that was previously entered by me in fragment when i press the back button
Here is the code:
FirstFragment extends Fragment {
private OnFragmentInteractionListener mListener;
private EditText inputName;
private EditText inputPhone;
private String userName;
private String userPhone;
public FirstFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_first, container, false);
inputName = (EditText) view.findViewById(R.id.edit_text_name);
inputPhone = (EditText) view.findViewById(R.id.edit_text_phone);
TextView submit = (TextView) view.findViewById(R.id.submit);
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (inputName.getText().toString().equals("")) {
Toast.makeText(getActivity(), "Name must be filled", Toast.LENGTH_LONG).show();
return;
}
else if(inputPhone.getText().toString().equals("")){
Toast.makeText(getActivity(),"please enter the phone number" , Toast.LENGTH_SHORT).show();
return;
}
userName = inputName.getText().toString();
userPhone = inputPhone.getText().toString();
onButtonPressed(userName, userPhone);
inputName.setText("");
inputPhone.setText("");
}
});
return view;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(String nameContent, String phoneContent) {
if (mListener != null) {
mListener.onFragmentInteraction(nameContent, phoneContent);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(String nameContent, String phoneContent);
}
}
SecondFragment extends Fragment {
//private OnFragmentInteractionListener mListener;
private TextView updateName;
private TextView updatePhone;
public SecondFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_second, container, false);
updateName = (TextView)view.findViewById(R.id.text_view_name);
updatePhone = (TextView)view.findViewById(R.id.text_view_phone);
return view;
}
public void updateTextField(String name, String phone){
updateName.setText(name);
updatePhone.setText(phone);
}
}
MainActivity extends AppCompatActivity implements FirstFragment.OnFragmentInteractionListener{
private FragmentActivity activity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onFragmentInteraction(String nameContent, String phoneContent) {
SecondFragment secondFragment = (SecondFragment)getSupportFragmentManager().findFragmentById(R.id.fragment_show);
secondFragment.updateTextField(nameContent, phoneContent);
}
public FragmentActivity getActivity() {
return activity;
}
}
**fragment_first.xml**
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.seasiainfotech.singhjasmeet.passinfragments.views.MainActivity">
<EditText
android:id="#+id/edit_text_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/enter_name"
android:inputType="text"
android:paddingEnd="5dp"
android:paddingStart="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintLeft_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.050" />
<EditText
android:id="#+id/edit_text_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/enter_phone"
app:layout_constraintTop_toBottomOf="#+id/edit_text_name"
android:inputType="phone"
android:paddingTop="25dp"
android:paddingStart="5dp"
android:paddingEnd="5dp"/>
<TextView
android:id="#+id/submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/edit_text_phone"
android:layout_marginTop="50dp"
android:padding="7dp"
android:text="#string/sbmt"
android:textSize="20sp"
android:textColor="#color/colorAccent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="#drawable/button_stroke"/>
</android.support.constraint.ConstraintLayout>
**fragment_Second.xml**
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.seasiainfotech.singhjasmeet.passinfragments.views.MainActivity">
<TextView
android:id="#+id/text_view_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textSize="30sp"
android:textColor="#color/colorPrimaryDark"/>
<TextView
android:id="#+id/text_view_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/text_view_name"
android:textSize="20sp"
android:padding="8dp"
android:textColor="#color/colorPrimary"/>
</android.support.constraint.ConstraintLayout>
activity_main.xml
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.seasiainfotech.singhjasmeet.passinfragments.views.MainActivity">
<fragment
android:id="#+id/fragment_input"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:name="com.seasiainfotech.singhjasmeet.passinfragments.fragments.FirstFragment"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<fragment
android:id="#+id/fragment_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:name="com.seasiainfotech.singhjasmeet.passinfragments.fragments.SecondFragment"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="#+id/fragment_input"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Override "onBackPressed" method in MainActivity
#Override
public void onBackPressed()
{
if(want_to_close_the_app){
//call super
super.onBackPressed();
}
else{
// dont call super
}
}
Give your fragments tags while adding them. Ex. Tag for FirstFragment is "firstFragment" and tag for SecondFragment is "secondFragment". Take a common String variable called current fragment in your activity and change it while adding fragment.
public class MainActivity extends Activity{
public static String currentFragment = null;
//while adding first fragment
currentFragment = "firstFragment";
//while adding second fragment
currentFragment = "firstFragment";
}
Now override onBackPressed in your activity as below.
#Override
public void onBackPressed() {
if(currentFragment.equals("secondFragment"){
//load first fragment
}else{
super.onBackPressed();
}
}
override onBackPressed method.
#Override
public void onBackPressed()
{
super.onBackPressed();// remove this line
...
//enter your code here.
}
and add this code.
getSupportFragmentManger().
beginTransaction().
replace().
addToBackStack().
.commit();
Related
I want to use an expandableRecyler but when i use the adapter it doesnt work. It doesnt give me any error or anything. just doesnt appear on the screen
I have this Fragment where i call the recyclerView
public class RecFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
Button btaddrec;
Dialog alerta;
View v;
RecyclerView rvRec;
public RecFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment RecFragment.
*/
// TODO: Rename and change types and number of parameters
public static RecFragment newInstance(String param1, String param2) {
RecFragment fragment = new RecFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v = inflater.inflate(R.layout.fragment_rec, container, false);
rvRec = v.findViewById(R.id.recyclerviewRec);
btaddrec = (Button) v.findViewById(R.id.btaddRec);
initData();
setRecycler();
btaddrec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getContext(), MainActivity.listarec.size() + "", Toast.LENGTH_SHORT).show();
}
});
return v;
}
private void setRecycler(){
RecyclerRec recyclerRec = new RecyclerRec(MainActivity.listarec);
rvRec.setLayoutManager(new LinearLayoutManager(getActivity()));
rvRec.setAdapter(recyclerRec);
rvRec.setHasFixedSize(true);
}
private void initData(){
MainActivity.listarec.add(new Recordatorio("Homework","Math and Science Homewowk","14:00"));
MainActivity.listarec.add(new Recordatorio("Homework","Math and Science Homewowk","14:00"));
}
}
Function initData add some objects to my list (i have checked that it works with the Button, my list has 2 items)
Function setRecycler set the adapter for the recyclerview
This is my class RecyclerRec
public class RecyclerRec extends RecyclerView.Adapter<RecyclerRec.RecVh>{
ArrayList<Recordatorio> listarec;
public RecyclerRec (ArrayList<Recordatorio> lista){
this.listarec = lista;
}
#NonNull
#Override
public RecVh onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rec_layout,parent,false);
return new RecVh(v);
}
#Override
public void onBindViewHolder(#NonNull RecVh holder, int position) {
Recordatorio rec = listarec.get(position);
holder.tvTitulo.setText(rec.getTitulo());
holder.tvCuerpo.setText(rec.getCuerpo());
holder.tvHora.setText(rec.getHora());
boolean expanded = rec.isExpanded();
holder.expandable.setVisibility(expanded ? View.VISIBLE : View.GONE);
}
#Override
public int getItemCount() {
return listarec.size();
}
public class RecVh extends RecyclerView.ViewHolder {
TextView tvTitulo,tvCuerpo,tvHora;
LinearLayout linearLayout;
ConstraintLayout expandable;
public RecVh(#NonNull View itemView) {
super(itemView);
tvTitulo = itemView.findViewById(R.id.tvTituloRec);
tvCuerpo = itemView.findViewById(R.id.tvCuerpo);
tvHora = itemView.findViewById(R.id.tvHoraRec);
linearLayout = itemView.findViewById(R.id.linearlayotuexpand);
expandable = itemView.findViewById(R.id.expandableRec);
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Recordatorio rec = listarec.get(getAdapterPosition());
rec.setExpanded(!rec.isExpanded());
notifyItemChanged(getAdapterPosition());
}
});
}
}
}
XML of fragment
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragments.ClasesFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerviewRec"
android:layout_width="match_parent"
android:layout_height="451dp"
android:layout_marginTop="50dp" />
<Button
android:id="#+id/btaddRec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="160dp"
android:layout_marginTop="520dp"
android:text="Añadir" />
(Framelayout tag is closed correctly, dunno why stackoverflow doesnt write it with ctrl+k)
XML of my item/row
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/tvTituloRec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:padding="10dp"
android:text="Titulo Recordatorio"
android:textAppearance="#style/TextAppearance.AppCompat.Medium"
android:textColor="#android:color/black"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/tvHoraRec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hora"
android:textSize="17dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/expandableRec"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tvTituloRec">
<TextView
android:id="#+id/tvCuerpo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:text="Cuerpo del recordatorio"
android:textAppearance="#style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toEndOf="#+id/textView"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
All seems to be in order but when i run the app it doesnt appear and doesnt give me any error.
As the picture show the DialogFragment It´s all white except for the Buttons. I have tried all kinds of layout parrams and ConstraintLayout settings but the white background feels like it´s some z-order thing,
Please advice
This is what the ANdroid Studio layout editor look likes
My xml:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:srcCompat="http://schemas.android.com/tools"
android:id="#+id/place_search_dialog"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="vertical"
android:visibility="visible">
<ImageView
android:id="#+id/place_search_dialog_header_image_IV"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:contentDescription=""
android:scaleType="centerCrop"
app:layout_constraintBottom_toTopOf="#+id/guideline478"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
srcCompat:src="#drawable/place_picker_dialog_nobackground"/>
<Button
android:id="#+id/btn_place_dialog_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:padding="10dp"
android:text="#string/cancel"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/btn_place_dialog_ok"/>
<Button
android:id="#+id/btn_place_dialog_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:padding="10dp"
android:text="#string/ok"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/btn_place_dialog_cancel"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"/>
<android.support.constraint.Guideline
android:id="#+id/guideline355"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.66"/>
<ImageView
android:id="#+id/imageView_street"
android:layout_width="74dp"
android:layout_height="48dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="#+id/btn_place_dialog_cancel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.348"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/place_search_dialog_header_image_IV"
app:layout_constraintVertical_bias="0.581"
app:srcCompat="#drawable/avatar"/>
<android.support.constraint.Guideline
android:id="#+id/guideline478"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.28"/>
</android.support.constraint.ConstraintLayout>
UPDATE
This is the DialogFragment
public class GooglePlaceDetailsDialogFragment extends DialogFragment {
private View mRootView;
private BasePlace place;
private Unbinder unbinder;
RequestResponse requestResponse;
private PlaceDetails placeDetails;
public interface ShowPlaceListener {
void onShowPlace(BasePlace item);
}
private ShowPlaceListener mShowPlaceListener;
public static GooglePlaceDetailsDialogFragment newInstance(BasePlace item) {
GooglePlaceDetailsDialogFragment fragment = new GooglePlaceDetailsDialogFragment();
fragment.setPlace(item);
return fragment;
}
// Called to do initial creation of a fragment. This is called after onAttach and before onCreateView
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
mShowPlaceListener = (ShowPlaceListener) getTargetFragment();
} catch (ClassCastException e) {
throw new ClassCastException("Calling fragment must implement Callback ShowPlaceListener");
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.dialog_fragment_show_google_place_details, container);
ImageView imageViewStreet = mRootView.findViewById(R.id.imageView_street);
// Just unpack the details to make it smoother
this.requestResponse = place.requestResponse;
this.placeDetails = place.requestResponse.placeDetails;
unbinder = ButterKnife.bind(this, mRootView);
getDialog().setTitle("lkjkjlkj ");
if (placeDetails.url.equals("")) {
if (LogManager.isDebugable()) {
Picasso.with(getActivity()).setIndicatorsEnabled(true);
}
Picasso.with(getActivity())
.load(R.drawable.anon_user_48dp)
.transform(new CircleTransformation())
.into(imageViewStreet);
} else {
if (LogManager.isDebugable()) {
Picasso.with(getActivity()).setIndicatorsEnabled(true);
}
Picasso.with(getActivity())
.load(placeDetails.url)
.transform(new CircleTransformation())
.into(imageViewStreet);
}
return mRootView;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onResume() {
super.onResume();
}
#OnClick(R.id.btn_place_dialog_ok)
public void onSearchClicked() {
if (mShowPlaceListener != null) {
mShowPlaceListener.onShowPlace(place);
}
dismiss();
}
#OnClick(R.id.btn_place_dialog_cancel)
public void onCancelClicked() {
dismiss();
}
private void setPlace(BasePlace place) {
this.place = place;
}
#Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
This is the creation
GooglePlaceDetailsDialogFragment dialog = GooglePlaceDetailsDialogFragment.newInstance(item);
dialog.setTargetFragment(this, 0);
DialogUtils.showDialogFragment(getFragmentManager(), dialog);
Util..
public class DialogUtils {
private static String showDialogFragment(FragmentManager fragmentManager, DialogFragment dialogFragment,
String fragmentTag, boolean onlyIfNotDuplicate) {
// If only showing non duplicates dialogs, make sure the fragment isn't already in the manager
boolean doesFragmentExist = fragmentManager.findFragmentByTag(fragmentTag) != null;
if (!(onlyIfNotDuplicate && doesFragmentExist)) {
dialogFragment.show(fragmentManager, fragmentTag);
}
return fragmentTag;
}
public static String showDialogFragment(FragmentManager fragmentManager, DialogFragment dialogFragment,
boolean onlyIfNotDuplicate) {
return showDialogFragment(fragmentManager, dialogFragment, generateFragmentTag(dialogFragment), onlyIfNotDuplicate);
}
private static String showDialogFragment(FragmentManager fragmentManager, DialogFragment dialogFragment,
String fragmentTag) {
return showDialogFragment(fragmentManager, dialogFragment, fragmentTag, true);
}
public static String showDialogFragment(FragmentManager fragmentManager, DialogFragment dialogFragment) {
return showDialogFragment(fragmentManager, dialogFragment, generateFragmentTag(dialogFragment));
}
private static String generateFragmentTag(Fragment fragment) {
return fragment.getClass().getName();
}
}
ok when I replace the srcCompat:src= with app:srcCompat=` the images show, Strange that AS did not complain abut this typo
I am trying to change the fragment when I click on a button. The button is inside a fragment and I want to go to another fragment. This code is not giving any error but not changing to desired fragment. It is just showing the background of container. Please help me why it is just showing the color of container and not changing to new fragment.
Here is my first Fragment-
public class IntroFragment1 extends Fragment {
public IntroFragment1() {
// Required empty public constructor
}
public static IntroFragment1 newInstance() {
return new IntroFragment1();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_intro1, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
/**
* Button to go to next tab in tutorial
* */
Button nextScreen = getView().findViewById(R.id.nextTabButtonIntro);
nextScreen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (vb1 != null) {
vb1.vibrate(300);
}
FragmentTransaction transaction = getFragmentManager().beginTransaction();
Fragment frag = IntroFragment2.newInstance();
transaction.replace(R.id.containerIntroScreen, frag);
transaction.commit();
}
});
}//End of onViewCreated
}
This is the XML of first Fragment. The next Button should take me to next fragment-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimaryDark"
android:orientation="vertical"
android:weightSum="1"
tools:context="com.example.fitbitsampleapp.AppIntroTabbedView.IntroFragment1">
<TextView
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="casual"
android:text="Track your daily activities. Stay healthy, Stay smart."
android:textSize="26dp" />
<Button
android:id="#+id/skipIntoButton"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:background="#drawable/background_button"
android:fontFamily="casual"
android:text="skip"
android:textAllCaps="true"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Large"
android:textColor="#000" />
<Button
android:id="#+id/nextTabButtonIntro"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:layout_weight="1"
android:background="#drawable/background_button"
android:fontFamily="casual"
android:text="next"
android:textAllCaps="true"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Large"
android:textColor="#000" />
</LinearLayout>
This is the fragment, I want to go to-
public class IntroFragment2 extends Fragment {
public IntroFragment2() {
// Required empty public constructor
}
public static android.support.v4.app.Fragment newInstance() {
IntroFragment2 fragment = new IntroFragment2();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_intro2, container, false);
}
The XML of the 2nd Fragment-
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorAccent"
tools:context="com.example.fitbitsampleapp.AppIntroTabbedView.IntroFragment2">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:text="2nd fragment" />
</RelativeLayout>
This is the layout of activity which has the fragments-
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.fitbitsampleapp.AppIntroTabbedView.IntroScreen">
<android.support.v4.view.ViewPager
android:background="#00F111"
android:id="#+id/containerIntroScreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
So initially the app opens with 1st transaction as expected. However when I click on next button in fragment 1, it should take me to fragment 2. But it just shows the Background color of ViewPager after the Fragment Transaction.
EDIT:
Here is my Main Activity as well which has the fragments-
public class IntroScreen extends AppCompatActivity {
public static Vibrator vb1;
public Button nextScreen;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intro_screen);
/***/
vb1 = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
/**
* Create the adapter that will return a fragment
* for each of the N primary sections of the activity.
* */
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
/** Set up the ViewPager with the sections adapter.*/
ViewPager mViewPager = findViewById(R.id.containerIntroScreen);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
switch (position) {
case 0:
return IntroFragment1.newInstance();
case 1:
return IntroFragment2.newInstance();
default:
return IntroFragment2.newInstance();
}
}
#Override
public int getCount() {
return 2;
}
}
}
SOLVED BY #MikeM. in the comments above.
Since I was already using a ViewPager, All that was required was to give the correct item number to my ViewPager.
int THE_POSITION_OF_THE_FRAGMENT_IN_VIEW_PAGER = 1;
mViewPager.setCurrentItem(THE_POSITION_OF_THE_FRAGMENT_IN_VIEW_PAGER);
I have an activity that holds a fragment, it adds it by doing this in the onCreate (From a Google example):
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
// Create a new Fragment to be placed in the activity layout
RecordFragment firstFragment = new RecordFragment();
// In case this activity was started with special instructions from an
// Intent, pass the Intent's extras to the fragment as arguments
firstFragment.setArguments(getIntent().getExtras());
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
This is the activity layout:
<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" />
This is the Fragment:
public class RecordFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_record, container, false);
}
And the fragment_record.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.controlcenter.RecordActivity$PlaceholderFragment" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Information:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<EditText
android:id="#+id/action_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10" />
<ImageView
android:id="#+id/arrow_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/ic_action_forward" />
</LinearLayout>
In the fragment there is a arrow button. I want the activity to add a listener to the button so when it is clicked the fragment will slide out and another fragment will slide in.
Im having trouble accessing that button, I'm trying to use
firstFragment.getView().findViewById(R.id.arrow_button)
But it appears getView is returning null although I overload the onCreateView() method.
The simple answer is that you don't. Treat the Fragment's view as something that's internal to the fragment. Instead, set the activity as a listener to the Fragment via an interface you define and then set the click listener in the fragment to call the fragment's listener.
public class MyFragment extends Fragment {
public interface MyListener {
public void onAction();
}
private MyListener mListener;
public void setListener(MyListener listener) {
mListener = listener;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_record, container, false);
root.findViewById(R.id.arrow_button).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if (mListener != null) {
mListener.onAction();
}
}
});
return root;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof MyListener) {
mListener = (MyListener) activity;
} else {
// Maybe throw an exception if you want to be strict
}
}
}
And your Activity class would need this:
public class MyActivity extends Activity implements MyFragment.MyListener {
public void onAction() {
// TODO whatever you need to do when the button is clicked
}
}
I am trying to do a very basic example with Fragments.
Structure : Fragment1 -> Fragment1Activity, Fragment2 -> Fragment2Activity.
Both activities have a STATIC Fragment in it.
Here are the XMLs:
activity_for_fragment_1.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.xx.fragmentstutorial1.Fragment1"
tools:context="com.xx.fragmentstutorial1.Fragment1Activity"/>
fragment1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textview_fragment_1"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="0.60"
android:text="This is Fragment 1"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="#+id/edittext_fragment_1_text"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="0.20"
android:text="Type your message here..." >
<requestFocus />
</EditText>
<Button
android:id="#+id/button_fragment_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Click Me" />
</LinearLayout>
activity_for_fragment_2.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment_2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.xx.fragmentstutorial1.Fragment2"
tools:context="com.xx.fragmentstutorial1.Fragment2Activity"/>
fragment_2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textview_fragment_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="This is Fragment 2"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textview_fragment_2_result"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="I will display text from \nFragment 1"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
Now, I have an Edittext and button in the fragment_1. When I click on the button, I want to get the text entered in EditText and set it to the textview(textview_fragment_2_result) in fragment_2
I was able to achieve this, but, I am not very convinced, that the approach I took was good enough. Please look at the java code below..
Fragment1Activity.java
public class Fragment1Activity extends SherlockFragmentActivity implements Fragment1.ButtonClickListener{
Fragment1 fragment1;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_for_fragment_1);
System.out.println("onCreate Fragment1Activity");
fragment1 = (Fragment1) getSupportFragmentManager().findFragmentById(R.id.fragment_1);
}
#Override
public void onButtonClick(String message) {
System.out.println("onButtonClick Fragment1Activity");
startActivity(new Intent(this, Fragment2Activity.class).putExtra("message", message));
}
}
Fragment1.java
public class Fragment1 extends SherlockFragment {
EditText message;
Button clickme;
ButtonClickListener listener;
public interface ButtonClickListener{
public void onButtonClick(String message);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof ButtonClickListener)
listener = (ButtonClickListener) activity;
else {
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
System.out.println("onCreateView Fragment1");
View view = inflater.inflate(R.layout.fragment_1, container, false);
message = (EditText) view.findViewById(R.id.edittext_fragment_1_text);
clickme = (Button) view.findViewById(R.id.button_fragment_1);
clickme.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (!message.getText().toString().equalsIgnoreCase("")) {
System.out.println("Message in Fragment1 = "+message.getText().toString());
listener.onButtonClick(message.getText().toString());
} else {
Toast.makeText(getActivity(),
"Please enter some message...", Toast.LENGTH_LONG)
.show();
}
}
});
return view;
}
}
Fragment2Activity.java
public class Fragment2Activity extends SherlockFragmentActivity {
Fragment2 fragment2;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_for_fragment_2);
fragment2 = (Fragment2) getSupportFragmentManager().findFragmentById(R.id.fragment_2);
fragment2.setMessage(getIntent().getExtras().getString("message").toString());
}
}
Fragment2.java
public class Fragment2 extends SherlockFragment {
String msg;
TextView textview;
public Fragment2() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_2, container, false);
textview = (TextView) view
.findViewById(R.id.textview_fragment_2_result);
textview.setText(msg);
return view;
}
public void setMessage(String message) {
msg = message;
textview.setText(msg);
}
}
I have set the text for textview in setMessage() of Fragment2.java, which I think is not a good approach. If i comment that out, I don't see any text in the textview of Fragment2.
Can someone help me out, on how to pass values between two static fragments correctly.
You should go with interface
Follow the Diagram Here :
Communication Between Two Fragment is Done Via Activity using Interface
Fragment A-------------------------->Activity-------------------->Fragment B
(defines Interface) (Implement interface) (pass it other Fragment B)
Hope this could help
Check This Out
What you have is mostly good. The part of transferring the data from Fragment1 to Activity1 is good. Once the data gets to Activity2, you are setting it in Fragment2. I would change this part a little.
In Activity2:
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_for_fragment_2);
fragment2 = (Fragment2) getSupportFragmentManager().findFragmentById(R.id.fragment_2);
fragment2.setArguments(getIntent().getExtras());
}
and in Fragment2.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle bundle = getArguments();
String message = bundle.getString("message");
View view = inflater.inflate(R.layout.fragment_2, container, false);
textview = (TextView) view
.findViewById(R.id.textview_fragment_2_result);
textview.setText(message);
return view;
}
Your approach seems correct. The connection between your Fragment1 and Activity1 is just like in the fragments guideline. Your fragment1 shouldn't know about fragment2 therefore it's OK to pass the responsibility to the fragment's container/parent - activity1 - that knows what to do with the data. This time again your approach is correct - activity1 starts it's slave/child etc. and is responsible to start it with correct data (passed through the intent extras). And then again you have a correct approach - when your activity2 is created you populate it's views with the appropriate content/data (the message) that was meant to be displayed in this activity and given to it by the "parent" activity.