Dynamically add elements to fragment - android

Hi I'm new to android and was trying to dynamically add content to a Fragment.
I've two Fragments inside an Activity. The first point to the second like this:
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_welcome,
container, false);
Button searchActivityBtn = (Button) rootView.findViewById(R.id.SearchActivityBtn);
searchActivityBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("##SecondActivity", "search btn click");
getFragmentManager().beginTransaction()
.replace(R.id.welcome_fragment, new searchAnnouncementsFragment()).addToBackStack(null).commit();
}
});
return rootView;
}
}
the second Fragment class is
public static class searchAnnouncementsFragment extends Fragment {
public searchAnnouncementsFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_search,
container, false);
return rootView;
}
//public void onStart(){
// super.onStart();
// RelativeLayout root = (RelativeLayout) getActivity().findViewById(R.id.annunciContainer);
// Log.d("##onstart", "root:" + (root == null));
//}
}
As you can see i tried to do something in onStart method but I've always a bunch of errors, the R.id.annunciContainer is the id of the fragment_search.xml layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id ="#+id/annunciContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white" >
What I'm trying to achieve is to dynamically add elements like other FrameLayout to my Fragment ( represented by the above RelativeLayout ).
Any thought?

You didn't mention the name of the activity, lets say the name as Activity1,
First create a linear layout or frame layout in the Activity1
Second add the following lines of code to your Activity1 for inflating PlaceholderFragment into your layout in Activity1
PlaceholderFragment pf = new PlaceholderFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.annunciContainer, pf,"place_holder");
ft.commit();
For inflating searchAnnouncementsFragment replace PlaceholderFragment with searchAnnouncementsFragment.

What I was searching for are ListView

Related

How can I replace fragment inside a fragment?

I have an Activity with a ViewPager, each page of the ViewPager has a Fragment.
Inside my Screen3Fragment I have a LinearLayout (lly_fragments) where I am showing some other fragments. I start by showing the fragment Screen3_1
public class Screen3Fragment extends Fragment {
private FragmentManager manager;
private FragmentTransaction transaction;
public static Screen3Fragment newInstance() {
final Screen3Fragment mf = new Screen3Fragment();
return mf;
}
public Screen3Fragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_screen3, container, false);
Screen3_1Fragment frag31 = new Screen3_1Fragment();
manager = getChildFragmentManager();
transaction = manager.beginTransaction();
transaction.add(R.id.lly_fragments,frag31,"frag31");
transaction.addToBackStack("frag31");
transaction.commit();
return v;
}
}
This works fine without problems. Problem comes when, from within frag31 (which is inside Screen3Fragment), I want to call fragt32, for that I do the following.
public class Screen3_1Fragment extends Fragment {
private ImageButton imgbt_timer;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_screen3_1,container,false);
imgbt_timer = (ImageButton) v.findViewById(R.id.bT_scr31_timer);
imgbt_timer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getChildFragmentManager().beginTransaction()
.replace(R.id.lly_fragments, new Screen3_2Fragment(), "frag32")
.commit();
}
});
return v;
}
}
As I read in other answers, the line transaction.replaceshould do the trick and replace the existing frag31 by the given frag32 inside the same given container lly_fragments.
However, I get java.lang.IllegalArgumentException: No view found for id..... I am not sure why.
getFragmentManager() will return always attributes from parent, in most cases the activities. getChildFragmentManager() wil return parent attributes (in your case, Screen3Fragment attributes). It should be used when you add a fragment inside a fragment.
In your case, Screen3Fragment should be added using getFragmentManager() and Screen3_1Fragment should be added using getChildFragmentManager() because Screen3_1Fragment is Screen3Fragment child. Screen3Fragment is the parent.
I recomand you to use always getFragmentManager() with add method, not replace because your parent will be the same.
getChildFragmentManager() can be used when you add a ViewPager inside a fragment.
You can use the callback, as following :
that worked for me, I hope my answers helps you
1) create a interface
public interface ChangeFragmentListener {
void onChangeFragmentLicked(int fragment);
}
2) implement the interface and transaction methods in your activity:
public class MainActivity extends AppCompatActivity implements ChangeFragmentListener {
FragmentTransaction fragmentTransaction;
Fragment1 fragment1;
Fragment2 fragment2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
fragment1 = new Fragment1();
fragment1.setChangeFragmentListener(this);
fragment2 = new Fragment2();
fragment2.setChangeFragmentListener(this);
initListeners();
}
void changeToFrag1() {
fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.activity_main_fragment_container,fragment1, "");
fragmentTransaction.commit();
}
void changeToFrag2() {
fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.activity_main_fragment_container, fragment2, "");
fragmentTransaction.commit();
}
#Override
public void onChangeFragmentLicked(int fragment) {
switch (fragment){
case 1:
changeToFrag1();
break;
case 2:
changeToFrag2();
break;
}
}
3) Create object from the interface to handle the callback:
public class Fragment1 extends Fragment {
private ChangeFragmentListener changeFragmentListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_fragment1, container, false);
view.findViewById(R.id.fragment1_textView).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
changeFragmentListener.onChangeFragmentLicked(2);
}
});
return view;
}
public Fragment1 setChangeFragmentListener(ChangeFragmentListener changeFragmentListener) {
this.changeFragmentListener = changeFragmentListener;
return this;
}
}

