Click button in one tab and change textview in the anoter tab - java

I have tab1 and tab3 also these have their classes and I want to click button in tab1 and change textview in the tab3, but I couldn't find anyway.
This is my tab1 class
public class tab1Contacts extends Fragment{
TextView tv;
EditText et;
TextView tv3;
personInfo pı;
public personInfo returnpı(){
return pı;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab1contents, container, false);
Button btn_jog = (Button) rootView.findViewById(R.id.jogging_button);
tv = (TextView) rootView.findViewById(R.id.newRecordText);
et = (EditText) rootView.findViewById(R.id.durationtext) ;
pı = new personInfo();
pı.eyesPower = 100;
pı.brainPower = 100;
pı.armsPower = 100;
pı.legsPower = 100;
pı.hearthPower = 100;
pı.energyLevel = 100;
pı.calorie = 2000;
pı.condition = 0;
btn_jog.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
int duration = Integer.parseInt(et.getText().toString());
pı.jogging(duration);
//I want to change here textview in the tab3.
}
});
return rootView;
}
}
This also my tab3 Class:
public class Tab3Contacts extends Fragment {
TextView tv3;
double newBrainpower;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab3contents, container, false);
tv3 = (TextView) rootView.findViewById(R.id.list_text) ;
return rootView;
}
}

btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//pager.setCurrentItem(yourindex);// if you use pager
getTabHost().setCurrentTab(yourindex);
}
});

If I'm reading your question correctly, then what you need is for tab3 to listen to events from tab1. For that you will want to implement some kind of internal notification/eventing system. This is typically handled through a notification handling class that will register observers/listeners.
An example from a project I've been maintaining:
public class NotificationManager {
public interface Observer {
public void update(String notificationName, Bundle data);
}
private static NotificationManager singletonNotifier = null;
private HashMap<String, ArrayList<Observer>> mObservables = null;
private NotificationManager() {
mObservables = new HashMap<String, ArrayList<Observer>>();
}
//enforce singleton
public static NotificationManager getInstance() {
if (singletonNotifier == null) {
singletonNotifier = new NotificationManager();
}
return singletonNotifier;
}
public void addObserver(String notificationName, Observer observer) {
// add to map
// in multi-threaded apps make sure you use synchronized or a mutex
}
public void removeObserver(String notificationName, Observer observer) {
// remove from map; mind threading
// overload as necessary for your design
}
public void notifyObservers(String notificationName, Bundle data) {
// go through your map of observers, build an array of observers
// that need to update, then for each observer, call
// observer.update(notificationName, data);
}
}
Then your tab3 class would need to implement the Observer interface and on object construction register itself with the NotificationManager with a string value for the type of notification it wants (use best practices for constants instead of string literal arguments), using the call
NotificationManager.getInstance().addObserver("Tab1DataChange", this);
It will need to implement the update(String, Bundle) method, which will make all the changes that you need.
Then in the class for the tab1 object, add to the click listener this call:
NotificationManager.getInstance().notifyObservers("Tab1DataChange", data);
Where data is any information that observers would need to know to respond. In keeping with the idea of decoupling code, do not put together a data bundle that is explicitly for one listener, because at some point you might need something else to listen for the same event. Save yourself some grief now by designing the data bundle to contain what would need to update regardless of who is consuming the event.
Some lessons learned for me:
Pay attention to Android lifecycle. OnPause and OnDestroy for the active view(s) should unregister the listener so that you don't end up with a null pointer exception if something triggers that event while the observer object is not available. OnCreate and OnResume should reregister. In some cases I have been able to not worry about OnPause/OnResume, but depending on your app you may need them.

Related

GetText from Fragment returns null but setText works

