How to update fragment in Swipe View with Tabs - android

the following: I'm using Swipe View with Tabs. Works quite smooth so far.
The thing is: I have two fragments/tabs. Each contains a ListView. I can remove an item from the left list. When I swipe to the right I want to update the list adapter so the left-deleted item is shown.
I tried onSwipeListerner, TabListener, onPageChangeListener (and on Resume() in the fragment itself). Nothing worked... Either the function is not called or I don't get the fragment object.
Does anybody know how I can call a function in my Fragment class when I swipe to this tab/fragment?
Thanks!

http://developer.android.com/training/basics/fragments/communicating.html#Deliver
I believe this is what you are looking to accomplish. But I don't think your plan of action is the best.
I would create an interface in my fragment where items will be deleted from such as
public class FragmentDeleteItemSharer extends Fragment{
// Interface in Fragment
public interface ShareDeletedItem{
// Interface method you will call from this fragment
public void shareItem(Object deletedItem);
}// end interface
// Instantiate the new Interface Callback
ShareDeletedItem mCallback = null;
// Override the onAttach Method
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
try{
// Attaches the Interface to the Activity
// must add "implements ShareDeletedItem" in your
// Activity or this Exception is thrown
mCallback = (ShareDeletedItem) activity;
}catch(Exception ex){
ex.printStackTrace();
}
}// end onAttach()
// the method which you use to
// remove an item from the current fragment's listview
// where position is from yourlistViewAdapter.getSelectedItemPosition();
public void removeListItem(int position){
// using the item position, get the item in your object array
Object objectToDelete = myObjects[position];
// pass this information to removeItemFromArray
// a method that creates a new object array from the data
Object [] newObjectList = removeItemFromArray(myObjects, objectToDelete);
// Then use the interface callback to tell activity item was deleted
mCallback.shareItem(objectToDelete);
// Call to the method where you update the UI with the Objects
// Are you using an arrayList? Not sure but probably have
// an ArrayList<Objects> myObjects, as reference above
updateUiWithData(newObjectList);
}
}// end this fragment
Then in your activity create an interface
public class MyActivity extends FragmentActivity implements ShareDeletedItem{
// Interface Object , must attach this interface to Fragment2, when its created
UpdateFragment2 mCallback = null;
// You must attach this interface to your Fragment2, when its created
// you could do so with your view pager, create a method that adds each
// fragment to the view pager, then call a new method like
// addinterface(fragmentReference)
public interface UpdateFragment2{
// method to call in your Fragment that shows queue of deletes
public void addItemtoList(Object newObject);
}
// Interface Callback from the Fragment that deletes an item
public void shareItem(Object deletedItem){
// call the interface method to share the item with the Fragment2
mCallback.addItemToList(deletedItem);
}
}
Finally, Implement this interface in your Fragment2
public class Fragment2 extends Fragment implements UpdateFragment2{
// Interface Method in charge of giving this fragment the deleted item
public void addItemToList(Object deletedItem){
// TODO: Add the Item to the list you currently have
// If the mObjects array is an array list
mObjects.add(mObjects[mObjects.length + 1], deletedItem);
}
}
Depending on how you create your fragments with your view pager call
try{
// or however you hold reference to the fragment
mCallBack = (UpdateFragment2) Fragment2.class;
}catch(Exception ex){ex.printStackTrace();}
This is the Full of It. Hope this helps you understand that the interface way is the way to go. This is kind of difficult to help with no code from you but this is how it is done. The hardest part is adding the interface to the fragment when you create the fragments with you view pager. Good Luck

Related

Set an ItemClickListener on FragmentStatePagerAdapter

I have implemented a ViewPager with FragmentStatePagerAdapter and i want an ItemClickListener so that i can open the detail screen when the user clicks on each fragment of the viewpager. I am not able to find any such methods which are available.
You should implement a callback interface to communicate between your fragments and your containing activity. In each fragment, set your needed listeners, and then pass any information needed back to your activity to handle the click.
public class MyFragment extends Fragment {
public interface MyFragmentListener {
void onTheActivityICareAbout();
}
private MyFragmentListener mCallback;
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mCallback = (MyFragmentListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement MyFragmentListener");
}
}
}
Then when you bind your view, set your listner to use the callback on whatever event you need and your activity has your centralized code to handle that. Any interface method can also be used to pass data back to the activity as well.
You can see this link for more details.
Your FragmentStatePageAdapter will have a method that looks like this:
override fun getItem(day: Int): Fragment = YourPageFrament.newInstance()
So, in the code for YourPageFragment, you can set on OnClickListener on the fragment itself.
You can set this listener by modifying the XML layout file for that fragment to include a Linear Layout or some kind of layout.
Then, in your YourPageFragment class, possibly in your onCreateView() method, you can set on OnClickListener on the fragment's layout.