Android - set button text from Fragment in Activity

I created new project with Navigation Drawer Activity template in Android Studio 2.2.2. I decided to use FrameLayout, so as i click on navigation menu item, new fragment loads.
In my content_main.xml i have FrameLayout element like this:
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
That is Frame where the content will be shown.
Then i have layout fragment_one.xml and its class FragmentOne and they look like this:
fragment_one.xml
<Button
android:text="Default Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/mybutton" />
FragmentOne class
public class FragmentOne extends Fragment {
Button btn;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, container, false);
btn = (Button) view.findViewById(R.id.mybutton);
return view;
}
public void changeBtnText(String txt)
{
btn.setText(txt);
}
}
In MainActivity's onCreate() method i have code:
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.content_frame, new FragmentOne()).commit();
FragmentOne fragment_obj = (FragmentOne)getSupportFragmentManager().
findFragmentById(R.id.frOne);
fragment_obj.changeBtnText("Changed text");
Here i get error:
Attempt to invoke virtual method 'void com.example.user.myapplication.FragmentOne.changeBtnText(java.lang.String)' on a null object reference
How I can change fragment's Button text from Main Activity by using changeBtnText(String txt) method?
Call changeBtnText(String txt) inside fragment not in the activity.
EDIT:
inside FragmentOne.class
public FragmentOne newInstance(String text) {
FragmentOne fragmentOne = new FragmentOne ();
Bundle args = new Bundle();
args.putInt("text", text);
fragmentOne .setArguments(args);
return fragmentOne ;
}
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, container, false);
btn = (Button) view.findViewById(R.id.mybutton);
String text = getArguments().getString("text", null);
changeBtnText(text);
return view;
}
in the Activity
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.content_frame, FragmentOne.newInstance("text")).commit();
You haven't created the Fragment, which is why it's null. You create a new one in line but don't save it.
Try this;
FragmentOne fragment_obj = new FragmentOne();
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.content_frame, fragmentOne).commit();
fragment_obj.changeBtnText("Changed text");

How to use shared element transition between FirstFragment (including RecyclerView) and SecondFragment

I could implement shared element transition between two fragments WITHOUT RECYCLERVIEW!!!
This is FirstFragment:
public class FirstFragment extends Fragment {
ImageView img_small;
LinearLayout layout_ofc_cities;
LinearLayout layout;
public FirstFragment() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_first, container, false);
img_small = (ImageView) view.findViewById(R.id.img_small);
layout_ofc_cities = (LinearLayout) view.findViewById(R.id.layout_ofc_cities);
layout = (LinearLayout) view.findViewById(R.id.layout);
layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_trans));
setExitTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.fade));
SecondFragment secondFragment = new SecondFragment();
secondFragment.setSharedElementEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_trans));
secondFragment.setEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.fade));
FragmentTransaction ft = getFragmentManager().beginTransaction()
.replace(R.id.container, secondFragment)
.addToBackStack(null)
.addSharedElement(layout_ofc_cities, "transitionTxt")
.addSharedElement(img_small, "transitionImg");
ft.commit();
}
}
});
return view;
}
}
and this is SecondFragment:
public class SecondFragment extends Fragment {
public SecondFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_second, container, false);
return view;
}
}
And it works!
but when I implements a RecyclerView in FirstFragment to use SharedElementTransition for a LinearLayout and an ImageView of RecyclerView to a LinearLayout and an ImageView in SecondFragment it doesn't work.
I want a sample code with two Fragments that the first one has RecyclerView in it, with animation between their shared elements. Can anyone help me?
I found the answer:
the solution is on this page:
http://jemsdevmobile.com/2016/02/11/lollipop-transition-between-activities/
just you need to change xml tags. for example change "imageview" to "ImageView"