In my MainActivity I call a Fragment and set the boolean mFragment to true when its active. Now I set some Text in the TextViews declared in the Fragment and it works fine. But when a Button declared in the Fragment calls a Method in the MainActivity suddently mFragment is false and I can't use getText from the TextViews because they are null. I have no idea why this is so.
Main Activity
public class MainActivity extends AppCompatActivity implements SensorEventListener {
MainFragment mainFragment;
HistoryActivity historyFragment;
boolean mFragment = false;
//....
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainFragment = new MainFragment();
historyFragment = new HistoryActivity();
if(!mFragment) {
getMainFragment();
}
//...SenserManager and so on
#Override
public void onSensorChanged(SensorEvent event){
if (mFragment) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
DecimalFormat df = new DecimalFormat("0.000");
//This works constantly:
mainFragment.textViewX.setText("X = " + df.format(x));
mainFragment.textViewY.setText("Y = " + df.format(y));
mainFragment.textViewZ.setText("Z = " + df.format(z));
}
}
public void writeEntry(){ //called in Fragment
if(mFragment) {
//This doesn't work (isn't even called because mFragment is false)
String x = (String) mainFragment.textViewX.getText();
String y = (String) mainFragment.textViewY.getText();
String z = (String) mainFragment.textViewZ.getText();
}
}
public void getMainFragment() {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, mainFragment);
transaction.addToBackStack(null);
transaction.commit();
mFragment = true;
}
Fragment
public class MainFragment extends Fragment {
TextView textViewX;
TextView textViewY;
TextView textViewZ;
Button button;
MainActivity mainActivity = new MainActivity();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
textViewX = (TextView) view.findViewById(R.id.textViewX);
textViewY = (TextView) view.findViewById(R.id.textViewY);
textViewZ = (TextView) view.findViewById(R.id.textViewZ);
button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mainActivity.writeEntry();
}});
return view;
}
}
Use callback interface to interact from fragment back to activity. Please refer. It's a very recommended method. http://developer.android.com/training/basics/fragments/communicating.html#Implement
Your architecture has many flaws. You create a fragment instance and are then calling methods on it. You can't do this in android for components such as activities, fragments, services etc (You can only do this for Java classes). You cannot simply create an object of fragment like this. All Fragments, Activities and Services in Android must go through their respective lifecycles so that they have a valid context attached to them.
Also the fragment activity interaction should be done via interfaces. Not by simply calling methods on their objects which must not be created in the first place. You might get it working but ultimately it will keep causing you problems. I recently answered two questions this and this which had the same problem. Seems like lot of people have this doubt.
Your communication and a few point is wrong.
With below usage probably you wanted to access current MainAcitivity's method or fields. But this isn't the current instance of MainAcitivity. You just have instantiated a new one (also without lifecycle of activity)
MainActivity mainActivity = new MainActivity();
So this why the mFragment boolen variable is false and also other items are null, like textviews.
You could refer below links
http://developer.android.com/intl/es/training/basics/fragments/communicating.html
http://www.truiton.com/2015/12/android-activity-fragment-communication/

How to update custom RecyclerView from FragmentDialog?

