Reputation: 6013
I'm having a lot of trouble getting Fragments to work with Tabs/Swiping. I have one activity and two Fragments, one which has a ListView. What I want is when I swipe from fragment 1 to the fragment with the ListView, to refresh the ListView or if possible recreate the second fragment....
What I am trying right now is to use FragmentTransaction.replace() like this:
public void onTabSelected(Tab arg0, android.app.FragmentTransaction arg1) {
// TODO Auto-generated method stub
Fragment frag = new FragmentTwo();
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
if (arg0.getPosition() == 1) {
trans.replace(R.id.pager, frag);
trans.addToBackStack(null);
trans.commit();
}
}
So I thought that when I swipe to tab 2, which is the one with the ListView, it would replace it with a new one, which it creates. What is actually happening is that when I swipe to tab 2, it recreates the fragment with the ListView (I know because I have a dialog in the onCreateView which shows to the screen) but then the fragment/tab is blank/black. What am I doing wrong? Where does this fragment which is created go?
I don't know if the code of the fragments is relevant but please let me know if I should post it and I can do that. This is my PagerAdapter class.
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FragmentOne();
case 1:
return new FragmentTwo();
case 2:
return new FragmentThree();
}
return null;
}
@Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
Thanks for any help! I'm really pulling my hair out over this one :(
When you swipe from tab 1 to tab 2, tab 2 shows my dialog and then loads the tab, but if I go back to tab 1 its all black...and if I then go to tab 2 again, it creates again and shows my dialog and then goes black as well...
public class FragmentTwo extends Fragment {
// Progress Dialog
private ProgressDialog pDialog;
// Creating JSON Parser object
JSONParser_Helpers2 jParser = new JSONParser_Helpers2();
ArrayList<HashMap<String, String>> tripList;
// url to get all products list
private static String url_all_trips = "http://10.0.2.2/android_connect/get_all_trips.php";
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_TRIPS = "trips";
private static final String TAG_TRIPID = "tripid";
private static final String TAG_TRIPNAME = "tripName";
private static final String TAG_UID = "uid32";
// products JSONArray
JSONArray trips = null;
View rootView;
Button btnRefresh;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//View rootView = inflater.inflate(R.layout.fragment_one, container, false);
rootView = inflater.inflate(R.layout.fragment_two, container, false);
btnRefresh = (Button) rootView.findViewById(R.id.refresh);
// Hashmap for ListView
tripList = new ArrayList<HashMap<String, String>>();
// Loading products in Background Thread
new LoadAllProducts().execute();
// Get listview
ListView lv = (ListView) rootView.findViewById(R.id.list);
// on seleting single product
// launching Edit Product Screen
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//getting values from selected ListItem
String tripid = ((TextView) view.findViewById(R.id.pid)).getText().toString();
//starting new intent
Intent in = new Intent(getActivity(), EditTrip_Activity.class);
//sending pid to next activity
in.putExtra(TAG_TRIPID, tripid);
//starting new activity and expecting some response back
startActivityForResult(in, 100);
}
});
return rootView;
}
/**
* Background Async Task to Load all product by making HTTP Request
* */
class LoadAllProducts extends AsyncTask<String, String, String> {
ListView lv = (ListView) rootView.findViewById(R.id.list);
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Loading your trips. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All products from url
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_trips, "GET", params);
// Check your log cat for JSON response
Log.d("All Trips: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
trips = json.getJSONArray(TAG_TRIPS);
// looping through All Products
for (int i = 0; i < trips.length(); i++) {
JSONObject c = trips.getJSONObject(i);
// Storing each json item in variable
String tripid = c.getString(TAG_TRIPID);
String tripname = c.getString(TAG_TRIPNAME);
String userId = c.getString("uid");
// creating new HashMap
DatabaseHandler_Helpers db = new DatabaseHandler_Helpers(getActivity());
HashMap<String, String> map = new HashMap<String, String>();
if (userId.equals(db.getUserDetails().get("uid"))) {
// adding each child node to HashMap key => value
map.put(TAG_TRIPID, tripid);
map.put(TAG_TRIPNAME, tripname);
// adding HashList to ArrayList
tripList.add(map);
} //else {
//map.put(TAG_TRIPID, "");
//map.put(TAG_TRIPNAME, "You have no tracked trips.");
//tripList.add(map);
//}
}
} else {
// no products found
// Launch Add New product Activity
Intent i = new Intent(getActivity(),
NewTrip_Activity.class);
// Closing all previous activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
((Activity) getActivity()).runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
getActivity(), tripList,
R.layout.list_item, new String[] { TAG_TRIPID,
TAG_TRIPNAME},
new int[] { R.id.pid, R.id.name });
// updating listview
((ListView) lv.findViewById(R.id.list)).setAdapter(adapter);
}
});
}
}
}
Upvotes: 10
Views: 11624
Reputation: 569
If anyone using viewpager2 then use the below constructor. FragmentStateAdapter(fragmentManager, lifecycle)
Upvotes: 0
Reputation: 505
My children fragments are in a ViewPager. I just replace the ViewPage adapter by FragmentStatePagerAdapter instead of FragmentPagerAdapter
Child Fragment ....
mViewPager.setAdapter(new SearchOriginTabsPagerAdapter(getFragmentManager()));
Adapter...
public class SearchOriginTabsPagerAdapter extends FragmentStatePagerAdapter {
public SearchOriginTabsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new NearbyFragment();
case 1:
return new RecentOriginFragment();
}
return null;
}
@Override
public int getCount() {
// get item count - equal to number of tabs
return 2;
}
}
Upvotes: 4
Reputation: 5425
Alright.. Here's the thing..
I didn't really use your code but used similar concept. Its gonna be a complete solution.
//This is the starting point of the app. It has many fragments and I am using my own json to get the data.
public class AllActivities extends FragmentActivity implements ActionBar.TabListener {
public ViewPager viewPager;
private AllPagesAdapter mAdapter;
private ActionBar actionBar;
private String [] tabs = {"Android","CoreJava","J2EE","Database","Web Services"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initializing all stuff
viewPager = (ViewPager)findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new AllPagesAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//Add the tabs here
for(String tab_name:tabs){
actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
}
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
@Override
public void onPageSelected(int position){
//on Page change, that particular page should be selected
actionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrolled(int arg0,float arg1,int arg2){
}
@Override
public void onPageScrollStateChanged(int position){
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction fragmentTransaction) {
viewPager.setCurrentItem(tab.getPosition());
}
}
//This is one of the fragment and assume that Expandablelistview is your list view.. In both the cases, i am setting the adapter in the onActivityCreated() method.
public class Android extends android.support.v4.app.Fragment {
ExpandableListAdapter listAdapter;
// private ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
ListView lv1;
private static final String QUESTION = "question";
private static final String ANSWERS = "answer";
// ArrayList<HashMap<String, String>> jsonlist = new ArrayList<HashMap<String, String>>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mikeview = inflater.inflate(R.layout.androidlayout, container, false);
return mikeview;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ExpandableListView expListView = null;
try{
expListView = (ExpandableListView) getActivity().findViewById(R.id.androidExpandableList);
}
catch (Exception e){
e.printStackTrace();
}
new Thread(){
@Override
public void run(){
}
}.start();
try {
setParent();
prepareChild();
} catch (Exception e) {
e.printStackTrace();
}
ExpandableListAdapter listAdapter = new ExpandableListAdapter(getActivity(), listDataHeader, listDataChild);
expListView.setAdapter(listAdapter);
// Listview on child click listener
expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
/*Toast.makeText(
getActivity(),
listDataHeader.get(groupPosition)
+ " : "
+ listDataChild.get(
listDataHeader.get(groupPosition)).get(
childPosition), Toast.LENGTH_SHORT)
.show();*/
return true;
}
});
// Listview Group expanded listener
expListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
@Override
public void onGroupExpand(int groupPosition) {
/* Toast.makeText(getActivity(),
listDataHeader.get(groupPosition) + " Expanded",
Toast.LENGTH_SHORT).show();*/
}
});
// Listview Group collasped listener
expListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
@Override
public void onGroupCollapse(int groupPosition) {
/*Toast.makeText(getActivity(),
listDataHeader.get(groupPosition) + " Collapsed",
Toast.LENGTH_SHORT).show();*/
}
});
}
public void setParent(){
listDataHeader = new ArrayList<String>();
try{
JSONObject json = new JSONObject(loadJSONFromAsset());
JSONArray array = json.getJSONArray("androidquestion");
for(int my =0;my<array.length();my++){
JSONObject c = array.getJSONObject(my);
String topics = c.getString(QUESTION);
listDataHeader.add(topics);
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
public void prepareChild() throws JSONException {
listDataChild = new HashMap<String, List<String>>();
try{
JSONObject json = new JSONObject(loadJSONFromAsset());
JSONArray array = json.getJSONArray("androidquestion");
for(int mz = 0;mz<array.length();mz++){
ArrayList<String> child = new ArrayList<String>();
JSONObject d = array.getJSONObject(mz);
String ans = d.getString(ANSWERS);
child = new ArrayList<String>();
child.add(ans);
int position = mz ;
listDataChild.put(listDataHeader.get( position),child);
}
}
catch(JSONException e) {
e.printStackTrace();
}
}
public String loadJSONFromAsset() {
String json = null;
try {
InputStream is = getActivity().getAssets().open("android.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
}
//This is the adapter.
public class AllPagesAdapter extends FragmentStatePagerAdapter {
public AllPagesAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new Android();
case 1:
return new CoreJava();
case 2:
return new J2EE();
case 3:
return new Database();
case 4:
return new WebServices();
}
return null;
}
@Override
public int getCount() {
return 5;
}
}
//This is the adapter for my expandable list view.. in your case, your can just use the listadapter or any other adapter you want to use. This is just an optional part.
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context _context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;
public ExpandableListAdapter(Context context, List<String> listDataHeader,
HashMap<String, List<String>> listChildData) {
this._context = context;
this._listDataHeader = listDataHeader;
this._listDataChild = listChildData;
}
@Override
public Object getChild(int groupPosition, int childPosititon) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.get(childPosititon);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.newlistitems,null);
}
TextView txtListChild = (TextView) convertView
.findViewById(R.id.newlistviewitems);
txtListChild.setText(childText);
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.size();
}
@Override
public Object getGroup(int groupPosition) {
return this._listDataHeader.get(groupPosition);
}
@Override
public int getGroupCount() {
return this._listDataHeader.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater myInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = myInflater.inflate(R.layout.newlistgroup, null);
}
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.newlistviewgroup);
lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(headerTitle);
return convertView;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
Upvotes: 0
Reputation: 5425
Try to extend FragmentStatePagerAdapter instead of FragmentPagerAdapter.
Here's my code for fragments and it works fine for me:
//Adapter
public class AllPagesAdapter extends FragmentStatePagerAdapter {
public AllPagesAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new Android();
case 1:
return new CoreJava();
case 2:
return new J2EE();
case 3:
return new Database();
case 4:
return new WebServices();
}
return null;
}
@Override
public int getCount() {
return 5;
}
}
//For example, this is one fragment:
public class Database extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View databaseview = inflater.inflate(R.layout.database, container, false);
return databaseview;
}
}
//My MainActivity
public class AllActivities extends FragmentActivity implements ActionBar.TabListener {
public ViewPager viewPager;
private AllPagesAdapter mAdapter;
private ActionBar actionBar;
private String [] tabs = {"Android","CoreJava","J2EE","Database","Web Services"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initializing all stuff
viewPager = (ViewPager)findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new AllPagesAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//Add the tabs here
for(String tab_name:tabs){
actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
}
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
@Override
public void onPageSelected(int position){
//on Page change, that particular page should be selected
actionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrolled(int arg0,float arg1,int arg2){
}
@Override
public void onPageScrollStateChanged(int position){
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction fragmentTransaction) {
viewPager.setCurrentItem(tab.getPosition());
}
}
Let me know if you also want the implementation of the listview in any one fragment.
Hope this helps..:)
Upvotes: 15