ViewPager updates listView in fragment B from a fragment A - android

I have a ViewPager with two Fragments. On the first one, there are buttons (it is a menu) and they represent different categories. On the second one, it is a listView which display data.
I am looking for a way to change the data to display on the listView when the user click on one of the menu items.
For example : the user click on the menu item 1 (fragment 1), the listView on the fragment 2 have to be updated with the corresponding data.
I read the documentations from Google Android developer about fragments but I couldn't work it out, I didn't find a solution to my problem.
Maybe I'm missing something ?
EDIT : I tried to clear my ListView by clearing the list of data (ArrayList> listItems) with listItems.clear(). I didn't find how to do adapter.clear(), it seems that this method doesn't exist in the class Adapter.
So to summarize : I created an update method in my fragment which contains the ListView (Fragment2). I called it through a callback method in the main activity, that part seems to work (I checked it with debug mode).
In the update method of my Fragment 2, I clear data with listItems.clear() and then the OnActivityCreated() of the fragment is executed. In it, there is the call of my thread which download data and then it create the ListView in OnPostExecute.
Here is a sample of my code (fragment2) :
// After data are ready
lvListe = (ListView) getView().findViewById(R.id.lvListe);
lvListe.setSelected(true);
lvListe.setScrollingCacheEnabled(false);
adapter = new LazyAdapter(getActivity(),
getActivity().getBaseContext(), listItems,
R.layout.affichageitem, new String[] { "image", "title",
"subtitle" }, new int[] { R.id.img_title,
R.id.titre_main, R.id.soustitre_main });
lvListe.setAdapter(adapter);
lvListe.setClickable(true);
lvListe.setOnItemClickListener(onItemClickListener);
// Update method :
public void update(String requete, String type)
{
this.type = type;
this.requete = requete;
listItems.clear();
}

The way that I would probably do it is to create a callback method in the Activity hosting the ViewPager and also a method in the second Fragment to update the data.
Then you would call it like:
class Fragment1...
{
...
callBackUpdate(data);
}
class Activity...
{
...
public void callBackUpdate(String data)
{
Fragment2.update(data);
}
}
class Fragment2...
{
...
public void update(String data)
{
//do whatever
}
}
The developers page shows how to create a callback method to the Activity.
edit: Actually that's how the Developer's page says to do it. They create the interface OnArticleSelectedListener for the callback.
edit: I'm assuming you are using this library for the LazyLoader: https://github.com/thest1/LazyList
If so, then you can just add the method to clear the data yourself. To do so, add a method like this in ListAdapter:
public void clear()
{
data = new String[](); //depends on what data is, if it's a List then just call data.clear() for example
imageLoader=new ImageLoader(activity.getApplicationContext()); //clear the images
notifyDataSetChanged(); //notify the adapter that the data has changed
}
This might not exactly fit how you currently have it, but you should get the idea.

Try using something known as a FragmentTransaction manager at http://developer.android.com/reference/android/app/FragmentTransaction.html
and also the FragmentManager http://developer.android.com/reference/android/app/FragmentManager.html
Check out some of the questions on stackoverflow related to FragmentManager and FragmentTransaction to figure this out. All you need to do is replace the fragment with a new one which is inflated by a particular xml

Related

Populating a listview in a different fragment

I have this code, which gets data from various EditTexts and adds this info into a ListView_item in fragment 1. This ListView_item is supposed to be populated in the ListView in fragment 2. I was thinking this might be possible with the help of the EventBus library but I have not quite yet gotten my head around how.
Here is my populate list method
public void populateList() {
ArrayAdapter<Appointment> adapter = new AppointmentListAdapter();
(The listview in fragment 2).setAdapter(adapter);
}
You have two ways to do this :
1) Using Interface: You will find lots of links for how to use interface for data passing.
2) Pass adapter through the activity :
step 1 : In your Fragment1 Make getParent() method :
private MyActivity getParent() {
return ((MyActivity) getActivity());
}
step 2 : In MyActivity Make populateList() method :
public void populateList(ArrayAdapter<Appointment> adapter){
SecondFragment mSecondFragment = (SecondFragment) getFragmentManager().findFragmentByTag(SecondFragment.TAG);
mSecondFragment.setAdapter(adapter);
}
step 3 : In your Fragment1 populateList method look like below :
public void populateList() {
ArrayAdapter<Appointment> adapter = new AppointmentListAdapter();
getParent().populateList(adapter);
}