I have an Activity A with a fragment frag2. Inside the fragment I have a RecyclerView and Adapter to show a list of custom class objects. Adding objects to the adapter is handled programmatically. I have a button inside TwoFragment that opens a FragmentDialog. I'd like to add an object to my Adapter by confirming this dialog, but it seems that the adapter is null when called from the FragmentDialog.
The same adapter is not null, and works if I call it from the fragment OnClick.
Moreover the adapter is null only after screen rotation, it works fine before rotating.
To communicate between the two Fragments I implement a communicator class in activity A.
Activity A
public void respond(String type) {
frag2.addSupport(type);
}
frag2
public RecyclerView rv;
public ArrayList<support> supports;
public myAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supports = new ArrayList<>();
adapter = new myAdapter(supports);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate( R.layout.fragment_two, container, false);
layout.setId(R.id.frag2);
if (savedInstanceState!=null)
{
supports = savedInstanceState.getParcelableArrayList("supports");
}
rv = (RecyclerView) layout.findViewById(R.id.rv);
adapter = new myAdapter(supports);
rv.setAdapter(myAdapter);
rv.setLayoutManager(new LinearLayoutManager(getActivity()));
rv.setItemAnimator(new DefaultItemAnimator());
#Override
public void onClick(View v) {
int id = v.getId();
switch (id){
case R.id.button1:
addSupport(type); // THIS WORKS ALWAYS, even after screen rotate
break;
case R.id.button2:
showDialog();
break;
}
}
public void showDialog(){
FragmentManager manager = getFragmentManager();
myDialog dialog = new myDialog();
dialog.show(manager, "dialog");
}
public void addSupport(String type){
adapter.addItem(new support(type)); // this line gives null pointer on adapter, but only if called after screen rotate and only if called from the dialog
}
dialog
communicator comm;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog, null);
comm = (myCommunicator) getActivity();
create = (Button) view.findViewById(R.id.button_ok);
create.setOnClickListener(this);
return view;
}
#Override
public void onClick(View v) {
if(v.getId()==R.id.button_ok)
{
// some controls to set type
comm.respond(type)
dismiss();
}
else {
dismiss();
}
myAdapter
public class myAdapter extends RecyclerView.Adapter<myAdapter.VH> {
private LayoutInflater inflater;
private ArrayList<support> data = new ArrayList<>();
// settings for viewholder
public myAdapter (ArrayList<support> data)
{
this.data=data;
}
public void addItem(support dataObj) {
data.add(dataObj);
notifyItemInserted(data.size());
}
}
logcat
FATAL EXCEPTION: main
java.lang.NullPointerException: Attempt to invoke virtual method 'myAdapter.addItem(myObject)' on a null object reference
I hope there are no mistakes, I shortened the code for better understanding. Keep in mind that everything works if I never rotate the screen.
I'm a beginner with android and I'm stuck with this for several days now. Please, help.
To understand the problem, it's as you say:
.. everything works if I never rotate the screen
So firstly to understand what happens on rotation, this is a quote from the Android Developer website:
Caution: Your activity will be destroyed and recreated each time the user rotates the screen. When the screen changes orientation, the system destroys and recreates the foreground activity because the screen configuration has changed and your activity might need to load alternative resources (such as the layout).
Ok, now to understand the error:
FATAL EXCEPTION: main
java.lang.NullPointerException: Attempt to invoke virtual method 'myAdapter.addItem(myObject)' on a null object reference
Essentially, in your dialog class, you have created a strong dependency by declaring :
comm = (myCommunicator) getActivity();
because comm references objects which would have been destroyed on rotation, hence the NullPointerException.
To further understand runtime changes, such as orientation changes, I'd recommend going through Handling Runtime Changes.
Update
Thank you for your answer, what would you recommend instead of comm = (myCommunicator) getActivity(); ?
The solution comes in 3 parts:
Make sure the onCreate of Activity A has the following:
#Override
public void onCreate(Bundle savedInstanceState) {
......
// find the retained fragment on activity restarts
FragmentManager fm = getFragmentManager();
frag2 = (Frag2) fm.findFragmentByTag(“frag2”);
// create frag2 only for the first time
if (frag2 == null) {
// add the fragment
frag2 = new Frag2();
fm.beginTransaction().add(frag2 , “frag2”).commit();
}
......
}
Add setRetainInstance(true) to the onCreate of frag2.
Remove the implicit referencing i.e. comm = (myCommunicator) getActivity();, and implement something more loosely coupled for dialog.
dialog
public interface Communicator {
void respond(String type);
}
Communicator comm;
....
public void addCommunicator(Communicator communicator) {
comm = communicator;
}
public void removeCommunicator() {
comm = null;
}
#Override
public void onClick(View v) {
if((v.getId()==R.id.button_ok) && (comm!=null))
{
// some controls to set type
comm.respond(type);
}
// Regardless of what button is pressed, the dialog will dismiss
dismiss();
}
This allows you do the following in frag2 (or any other class for that matter):
frag2
<pre><code>
public class Frag2 extends Fragment implements dialog.Communicator {
........
public void showDialog() {
FragmentManager manager = getFragmentManager();
myDialog dialog = new myDialog();
dialog.addCommunicator(this);
dialog.show(manager, "dialog");
}
#Override
public void respond(String type){
adapter.addItem(new support(type));
}
}

Problems with global variable in inner OnItemClickListener class

I have an android fragment, that has a listview. for that listview I implemented an inner OnItemClickListener class.
When there's a click, I save the selection in a global variable called SelectedIndex.
If I click again on that list, I can see the previous selection correctly, So its saving the state on the global variable correctly.
The problem is when I try to access to that same global variable from another inner class, for example, one class used for listen to clicks on a button. Is always showing the value I used for initialize the varialbe (-1).
The code of the fragment:
/**
* A placeholder fragment containing the view for the recentCalls list
*/
public class RecentCallsFragment extends Fragment {
private Cursor cursorAllRows;
private RecentCallsTable rcTable;
private ListView list;
private RecentCallsAdapter adapter;
Button btnDelete, btnCreditRequest, btnCreditBlock, btnSendTo;
int selectedIndex; //this is the global variable that I am using.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rcTable = new RecentCallsTable(getActivity());
cursorAllRows = rcTable.getRecentCallsCursor();
adapter = new RecentCallsAdapter(getActivity(), cursorAllRows);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
list = (ListView) view.findViewById(R.id.listViewMain);
btnDelete = (Button) getActivity().findViewById(R.id.buttonDelete);
btnCreditRequest = (Button) getActivity().findViewById(R.id.buttonCr);
btnCreditBlock = (Button) getActivity().findViewById(R.id.buttonCRD);
list.setAdapter(adapter);
list.setOnItemClickListener(new ItemClickHandler()); //Add the inner ItemClickLister
btnSendTo = (Button) getActivity().findViewById(R.id.buttonSendTo);
btnSendTo.setOnClickListener(new DebugOnClick());//here I add the inner clicklister
return view;
}
/**
* Class that handles the one click action on the list
*/
public class ItemClickHandler implements AdapterView.OnItemClickListener{
//when there's one fast click, keep the selection on the item or remove it if already has it
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
int prevSelection = adapter.getSelectedIndex();
Toast.makeText(getActivity(), Integer.toString(selectedIndex), Toast.LENGTH_SHORT).show();
int newSelection = position;
if(prevSelection == position){
newSelection = -1;
}
selectedIndex = newSelection; //here I change the value of the global variable
adapter.setSelectedIndex(newSelection);
adapter.notifyDataSetChanged();
}
}
public class DebugOnClick implements View.OnClickListener{
public DebugOnClick(){
}
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), Integer.toString(selectedIndex), Toast.LENGTH_SHORT).show(); //here I show the value of the global variable and is always -1
}
}
}
Which may be the problem?
There is one possibility that comes into my mind. When you have an inner class instantiated it implicitly binds with an instance of the hosting class (as if it were a reference of the hosting class). So I assume that the inner classes that you use are each linked with a different instance of the hosted class and thus using a different selectedIndex. Your global variable is not really global, its an instance variable.
I just found the problem. The buttons are in the main activity, so I just moved the global variable to the main Activity and started to manipulate it from the fragments like this:
MainActivity ma = (MainActivity) getActivity();
ma.rcSelected = newSelection;

