Pass data between fragments and view pager2 - java

I have a main fragment and two fragments in view pager (About/Reviews).
I call api to load data when navigation bar selected. I want to data model I have called api can be used between three fragments. I don't want to call api three times when the fragments load.

ok you want to call the api only once , that is when the activity is created right ?
ok for that initialize a int variable and set the value to 0;
int a=0;
then use condition to call your api
if(a==0)
{
//Your code To call Api
a=1;
}
So Here After U call Your Api Once "a is set to 1" which does not satisfy the condition and it does not call the api for the second time ...
but "a=0" when the your class or activity is created or called ..the api is also called
This Solution Is Given , Keeping That The Activity Is Not Recalled Or Recreated Unnecessarily ( Or The Activity Is Not Recalled/Recreated On Changing The Fragment )

when you create the fragment just pass the data.
Fragment fragment = new DemoFragment();
Bundle args = new Bundle();
args.putString("TERM", "FINEL TERM");
fragment.setArguments(args);
You can receive data from the fragment
Bundle args = getArguments();
String termStatus = args.getString("TERM")

Related

DialogFragment - show() method

I would like to see DialogFragment after pressing the button, I have two code snippets:
First:
if (view.equals(b1)) {
Fragment2 fr2 = new Fragment2();
fr2.show(manager, "addCity");
}
I don't understand why this tag is in the show () method, since it has no effect on program change.
Second:
Fragment fr = manager.findFragmentByTag("addCity");
if (view.equals(b1)) {
if (fr != null) {
manager.beginTransaction().remove(fr).commit();
}
Fragment2 fr2 = new Fragment2();
fr2.show(manager, "addCity");
}
In the second example, I don't understand what this line of code is for:
Fragment fr = manager.findFragmentByTag("addCity");
Since the reference variable fr will always be null because there is currently no fragment under the name of such a tag.
In addition, why does this condition appear, since just the previous change fr will always be null, so this if will never come true.
if (fr != null) {
manager.beginTransaction().remove(fr).commit();
}
When you use show(manager, "addCity"), then second parameter is the tag for the Fragment. By using findFragmentByTag() with the same tag, you're looking to see if the DialogFragment already exists and, if it does (fr != null), then remove it.
This is very defensive code, probably made in an attempt to avoid users very, very quickly double tapping the button. However, because it doesn't use showNow() (instead of show()), it actually doesn't do a good job at this because show() is asynchronous.
In general, you don't need this code at all - just call show() without any of the ceremony, using whatever tag you want (the tag only matters if you're later trying to use findFragmentByTag() to retrieve your DialogFragment after the fact).
But if you do want to be defensive and avoid even the extremely rare chance that the user opens up two dialogs, then you need to
1) Use showNow() instead of show() so that the FragmentManager is immediately updated, ensuring that findFragmentByTag() actually does return the Fragment in that case
2) Instead of removing and then calling show() again, just don't call show() if it already being shown - you're just doing extra work.
This would mean your code would look like
if (view.equals(b1)) {
Fragment existingDialog = manager.findFragmentByTag("addCity");
// Only add a new dialog if it isn't already present.
if (existingDialog == null) {
Fragment2 fr2 = new Fragment2();
fr2.showAll(manager, "addCity");
}
}

Issue trying to make a Arrayadapter into Int Array

