in my application there is an activity which is having multiple fragments and activity having a spinner when the change operation occurs on spinner then all fragment should change the value, suppose
Activity temp --> fragment A --> fragment B --> fragment C
i can pass data from activity to fragment A -->B-->C using intent but if current fragment is C and the value changes from spinner then fragment C should have latest value and when i press back button then flow is
fragment C --> fragment B --> Fragment A should have latest values,
so how to maintain multiple fragment data passing from single activity
Acivity temp.java
public interface FragmentCommunicator {
void passDataToFragment(String data);
}
private class onItemSelect implements android.widget.AdapterView.OnItemSelectedListener {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (f instanceof FragmentA) {
fragmentCommunicator.passDataToFragment(data[position]);
}
}
}
FragmentA.java
public class FragmentA extends Fragment implements temp.FragmentCommunicator {
#Override
public void passDataToFragment(String data) {
this.data = data;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
((temp) context).fragmentCommunicator = this;
}
}
Using Interface we can achieve it. Simply we can call it as Data change listener.
Just follow my code to know how it works.
1.TempActivity.java
public class TempActivity extends AppCompatActivity {
public List<FragmentCommunicator> fragmentCommunicators = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_temp);
final Spinner spinner1 = (Spinner) findViewById(R.id.spinner1);
spinner1.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new String[]{"Value One", "Value Two", "Value Three"}));
spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
for (FragmentCommunicator fragmentCommunicator : fragmentCommunicators) {
fragmentCommunicator.passDataToFragment(spinner1.getSelectedItem().toString());
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
ViewPager viewPager1 = (ViewPager) findViewById(R.id.viewPager1);
FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager());
adapter.addFragment(new FirstFragment(), "FirstFragment");
adapter.addFragment(new SecondFragment(), "SecondFragment");
adapter.addFragment(new ThirdFragment(), "ThirdFragment");
viewPager1.setAdapter(adapter);
viewPager1.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
for (FragmentCommunicator fragmentCommunicator : fragmentCommunicators) {
fragmentCommunicator.passDataToFragment(spinner1.getSelectedItem().toString());
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
2.activity_temp.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Spinner
android:id="#+id/spinner1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp" />
<android.support.v4.view.ViewPager
android:id="#+id/viewPager1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
3.FragmentCommunicator.java
public interface FragmentCommunicator {
void passDataToFragment(String data);
}
4.FragmentAdapter.java
public class FragmentAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public FragmentAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
5.FirstFragment.java
public class FirstFragment extends Fragment implements FragmentCommunicator {
private TextView textView1;
public FirstFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_first, container, false);
textView1 = (TextView) view.findViewById(R.id.textView1);
if (getActivity() instanceof TempActivity) {
((TempActivity) getActivity()).fragmentCommunicators.add(this);
}
return view;
}
#Override
public void passDataToFragment(String data) {
textView1.setText(data);
}
}
6.fragment_first.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_orange_light">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#android:color/black"
android:textSize="24sp" />
</FrameLayout>
7.Follow same steps for remaining fragments.
Create new fragment.
Implement FragmentCommunicator interface.
Add implemented interface in Activity’s interface list.
8.Build and run you application. We achieved.
You can grab my example project here.
Happy coding…
Please use LocalBroardCast or eventBus, both is same:
Evenbus example
Check for Observer pattern. I do this for multiple fragments of each tab. All fragments implement an interface with sendData(String data) method and MainActivity has a addListener method that adds these interfaces to list object. All fragments use(MainActivity)activity.addListener(this); to register itself as an observer.
If an event triggers sending data, using foreach loop in MainActivity send data to send all registered listeners, in this case fragments.
Like all registers i register in onResume and remove listeners(empty list) onPause methods.
I would do it like this:
Create a new interface to provide the data needed to the fragments.
for example:
public interface MyDataInterface {
Data getDate();
}
Implement the interface in your Activity:
public class MainActivity extends Activity implements MyDataInterface {
// ...
#Override
public Data getDate() {
return dataForFragments;
}
}
Now when your Fragment is attached to the Activity (it's context),
Check if the context is implementing your interface and then use it to pull data from the Activity.
public class MyFargment extends Fragment {
private Data mData;
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof MyDataInterface) {
MyDataInterface myDataInterface = (MyDataInterface) context;
mData = myDataInterface.getDate();
}
}
}
And if you need the data inside your Fragment onResume() method:
#Override
public void onResume() {
super.onResume();
if (getActivity() instanceof MyDataInterface) {
MyDataInterface myDataInterface = (MyDataInterface) getActivity();
mData = myDataInterface.getDate();
}
}
/Try to implement the below code Snippet/
Make a Public String or any type of Method in your Activity atatched to Fragments
Inside your Activity:
String name = "Jack";
public String getname()
{
return name;
}
Inside your Fragment:
Activity mactivity;
MainActivity main_activity;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mactivity = getActivity();
main_activity = (MainActivity) mactivity;
String name = main_activity.getname();
}
That's all same this for all the fragments..Using this you can transfer data form Single Activity to all Multiple Attached Fragments.
Related
here i have a fragment interaction, where if recycler view item get clicked it passed data to MainActivity and then MainActivity call DetailFragment.updateText() method to update it's view but the views are not initialized even though i did that in onViewCreated(), if DetailFragment.updateText() is getting called before views are initialized then how can i make sure they get called after views have been initialized.
* note i added the DetailFragment to a DetailActivity through XML fragment tag, and the same for ListFragment and MainActivity
MainActivity
public class MainActivity extends AppCompatActivity implements ListFragment.Listener {
// the method to be called when an item in recycler view is clicked
// so i can pass this data to DetailFragment
#Override
public void listenerMethod(String firstName, String lastName) {
DetailFragment detailFragment = new DetailFragment();
detailFragment.updateText(firstName, lastName);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
ListFragment
public class ListFragment extends Fragment {
private static final String TAG = "ListFragment";
private RecyclerView recyclerView;
private RecyclerViewAdapter recyclerViewAdapter;
// fragment communication interface
public interface Listener {
void listenerMethod(String firstName, String lastName);
}
private Listener listener;
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
try {
this.listener = (Listener) context;
} catch (ClassCastException e) {
Log.d(TAG, "onAttach: "+ e.getMessage());
}
}
public ListFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_list, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
recyclerView = getView().findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
// some dummy data to fill the recycler view
ArrayList<User> users = new ArrayList<>();
users.add(new User("hiwa", "jalal"));
users.add(new User("mohammed", "abdullah"));
recyclerViewAdapter = new RecyclerViewAdapter(users, getActivity(), listener);
recyclerView.setAdapter(recyclerViewAdapter);
}
}
RecyclerViewAdapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private List<User> userList;
private Context context;
private ListFragment.Listener listener;
public RecyclerViewAdapter(List<User> userList, Context context, ListFragment.Listener listener) {
this.userList = userList;
this.context = context;
this.listener = listener;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_row
, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
User user = userList.get(position);
holder.tvFirstName.setText(user.getFirstName());
holder.tvLastName.setText(user.getLastName());
}
#Override
public int getItemCount() {
return userList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvFirstName;
public TextView tvLastName;
public ViewHolder(#NonNull View itemView) {
super(itemView);
tvFirstName = itemView.findViewById(R.id.row_first_name);
tvLastName = itemView.findViewById(R.id.row_last_name);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
User user = userList.get(getAdapterPosition);
listener.listenerMethod(user.getFirstName(), user.getLastName());
}
});
}
}
}
DetailFragment
public class DetailFragment extends Fragment {
private TextView tvFirstName;
private TextView tvLastName;
public DetailFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_detail, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tvFirstName = view.findViewById(R.id.detail_frag_first_name);
tvLastName = view.findViewById(R.id.detail_frag_last_name);
}
// update the details fragment views
public void updateText(String firstName, String lastName) {
tvFirstName.setText(firstName);
tvLastName.setText(lastName);
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<fragment
android:id="#+id/main_fragment_list"
android:name="com.example.peacewithfragments.ListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
activity_detail
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DetailsActivity">
<fragment
android:id="#+id/detailsActivity_fragment_container"
android:name="com.example.peacewithfragments.DetailFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
You create a new instance of the DetialsFragment every time you trigger the method of your listener. If you have defined the fragment in your layout xml, you must get the correct instance of the fragment from the fragmentmanager (or supportFragmentManager as you are using AppCompatActivity.
#Override
public void listenerMethod(String firstName, String lastName) {
// find the fragment by its id, sometihng like that
// id is the fragments id you defined in the layout xml
DetailsFragment detailFragment = (DetailsFragment)supportFragmentManager.findFragementById(R.id.frag_details);
detailFragment.updateText(firstName, lastName);
}
You can't directly access DetailFragment from your MainActivity as it's not part of MainActivity. So, first you have to navigate to DetailActivity and then access DetailFragment. Check below:
public class MainActivity extends AppCompatActivity implements ListFragment.Listener {
private DetailFragment detailFragment;
#Override
public void listenerMethod(String firstName, String lastName) {
if(detailFragment != null) {
detailFragment.updateText(firstName, lastName);
} else {
Intent detailIntent = new Intent(this, DetailsActivity.class);
detailIntent.putExtra("FirstName", firstName);
detailIntent.putExtra("LastName", lastName);
startActivity(detailIntent);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View view = findViewById(R.id.tablet_detail_container);
if (view != null) {
detailFragment = new DetailFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.tablet_detail_container, detailFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
}
Then in your DetailsActivity accept those extra and pass it to DetailFragment like below:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
...
String firstName = getIntent().getStringExtra("FirstName");
String lastName = getIntent().getStringExtra("LastName");
DetailFragment detailFragment = getSupportFragmentManager().findFragmentById(R.id.detailsActivity_fragment_container);
if(detailFragment != null)
detailFragment.updateText(firstName, lastName);
}
This is an adapter for my RecyclerView. It is meant to pass data from the RecyclerView to my Fragment, but I'm not able to do that from the onClick() method.
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bundle bundle = new Bundle();
bundle.putString("name",name.getText().toString() );
OneFragment myFrag = new OneFragment();
myFrag.setArguments(bundle);
}
My Fragment
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
txt_name=(TextView) txt_name.findViewById(R.id.name_emp);
String name = getArguments().getString("name");
txt_name.setText(name);
}
I'm not sure what are you intending to do. But after you set a bundle to a fragment you have to start the fragment with a transaction like this
getSupportFragmentManager().beginTransaction().add(<id of the container>, myFrag).commit();
Look the documentation on fragments
Like Below code create a method to your Activity, Where you have fragment :
Recyclerview Adapter Code :
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity)context).sendData(name.getText().toString());
}
Get String in your MainActivity and call Fragment from Activity :
MainActivity Code :
String name;
public void sendData(String nameAdapter)
{
name = nameAdapter;
if(name!=null){
MedicineFragment med_frag = MedicineFragment.newInstance(name);
getSupportFragmentManager().beginTransaction()
.replace(R.id.content_frame, med_frag)
.commit();
}
}
get name of Name in your fragment like this :
Fragment Code :
String name;
public static MedicineFragment newInstance(String nameValue) {
Bundle args = new Bundle();
MedicineFragment fragment = new MedicineFragment();
name = nameValue;
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
inside your main_activity.xml you have to take FrameLayout , by only this layout your fragment will change one to another.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/search_layout"
android:background="#color/blue_veryLight"
android:id="#+id/content_frame">
</FrameLayout>
I know that I am late to the party. Still, I'll post an answer here.
In your adapter class make these changes.
public class FooAdapter extends extends RecyclerView.Adapter<FooAdapter.FooHolder> {
private RvClickListener mClickListener;
......
// rest of the code here
......
public FooAdapter(<other parameters>, RvClickListener clickListener) {
.....
// other variables initializations here
.....
mClickListener = clickListener;
}
......
// rest of the code here
......
#Override
public void onBindViewHolder(FooHolder holder, int position) {
// rest of the code
holder.itemView.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mClickListener != null) {
mClickListener.onClick(name.getText().toString());
}
}
});
}
// other codes here
public interface RvClickListener {
void onClick(String name);
}
}
Now it's time to the adapter in our Fragment class. You need to change the code as below.
public class FooFragment extends Fragment {
// other codes here
// before setting adapter to RecyclerView make these changes.
FooAdapter adapter = new FooAdapter(
<other parameters>,
new RvClickListener() {
#Override
public void onClick(String name) {
// do whatever you want
}
});
}
In my main activity I have multiple Fragments that you can navigate through a bottom navigation (Replace a FrameLayout container in main activity XML)
One of those Fragments contains a ViewPager that should show multiple Fragments (MyFragment) using a FragmentStatePagerAdapter (MyAdapter).
First time I open that Fragment it works just fine but when I navigate to a different one and then come back the first two Fragments in the Pager are grey and unpopulated. Anyone got an idea what the problem might be?
The Adapter is set up like this:
This is called in onFragmentViewCreated
private void setUpHeaderPager() {
featuredAdapter = new MyAdapter(getActivity().getSupportFragmentManager());
myPager.setAdapter(myAdapter);
pageIndicatorView.setViewPager(myPager);
pageIndicatorView.setAnimationType(AnimationType.WORM);
compositeSubscription.add(apiService.getMyPOJOs()
.subscribeOn(networkScheduler)
.observeOn(uiScheduler)
.subscribe(new Action1<List<MyPOJO>>() {
#Override
public void call(List<MyPOJO> myPOJOs) {
myAdapter.setItems(myPOJOs);
pageIndicatorView.setCount(myPOJOs.size());
myPager.setCurrentItem(0);
pageIndicatorView.setSelection(0);
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
throwable.printStackTrace();
}
}));
}
And this is what the Adapter looks like:
private class MyAdapter extends FragmentStatePagerAdapter {
private List<SomePOJO> items = new ArrayList<>(0);
public void setItems(#Nonnull List<Collection> items) {
this.items = items;
notifyDataSetChanged();
}
FeaturedReleasesAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public Fragment getItem(int position) {
return MyFragment.newInstance(items.get(position));
}
#Override
public int getCount() {
return items.size();
}
}
Just in case the relevant code of MyFragment:
public class FeaturedReleaseFragment extends BaseFragment {
private MyPOJO someObject = null;
// Bind some views
public static MyFragment newInstance(MyPOJO someObject) {
MyFragment fragment = new MyFragment();
fragment.someObject = someObject;
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_my_fragment, container, false);
ButterKnife.bind(this, rootView);
populate();
return rootView;
}
private void populate() {
if (MyPOJO != null) {
// set some text and load images
}
}
onFragmentViewCreated is called just fine, the adapters getItem is not...
It may be how you're navigating between the bottom navigation fragments and subsequently whats happening with their lifecycle.
If you are using .replace on the FragmentTransaction, try using .show and .hide instead.
Something like the following might do it:
public void navigateToFragment( Fragment frag ) {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.hide(currentFragment);
if ( !fragment.isAdded() ) {
transaction.add(R.id.container,fragment)
} else if ( !fragment.isHidden() ) {
transaction.show(fragment);
}
transation.commit();
}
I've been going around in circles trying to do something that seems pretty basic. I have a DialogFragment that accepts a users input, then, on submission, refreshes a ListView in a Fragment that is part of a ViewPager.
I have everything working except the Fragment with the ListView does not refresh itself. It's a little confusing though, because it does refresh the data, but I have to swipe a couple views, then back again to see the updated data.
After doing some research, I'm supposed to use getItemPosition and notifyDataSetChanged on the ViewPager and it should work. The problem is that calling notifyDataSetChanged results in a Recursive entry to executePendingTransactions exception being thrown:
Main Activity
public class Main extends SherlockFragmentActivity implements MyListFragment.OnRefreshAdapterListener, DialogConfirmation.OnRefreshKeywordsListener //Updated Code
{
private static List<Fragment> fragments;
#Override
public void onCreate(final Bundle icicle)
{
setContentView(R.layout.main);
}
#Override
public void onResume()
{
mViewPager = (ViewPager)findViewById(R.id.viewpager);
fragments = new ArrayList<Fragment>();
fragments.add(new MyListFragment()); //fragment with the ListView
fragments.add(MyDetailFragment.newInstance(0));
fragments.add(MyDetailFragment.newInstance(1));
fragments.add(MyDetailFragment.newInstance(2));
mMyFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mMyFragmentPagerAdapter);
}
private static class MyFragmentPagerAdapter extends FragmentStatePagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
return fragments.get(index);
}
#Override
public int getCount() {
return 4;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
#Override
public void onRefreshAdapterListener() {
this.mMyFragmentPagerAdapter.notifyDataSetChanged();
}
//Updated Code
#Override
public void onRefreshTextListener() {
MyListFragment tf = (MyListFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentText);
if (tf == null)
tf = (MyListFragment)this.fragments.get(0);
tf.RefreshText();
}
}
ListFragment
public class MyListFragment extends SherlockListFragment
{
OnRefreshAdapterListener mRefreshAdapter;
#Override
public void onActivityCreated(Bundle savedState) {
adapter = new CustomAdapter();
/*code to add items to adapter */
this.setListAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
if (getArguments() != null && getArguments().getString("text").length() > 0)
{
SaveText(getArguments().getString("text"));
this.mRefreshAdapter.onRefreshAdapterListener(); //this line causes a "java.lang.IllegalStateException: Recursive entry to executePendingTransactions" exception
}
return inflater.inflate(R.layout.listing, container, false);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mRefreshAdapter = (OnRefreshAdapterListener)activity;
}
public interface OnRefreshAdapterListener {
public void onRefreshAdapterListener();
}
#Override
public void onDialogTextAdd(final String text) {
}
}
DialogFragment
public class DialogTextAdd extends DialogFragment implements OnEditorActionListener {
private EditText mText;
OnRefreshTextListener mTextKeywords; //Updated Code
public interface DialogTextAddListener {
void onDialogTextAdd(final String inputText);
}
public DialogTextAdd() {
// Empty constructor required for DialogFragment
}
//Updated Code
#Override
public void onAttach(Activity act) {
super.onAttach(act);
mTextKeywords = (OnRefreshTextListener)act;
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.dialog_edit, container);
mText = (EditText)view.findViewById(R.id.text_add);
getDialog().setTitle("Add Text");
// Show soft keyboard automatically
mText.requestFocus();
getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
mText.setOnEditorActionListener(this);
return view;
}
#Override
public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event) {
if (EditorInfo.IME_ACTION_DONE == actionId) {
MyListFragment mf = new MyListFragment();
Bundle args = new Bundle();
args.putString("text", mText.getText().toString());
mf.setArguments(args);
//this seems to be intefering with the notifyDataSetChanged in the listing fragment
getActivity().getSupportFragmentManager().beginTransaction().add(mf, "my_fragment").commit();
mTextKeywords.onRefreshTextListener(); //Updated Code
this.dismiss();
return true;
}
return false;
}
}
I have everything working except the Fragment with the ListView does
not refresh itself.
There is no point on creating and adding to the FragmentActivity a new instance of MyListFragment. From your code it appears that you store the fragments that you use in a list so you have references to them(also, just out of curiosity, did you setup the fragments in portrait, did a rotation of the phone and retried to use the DialogFragment?). Having references to those fragment means you could always get them from the list and use them to call a refresh/update method.
i dont understand the use for fragments in android, and im use the viewpagelibrary (https://github.com/JakeWharton/Android-ViewPagerIndicator)
I try to use fragments with this. I have fragmentacitivy this this code:
public class FragmentosActivity extends FragmentActivity {
private PagerAdapter mPagerAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.fragmentos_layout);
// initialsie the pager
this.inicializaPaginas();
}
//Este metodo inicia todos los fragments
private void inicializaPaginas() {
FragmentAdapter adapter =
new FragmentAdapter(getSupportFragmentManager());
adapter.addFragment(new Mapa());
adapter.addFragment(new Cercanos());
ViewPager pager = (ViewPager) super.findViewById(R.id.indicator);
pager.setAdapter(this.mPagerAdapter);
}
FragmentAdapter
public class FragmentAdapter extends FragmentPagerAdapter {
List<Fragment> fragments = null;
public FragmentAdapter(FragmentManager fm) {
super(fm);
fragments = new ArrayList<Fragment>();
}
public void addFragment(Fragment fragment){
fragments.add(fragment);
}
#Override
public Fragment getItem(int arg0) {
return fragments.get(arg0);
}
#Override
public int getCount() {
return fragments.size();
}
}
and viewpager adapter (is an adapter for the library)
public class ViewPagerAdapter extends PagerAdapter implements TitleProvider
{
private static String[] titles = new String[]
{
"Listado",
"Mapa"
};
private final Context context;
public ViewPagerAdapter( Context context )
{
this.context = context;
}
#Override
public String getTitle( int position )
{
return titles[ position ];
}
#Override
public int getCount()
{
return titles.length;
}
#Override
public Object instantiateItem( View pager, int position )
{
LinearLayout v = (LinearLayout) LayoutInflater.from(this.context).inflate(R.layout.cercanos, null);
if (position == 0) {
v = (LinearLayout) LayoutInflater.from(this.context).inflate(R.layout.cercanos, null);
} else {
v = (LinearLayout) LayoutInflater.from(this.context).inflate(R.layout.mapa, null);
}
((ViewPager) pager).addView(v, 0);
return v;
}
#Override
public void destroyItem( View pager, int position, Object view )
{
}
#Override
public boolean isViewFromObject( View view, Object object )
{
return view.equals( object );
}
#Override
public void finishUpdate( View view ) {}
#Override
public void restoreState( Parcelable p, ClassLoader c ) {}
#Override
public Parcelable saveState() {
return null;
}
#Override
public void startUpdate( View view ) {}
}
and fragment_layout is:
?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.viewpagerindicator.TitlePageIndicator
android:id="#+id/indicator"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="#style/Widget.IndicadorTitulo" />
/>
</LinearLayout>
and mapa.class and cercanos.class are class that extends of fragment without code.
The app dont show noting, it crashes and show me "can't instantiate class com.rbrlnx.controles.FragmentAdapter; no empty constructor "
Im looking for fragments example tutorial but all are very dificults to learn and traduce (Im spanish) anyone can help me please? If u have easy code to learn for fragments will its perfect.
Thanks
have you already solved your problem?
your message:
can't instantiate class com.rbrlnx.controles.FragmentAdapter; no empty constructor
looks like you maybe haven't have a:
public static HistoryFragment newInstance(Context context, TextView textViewSubText)...
public void onActivityCreated(Bundle savedInstanceState)...
or..
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
method.
can you post your stacktrace message?
cheers,
mike