Android RecyclerView infinity scrolling: how to add more items to dataset

I have implemented my RecyclerView and even added an onscrolllistener to support infinity scrolling and now I'm stuck with a, hopefully, easy problem: How can I add the newly loaded data to the existing dataset?
My current approach: I create a new array with the length of the existing dataset + the length of the newly loaded data. I System.arraycopy my existing dataset and add the new content with a for-loop.
This works but the list is always reset (scrolls back to the top) and I assume my way to add additional content is overly complicated/wrong, though the tutorials I have looked at seem to pass over this "detail".
Update: I'm currently calling "scrollToPosition" on the UI-Thead after the data has been loaded, but I doubt this is the correct way of doing this or am I wrong?
You shouldn't be adding stuff to your dataset, you will sooner or later run out of memory. What you can do is return a big number (I used Short.MAX_VALUE) item in getItemCount inside your adapter and in the method that requests a view for postion you should do position % list.size();
It is not a truly endless RecyclerView this way, but good enough. I will paste some code tomorrow, I don't have it here now :/
I think you have to add items inside your adapter. Let`s say
class Adapter extends Recycler.Adapter<Recycler.ViewHolder>{
List<YourCustomObject> list;
public Adapter(){
list = new ArrayList<>();
}
public void addItem(YourCustomObject item){
list.add(item);
notifyItemDateSetChanged(); //This method for adapter to notice that list size have been changed
}
// Here your views
}
There is implementation of Your fragment or Activity where you retrieve data from internet.Let` say
class MainActivity extends AppCompactActivity{
Adapter adapter = new Adapter();
List<YourCustomObjects> objects;
public void onCreateView(){
//////// Something yours
}
public void onLoadMore(){
///// Your operation to retrieve data and init it to your list objects
for(YourCustomObject object : objects){
adapter.addItem(object);
}
}
}

Remove all items in custom BaseAdapter and add new ones

I'm getting trouble by doing some simple task with my adapter.
I've class that implementing BaseAdapter, associated to a ListView.
After I've created this adapter and showed it to the user, if some event occours, I would remove all elements inside adapter, and adding new ones.
I have implement this method inside my BaseAdapter:
public void clearAndBuild(ArrayList<PictureObject> new_pics, String some_text) {
pics.clear();
pics.addAll(new_pics);
this.hashtag = hashtag;
//do something else
}
(where pics is an ArrayList containing items to put inside ListView). In my activity, fo refresh all i call:
adapter.clearAndBuild(pics, tag);
adapter.notifyDataSetChanged();
but it doesn't work.
After i call that method, old items inside listView are removed, but new ones is not showed (i get an empty listview).
What's wrong?
the only reason could be that you are reusing the same references for pics and new_pics. Make a deep copy of new_pics before calling clear() on pics
you can do this:
public void clearAndBuild(ArrayList<PictureObject> new_pics, String some_text) {
pics. = new ArrayList<PictureObject>(new_pics);
this.hashtag = hashtag;
//do something else
}

How do I update ListView in another Fragment?