Make an AdapterArray become an IntArray because I can't send to another activity an adapter array.
I'm creating a racing timer in Android Studio Java and I have saved my data about the race (example: time of all turns) in an Array Adapter. But when I try to send it to another Activity the function doesn't accept ArrayAdapter so I created a function to turn ArrayAdapter into an IntArray the problem is that whenever I run that function the program crashes.
I'm looking for an answer to this problem by correcting my code or doing a completely different one if I had to.
public int[] AdapterToInt(ArrayAdapter adapter)
{
int[] a = new int[adapter.getCount()];
for (int i = 0; i < adapter.getCount(); i++)
{
a[i] = Integer.valueOf(adapter.getItem(i));
}
return a;
}
public void onButtonClickSaveTimes(View view) {
int[] array;
array = AdapterToInt(adapter1);
TextView textoexemplo = (TextView) findViewById(R.id.textViewhorario);
Intent myIntent = new Intent(getBaseContext(), Main5Activity.class);
myIntent.putExtra("car1", AdapterToInt(adapter1));
myIntent.putExtra("car2", AdapterToInt(adapter2));
myIntent.putExtra("car3", AdapterToInt(adapter3));
myIntent.putExtra("car4", AdapterToInt(adapter4));
myIntent.putExtra("car5", AdapterToInt(adapter5));
startActivity(myIntent);
}
I expect it to send the ArrayAdapter to another activity or at least making my function work and turn ArrayAdapter into ArrayInt so i can send it through myIntent.putExtra, but the actual output is a app crash.
The problem is likely here:
a[i] = Integer.valueOf(adapter.getItem(i));
Since adapater.getItem(i) returns an object that you likely will not be able to convert into an integer, you are probably going to have issues here.
You could instead use adapter.getItemId(i) which would return a long as opposed to an object.
However, that idea also doesn't seem to great so I would try to see if anything from here works for you.
And if none of that works it probably makes more sense to just send over all the data you need to reconstruct your ArrayAdapter to the other activity.
This link may also help:
How do I pass custom ArrayAdapter Object between Intents with serialization

Fragment unable to restore correct View on rotate