Adding a listener between two fragments

I have two fragments, A and B let's say, where B contains a list. I would like to add a listener on Fragment B that notifies Fragment A of the chosen list item. I couldn't figure out how to initialize the listener in Fragment B since it is bad practice to pass arguments in fragment's constructors.
NOTE: Fragment B is contained inside Fragment A. i.e. I have a FrameLayout in Fragment A; and Fragment B covers that FrameLayout.
Any idea how I could do that?
If you're saying that Fragment B is a child fragment of Fragment A (that is, you've added it to Fragment A using Fragment A's getChildFragmentManager()), then you can use the same approach that you use for Activity interfaces, but using getParentFragment() instead of getActivity().
For example:
Fragment B:
#Override
public void onAttach(Context context) {
MyInterface myInterface = (MyInterface) getParentFragment();
}
Assuming that Fragment A implements MyInterface.
One convenience method we've used to avoid having to know whether a Fragment is hosted by another Fragment or an Activity is something like:
public static <T> getInterface(Class<T> interfaceClass, Fragment thisFragment) {
final Fragment parent = thisFragment.getParentFragment();
if (parent != null && interfaceClass.isAssignableFrom(parent)) {
return interfaceClass.cast(parent);
}
final Activity activity = thisFragment.getActivity();
if (activity != null && interfaceClass.isAssignableFrom(activity)) {
return interfaceClass.cast(activity);
}
return null;
}
Then you can just use:
MyInterface myInterface = getInterface(MyInterface.class, this);
and it doesn't matter whether Fragment B is hosted as a child Fragment or in an Activity directly.
A better approach for this situation, since what you want to do is communication between fragments, is to use an interface. You want to notify A when B has changed. This should be done through the parent activity. Here is the android documentation on the topic: https://developer.android.com/training/basics/fragments/communicating.html.
The gist of it is that you want to define an interface with a method called OnItemSelected (you can name it whatever you want). In B, you want a reference to this interface. When an item is selected, call your new OnItemSelected method. Implement this interface in the parent activity of the two fragments. In the implementation, you can put whatever code you want to modify A.
An example
CommunicationInterface
public interface CommunicationInterface {
public void onItemSelected(int position);
}
FragmentB
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
CommunicationInterface myInterface = (CommunicationInterface) getActivity();
// What ever else you want here
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
myInterface.onItemSelected(position);
}
MainActivity
public class MainActivity extends FragmentActivity implements CommunicationInterface {
// What ever other code you have
#Override
public void onItemSelected(int position) {
FragmentA fragA = (FragmentA)
getSupportFragmentManager().findFragmentById(R.id.fragment_a);
// Code to interact with Fragment A
}
Checkout the contract pattern https://gist.github.com/JakeWharton/2621173
If you are using multiple fragment, you dont have do it for every fragment, just add it to your BaseActivity if you have one.
This example shows the communication between activity and fragment. But for nested fragment you can replace the acitivy with getParentFragment();

android replacing fragment on event from another fragment

any android developer here? i need to ask something regarding communication between different fragment like i select something from list of fragment one and on that even fragment two is replaced with another layout?
i have listview adapter in fragment 1 and its view in fragment two.
in fragment one i have already implement onClickListener and switch by getting the position from clicklistener method. i used fragment manager but not getting the way i want.
please reply with code and explanation!
any help will be appreciated!
If I understand your question, what you're trying to implement is a "master-detail" flow. Let us call your first Fragment the list Fragment and your second Fragment the detail Fragment and let us assume that they both exist within a parent Activity.
To establish communication between your list Fragment and your detail Fragment, you could define a callback interface that the parent activity of both Fragments implement. So, in your list Fragment, you would have:
public class MyListFragment extends ListFragment {
// Create a reference to your callback
private ListItemSelectedListener mCallback;
// Define your callback interface
public interface ListItemSelectedListener {
onListItemSelected(int position, Object data);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the parent activity
mCallback.onListItemSelected(position, getData(position));
}
}
Then, your parent activity implements the callback listener and triggers a change in the detail Fragment when necessary.
public class MasterDetailActivity extends Activity
implements MyListFragment.ListItemSelectedListener {
//....
// Implement the callback method defined in the interface
public void onListItemSelected(int position, Object data) {
// Get a reference to your detail Fragment
DetailFragment detailFragment = (DetailFragment)
getFragmentManager().findFragmentById(R.id.detail_fragment);
/* This is assuming both the list fragment and the detail fragment
* exist within the parent Activity
*/
if (detailFragment != null) {
detailFragment.changeDetailView(position, data);
}
}
}
Check out Google's document on Fragment communication to learn more.

How to update the ListView of a Fragment from another Fragment?

How can I communicate a listview of a ListFragment after an event of a Fragment inside another Fragment?
In the ListFragment (fragment A) I have a method to refresh the ListView. But also, I need to refresh it after a click of a Button inside a Fragment, wich is child of another Fragment (fragment b)
Its like Fragment A (listFragment) | Fragment B (detailview)
(fragment C - child fragment of B)
How can I do it?
You can access another Fragment by its tag:
// find your fragment
YourFragment f = (YourFragment) getSupportFragmentManager().findFragmentByTag("yourFragTag");
// update the list view
f.updateListView();
The tag of your Fragment is set when it is attached to a container layout:
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.frameBuy, YourFragment.newInstance(), "yourFragTag").commit();
So when you click your Button, find the Fragment you want to refresh by its tag, and then call your refresh method.
IF you are using a ViewPager, this is how to get the Fragments tag:
/**
* Gets the fragment tag of a fragment at a specific position in the viewpager.
*
* #param pos the pos
* #return the fragment tag
*/
public String getFragmentTag(int pos){
return "android:switcher:"+R.id.yourViewPagerId+":"+pos;
}
You can do it with a few simple steps:
Create a listener interface for component to listen to the button click event from FragmentC. For example:
public interface FragmentCButtonListener {
public void onButtonClicked();
}
Add a method in FragmentC to allow listener registration. FragmentC will keep track of the listener, and call the listener callback as soon as the button is clicked. For example:
public class FragmentC extends Fragment {
FragmentCButtonListener myListener;
public void registerListener (FragmentCButtonListener listener) {
myListener = listener;
}
}
FragmentA should implement FragmentCButtonListener interface, register itself as a listener to FragmentC, and refresh the list view when it receives the callback from FragmentC. For example:
public class FragmentC extends Fragment implements FragementCButtonListener {
FragmentC fragmentC;
public void onCreate() {
fragment = new FragmentC();
fragment.registerListener (this);
}
public void onButtonClicked() {
//refresh the list view
}
}
Please note, I assume the FragmentA has a reference to FragmentC in the sample. If not, just make sure the container class of all fragments registers itself as the listener of FragmentC. The container class can as FragmentA to update listview once it receives callback from FragmentC.
follow these steps
We have two fragments called AddFragmentand ListFragment, and upon adding an item on first fragment you want the updated list be shown on list fragment (what sort of sorcery is this!!!).
Step 1 create the listener interface on class level of AddFragment with a method that is going to be implemented by the other guy (ListFragment ) and create Interface type variable
public class AddFragment extends Fragment{
//listener varriable
//listener
public interface OnCategoryAddedListener{
public void refreshList();
}
private static OnCategoryAddedListener meAddListener;
}
Step 2 create register method on class level of the same AddFragment class and set listenter variable
public class AddFragment extends Fragment{
public void registerListener(OnCategoryAddedListener listener)
{
meAddListener = listener;
}
}
Step 3 upon any event cud be button click or yelling at ur application(that is considered rude event in android :-) ) check for listener object meAddListener variable and call the interface,
in a Shakespeare’s nutshell it means “for thou who implement ye interface and brought the method within ur class shelter, I shall give u my utmost privilege and blessing to …. ”
Step 4 On ListFragment implement the AddFragment’s interface,no turning back just go implement its method. Within that method u just call abracadabra to repopulate ur list or any sort of updatable android view object… and ur done
public class ListFragment extends Fragment implements AddFragment.OnCattegoryAddedListener{
//refer to AddFragment
AddFragment addFragment;
//once the fragment is within the memory scope u instantiate AddFragment
//and register listener with AddFragment context which inherently implement OnCategoryAddedListener
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
categoryAddFragment = new CategoryAddFragment();
categoryAddFragment.registerListener(this);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
fillList();
}
public void fillList() {
ArrayAdapter<String> catArrayAdapter = new ArrayAdapter<>(context,android.R.layout.simple_list_item_1,getItems());
setListAdapter(catArrayAdapter);
}
//le interface method u can count on to refresh ur list content
public void refreshList(){
fillList();
}
check this out for a little more
enjoy the java magic