I have an Activity which holds a ViewPager with 2 Fragments. One fragment is for adding items to ListView and another fragment is holding the ListView.
I've been trying for almost 3 days now without any positive results. How do I update the other fragment's ListView from the first fragment?
I'm trying to call the method that updates ListView from the Activity that holds ViewPager but it doesn't work.
Calling the method from ViewPager activity :
#Override
public void onPageSelected(int position) {
library.populateListView(getApplicationContext());
aBar.setSelectedNavigationItem(position);
}
This is the populateListView method:
public void populateListView(Context context){
CustomListViewAdapter customAdapter = new CustomListViewAdapter(getDatabaseArrayList(context), getActivity());
if (lView != null)
{
lView.setAdapter(customAdapter);
}
customAdapter.notifyDataSetChanged();
}
However this doesn't work because the lView variable (ListView) is null because the fragment isn't shown at the moment when this is being called.
I am assuming that function populateListView() is a function of the Fragment containing the ListView. You are calling populateListView() on every call to onPageSelected. Should you not check what is the position that is being selected. Anyway the populateListView() method should be a public method of the Fragment containing ListView. And You Can Instantiate The Fragment from the Viewpager adapter in the Activity and than call this method. In That way the listView should not be null.
#Override
public void onPageSelected(int position) {
ListViewFragment frag=(ListViewFragment)adapter.instantiateItem(viewPager, 1);
//here adapter is the ViewPager Adapter and you must supply the viewpager that contains
//the fragments and also the position of the fragment to instantiate.
//For example 0 or 1 etc.
frag.populateListView(getApplicationContext());
aBar.setSelectedNavigationItem(position);
}
Understand Fragments
Please see this link. I have gone in great detail explaining the concept of fragments.
Pay particular attention to the definition of rootview:
public void onActivityCreared(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
// Do stuff on creation. This is usually where you add the bulk of your code. Like clickListners
// You can define this object as any element in any of your xml's
View rootview = inflater.inflate(R.layout.xml_the_fragment_uses container,false);
rootview.findViewById(R.id.your_id).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do something
}
});
}
In the above case I defined a button for an on click listener, but you can just as easily define a ListView along with its appropriate methods.
Alternate Solution
A second method could be using getView or getActivity (check the communicating with activity section).
For example:
ListView listView = (ListView) getView().findViewById(R.id.your_listView_id);
OR (more likely solution for your problem)
View listView = getActivity().findViewById(R.id.list);
Please read this post for additional information.
Good Luck.
To do this safely, you have to keep your listview data in a higher level Parent-Activity not the fragments. Make your MainActivityclass singleton class by making the constructor private and create a getInstance method that return the only initialized instance of your `MainActivity.
This will allow you to keep your data instance safe from being re-initialized or lost. Then, in onResume of your fragment re-set the data (get it from the MainActivity) to your listview adapter and call notifyDataSetChanged() method from the adapter instance.
This will do the trick.

Adapter not working

In my OncreateView() set the adapter which is working when i am first loading the page. When i go to another page and make changes then come back to this fragment it is not working adapter.notifyDatasetchanged().
#Override
public void onStart() {
super.onStart();
groupItem.clear();
childItem.clear();
List<String> child_Category;child_Category=new ArrayList<String>();
groupItem = obj_Listdatabase.fetchcategory();
childItem.clear();
ListIterator<String> iterator = groupItem
.listIterator();
while (iterator.hasNext()) {
String categoryname = iterator.next();
child_Category = new ArrayList<String>();
child_Category = obj_Listdatabase
.fetchchildlist(categoryname);
childItem.add(child_Category);
}
adapter.notifyDataSetChanged();
}
Hai I got output for this one:
groupItem.addAll(obj_Listdatabase.fetchcategory());
Instead of This
//groupItem = obj_Listdatabase.fetchcategory();
Because i change the reference in assignment statement(=) for that adapter.So i use addAll() method to store the values only instead of reference.
You should reaaaally indent your code more cleanly, never use several ";" on the same line for example.
And you can definitely use BaseExpandableListAdapter the issu is somewhere else..
You should also notice that onCreate view is more suitable for "creating view" so all the adapter stuff should be somewhere else like onViewCreated, or onActivityCreated as you need (it's just some advices)
I assume your adapter is in a Fragment since you use GetActivity() and in the constructor of your adapter you pass a reference to the activity (context), the group list and the child list.. ok
we ll assume that you are using the fragment onStart. From the official doc :
Called when the Fragment is visible to the user. This is generally tied to Activity.onStart of the containing Activity's lifecycle.
So normally this method is called after onViewCreate, onViewCreated .. etc at least the first time you code is running. So this is ok
Did you try using adapter.notifyDataSetInvalidate() and then do adapter.notidyDataSetChanged ?
One last thing, since you actually pass the data to your adapter by the constructor, when you update your lists how can the adapter be aware of the changes ? Are your lists global (static) ?
If not, before doing adapter.notifyDataSetChanged() you should pass the lists (group and child) to the adapter with some setter..
good luck

Categories

Resources