I'm using a fragment with two primary views that have setVisibility() to show or hide based on the results of an AsyncTask used to search for data online.
For example, here is the method to switch between Views:
private void switchView()
{
Log.d(LOG_TAG, "switchView(): show = " + show);
mListView.setVisibility(show ? View.VISIBLE : View.GONE);
searchView.setVisibility(show ? View.GONE : View.VISIBLE);
mCompanyArrayAdapter.notifyDataSetChanged();
}
I'm taking this approach so that when the AsyncTask is complete it can parse the data into wrapper classes and create an ArrayList of these objects for use in the ListView adapter. (If there is another way to pass custom classes to another fragment, I would be open to using that.)
Once result == true from Async it hides the searchView and shows the mListView. However on rotate, the screen returns back to the searchView instead of continuing to display the mListView results.
I'm confused by the Log output that shows what I believe to two calls to onCreateView from the same fragment (DiscoverFragment), seen here:
10-17 10:29:21.872 6603-6603/nz.co.exium.panther D/DiscoverFragment﹕ onCreateView: savedinstancestate is null = false
10-17 10:29:21.877 6603-6603/nz.co.exium.panther D/AbsListView﹕ Get MotionRecognitionManager
10-17 10:29:21.882 6603-6603/nz.co.exium.panther D/DiscoverFragment﹕ onCreateView: savedinstancestate is null = true
So the first shows that the savedInstanceState is found != null and sets the boolean value appropriately but then another onCreateView() is called where savedInstanceState is null and sets it back to false. Why the double onCreateView() after rotate?
Thanks for the help.
As requested, code that replaces the fragments in the MainActivity (using a FrameLayout for the content_frame and position == DrawerLayout position item).:
getFragmentManager().beginTransaction()
.replace(R.id.content_frame, Fragment.instantiate(
getApplicationContext(), mClasses[position]))
.commit();
From my MainActivity.onCreate():
if (savedInstanceState == null) {
selectItem(0);
} else if (placeID == null || placeID.isEmpty()) {
selectItem(savedInstanceState.getInt(SELECTED_KEY));
} else {
selectItem(2);
}
I already perform a check for a previous savedInstanceState, if null set the default Fragment. If the variable placeID (from a BroadcastReceiver) is null/empty then restore previous state. Else, go to the Fragment that will display the Notifications data.
Fragments are automatically recreated on rotation as part of restoring the state. Therefore you should only call selectItem() when savedInstanceState == null - otherwise you'll get your restored fragment (with its restored state), then immediately replace it with a brand new instance (without the restored state).
So, what happens here is this:
Your activity is created, and one fragment is added to it
You rotate your device
Your activity gets recreated (along with the fragment previously added), and in onCreate, you add a new fragment, which means you have two fragments added in your activity
the easiest way to deal with this is to perform a check in your activity:
if (savedInstanceState == null){ // add fragment }
the other method is to prevent activity recreation by specifying config changes in your AndroidManifest.xml

Getting a value from a class extending activity in a plugin

When jumping from Activity to activity via Cordova, plugin, i want to be able to put additional information into a bundle and pass it along with the intent. I seem to have issues getting the current activity and then getting a value via
public int getCounter(){return counter;}
I have a Activity Definition which, onCreate will set counter to a value from the passed in bundle.
I have a Cordova plugin then which i am working with, which will carry out the intent to next activity.
Echo Class is a mediary which will jump between acticities based on html clicks.
//In the Class: public class Echo extends CordovaPlugin
private void launchSecondActivity(String data, CallbackContext cc){
Bundle b = new Bundle();
int tmp = ((SecondaryActivity)cordova.getActivity()).getCounter();
tmp++;
b.putInt("id", tmp);
Intent i = new Intent(cordova.getActivity().getApplicationContext(), SecondaryActivity.class);
i.putExtras(b);
cordova.getActivity().startActivity(i);
cc.success();
}
It seems that it causes a seg fault of sorts, when i am trying to assign counter to tmp, in the line:
int tmp = ((SecondaryActivity)cordova.getActivity()).getCounter();
Is there something i am doing wrong? I am trying to get the currently active activity, and then call a public function in that activity.
End Goal: I am trying to take an int, and keep passing it into intents, incremented. So that way, it will know how deep into the activity chain it is. I am working on nested state saving and curious as to the depth i am at, at any given time. The tmp being passed into the activity will be incremented each time, so it will maintain a depth.
Instead of creating a class with get counter, storing the int in the Bundle and passing it to the next activity would be far easier.
Example:
//send item to plugin.
int item = 0; // or whatever it is
Bundle b = new Bundle();
b.put("ident", item);
Intent i = new Intent();
i.putExtras();
//...
And then on the next activity.
public void onCreate(Bundle savedInstanceState)
{
int item = getIntent().getExtras().getInt("ident");
}
Then you can do with it what you will. The answer overall while the previous activity as the old number. What does that mean? It means that you can increment and do whatever you want with it when passing it to the next activity. It is copied, so you can incrememnet and store it recursively. Allowing you to even say something like:
if (item ==0){/*set new source for Activity*/}
else if(item == 1){/*set source 2*/}
//etc.

Android - Add Custom View to ListView

I have a ListView, and I have a custom View, PostView.
How would I go about creating a new PostView(), and adding it to the ListView via .addFooterView(), but still being able to access the object representation of the PostView.
Right now I'm trying:
// the footer
p = new PostView( this );
p.setTargetUri( C.API_CONTENT );
p.setRenderMode( PostView.MODE_TEXT | PostView.MODE_IMAGE );
commentListView.addFooterView( p );
But that is failing, when I try to access the should have been inflated XML components.
Mainly:
public void setRenderMode( int renderMode )
{
this.renderMode = renderMode;
// fails
this.postImagePreview = (ImageView)findViewById( R.id.new_post_image_preview );
}
Am I going about this wrong? I have an onFinishInflate() defined, but maybe I'm prematurely accessing the Views?
Why not hang on to the instance in a member variable instead of calling findViewById later?
Is your setRenderMode within PostView or the Activity that uses PostView?
If it is in the activity, you should be doing:
this.postImagePreview = (ImageView)p.findViewById( R.id.new_post_image_preview );
with p being a reference to your PostView that you have created.
The solution for me was to just have a super custom List Adapter, that was capable of returning different types of views, and manually adding a header and footer view around the generated list content.

Categories

Resources