update TextView in fragment A when clicking button in fragment B

I have two fragments sitting side by side in the same activity. When I touch a button in the right fragment (fragment B), I need a TextView in the left fragment to update (fragment A). I have looked all over for the best way to do this, but nothing seems to work for my needs. Could someone possibly give me an example of how I would code this? Fragment A is set through the XML layout, and fragment B gets loaded programmatically into a container. I have tried accomplishing this by using a method in fragment A to update the text, and calling on that method from a method in the parent activity. I then call on the method in the parent activity from fragment B.
This is the code in fragment B that declares the interface and calls a method in the interface
AttackCards attackCards;
public interface AttackCards {
public void deckSize();
}
public void onAttach(DeckBuilder deckBuilder) {
super.onAttach(deckBuilder);
attackCards = (AttackCards) deckBuilder;
}
attackCards.deckSize(); //this is in my onclick methods
This is the code in the activity that implements the interface and calls the method in fragment A
public class DeckBuilder extends Activity implements AttackCards{
public void deckSize() {
DeckBuilderFragment deckBuilderFragment = (DeckBuilderFragment)getFragmentManager().
findFragmentById(R.id.deckbuilder_fragment);
deckBuilderFragment.deckSize();
}
This is the method in fragment A that appends the textview with the contents of a shared preferences value
public void deckSize() {
deckSize = (TextView) getView().findViewById(R.id.decksize);
final SharedPreferences defaultDeck = getActivity()
.getSharedPreferences("defaultDeck", Context.MODE_PRIVATE);
deckSize.setText(String.valueOf(defaultDeck.getInt("decksize", 0)));
}
Sadly this attempt simply brings me a nullpointer when touching a button. I am getting a null pointer at
attackCards.deckSize(); //this is in my onclick methods
Could someone please help me out with an example of how to do this correctly?
One fragment should not communicate to another fragment directly. It should do so through attached activity. The detail explanation with code example is available here
Android Developer site
Declare an interface in Fragment B, and implement the interface in the activity. Call the interface through callback in Fragment B when button is clicked. You can have a public function in Fragment A to update the TextView, so activity directly call the function to update the text.
You can define an interface in Fragment B and implement it on the MainActivity. Then on the callback method (onClickOnB in this case) set the text on the TextView. You should obtain a reference of the TextView in the Activity's onCreate() after setContentView(). This works because Fragment A is static. Otherwise, you can create a public method inside Fragment A so you can set the text from inside the callback by getting a reference of Fragment A and calling such method.
Fragment B
public class FragmentB extends Fragment implements onClickListener{
ClickOnB listener;
public void setOnFragmentBClickListener(ClickOnB listener){
this.listener = listener;
}
#Override
public void onClick(View v){
//stringMessage is a `String` you will pass to `Fragment` A to update its `TextView`
listener.onClickOnB(stringMessage);
}
interface ClickOnB{
public void onClickOnB(String message);
}
}
MainActivity
public class MainActivity extends Activity implements ClickOnB{
#Override
protected onCreate(Bundle savedInstanceState){
//Get a reference of `Fragment` B somewhere in your code after you added it dynamically and set the listener.
((FragmentB)getFragmentManager().findFragmentByTag("FragmentB")).setOnFragmentBClickListener(this);
}
#Override
public void onClickOnB(String message){
//Set the text to the `TextView` here (I am assuming you get a reference of the `TextView` in onCreate() after inflating your layout.
mTextView.setText(message);
}
}

Categories

Resources