I'm am trying to add dynamycally multiple fragments I'm creating to a framelayout, using FragmentTransaction's add() method. Each time I try to do it, Fragments are just replacing one an other.
Here is my code :
public class FragmentMerchandSearch extends Fragment {
public FragmentMerchandSearch() {
// 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_merchand_search, container, false);
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
for(int i = 0; i < 10; i++){
Fragment newFragment = new FragmentMerchandPresentation();
ft.add(R.id.container_merchand_presentation_for_search, newFragment);
}
ft.commit();
return view;
}
}
Here is the code of FragmentMerchandPresentation:
public class FragmentMerchandPresentation extends Fragment {
public FragmentMerchandPresentation(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_presentation_merchand, container, false);
return view;
}
}
Here is XML of fragment_merchand_search:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/container_merchand_presentation_for_search">
</FrameLayout>
</LinearLayout>
</ScrollView>
And XML of fragment_presentation_merchand:
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hey !"/>
</LinearLayout>
You are adding your fragments inside a FrameLayout, this means one is above another.
To add them vertically, use a LinearLayout as a container.
Just change your fragment_merchand_search.xml to:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/container_merchand_presentation_for_search"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</ScrollView>
Just change this line:
ft.add(R.id.container_merchand_presentation_for_search, newFragment);
to this:
ft.replace(R.id.container_merchand_presentation_for_search, newFragment);
Related
Can't get rid of this problem. I saw a couple other questions with a similar problem, but nothing fixed it.
Short story: I replace my placeholders with fragments in my MainActivty and would like to call a public method from that new fragment. But calling the fragment from his Tag, leads to a "Null object reference" error.
I tried multiple ways to set and call the Tag but without success
Main.xml
<?xml version="1.0" encoding="utf-8"?>
<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:id="#+id/mainActivity"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:menu="#menu/quick_settings"
tools:context="....">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/scrollView">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/fragment1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
<LinearLayout
android:id="#+id/fragment2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
<LinearLayout
android:id="#+id/fragment3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
...
Main.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_annual_service);
createList();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void createList() {
Resources r = getResources();
String packageName = getPackageName();
//Array with all Fragments
fragmentList = new Fragment[]{
new FragmentA,
new FragmentB,
new FragmentC,
...
};
numberOfFragments = fragmentList.length;
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
for (int arrayIndex=0, fragmentNumber=1; fragmentNumber <= numberOfFragments; arrayIndex++, fragmentNumber++){
fragmentTransaction.replace(r.getIdentifier("fragment" + fragmentNumber, "id", packageName), fragmentList[arrayIndex], "fragment0"+fragmentNumber); // also try to set the TagName
}
fragmentTransaction.commit();
fragmentManager.executePendingTransactions();
((Unfold)fragmentManager.findFragmentByTag("fragment01")).unfold(); // Method is implemented by a interface
FragmentA.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/FragmentA"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingEnd="20dp"
android:paddingStart="45dp"
android:visibility="gone">
...
</LinearLayout>
FragmentA.java
Button backBtn;
TextView header;
LinearLayout llayout;
Drawable defaulBG;
View view;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return setListener(inflater, container);
}
private View setListener(LayoutInflater inflater, ViewGroup container){
view = inflater.inflate(R.layout.fragment_general_information, container, false);
header = (TextView) view.findViewById(R.id.generalInformationHeaderText);
header.setOnClickListener(this);
llayout = (LinearLayout) view.findViewById(R.id.content);
defaulBG = inForkliftBtn.getBackground();
backBtn = (Button) view.findViewById(R.id.backBtn);
setRetainInstance(true);
return view;
}
public void unfold(){
if(llayout.getVisibility() == View.GONE){
llayout.setVisibility(View.VISIBLE);
}else{
llayout.setVisibility(View.GONE);
}
}
Call executePendingTransactions() on fragment manager after committing transaction
...
fragmentTransaction.commit();
fragmentManager.executePendingTransactions();
((Unfold)fragmentManager.findFragmentByTag("fragment01")).unfold();
EDIT 1
You can try another option:
Do not add the executePendingTransactions()
In fragment's onViewCreated, if getTag() mathes "fragment01" call unfold method
i am trying to replace a displaynews fragment with homescreen fragment but the fragment is being adding instead of replacing in the code here
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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:id="#+id/content_main"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.ajitesh.newson.MainActivity"
tools:showIn="#layout/app_bar_main">
<fragment
android:id="#+id/home_fragment"
android:name="com.ajitesh.newson.DisplayNews"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
mainacitivity.class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentClass=HomeScreen.class;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.home_fragment,fragment).commit();
displaynews.class
public class DisplayNews extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.displaynews, container, false);
}
}
displaynews.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:id="#+id/display_news"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="helllooooo"/>
</LinearLayout>
HomeScreen.class
public class HomeScreen extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.home_screen, container, false);
}
}
home_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/text1"
android:text="this is home page"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click"/>
</LinearLayout>
Fragments cannot be replaced if hard-coded in xml, you should add it dynamically to replace a fragment with another.
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
source // example -- still getting problems? You may find a solution here
I have two fragments A and B.Fragment A has a view which when clicked opens Fragment B which occupies the frame layout in activity_main.xml.The frame layout originally has a recyclerview in it.But when simply tapped on Fragment B the recyclerview in activity_main.xml is responding.
Fragment A:
public class Motels extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.motels, container, false);
final Toolbar toolbar=(Toolbar) getActivity().findViewById(R.id.toolbar);
toolbar.setTitle("Motels");
final FragmentManager fragmentManager = getFragmentManager();
RippleView rippleView6=(RippleView) v.findViewById(R.id.ripple6);
rippleView6.setOnRippleCompleteListener(new RippleView.OnRippleCompleteListener() {
#Override
public void onComplete(RippleView rippleView2) {
Log.d("Sample", "Ripple completed");
MotelVaik motelVaik= new MotelVaik();
FragmentManager fragmentManager6=getFragmentManager();
final FragmentTransaction transaction6= fragmentManager.beginTransaction().setCustomAnimations(R.anim.enter_from_left_, R.anim.exit_to_right,R.anim.enter_from_right,R.anim.exit_to_left);
transaction6.replace(R.id.frame, motelVaik);
transaction6.addToBackStack("vaik").commit();
}
});}}
Fragment B:
public class MotelVaik extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.motel_vaikkom,container,false);
return v;}}
activity_main.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main"
>
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="450dp"
>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recyclerview"
android:layout_marginTop="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:scrollbarStyle="insideOverlay"
>
</android.support.v7.widget.RecyclerView>
</FrameLayout>
</LinearLayout>
In the xml of fragment B, on the root element just add
android:clickable="true"
make sure the height of the layout is match_parent
The slidingPaneLayout does not slide!
pane.isSlideable() is false!
I inflate the layout in this way:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
slidingView = inflater.inflate(R.layout.available_nodes_fragment, container, false);
SlidingPaneLayout pane = (SlidingPaneLayout)slidingView.findViewById(R.id.sliding_pane_layout);
Fragment fragmentA = new ListNodesFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.child_fragmentA, fragmentA );
Fragment fragmentB = new ReserveNodesFragment();
transaction.add(R.id.child_fragmentB, fragmentB);
transaction.commit();
//pane.setPanelSlideListener(new SliderListener());
pane.openPane();
Log.i("Available Nodes","PANE IS SLIDABLE" + pane.isSlideable());
return slidingView;
}
The available_nodes_fragment layout that i inflate is :
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="#+id/child_fragmentA"
android:layout_width="180dp"
android:layout_height="match_parent"
android:layout_gravity="left" />
<FrameLayout
android:id="#+id/child_fragmentB"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_gravity="right" />
</LinearLayout>
</android.support.v4.widget.SlidingPaneLayout>
I do not know why the SlidingPaneLayout does not slide. I do not know if this problem has to do with the fact that i use nested fragments.
I have some progress.
I changed the available_nodes_fragment layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/reserve_nodes"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
android:orientation="vertical" >
<android.support.v4.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/child_fragmentA"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_gravity="left"
android:layout_marginRight="25dp"
android:background="#A588DC" />
<FrameLayout
android:id="#+id/child_fragmentB"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:background="#B6D4D3"
android:layout_gravity="right" />
</android.support.v4.widget.SlidingPaneLayout>
<Button
android:id="#+id/btnReserveNodes"
android:layout_width="wrap_content"
android:layout_height="70dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="30dp"
android:text="Reserve"/>
</RelativeLayout>
Now, the SlidePaneLayout layout slides. I do not know why. When i changed the fixed layout_width of the FrameLayouts to wrap_content, the SlidePaneLayout started to slide.
My problem now is that i want the FrameLayout with id= "child_fragmentA" with the ListView to get the 30% of the screen horizontally. I did not found a way to do it, since FrameLayout does not support weights.
I also provide the code of ListNodesFragment and ReserveNodesFragment.
ListFragments.java
public class ListNodesFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View listNodesView = inflater.inflate(R.layout.nodes_categories_listview, container, false);
String[] items = { getResources().getString(R.string.orbit_nodes),
getResources().getString(R.string.grid_nodes),
getResources().getString(R.string.usrp_nodes),
getResources().getString(R.string.diskless_nodes),
getResources().getString(R.string.icarus_nodes) ,
getResources().getString(R.string.base_station)
};
ListView nodesListView = (ListView) listNodesView.findViewById(R.id.nodes_list);
ArrayAdapter<String> adapt = new ArrayAdapter<String>(getActivity(), R.layout.nodes_categories_listview_item, items);
nodesListView.setAdapter(adapt);
return listNodesView;
}
}
ReserveNodesFragment.java
public class ReserveNodesFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View reserveNodesView = inflater.inflate(R.layout.reserve_nodes_fragment, container, false);
TextView txtView = (TextView) reserveNodesView.findViewById(R.id.textView1);
txtView.setText("fragment 2");
return reserveNodesView;
}
}
im trying to set up a simple app using 2 fragments. For this i created 3 classes:
MainActivity:
public class MainActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment_A frag_A = new Fragment_A();
fragmentTransaction.add(R.id.map_container, frag_A);
Fragment_B frag_B = new Fragment_B();
fragmentTransaction.add(R.id.map_container2, frag_B);
fragmentTransaction.commit();
}
}
Fragment_A:
public class Fragment_A extends Fragment{
MapView map;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_a_layout, container, false);
map = (MapView) v.findViewById(R.id.map_object);
map.onCreate(savedInstanceState);
return v;
}
}
Fragment_B:
public class Fragment_B extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_b_layout, container, false);
v.setBackgroundColor(Color.BLUE);
return v;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/map_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/map_container1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:orientation="horizontal" >
</LinearLayout>
<LinearLayout
android:id="#+id/map_container2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:orientation="horizontal" >
</LinearLayout>
</LinearLayout>
fragment_a_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map_object"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"/>
</FrameLayout>
fragment_b_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
It happens that everytime i try to run this app i have this:Binary XML file line #6 Error inflating class fragment, where #6 is:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/map_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
...
I dont understand what can be the problem, I simply want to see both fragments on my screen.