Using Fragments and Creating "Starting Page"

I'm new in Android App developing via Java. I'm using Eclipse. If I create an Activity, Eclipse automatically generates a Placeholderfragment Class and Fragment.xml. Can I disable this function? Or is it not advisable to do that? I delete those files because I find it more complicated to use than just write in one xml file at the moment.
Second question is how do I implement a "starting Page" for my App? For example some sort of a logopage which automatically disables after a few seconds and switches to a new activity. Create a separate Activity for it or do I use something else?
Actually you need two activities, one startup Activity which is used to show your logo or some guide,the other is a MainActivity which should be started by the startUp Activity.
In short You can do something like this:
public class MainActivity extends FragmentActivity {
Fragment fragment;
String className;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("MainActivity", "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Store the name of the class
className=MainActivity.class.getSimpleName();
//First fragment should be mounted on oncreate of main activity
if (savedInstanceState == null) {
/*fragment=FragmentOne.newInstance();
getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment).addToBackStack(className).commit();
*/
Fragment newFragment = FragmentOne.newInstance();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container, newFragment).addToBackStack(null).commit();
Log.d("FRAGMENT-A", "fragment added to backstack");
}
}
}
FragmentOne.java
public class FragmentOne extends Fragment{
String className;
public static FragmentOne newInstance(){
Log.d("FragmentOne", "newInstance");
FragmentOne fragment = new FragmentOne();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d("FragmentOne", "onCreateView");
View view=inflater.inflate(R.layout.fragment_one, container, false);
//Store the name of the class
className=FragmentOne.class.getSimpleName();
return view;
}
}
Let me know if you need any more info
Well, in a Single Activity setup, the way I did this was the following:
public class SplashFragment extends Fragment implements View.OnClickListener
{
private volatile boolean showSplash = true;
private ReplaceWith activity_replaceWith;
private Button splashButton;
public SplashFragment()
{
super();
}
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
try
{
activity_replaceWith = (ReplaceWith) activity;
}
catch (ClassCastException e)
{
Log.e(getClass().getSimpleName(), "Activity of " + getClass().getSimpleName() + "must implement ReplaceWith interface!", e);
throw e;
}
startSwitcherThread();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_splash, container, false);
splashButton = (Button) rootView.findViewById(R.id.fragment_splash_button);
splashButton.setOnClickListener(this);
return rootView;
}
public void startSwitcherThread()
{
Thread splashDelay = new Thread()
{
#Override
public void run()
{
try
{
long millis = 0;
while (showSplash && millis < 4000)
{
sleep(100);
millis += 100;
}
showSplash = false;
switchToFirstScreen();
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
splashDelay.start();
}
private void switchToFirstScreen()
{
activity_replaceWith.replaceWith(new FirstFragment());
}
#Override
public void onClick(View v)
{
if(v == splashButton)
{
if(showSplash == false)
{
switchToFirstScreen();
}
}
};
}
Where the ReplaceWith interface is the following:
import android.support.v4.app.Fragment;
public interface ReplaceWith
{
public void replaceWith(Fragment fragment);
}
And the replace function is implemented like so:
#Override
public void replaceWith(Fragment fragment)
{
getSupportFragmentManager()
.beginTransaction().replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commit();
}
Now, most people will say this is not a good approach if you're using multiple activities, and/or using multiple orientations and aren't just simply displaying a single Fragment in a single Activity no matter what. And they are completely right in saying so.
Multiple orientations would require the Activity to be responsible for knowing what is the "next" Fragment at a given replace call, and where to place it (which container, or to start it in a new Activity). So this is a valid approach only if you are certain that you only have one container and there is one Fragment shown at a given time.
So basically, if this does not apply to you, then you need to utilize the same approach (make a specific delay before you replace the current Fragment or Activity with another one, this specific code allows you that once the splash has been shown once, then clicking the button will automatically take you to the next screen - typical game splash setup, really), but use activity callbacks specific to the Fragment in order to swap one out for the other.
A Fragment setup I recommend and isn't relying on this special case can be seen here: Simple Android Project or its equivalent on Code Review: Fragment Start-Up Project

Transferring multiple strings between Fragments of the same activity with tags

I am having trouble figuring out how to share data between my two fragments which are hosted on the same activity.
The objective:
I want to transfer string from the the selected position of a spinner and an image url string from a selected list view position from fragment A to fragment B.
The Attempt:
I read the fragments doc on this problem here http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
And went ahead an created the following Interface to use betweeen the Fragments and the Host Activity.
public interface OnSelectionListener {
public void OnSelectionListener(String img, String comments );
}
Then I proceeded to implement it in my fragment A's onCreateView method like so:
postList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
ListData link = data.get(position);
String permalink = link.getComments();
String largeImg = link.getImageUrl();
Fragment newFragment = new DetailsView();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
//pass data to host activity
selectionListener.OnSelectionListener(permalink,largeImg);
}
});
And also in the onAttach method
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
selectionListener = (OnSelectionListener)getActivity();
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement onSelectionListener");
}
}
In the Host activity I implemented the interface I wrote and overrided the method like so:
#Override
public void OnSelectionListener(String img, String comments) {
DetailsView detailsView = new DetailsView();
DetailsView dView = (DetailsView)getSupportFragmentManager().findFragmentByTag(detailsView.getCustomTag());
dView.setInformation(img, comments);
}
In Fragment B I set a "tag" the following way
private String tag;
public void setCustomTag(String tag)
{
this.tag = tag;
}
public String getCustomTag()
{
return tag;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setCustomTag("DETAILS_VIEW");
And my thinking is that that the information can be passed to Fragment B by calling this method from the host activity
void setInformation (String info, String img){
RedditDetailsTask detailsTask = new RedditDetailsTask(null,DetailsView.this);
detailsTask.execute(info);
setDrawable(img);
}
What I need:
I want to know how to properly use tags to get this to work, I dont have any fragment id's declared in my xml and rather opted to exchange fragments in a fragment_container.
I also am not sure if this is a good way to pass multiple strings between fragments. I am a newbie programmer so I know my logic probably looks pretty embarrassing but I am trying to do my best learn to do this right. I would appreciate it if you more senior developers can point me in the right direction for doing this.
You don't need to use tags. Take a look at this example. The Activity implements an interface that allows you to talk from Fragment1 back to the Activity, the Activity then relays the information into Fragment2.
I've left out all the android stuff about FragmentManager etc.
interface FragmentListener {
void onTalk(String s1);
}
public class MyActivity extends Activity implements FragmentListener {
Fragment2 fragment2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
// Find fragment2 and init
}
#Override
public void onTalk(String s1) {
fragment2.onListen(s1);
}
private static class Fragment1 extends Fragment {
private FragmentListener communication;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
communication = (FragmentListener) activity;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_one, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// or in an onClick listener
communication.onTalk("blah blah");
}
}
private static class Fragment2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_two, container, false);
}
public void onListen(String s1) {
Log.d("TADA", s1);
}
}
}
My approach would be, when you get the callback in activity through the OnSelectionListener interface, I would create the Fragment B object and set arguments to it as follows:
#Override
public void OnSelectionListener(String img, String comments) {
DetailsView detailsView = new DetailsView();
Bundle args=new Bundle();
args.putString("img",img);
args.putString("comments",comments);
detailsView.setArguments(args);
//code here to replace the fragment A with fragment B
}
Then in Fragment B's onCreate method you can retrieve the values as follows:
#Override
public void onCreate(Bundle savedInstanceState) {
Bundle args=getArguments();
String img=args.getString("img");
String comments=args.getString("comments");
//do whatever you want to do with the varaibles
}
You could try to make two public static String's in your B fragment.
it Would look like something like this
public static String img;
public static String comment;
The you set the variables before making the transaction to fragment B
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
SecondFragment.img = new String("imgString"); //Making a new string so incase you change the string in bfragment, the values wont change in here
SecondFragment.comment = new String("comment");
// Commit the transaction
transaction.commit();
Then in the onStop(), or onDestroy() - depending on when you want the variables to be null, check this - you set the the static variables to null, so they dont take memory space
public void onDestroy(){
super.onDestroy();
img = null;
comment = null;
}

Categories