I am meeting with Fragment for the first time. So it is a bit complicated to me. I am reading a tutorial at android-hive. But I am unable to understand a point. There are something I don't understand.
There are oneFragment(), twoFragment()... But I can't initiate them. So, please complete any of those... oneFragmemt() or twoFragment() from this link. I will be so pleased. Help me...
Muhamar, you always need to initiate the fragment inside an activity. If your fragment 1 has this code:
public class OneFragment extends Fragment{
public OneFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#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);
}
}
then in the main activity you can initiate like in the tutorial says:
public class MainActivity extends AppCompatActivity {
//blabla
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//blablabla
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new OneFragment(), "ONE");
//blabla
viewPager.setAdapter(adapter);
}
In this case the main activity is using an adapter to display more than one fragment, so you should have in your code more the file of the adapter, which you can find also in the tutorial.
UPDATE:
if you don't want to initalize the fragment with the adapter, you have to do two things to initialize the fragment:
1) Put fragment in layout: in the layout of your main activity you have to include a fragment and identify it (in this example android:id="#+id/headlines_fragment"):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="com.example.android.fragments.HeadlinesFragment"
android:id="#+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
2) Insert the fragment in your main activity: with the following code you can add the freagment in your activity:
public class MainActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
OneFragment firstFragment = new OneFragment();
// 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.headlines_fragment, firstFragment).commit();
}
}
UPDATE 2: to initialize from the adapter you just have to add it on the main activity, as the tutorial says. add this class on main activity:
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
Hope it helps ;)
Related
I wanted to go from One Fragment to another fragment from adapter class of first fragment (My first fragment contains recycler view and i am polulating it with data from realtime firebase )using intent using Java. I wanted to use intent because i wanted to start a new fragment with additional data from the adapter like userid and postid by using
intent.putExtra("publisherid", firebaseUser.getUid());
Can you guys help me by giving some sample code steps to follow
Create an interface
interface AdapterItemClickListener {
void onItemClickListener(String publisherid)
}
in first fragment where is recycler view
public class FirstFragment extends Fragment implements AdapterItemClickListener {
/////another code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
///another code
MyAdapter myAdapter = new MyAdapter(this);
//another code
}
void onItemClickListener(String publisherid) {
SecondFragment secondFragment = new SecondFragment()
Bundle args = new Bundle();
args.putString("publisherid", publisherid);
secondFragment .setArguments(args);
FragmentTransaction ft =
getParentFragmentManager().beginTransaction();
ft.replace(R.id.your_placeholder, secondFragment);
ft.commit();
}
}
Your adapter
public class MyAdapter extends RecyclerView.Adapter<EmployeeViewHolder> {
///another variablkes
AdapterItemClickListener itemClickListener;
public MyAdapter (AdapterItemClickListener itemClickListener){
this.itemClickListener = itemClickListener;
}
#Override
public void onBindViewHolder(#NonNull EmployeeViewHolder holder, int position) {
///another code
holder.itemView.setOnClickListener (v -> {
itemClickListener.onItemClickListener(firebaseUser.getUid());
});
}
///another adapter code
}
second Fragment
public class SecondFragment extends Fragment {
///another code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
///another code
String publisherid = getArguments().getString("publisherid");
}
///another code
}
I am very new to android , this time i created a view-pager tabbed activity by looking a video tutorial. the problem or the need is to show 3 different fragments if the user slides the position like tab1(shows first fragment),tab2 (shows second fragment) tab3 (shows third fragment)
Now it is showing one and only fragment for all tabs
this is my adapter class named datafragment
package com.example.jaison.news;
public class datafragment extends Fragment {
View view;
ViewPager viewPager;
TabLayout tabLayout;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view= inflater.inflate(R.layout.sample,container,false);
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPager.setAdapter(new sliderAdapter(getChildFragmentManager()));
tabLayout = (TabLayout) view.findViewById(R.id.sliding_tabs);
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return view;
}
private class sliderAdapter extends FragmentPagerAdapter{
final String tabs[]={"tab1", "tab2","tab3"};
public sliderAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
return fragment;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
return tabs[position];
}
}
}
for those who did not get my point , all i need is implement the code something just like this, but i am not sure about this..
switch (position) {
case 0:
//showing first fragment
case 1:
//showing second fragment
case 2:
//showing third fragment
default:
return new Fragment();
}
change your getItem method like this
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position){
case 0:
fragment = new Tab1Fragment();
break;
case 1:
fragment = new Tab2Fragment();
break;
case 2:
fragment = new Tab3Fragment();
break;
}
return fragment;
}
You need to create an instance of your viewPagerAdapter and then add items to it.
Something like this:
ViewPagerAdapter viewpagerAdapter = new ViewPagerAdapter(getChildFragmentManager());
viewPager.setAdapter(viewpagerAdapter);
// then add items to it as you add items to a recyclerview adapter or to any list
viewpagerAdapter.addFragment(new Fragment1(), "title1");
And the custom code for the viewpager Adapter is:
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
Also since you are new to programming, would advice you to use proper nomenclature, for eg. names of classes always begin with initial letter Uppercase
class ClassName
void methodName
MainActivity
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new OneFragment(), "ONE");
adapter.addFragment(new TwoFragment(), "TWO");
adapter.addFragment(new ThreeFragment(), "THREE");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
OneFragment.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class OneFragment extends Fragment{
public OneFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#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);
}
}
fragment_one.xml
<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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/one"
android:textSize="40dp"
android:textStyle="bold"
android:layout_centerInParent="true"/>
</RelativeLayout>
Likewise create few more fragment activities with same code we used for OneFragment.java.
See this simple complete example:
Here I used TabLayout also which is often used with ViewPager, so will be useful for you on next.
It requires API:
compile 'com.android.support:design:25.3.1'
You can ignore and remove all parts of TabLayout from xml and java files if want to go simpler at this instance.
1. activity_main.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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/viewPager"/>
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
app:tabIndicatorColor="#color/colorPrimaryDark"
app:layout_scrollFlags="scroll|enterAlways"
android:id="#+id/tabLayout"/>
</RelativeLayout>
2. Fragment Tab1.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="TAB 1"
android:id="#+id/textTab1"/>
</RelativeLayout>
3. Fragment Tab2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="TAB 2"
android:id="#+id/textTab2"/>
</RelativeLayout>
4. Fragment Tab3.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="TAB 3"
android:id="#+id/textSpacerNoTitleab3"/>
</RelativeLayout>
5. MainActivity.java
public class MainActivity extends AppCompatActivity
implements TabLayout.OnTabSelectedListener, ViewPager.OnPageChangeListener{
ViewPager viewPager;
TabLayout tabLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.addTab(tabLayout.newTab().setText("Page 1"));
tabLayout.addTab(tabLayout.newTab().setText("Page 2"));
tabLayout.addTab(tabLayout.newTab().setText("Page 3"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.addOnTabSelectedListener(this);
viewPager.setAdapter(new VPAdapter(getSupportFragmentManager()));
viewPager.addOnPageChangeListener(this);
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
w("onTabSelected(): "+tab.getPosition());
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
w("onPageSelected(): "+position);
TabLayout.Tab tab = tabLayout.getTabAt(position);
if(tab!=null)tab.select();
}
#Override
public void onPageScrollStateChanged(int state) {
}
void w(String string){
Log.w("MKN",getClass().getSimpleName()+" "+string);
}
}
6. Fragment class Tab1.java
public class Tab1 extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.tab1,container,false);
}
}
7. Fragment class Tab2.java
public class Tab2 extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.tab2,container,false);
}
}
8. Fragment class Tab3.java
public class Tab3 extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.tab3,container,false);
}
}
9. Adapter class VPAdapter.java
public class VPAdapter extends FragmentPagerAdapter {
public VPAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if(position == 0) return new Tab1();
if(position == 1) return new Tab2();
if(position == 2) return new Tab3();
throw new IllegalStateException("Unexpected position " + position);
}
#Override
public int getCount() {
return 3;
}
}
Use this :
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
// adding the fragments here with titles
adapter.addFragment(new OneFragment(), "ONE");
adapter.addFragment(new TwoFragment(), "TWO");
adapter.addFragment(new ThreeFragment(), "THREE");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
//return null;
}
}
then set it like this:
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) view.findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
hope it helps!!!
I am having a rather annoying problem using tabs in android. I am not sure how they work, problem I am having is knowing where to put the logic of my code. say for example on the first tab I wanted to apply a calendar and the second tab upload a file, for example where would I put this logic, I have 3 xml fragments and so far I have been trying to code the logic by the onCreateView. If anyone could explain how tabbed activities work I would be eternally grateful I used the default android set up for a tabbed activity and added 3 fragments.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(getArguments().getInt(ARG_SECTION_NUMBER)==1) {
View rootView = inflater.inflate(R.layout.fragment_message, container, false);
return rootView;
}
else if(getArguments().getInt(ARG_SECTION_NUMBER)==2){
View rootView = inflater.inflate(R.layout.fragment_read, container, false);
TextView textView= (TextView)rootView.findViewById(R.id.textView_two);
textView.setText("Working");
return rootView;
}
else{
View rootView = inflater.inflate(R.layout.fragment_calendar, container, false);
// would I put my logic here?
return rootView;
}
}
}
Update 2
So now I am trying to listen for button presses and show a toast on one of the fragments,the button does not respond and the Toasts do not appear.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View rootView=inflater.inflate(R.layout.fragment_calendar, container, false);
//final ActionBar actionBar = getSupportActionBar();
//actionBar.setDisplayHomeAsUpEnabled(false);
//actionBar.setTitle(null);
//Toast.makeText(getActivity(),"AKHBKH",Toast.LENGTH_LONG).show();
Button button1=(Button)rootView.findViewById(R.id.button_test1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.i("","");
Toast.makeText(getActivity(),"ddfdf",Toast.LENGTH_LONG).show();
}
});
PS I have tried all these on the Toast
getActivity()
getActivity().getApplicationContext()
getBaseContext()
getContext()
You can take three fragments and All the logic you want to implement should be in each of the fragment respectively. Take MainActivity to View all the fragments. Here i'll share my piece of code.
MainActivity
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new Admin(), "ADMIN");
adapter.addFragment(new Faculty(), "FACULTY");
adapter.addFragment(new Student(), "STUDENT");
viewPager.setAdapter(adapter);
}
//----------------------------------------------------------------------------------------------
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
#Override
public void onBackPressed(){
//Do Here what ever you want do on back press;
}
}
I'll share the code of any one of the fragments: Admin
public class Admin extends Fragment {
EditText aid;
EditText apassword;
Button submit1,changepass;
String id = null, pass = null;
String table = null;
public Admin() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView=inflater.inflate(R.layout.fragment_admin, container, false);
aid=(EditText)rootView.findViewById(R.id.admin_id);
apassword=(EditText)rootView.findViewById(R.id.admin_password);
changepass=(Button)rootView.findViewById(R.id.changePass);
submit1=(Button)rootView.findViewById(R.id.submit1);
submit1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
submit1();
}
});
changepass.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent in=new Intent(getActivity(),ChangePassword.class);
startActivity(in);
}
});
// Inflate the layout for this fragment
return rootView;
}
//For Admin login Authentication
public void submit1() {
id = aid.getText().toString();
pass = apassword.getText().toString();
Log.d("id", id);
Log.d("pass", pass);
table="admin";
// new ExecuteTask().execute(id, pass, table);
}}
Initially create an activity MainActivity.
You must create 3 fragments.Extend your activity from FragmentActivity and also implement ActionBar.TabListener
Refer this tutorial:
http://www.androidhive.info/2013/10/android-tab-layout-with-swipeable-views-1/
I want to rewrite my activities to dialogs, and I want to replace dialogs programmatically. I tried fragments staticaly and it is works fine. When I programmatically call fragment and debug it with breakpoints I don't understand why its lifecycle starts from onCreate() and ends on it... Why from onCreate() and don't from onAttach() like when I call it statically? here is my code, help me plz!!!
base_activity.xml `
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/base_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/base_fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
`
BaseActivity.java
public class BaseActivity extends AppCompatActivity {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.base_activity);
DietsFragment dietsFragment = new DietsFragment();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.base_fragment_holder, dietsFragment);
fragmentTransaction.commit();
}
}
DietsFragment.java
public class DietsFragment extends Fragment
implements AdapterView.OnItemClickListener,
View.OnClickListener {
public FragmentEventListener fragmentEventListener;
Cursor diets;
DietAdapter adapter;
DietHelper helper;
ListView listView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.activity_diets, container, false);
listView = (ListView) view.findViewById(R.id.act_diets_lv_diets);
if (listView != null) {
listView.setOnItemClickListener(this);
}
FloatingActionButton floatingActionButton = (FloatingActionButton) view.findViewById(R.id.act_diets_fab);
if (floatingActionButton != null)
floatingActionButton.setOnClickListener(this);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
setHelper(new DietHelper(getActivity()));
setDiets(getHelper().getAllTableRecordsCursor());
setAdapter(new DietAdapter(getActivity(), getDiets()));
listView.setAdapter(getAdapter());
fragmentEventListener = (FragmentEventListener) getActivity();
}
public void setDiets (Cursor diets) {
this.diets = diets;
}
public void setAdapter (DietAdapter adapter) {
this.adapter = adapter;
}
public void setHelper (DietHelper helper) {
this.helper = helper;
}
public Cursor getDiets() {
return diets;
}
public DietAdapter getAdapter() {
return adapter;
}
public DietHelper getHelper() {
return helper;
}
}
in DietsFragment and BaseActivity i hide its implementetions of OnClickListener, OnItemClickListener and FragmentEventListener, cause it works fine when i add fragment in BaseActivity statically from xml with
I've just found my mistake... I overloaded findViewbyId(int resId) in BaseActivity and that all my problem, and now i'm asking myself WHY I OVERLOAD THAT METHOD WHAT WAS I WANTED TO DO WITH IT?
Here is my the problem, I have an activity, which includes a Fragment that has a ViewPager using (FragmentStatePagerAdapter), all works perfect when the Activity loads for the first time, but when setting setRetainInstance(true) to the parent fragment (the one with the pager), and orientation changes on the activity, it causes
java.lang.IllegalStateException: No activity
When trying to add the saved fragment, here is the code:
Activity:
public class DetailActivity{
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frame_layout_with_progress_container);
...
// 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.
FragmentManager fm = getSupportFragmentManager();
if (savedInstanceState != null) {
Fragment f = fm.findFragmentById(R.id.container);
if(f instanceof DetailPagerFragment){
detailPagerFragment = (DetailPagerFragment) f;
}
}
}
#Override
protected void onPostResume() {
super.onPostResume();
//If fragment is null, create a new instance
if(detailPagerFragment==null){
detailPagerFragment =
DetailContainerFragment.newInstance(details, initialPosition);
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container, detailPagerFragment);
ft.commit();
}
Note: that i have to save the fragment instance on onCreate because when the code reaches onStart the reference for this fragment was null (this issue is not important for the time it has something to do with the NavigationDrawer), so i need to manually save the instance of the fragment.
Activity layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/container"/>
</RelativeLayout>
ViewPager Fragmentm this class extends for DetailPagerFragment which is a custom pager fragment it only wraps common code for pagers (for example view inflation, uses inflateView method), this is why the pager is added on a fragment instead of directly to the activity:
public class DetailContainerFragment extends DetailPagerFragment {
List<Detail> details;
public static DetailContainerFragment newInstance(List<Detail> details,int selectedPosition) {
DetailContainerFragment df = new DetailContainerFragment();
df.setSelectedPosition(selectedPosition);
df.setDetails(details);
return df;
}
public void setDetails(List<Detail> details) {
this.details = details;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
/**
* Inflates the view to be used by this fragment
*
* #param inflater
* Inflater to use
* #return Inflated view
*/
#Override
public View inflateView(LayoutInflater inflater) {
return inflater.inflate(R.layout.detail_pager_fragment, null);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
DetailStatePagerAdapter detailStatePagerAdapter = new DetailStatePagerAdapter(getChildFragmentManager());
setPagerAdapter(detailStatePagerAdapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
private class DetailStatePagerAdapter extends FragmentStatePagerAdapter {
public DetailStatePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return DetailFragment.newInstance(details.get(position));
}
#Override
public CharSequence getPageTitle(int position) {
return details.get(position).getTitle();
}
#Override
public int getCount() {
return details.size();
}
}
}
I had a similar problem with child fragments in a ViewPager.
The parent fragment created new instances of the child fragments to be used with the ViewPager while the adapter kept instances of the old child fragments used before the configuration change.
I ended up cleaning the ChildFragmentManager before initializing the adapter with it:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mPager = (ViewPager) view.findViewById(R.id.pager);
cleanChildFragments(getChildFragmentManager());
mPagerAdapter = new MyPagerAdapter(getChildFragmentManager(), getTabFragments());
mPager.setAdapter(mPagerAdapter);
}
/**
* This is necessary to have a clean ChildFragmentManager, old fragments might be called otherwise
* #param childFragmentManager
*/
private void cleanChildFragments(FragmentManager childFragmentManager) {
List<Fragment> childFragments = childFragmentManager.getFragments();
if (childFragments != null && !childFragments.isEmpty()) {
FragmentTransaction ft = childFragmentManager.beginTransaction();
for (Fragment fragment : childFragments) {
ft.remove(fragment);
}
ft.commit();
}
}
Maybe this helps someone...