I have this listview which is a list of news items. I want to display a detailed version of a particular news item when that news item is clicked in the listview.
So far i was able to create the listview and display the news items in a listview. (NOTE: news items are taken from a JSON)
I was able to display a view when a news item is clicked in the listview. but the PROBLEM is when a listview item is clicked, a view of detailed version of news items is displayed BUT it shows all the detailed version of news.
I WANT TO SHOW ONLY THE DETAILED VERSION OF THE NEWS ITEM THAT WAS CLICKED. how can i do this?
after researching i think i should use a bundle for this.but i have no idea how to do this.
I'll post my classes here
NewsFragment.java
public class NewsFramgment extends Fragment {
private ListView listView;
private ArrayList<BaseElement> News;
private LazyAdapter adapter;
private Activity activity;
private CommonVariable commonVariable;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.news_fragment, container,
false);
activity = this.getActivity();
commonVariable = (CommonVariable) activity.getApplication();
listView = (ListView) view.findViewById(R.id.list);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id)
{
android.support.v4.app.Fragment detail = new NewsDetailFragment();
android.support.v4.app.FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().add(R.id.content_frame, detail).addToBackStack("back").commit();
}
});
new BackGround().execute();
return view;
}
public class BackGround extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
News = JSONServices.getNewsDescription();
return null;
}
#Override
/* check again */
protected void onPostExecute(Void result) {
commonVariable.setNewsDescription(News);
adapter = new LazyAdapter(News, activity,Element.NEWS_LIST.getType());
listView.setAdapter(adapter);
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
}
}
NewsDetailFramgment.java
public class NewsDetailFragment extends Fragment {
private View view1;
private ArrayList<BaseElement> newsdetail;
private LazyAdapter adapter;
private Activity activity;
private CommonVariable commonVariable;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.newsdetail_fragment, container,
false);
activity = this.getActivity();
commonVariable = (CommonVariable) activity.getApplication();
view1 = (View) view.findViewById(R.id.list);
new BackGround().execute();
return view;
}
public class BackGround extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
newsdetail = JSONServices.getNewsDescription();
return null;
}
#Override
/* check again */
protected void onPostExecute(Void result) {
commonVariable.setTheater(newsdetail);
adapter = new LazyAdapter(newsdetail, activity,Element.NEWS_DETAIL.getType());
((AdapterView<ListAdapter>) view1).setAdapter(adapter);
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
}
}
It looks like you're calling newsdetail = JSONServices.getNewsDescription(); and then assigning that result to your adapter in NewsDetailFragment. What is being returned by JSONServices.getNewsDescription();? I imagine it is all of the NewsDetail articles.
#Raghunandan is right, the example shows how to handle two fragments in an activity and show the 'Detail' fragment based on which item was selected in the 'News' list.
You could implement the calls in your parent Activity as shown in the example under 'Implement the Interface'.
YourParentActivity.java
public static class YourParentActivity extends Activity {
implements NewsFragment.OnHeadlineSelectedListener{
...
}
public void onArticleSelected(int position) {
NewsDetailFramgment articleFrag = (NewsDetailFramgment)
getSupportFragmentManager().findFragmentById(R.id.news_detail_framgment);
if (articleFrag != null) {
// If article frag is available, we're in two-pane layout...
// Call a method in the NewsDetailFramgment to update its content
articleFrag.updateArticleView(position);
} else {
// Otherwise, we're in the one-pane layout and must swap frags...
// Create fragment and give it an argument for the selected article
NewsDetailFramgment newFragment = new NewsDetailFramgment ();
Bundle args = new Bundle();
args.putInt(NewsDetailFramgment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
}
Notice that onArticleSelected() accepts int position? This is the position in the News Headlines adapter that was clicked. You can use this to get the corresponding News Detail item from your Details result.
This is purely an outline based on the example, but should show you what you need to do in your parent activity.
Read the example and add the relevant parts to your fragments (look at 'Define an Interface' for changes to your NewsFragment.java).
Edit
You need to define an interface in your NewsFragment class as shown in the documentation under 'Define an Interface'.
// Container Activity must implement this interface
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
This provides a callback to your parent class to handle when a news headline is pressed with the position of the headline which was selected. In the example it calls onArticleSelected(int position); in your parent activity to then populate the NewsDetailFragment.
Related
MainActivity on startup add a fragment layout to Relativeview, then i send a data to fragment to add it to ExpandablelistView but my app shows me error that couldn't recognize ExpandablelistView.
MainActivity:
public class MainActivity extends AppCompatActivity implements FragmentAddCatergory.onClickButtonListener {
private FragmentManager manager;
private FragmentTransaction transactionShowList;
private FragmentTransaction transactionAddCatergory;
private FragmentAddCatergory addCatergory;
private FragmentShowCategory showCategory;
private boolean addcategory;
private TextView txtAddCategory;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = getFragmentManager();
transactionShowList = manager.beginTransaction();
showCategory = new FragmentShowCategory();
addCatergory=new FragmentAddCatergory();
transactionShowList.add(R.id.Fragment_container, showCategory);
transactionShowList.commit();
addcategory=false;
txtAddCategory = (TextView) findViewById(R.id.txtaddcategory);
txtAddCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ChangeFragment();
}
});
}
public void ChangeFragment(){
transactionAddCatergory=manager.beginTransaction();
if (addcategory){
transactionAddCatergory.replace(R.id.Fragment_container,addCatergory);
txtAddCategory.setText("Do you want to see your List?Show me!");
addcategory=false;
}else{
transactionAddCatergory.replace(R.id.Fragment_container,showCategory);
txtAddCategory.setText("Do you want to add a Category?Create One");
addcategory=true;
}
transactionAddCatergory.commit();
}
#Override
public void ClickButton(String group, String child) {
FragmentShowCategory a=new FragmentShowCategory();
a.showExpand(this,group,child);
}}
in last above code i make object from first fragment and send a data and in below code is code of first fragment
public class FragmentShowCategory extends Fragment {
private View view;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
view = inflater.inflate(R.layout.activity_expandable_list_view, container, false);
return view;
}
public void showExpand(Context context, String g, String c) {
Toast.makeText(context, g + " is " + c, Toast.LENGTH_LONG).show();
HashMap<String, List<String>> carsDetails = DataProvider.getInfo(g, c);
List<String> carsBrands = new ArrayList<String>(carsDetails.keySet());
ItemClass adapter = new ItemClass(context, carsDetails, carsBrands);
ExpandableListView list = (ExpandableListView) view.findViewById(R.id.expandList);
list.setAdapter(adapter);
}}
but when i ran my app, i get error that i don't know why in line of:
ExpandableListView list = (ExpandableListView) view.findViewById(R.id.expandList);
i'd appreciate to help me.
Your fragment's view hierarchy is not inflated automatically just because you created an instance of your fragment, as you do in ClickButton. The onCreateView() method that has to be called first in order to inflate your views is part of the fragment's lifecycle. You should let Android instantiate your fragment, and acquire it's instance through the FragmentManager.
This tutorial explains basics about fragments very well.
I have a activity with an container inside of it in which I display a list generated by a listFragment. Now I want handle clicks on list items by "forwarding" the onItemClick method via a pulic interface to the mainActivity. I did setOnItemClickLIstener and I also tried many solutions I found here and elsewhere e.g. setting
android:focusable="false"
android:focusableInTouchMode="false"
in the xml file for my custom list items.
The fragment code looks like this (I will not post the whole code to keep it simple, if needed I will provide further parts of the code)
public class DishListFragment extends ListFragment implements ListView.OnItemClickListener {
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private static final String ARG_PARAM3 = "param3";
private static final String ARG_PARAM4 = "param4";
private static final String ARG_PARAM5 = "param5";
//List of Dishes to contain the dishes we get from the server
//Todo: fill with dynamic content
private ArrayList<DishListItem> dishes;
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
private ListView mListView;
private ListAdapter mAdapter;
public static DishListFragment newInstance(Date day, boolean soup, boolean meat,
boolean veggies, boolean sideDishes) {
DishListFragment fragment = new DishListFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, String.valueOf(day));
args.putString(ARG_PARAM2, String.valueOf(soup));
args.putString(ARG_PARAM3, String.valueOf(meat));
args.putString(ARG_PARAM4, String.valueOf(veggies));
args.putString(ARG_PARAM5, String.valueOf(sideDishes));
fragment.setArguments(args);
return fragment;
}
public DishListFragment() { }
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//dummy list of dishes addad for developing purposes
// Todo: implement dynamic server generated list content
// create this array to test the comment function
String[] commentDummy = new String[]{"gut", "lecker", "schlecht"};
dishes = new ArrayList<DishListItem>();
dishes.add(new DishListItem("Rigatonelli", commentDummy, 2.0f ,4));
dishes.add(new DishListItem("Spinatcremesuppe"));
dishes.add(new DishListItem("Hackbällchen"));
dishes.add(new DishListItem("Gemüsepfanne"));
dishes.add(new DishListItem("Reis"));
dishes.add(new DishListItem("Rumpsteak"));
dishes.add(new DishListItem("Rumpsteak"));
dishes.add(new DishListItem("Rumpsteak"));
dishes.add(new DishListItem("Rumpsteak"));
dishes.add(new DishListItem("Rumpsteak"));
dishes.add(new DishListItem("Rumpsteak"));
//end here
// set an adapter to the list and let it display the list
// Todo: implement custom list view elements for graphical UI
// Todo: implement custom adapter to handle user preferences (meat/ veggies/ soups/ sidedishes)
mAdapter = new DishListAdapter(getActivity(),dishes);
}
//create on click adapter to handle clicks on list items
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
DishListItem dishItem = this.dishes.get(position);
Toast.makeText(getActivity(), dishItem.getDishName() +" clicked!", Toast.LENGTH_SHORT).show();
mListener.onDishClicked(dishes, position);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_dishlist, container, false);
View header = inflater.inflate(R.layout.list_header_day_date, mListView ,false);
mListView = (ListView) view.findViewById(android.R.id.list);
mListView.addHeaderView(header);
mListView.setAdapter(mAdapter);
// Set OnItemClickListener so we can be notified on item clicks
mListView.setOnItemClickListener(this);
return view;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public void setEmptyText(CharSequence emptyText) {
View emptyView = mListView.getEmptyView();
if (emptyText instanceof TextView) {
((TextView) emptyView).setText(emptyText);
}
}
/**
* 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
public void onDishClicked(ArrayList<DishListItem> dishes, int position);
}
}
The main activity looks like this
public class CulinariumSpeiseplan extends ActionBarActivity
implements DishListFragment.OnFragmentInteractionListener
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_culinarium_speiseplan);
//add list fragment to the activity layout (put it into the container)
if(savedInstanceState == null){
getFragmentManager().beginTransaction()
.add(R.id.listDishesContainer, new DishListFragment())
.commit();
}
}
{
#Override
public void onDishClicked(ArrayList<DishListItem> dishes, int position) {
Toast.makeText(this, dishes.get(position).getDishName() +" clicked!", Toast.LENGTH_SHORT).show();
SingleDishEnhancedView singleDishEnhancedView = SingleDishEnhancedView.newInstance(dishes, position);
singleDishEnhancedView.show(getFragmentManager(), "DishDisplay");
}
}
the toasts are just for test purposes but they don't get displayed either. I hope I am not being completely stupid but I just can't seem to find an answer to that problem.
Thank you for your time.
EDIT: I should also mention, that I do neither get an compilation error, nor does the app crash at any point. The list is scrollable and does behave as you would expect it, you can even see the little click animation as you click on one of the items.
EDIT2: I updated the code because the comments were pointing out some significant bits were missing. I hope the updated code makes it more clear.
The solution was fairly simple the onItemClick method has to use ListView instead of AdapterView, although I'm not really sure why this didn't cause a crash or at least some kind of warning. Either ways, the problem is solved. Thanks for the comments, they led me the right way.
I'm trying to do something pretty basic but can't seem to get it to work.
I have a ViewPager and am using a FragmentPagerAdapter to populate it with fragments. I always have 3 fragments (call them A, B, C) and on fragment C I have a simple ListView. Whenever the user clicks an item on that ListView, I want to add a new fragment (Fragment D) to the ViewPager which will show details related to that list item.
If the user goes back to Fragment C, they can click on another list item and the contents of Fragment D should be updated with other details.
This is the code for the PageAdapter:
public class TopPagerAdapter extends FragmentPagerAdapter {
private final ArrayList<Fragment> fragments = new ArrayList<Fragment>();
public TopPagerAdapter(FragmentManager fm) {
super(fm);
fragments.add(0, new FragmentA());
fragments.add(1, new FragmentB());
fragments.add(2, new FragmentC());
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return null;
}
public void addFragmentD(FragmentD frag) {
fragments.add(3, frag);
notifyDataSetChanged();
}
public void removeFragmentD() {
fragments.remove(3);
notifyDataSetChanged();
}
}
And this is how it is used (when the user clicks on a list item in Fragment C):
rowView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentD frag = new FragmentD();
Bundle args = new Bundle();
args.putString("name", mName.getText().toString());
frag.setArguments(args);
adapter.addFragmentD(frag);
}
});
And this is the actual code of Fragment D (all it does is get the bundle that is passed to it and display it):
public class FragmentD extends Fragment {
private Context mContext;
private TextView mName;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.mContext = activity;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_d, container, false);
mName= (TextView) view.findViewById(R.id.name);
String name = (String) getArguments().get("name");
mName.setText(name);
return view;
}
}
The end result is that FragmentD gets added correctly and it displays the correct info that gets passed to it via the Bundle, but it only works the first time. If I go back to FragmentC and click on another list item, that same FragmentD shows up and even though I am creating a new instance of FragmentD, its onCreateView method never get called. It's as if it stays in memory and never removed.
Any ideas how to make this work? Thanks.
I hope someone can assist please. I have a Fragment hosting multiple list fragments using support library. The list fragments are supposed to display data that i retrieve form an async task in the parent fragment. I have been trying to figure out exactly how the data is being loaded because it is not loading correctly.
Each time the list display fragment is launched it preforms an async task to get and parse Json into an ArrayList <ArrayList <HashMap <String, String> > >
Each List fragment queries the parent fragment for data at its position in the ArrayList.
eg. For the 3rd page in it should retrieve arrList[2] which contains an `ArrayList <HashMap <String, String> > to display as a list.
The pager is acting weird. Maybe i am not understanding the lifecycle of the fragments or how the pager uses them. I have 7 Fragments. If i start on frag3 the pager will show fragment 3 with no data on it. It also loads fragment 2 and 4 with no data. If i go left to frag 1 it will display fragment 1 correctly and load fragment 0. I can properly switch to frag 0 but if i switch to frag 2 it loads data from frag 0 and loads frag 0's data into all of the rest of the views. If i go back and forth enough it will replace all data in every fragment with data from frag 0. I believe that it does not load data immediately because it does not have the data when the viewpager launches. I have not made it wait for the async task yet.
I thought that each fragment gets its view redrawn each time it is taken far enough from view. So i put Update in the onCreateView() of the fragment. I feel like this is a small thing that i have just misplaced or i am overlooking it. I tried to implement FragmentStatePagerAdapter but i do not think that i did it right.
Any Help is much Appreciated And i am very open to discussion if i am just doing things horribly wrong. I usually do. It never fails. Create something to find out i need to rewrite everything.
public class ListFragmentDisplay extends SherlockFragment {
public static final String TAG = "listFragmentDisplay";
Calendar calendar = Calendar.getInstance();
private int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
// listbyday is a list of hash maps each list of hash maps represents a day
// of the week with items for that Object
private ArrayList<ArrayList<HashMap<String, String>>> listByDay = null;
private String objectName = null;
private ViewPager pager;
private FragAdapter adapter;
public ArrayList<HashMap<String, String>> getList(int day) {
return listByDay.get(day);
}
private void getObjectName() {
barName = ((MainFragActivity) getActivity()).getobjectSelected();
}
public static ListFragmentDisplay newInstance() {
return new ListFragmentDisplay();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the ListView layout file.
initArrList();
getObjectName();
fillList();
return inflater.inflate(R.layout.list_view, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
pager = (ViewPager) view.findViewById(R.id.viewPager);
adapter =new FragAdapter(getChildFragmentManager());
if (pager.getAdapter() == null)
pager.setAdapter(adapter);
reload();
pager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageScrollStateChanged(int arg0) {}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {reload();}
#Override
public void onPageSelected(int arg0) {
}
});
pager.setCurrentItem(dayOfWeek-1);
}
private void initArrList() {
if (listByDay == null) {
listByDay = new ArrayList<ArrayList<HashMap<String, String>>>();
} else {
listByDay.clear();
}
for (int i = 0; i < 7; i++) {
ArrayList<HashMap<String, String>> hm = new ArrayList<HashMap<String, String>>();
listByDay.add(hm);
}
}
synchronized private void fillList() {
LoadWebTask lWT = new LoadWebTask();
executeAsyncTask(lWT, getSherlockActivity().getApplicationContext());
}
FragmentPager
public class FragAdapter extends FragmentPagerAdapter {
private static final String[] CONTENT = new String[] { "frag0", "frag1",
"frag2", "frag3", "frag4", "frag5", "frag6" };
public FragAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
return MyListFragment.newInstance(arg0);
}
#Override
public int getCount() {
return CONTENT.length;
}
#Override
public CharSequence getPageTitle(int position) {
return CONTENT[position % CONTENT.length];
}
}
ListFragment
public class MyListFragment extends SherlockListFragment {
public static final String NAME_TAG = "name";
public static final String DESCRIPTION_TAG = "description";
private static int dow;
public static final String TAG = "listFragment";
// Keys used in Hashmap that will be mapped to the rows
String[] dFrom = { NAME_TAG, DESCRIPTION_TAG };
private ArrayList<HashMap<String, String>> list;
int[] dTo = { R.id.name, R.id.description };
public void upDateList() {
//**************************Not really sure if this is how things are supposed
//** to be done. For my small data- set i feel like it will work but i would
//** be interested in knowing how else this might be done.
ListFragmentDisplay lFD = (ListFragmentDisplay) this
.getParentFragment();
dList = lFD.getList(dow);
}
public static MyListFragment newInstance(int pos) {
MyListFragment frag = new MyListFragment();
dow = pos;
return (frag);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
upDateList();
View results = inflater.inflate(R.layout.list_fragment, container,
false);
SimpleAdapter adapter = new SimpleAdapter(getParentFragment()
.getActivity(), list, R.layout.listrow, dFrom, dTo);
setListAdapter(adapter);
return results;
}
}
Edit. Solved Code: In List Fragment
The Initial Question has been solved. I am only in the process of implementing the onPostExecute callback to the ListFragmentDisplay. Much Thanks to Luksprog for solving my very noobish mistake. I made dow static without knowing its affect. I think it was actually something that Eclipse offered to solve a conflict. I should have read it closer.
public class MyListFragment extends SherlockListFragment {
public static final String NAME_TAG = "name";
public static final String DESCRIPTION_TAG = "description";
public static final String TAG = "listFragment";
// Keys used in Hashmap that will be mapped to the rows
String[] dFrom = { NAME_TAG, DESCRIPTION_TAG };
private ArrayList<HashMap<String, String>> list;
int[] dTo = { R.id.name, R.id.description };
SimpleAdapter adapter = null; **NEW**
public void upDateList() {
ListFragmentDisplay lFD = (ListFragmentDisplay) this
.getParentFragment();
dList = lFD.getList(getArguments().getInt(TAG)); **NEW**
if(adapter != null) **NEW**
adapter.notifyDataSetChanged(); **NEW**
}
public static MyListFragment newInstance(int pos) {
MyListFragment frag = new MyListFragment();
Bundle args = new Bundle(); **NEW**
args.putInt(TAG, pos); **NEW**
frag.setArguments(args); **NEW**
return (frag);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
upDateList();
View results = inflater.inflate(R.layout.list_fragment, container,
false);
adapter = new SimpleAdapter(getParentFragment()
.getActivity(), list, R.layout.listrow, dFrom, dTo);
setListAdapter(adapter);
return results;
}
}
Is there any reason why you made the dow variable from MyListFragment as static? With the static keyword your fragments from the ViewPager will share their position so you'll call the lFD.getList(dow); method with the wrong position most of the cases. Make dow a private instance field: private int dow;
About the rest of the code, it looks ok, see if the change above solves the problem. To update your data in the inner fragments you could follow this scenario:
start with an empty list of data in ListFragmentDisplay and start the task
initially, your inner ListFragmnents will see that the data list is empty so you'll initialize them with an empty list(the getList(int day) method should just return an empty list if there is no data in the listByDay field)
your task now finishes. Suppose you have a callback from the onPostExecute method of the AsyncTask. In that callback which the ListFragmentDisplay will implement you'll update every Fragment from the ViewPager which is either currently visible to the user or it's in the FragmentPagerAdapter alive(so each Fragment which is not null and its getView() method doesn't return null from the ViewPager will be updated). The other Fragments will self update because the onCreateView method will need to be called for them and you have the updateList call in there.
For the point above keep in mind that calling the updateList method will not update a visible Fragment because in that method you just update the list of the Fragment you don't call notifyDataSetChanged on the adapter to let it know that the data has changed.
I have two almost identical ListFragment A & B, except that they draw data from their respective Asynctasker.
onListItemClick at A will result in Fragment A being replaced by B. However, my app always get stuck at the constructor of its CustomAdapter in B.
private class CustomAdapter_B extends ArrayAdapter<MatchType> {
// Stuck Here
CustomAdapter_B() {
super(getActivity(), R.layout.color_match_type_s2, matches_type_s2);
}
Fragment A
public class Fragment A extends ListFragment implements AsyncTaskCompleteListener<ArrayList<MatchType>>{
ArrayList<MatchType> matches_type = new ArrayList<MatchType>();
private ProgressDialog dialog;
private static FirstPageFragmentListener main_caller;
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
//Interface, triggering Fragment Replace in my Fragment Adapter
main_caller.onMySignalWithNum(1, (matches_type.get(position).getLink()));
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.dialog.show();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// AsyncTasker to draw data for ArrayAdapter
LoadMatchType lmt = new LoadMatchType(this);
lmt.execute();
}
#Override
public void onTaskComplete(ArrayList<MatchType> result) {
dialog.dismiss();
//result.remove(result.size()-1);
matches_type = result;
setListAdapter(new CustomAdapter());
}
}
//Custom Adapter
private class CustomAdapter extends ArrayAdapter<MatchType> {
CustomAdapter() {
super(getActivity(), R.layout.color_match_type, matches_type);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View row = convertView;
if (row == null) {
LayoutInflater inflater = getActivity().getLayoutInflater();
row = inflater.inflate(R.layout.color_match_type, parent, false);
}
TextView tv_type = (TextView) row.findViewById(R.id.textView_type);
tv_type.setText(matches_type.get(position).getType());
TextView tv_tweet = (TextView) row.findViewById(R.id.textView_tweet);
tv_tweet.setText(matches_type.get(position).getTweet());
TextView tv_tph = (TextView) row.findViewById(R.id.textView_tph);
tv_tph.setText(matches_type.get(position).getTph());
return row;
}
}
public static Fragment newInstance(
FirstPageFragmentListener pageFragmentListener) {
// TODO Auto-generated method stub
footOddsFragment frag = new footOddsFragment();
main_caller = pageFragmentListener;
return frag;
}
}
//INTERFACE
interface AsyncTaskCompleteListener<T> {
public void onTaskComplete(ArrayList<MatchType> result);
}
Fragment B is about the same.
The app will get stuck at Fragment B's CustomAdapter constructor and the screen will be blank.
Oh, and everything works fine if I abandon Fragment B and just call the Asynctasker_B in onListItemClick in Fragment A. Just that I can't press back to view the previous list.
Forget Fragment B. Override your back press, put an if in there to determine if List B is active, if it is, change it back, otherwise perform the normal back function.
public void onBackPressed() {
// Code here to change list or go back.
return;
}