How do you programmatically set ViewPager tabs from inside a fragment? - java

I have a database that provides an array of Strings, accessed from within a Fragment. I want these Strings to go back to the activity attached to the Fragment and set the titles of the tabs in a ViewPager. How can I do this?
This is how I want to do it:
Database String[] → Fragment → Attached activity's ViewPager → New
tabs
Edit: Here is my entire Activity and PagerAdapter code.
Here is my Fragment code

Suppose you have array of Strings and you want to send them to your activity from Fragment, make an interface like
public class MyFragment extends Fragment {
CustomStrings mCallback;
// Container Activity must implement this interface
public interface CustomStrings {
public void onStringRecieved(String[] stringss);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (CustomStrings) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
And then simple use this when you need to send data
mCallback.onStringRecieved(yourStrings); //your data here
And then in your activity implement it
public class MainActivity extends Activity
implements MyFragment.CustomStrings{
...
public void onStringRecieved(String[] stringss) {
// Do something here to use these strings
Toast.makeText(getContext(), ""+strings, Toast.LENGTH_SHORT).show();
}
Hope this solves your problem, for more information refer this

Related

SetText in fragment from outside class

I have a fragment that displays data from APIs, but i dont want to be calling apis everytime the fragment is called.. so am making api call from a different class and and calling a method in the fragment to update UI (textViews)
but am getting null exception for the textViews but data is 100% there
and if i try to hardcode textView.setText("Hello") it works..
one of the task of fragment is change ui !!! you must change ui in activity or fragment
you must use interface . your server class :
public class server {
.
.
.
public void callServer(IServerResponse iResponse){
.
.
.
iResponse.onResponse(//your data such as List or string or json and etc);
}
public interface IServerResponse{
// use parameter type as you want like List or string ,etc..
void onResponse(String data);
}
}
your fragment or activity implement your interface :
public class SomeFragment extends Fragment implements Server.IServerResponse{
....
#Override
public View onCreateView(...){
...
Server server=new Server();
server.callServer(this);
}
#Override
public void IServerResponse(String data){
textview.SetText(data);
}
}
You should create a FrameLayout in your activity
And use this code:
FragmentA newFragment = new FragmentA ();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container, newFragment).commit();
and than set your text
String editValueName= editName.getText().toString();
String lastStatus = valueStatus.getText().toString();
newFragment .setText(editValueName, lastStatus);
Try for quick fix if it is working for the output of your desire
Make Textview static in class(youractivity) where textview is originated like
public static TextView textview;
And in fragment
if(youractivity.textView!=null){ youractivity.textView.setText("your desire text"); }

FragmentManager has not been attached to a host [duplicate]

I have an Actvivity with a ListView, I set an adapter
MyAdapter extends BaseAdapter
that adapter has a callback interface
OnPdfClickedListener callback;
public interface OnPdfClickedListener {
public void onPdfClicked();
}
and in the Activity
MyActvivity implements MyAdapter.OnPdfClickedListener
and
#Override
public void onPdfClicked() {
Log.d("TEST", "PDF CLICKED in ACTVIIVTY");
}
This is pretty much the same as described here, which works like charm for fragments.
When trying the same from the adapter the callback object is null.
I also tried instantiating like
OnPdfClickedListener callback = new OnPdfClickedListener() {
#Override
public void onPdfClicked() {
// TODO Auto-generated method stub
}
};
I have no errors then but the respective method in the Activity is never called.
My question is 1. why isn't the callback object null when used in a fragment, it's never instantiated
and 2. how can I callback to an Activity from an adapter?
why isn't the callback object null when used in a fragment, it's never instantiated
Your Activity most likely isn't registered as a listener, with the callback variable you created(which has nothing to do with the Activity) an instance of OnPdfClickedListener and (probably) used that when the event happened.
how can I callback to an Activity from an adapter?
Pass a reference to the Activity to your MyAdapter class, cast it to OnPdfClickedListener and use that to call onPdfClicked instead of the current callback variable.
Try adding this:
In your Activity which implements the interface:
new MyAdapter(this,....);
In your Adapter:
MyAdapter(Context context, ...){
callback = (OnPdfClickedListener)context;
}

Editing Fragment UI items with AsynTask

I'm working on an Android application that finds the computers on local network. It using AsynTask in background to discover that devices, i'm also using fragment pages to show results. The problem is i'm not able to make AsyncTask to edit fragment items. How can i handle it
you can use interface for interaction between AsyncTask and your fragment:
interface TaskListener {
void onTaskComplete(Data data);
}
implement fragment ... TaskListener
class YourFragment implements TaskListener {
// your fragment code is here
#Override
public void onTaskComplete(Data data) {
//this method will call from AsyncTask
//update your fragment ui here
}
}
assign the TaskListener to the AsyncTask in Constructor
public AsycTask(TaskListener listener) {
this.listener = listener;
}
call the onTaskComplete in "onPostExecute" method of AsyncTask:
#Override
protected void onPostExecute(Data data) {
listener.onTaskComplete(data);
}
Only the activity which created the fragment can access the fragment. Create a function in the activity which changes the elements in the fragment. Then call that function from the AsyncTask and pass along any information the fragment will need in the parameters of the function.

Communication between Fragments without Using Interface

I was trying to communicate between two fragments, but I'm just a beginner so I want to know if there is any solution not using interface....
If there are Fragment A, B, and their Activity:
Sending values from Fragment A to Activity
(In here, Fragment A is a current state)
Sending values from Activity to Fragment B
I know direct communication between two fragments is almost impossible,
but I don't think that makes me to use an interface.
Also, is there any method to use like putExtra() for fragment? I only know using Serializable.
Have a look at the Android deverlopers page: http://developer.android.com/training/basics/fragments/communicating.html#DefineInterface
Basically, you define an interface in your Fragment A, and let your Activity implement that Interface. Now you can call the interface method in your Fragment, and your Activity will receive the event. Now in your activity, you can call your second Fragment to update the textview with the received value
// You Activity implements your interface
public class YourActivity implements FragmentA.TextClicked{
#Override
public void sendText(String text){
// Get Fragment B
FraB frag = (FragB)
getSupportFragmentManager().findFragmentById(R.id.fragment_b);
frag.updateText(text);
}
}
// Fragment A defines an Interface, and calls the method when needed
public class FragA extends Fragment{
TextClicked mCallback;
public interface TextClicked{
public void sendText(String text);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (TextClicked) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement TextClicked");
}
}
public void someMethod(){
mCallback.sendText("YOUR TEXT");
}
#Override
public void onDetach() {
mCallback = null; // => avoid leaking, thanks #Deepscorn
super.onDetach();
}
}
// Fragment B has a public method to do something with the text
public class FragB extends Fragment{
public void updateText(String text){
// Here you have it
}
}
You can communicate between fragments directly by using EventBus - send ordinary or sticky events by one fragment and subscribe to that event in another one.
If don't want message to be lost, use sticky events - it work as sticky Intent in Android. It will be around until it is removed by targer fragment or because another event is pending.
Yes you can transfer data between fragments using bundle like you do in Activity using putExtra
Bundle = bundle = new Bundle();
bundle.putString("key","value");
bundle.putSerializable("serialzedKey",SerializedValue);
FragmentTransaction fts = ((BaseActivity) mContext).getSupportFragmentManager().beginTransaction();
fragment.setArguments(bundle);
fts.add(R.id.fragmentHolder, fragment);
fts.addToBackStack(fragment.getClass().getSimpleName());
fts.commit();
In other fragment you can retrieve data using getArguments()
String key = getArguments().getString("key");
SerializedModel = getArguments().getSerializable("serialzedKey");
you can call a method from the parent activity class that calls a method from fragment B like ((YourActivity)getActivity()).callMethod(T yourData)
Take a look at my Github repo on using interfaces to communicate between fragments.
This is just a really simple example but displays the key concepts.
https://github.com/stoddayy/FragmentInteractionExample

Fragment communicating with an Activity

I am confused about how communication with a Fragment and an Activity is made. For example, an interface was defined here (https://developer.android.com/training/basics/fragments/communicating.html).
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
// Container Activity must implement this interface
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
...
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// The user clicked on a list item.
mCallback.onArticleSelected(position);
}
}
Eventually, the following method is called from the MainActivity.
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// Do something
}
}
My questions are:
How does mCallback "know" which onArticleSelected method to call (as there might be other classes that have implemented OnHeadlineSelectedListener).
mCallback.onArticleSelected(position);
I wouldn't be confused if it went:
mCallback = new OnHeadSelectedListener() {
#Override
public void onArticleSelected(int position)
// Do something
}
and then mCallback is referred in some way in MainActivity to utilize the onArticleSelected method in some way. In the example code, however, the line intelligently sticks to "an" interface. How does that happen?
Also, I found that the Log I implemented onArticleSelected method from MainActivity is called previously to the one in onListItemClick method in HeadlineFragment. Is it expected?
Since you defined the OnHeadlineSelectedListener interface with only one method, and your activity implements it, there's no ambiguity in choosing the method when you use the activity as instance of this interface, 'cause all you know about activity while using it as instance of OnHeadlineSelectedListener interface is a presence of onArticleSelected(int) method in it.
It depends on when you call the logging function - before or after calling the callback method.
P.S. While this kind of communication between Activity and Fragment (or any other objects) is perfectly fine, personally I prefer the Event Bus approach, 'cause it gives us a possibility to organize code in a low coupled manner. Here are some nice implementations of Event Bus pattern:
https://github.com/greenrobot/EventBus
http://square.github.io/otto/
Take a look at them if you are interested in this approach.
Your mCallback is your activity, in the onAttach method of your fragment, you will set the activity as listener for your fragment. By this way, this is normal that the activity is notified when you call mCallback.onArticleSelected(position);
For your first part of question
You should have a look on onAttach and onDetach methods-
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement OnHeadlineSelectedListener.");
}
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
Second part-
The behavior is not expected.
You should not make your activity class static as well.

Categories

Resources