Load view from fragment when the fragment loaded

I have button to go to (load) this new fragment
buttonToFragment1.setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View arg0) {
// return inflater.inflate( R.layout.fragment_one, container, false);
Fragment fr = new FragmentOne();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_awal, fr);
fragmentTransaction.commit();
}
}
);
the current fragment (R.id.fragment_awal) now replaced with loaded new fragment (R.id.fragment_one) which has layout (fragment_one.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"
android:background="#00c4ff">
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Ini fragment 1"
android:textStyle="bold" />
</LinearLayout>
and the class is :
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
//Inflate the layout for this fragment
return inflater.inflate( R.layout.fragment_one, container, false);
}
}
My question is how to load this TextView1 so that I can do such :
TextView textFragment = (TextView)findViewById(R.id.textView1);
textFragment.setText(" new text");
which basically set text to a view inside the new loaded fragment.
EDIT : May I know who answered this question earlier??? basically he did answered this correct, I just somehow so confused. He just deleted the answer. I want to accept his answer.
Fragments are essentially view containers that contain a hierarchy of views. When a fragment is inserted into the view hierarchy, it must have an activity as its root. There can be more 0 or more fragments active at any given time.
In loose words, you're replacing the current view with the view of another fragment (FragmentOne).
To access the TextView with id textView1, you need to qualify the findViewById method with the current view of the fragment.
Change your fragment code to:
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
//Inflate the layout for this fragment
View view = inflater.inflate( R.layout.fragment_one, container, false);
// The findViewById method returns child views from either a Context,
// an Activity or another View itself.
TextView textFragment = (TextView) view.findViewById(R.id.textView1);
textFragment.setText(" new text");
return view;
}
}
You need to inflate the layout and after that you can reference the TextView:
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
//Inflate the layout for this fragment
View view = inflater.inflate( R.layout.fragment_one, container, false);
TextView textFragment = (TextView) view.findViewById(R.id.textView1);
textFragment.setText(" new text");
return view;
}

Moving from one nest fragment to another

I'm new to Android and I'm playing with Fragments, I know that there exist many examples to learn how Fragments work, unfortunately there is not many examples using Nested-Fragments (which are in the same Activity).
This is my code below, ive encountered 2 problems:
The Root Fragment is visible after I add the secondary Fragment.
both Fragment use same design, but when I add the FragmentIi can see the dimensions of the widgets and the position on the screen are not the same.
I Need some feedback how to do it right.
Thank you!
public class LoginActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_login,
container, false);
TextView tv = (TextView) rootView.findViewById(R.id.signUpText1);
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
FragmentTransaction ft = getFragmentManager()
.beginTransaction();
ft.replace(R.id.loginViewPlaceholder, new SignupFragment());
ft.commit();
}
});
return rootView;
}
}
public static class SignupFragment extends Fragment {
public SignupFragment() {
// TODO Auto-generated constructor stub
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View signupView = inflater.inflate(R.layout.fragment_signup,
container, false);
return signupView;
}
}
}
The replace method will remove a fragment from the specified container and add the new one its place. In your example, it looks like you are adding the PlaceholderFragment to the container android.R.content and the SignupFragment to the container R.id.loginViewPlaceholder. If you want the SignupFragment to replace the PlaceholderFragment you will have to either use the same container for both, or you will have to do separate remove() and add() calls for your transaction.

Categories

Resources