I have app with FragmentStatePagerAdapter. One of the fragment contains some linearlayouts. I also have ActionBar. When i click at icon(button) on ActionBar, I will update my ArrayList with strings. After update ArrayList i want to update LinearLayout in fragment.
This is my Java code of FragmentPagerAdapter:
public class SectionsPagerAdapter extends FragmentStatePagerAdapter{
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
switch (position) {
case 0: {
Fragment fragment = new NejblizsiBary();
Bundle args = new Bundle();
args.putInt(NejblizsiBary.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
case 1: {
Fragment fragment3 = new Mapa();
Bundle args = new Bundle();
args.putInt(Mapa.ARG_SECTION_NUMBER, position + 2);
fragment3.setArguments(args);
return fragment3;
}
case 2: {
Fragment fragment2 = new OblibeneBary();
Bundle args = new Bundle();
args.putInt(OblibeneBary.ARG_SECTION_NUMBER, position + 3);
fragment2.setArguments(args);
return fragment2;
}
default:
return null;
}
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section3).toUpperCase(l);
case 2:
return getString(R.string.title_section2).toUpperCase(l);
}
return null;
}
}
Here is my class with creating content of Fragment:
public class NejblizsiBary extends Fragment implements LocationListener {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static final String ARG_SECTION_NUMBER = "section_number";
public NejblizsiBary() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_dummy,
container, false);
LinearLayout mainLayout = (LinearLayout) rootView.findViewById(R.id.hl);
getApplicationContext();
LayoutInflater inflater_layout = (LayoutInflater) getApplicationContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for(int i = 0; i < pocet_baru;i++){
View itemBox = inflater_layout.inflate(R.layout.jedenbar,null);
itemBox.setId(i);
TextView nazev = (TextView)itemBox.findViewById(R.id.nazev);
nazev.setText(bary.get(i).getNazev());
View.OnClickListener handler = new View.OnClickListener(){
#Override
public void onClick(View arg0) {
Detaily dialog = new Detaily();
Bundle args = new Bundle();
int id = arg0.getId();
args.putDouble("hlat", mLatitude);
args.putDouble("hlong", mLongitude);
args.putDouble("lat", bary.get(id).getLatitude());
args.putDouble("long", bary.get(id).getLongtitude());
args.putString("nazev", bary.get(id).getNazev());
args.putString("adresa", bary.get(id).getAdresa());
args.putString("mesto", bary.get(id).getMesto());
args.putString("popis", bary.get(id).getPopis());
dialog.setArguments(args);
dialog.show(getActivity().getFragmentManager(), "MyDialog");
}
};
itemBox.setOnClickListener(handler);
mainLayout.addView(itemBox);
}
return rootView;
}
Can U help me with my problem pls?
Simplest and most straight forward way is to register each fragment on its activity while creating it. Then delegate event made by actionbar button through the activity to appropriate fragment.
Other way is to use some kind event distribution observer pattern or event-bus patter.
I use event-bus implemented by RoboGuice personaly. Other implementations could be found in Guava or Otto libraries.
Related
I Have 4 Fragments in 1 Activity. I need to make sure that on every fragment change the fragment is refreshed because I load JSON Data in every fragment. I use FragmentPager Adapter and RecyclerView to Show Data
This is my Adapter ( SickAdapter.java ) the code :
public class SickAdapter extends FragmentPagerAdapter{
private static final String TAG = SickAdapter.class.getSimpleName();
private static final int FRAGMENT_COUNT = 4;
public SickAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new SickFragmentToAll();
case 1:
return new SickFragmentToPending();
case 2:
return new SickFragmentToApproved();
case 3:
return new SickFragmentToDenied();
}
return null;
}
#Override
public int getCount() {
return FRAGMENT_COUNT;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0:
return "All";
case 1:
return "Pending";
case 2:
return "Approved";
case 3:
return "Denied";
}
return null;
}
}
In my Class ( SickClass.java ) I create SickClass and I Call SickAdapter, I explode them, and this is my Code :
public class SickClass extends Fragment {
private static final String TAG = SickClass.class.getSimpleName();
private SickAdapter mAdapter;
private TabLayout tabLayout;
private ViewPager viewPager;
public SickClass() {
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.employee_leave_class, container, false);
tabLayout = (TabLayout)view.findViewById(R.id.tabs);
viewPager = (ViewPager)view.findViewById(R.id.view_pager);
if(mAdapter == null) {
mAdapter = new SickAdapter(getChildFragmentManager());
}
viewPager.setAdapter(new SickAdapter(getChildFragmentManager()));
tabLayout.setupWithViewPager(viewPager);
viewPager.setCurrentItem(1, true);
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return view;
}
}
Try below code for reload your fragment;
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(YOUR_FRAGMENT_NAME.this).attach(YOUR_FRAGMENT_NAME.this).commit();
You can use startActivityForResult() to get the result from the activity.
References:
ViewPager PagerAdapter not updating the View
How to refresh a Fragment of a FragmentPagerAdapter?
I'm new at Android programming and I need your help. Please.
What I want to do.
I created listview, from listview I created OnItemClickListener to TabbedActivity.
Now I want for each listview item to show different text on TabbedActivity.
This is MainActivity:
public class MainActivity extends AppCompatActivity {
Toolbar toolbar;
ListView listview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(getResources().getString(R.string.app_name));
listview = (ListView) findViewById(R.id.listview);
ArrayAdapter<String> mAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.bolesti));
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int i, long id) {
switch (i){
case 0:
Intent intent = new Intent(MainActivity.this, TabbedActivity.class);
startActivity(intent);
break;
case 1:
Intent intent1 = new Intent(MainActivity.this, TabbedActivity.class);
startActivity(intent1);
break;
}
}
});
listview.setAdapter(mAdapter);
}}
TabbedActivity:
public class TabbedActivity extends AppCompatActivity {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabbed);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_tabbed, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tabbed, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
switch (position){
case 0:
Tab1Opis tab1 = new Tab1Opis();
return tab1;
case 1:
Tab2Simptomi tab2 = new Tab2Simptomi();
return tab2;
case 2:
Tab3Uzroci tab3 = new Tab3Uzroci();
return tab3;
case 3:
Tab4Lijecenje tab4 = new Tab4Lijecenje();
return tab4;
default:
return null;
}
}
#Override
public int getCount() {
// Show 3 total pages.
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Opis";
case 1:
return "Simptomi";
case 2:
return "Uzroci";
case 3:
return "Lijecenje";
}
return null;
}
}}
TabbedActivity contains 4 tabs, all of them have different .java class example:
public class Tab2Simptomi extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_simptomi, container, false);
return rootView;
}}
I need to change text in every fragment when I click on different listview item.
Can you help me? Thank you.
Check the pictures. Thank you a lot.
You can pass text from your MainActivity to TabbedActivity fragment Tab2Simptomi as below:
1. Pass text from MainActivity to TabbedActivity, using Intent extras.
Update onItemClick() as below:
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int i, long id) {
switch (i){
case 0:
Intent intent = new Intent(MainActivity.this, TabbedActivity.class);
intent.putExtra("YOUR_TEXT", "Text One");
startActivity(intent);
break;
case 1:
Intent intent1 = new Intent(MainActivity.this, TabbedActivity.class);
intent1.putExtra("YOUR_TEXT", "Text Two");
startActivity(intent1);
break;
}
}
});
2. Pass text from TabbedActivity to Tab2Simptomi, setting bundle as arguments of fragments inside SectionsPagerAdapter.
In TabbedActivity onCreate() method, get text that was passed from MainActivity
public class TabbedActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabbed);
// Get text
String text = getIntent().getStringExtra("YOUR_TEXT");
// Pass text to SectionsPagerAdapter
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), text);
.............
......................
}
}
Update SectionsPagerAdapter to pass text to Fragments:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private String yourText;
public SectionsPagerAdapter(FragmentManager fm, String yourText) {
super(fm);
this.yourText = yourText;
}
#Override
public Fragment getItem(int position) {
Bundle bundle = new Bundle();
bundle.putString("YOUR_TEXT", yourText);
switch (position){
case 0:
Tab1Opis tab1 = new Tab1Opis();
tab1.setArguments(bundle); // Pass text to Tab1Opis fragment
return tab1;
case 1:
Tab2Simptomi tab2 = new Tab2Simptomi();
tab2.setArguments(bundle);
return tab2;
case 2:
Tab3Uzroci tab3 = new Tab3Uzroci();
tab3.setArguments(bundle);
return tab3;
case 3:
Tab4Lijecenje tab4 = new Tab4Lijecenje();
tab4.setArguments(bundle);
return tab4;
default:
return null;
}
}
#Override
public int getCount() {
// Show 3 total pages.
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Opis";
case 1:
return "Simptomi";
case 2:
return "Uzroci";
case 3:
return "Lijecenje";
}
return null;
}
}}
3. Finally get text from individual Frgament and do whatever you want.
Update Tab2Simptomi as below:
public class Tab2Simptomi extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_simptomi, container, false);
String finalText = getArguments().getString("YOUR_TEXT");
// Do something with finalText
Toast.makeText(getActivity(), "Final Text: " + finalText, Toast.LENGTH_SHORT).show();
return rootView;
}
}
UPDATE:
Assuming your fragment texts are static.
1. Pass texts from MainActivity to TabbedActivity, using Intent extras.
Update onItemClick() as below:
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int i, long id) {
switch (i){
case 0:
Intent intent = new Intent(MainActivity.this, TabbedActivity.class);
intent.putExtra("OPIS", "Item1 :: Text for Fragment OPIS");
intent.putExtra("SIMPTOMI", "Item1 :: Text for Fragment SIMPTOMI");
intent.putExtra("UZROCI", "Item1 :: Text for Fragment UZROCI");
intent.putExtra("LIJECENJE", "Item1 :: Text for Fragment LIJECENJE");
startActivity(intent);
break;
case 1:
Intent intent1 = new Intent(MainActivity.this, TabbedActivity.class);
intent1.putExtra("OPIS", "Item2 :: Text for Fragment OPIS");
intent1.putExtra("SIMPTOMI", "Item2 :: Text for Fragment SIMPTOMI");
intent1.putExtra("UZROCI", "Item2 :: Text for Fragment UZROCI");
intent1.putExtra("LIJECENJE", "Item2 :: Text for Fragment LIJECENJE");
startActivity(intent1);
break;
}
}
});
2. Pass texts from TabbedActivity to Tab2Simptomi, setting bundle as arguments of fragments inside SectionsPagerAdapter.
In TabbedActivity onCreate() method, get text that was passed from MainActivity
public class TabbedActivity extends AppCompatActivity {
ArrayList<String> stringArray;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabbed);
stringArray = new ArrayList<String>();
// Get texts
String textOPIS = getIntent().getStringExtra("OPIS");
String textSIMPTOMI = getIntent().getStringExtra("SIMPTOMI");
String textUZROCI = getIntent().getStringExtra("UZROCI");
String textLIJECENJE = getIntent().getStringExtra("LIJECENJE");
// Add text to ArrayList
stringArray.add(textOPIS);
stringArray.add(textSIMPTOMI);
stringArray.add(textUZROCI);
stringArray.add(textLIJECENJE);
// Pass ArrayList to SectionsPagerAdapter
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), stringArray);
.............
......................
}
}
Update SectionsPagerAdapter to pass text to Fragments:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private ArrayList<String> stringList;
public SectionsPagerAdapter(FragmentManager fm, ArrayList<String> stringArray) {
super(fm);
this.stringList = stringArray;
}
#Override
public Fragment getItem(int position) {
Bundle bundle = new Bundle();
bundle.putString("YOUR_TEXT", stringList.get(position)); // Get string from stringList using position
switch (position){
case 0:
Tab1Opis tab1 = new Tab1Opis();
tab1.setArguments(bundle); // Pass text to Tab1Opis fragment
return tab1;
case 1:
Tab2Simptomi tab2 = new Tab2Simptomi();
tab2.setArguments(bundle);
return tab2;
case 2:
Tab3Uzroci tab3 = new Tab3Uzroci();
tab3.setArguments(bundle);
return tab3;
case 3:
Tab4Lijecenje tab4 = new Tab4Lijecenje();
tab4.setArguments(bundle);
return tab4;
default:
return null;
}
}
#Override
public int getCount() {
// Show 3 total pages.
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Opis";
case 1:
return "Simptomi";
case 2:
return "Uzroci";
case 3:
return "Lijecenje";
}
return null;
}
}}
3. Finally get text from individual Frgament and do whatever you want.
Update Tab2Simptomi as below:
public class Tab2Simptomi extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_simptomi, container, false);
String finalText = getArguments().getString("YOUR_TEXT");
// Do something with finalText
TextView yourTextView = (TextView) rootView.findViewById(R.id.your_textview);
// Show text on TextView
yourTextView.setText(finalText);
Toast.makeText(getActivity(), "Final Text: " + finalText, Toast.LENGTH_SHORT).show();
return rootView;
}
}
Hope this will help~
In MainActivity
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int i, long id) {
Intent intent = new Intent(MainActivity.this, TabbedActivity.class);
switch (i){
case 0:
intent.putExtra("Title", "Title1");
break;
case 1:
intent.putExtra("Title", "Title2");
break;
}
startActivity(intent);
}
});
In TabbedActivity,String title is Title1 or Title2 based on what was clicked in MainActivity.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabbed);
String title = getIntent().getStringExtra("Title");
Toast.makeText(this, ""+title, Toast.LENGTH_SHORT).show();
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
}
Friends, I've spent enough time to find an answer to my question(here and on android's site) But no luck.
Here is the logic:
From DialogFragment upon finishing putting user's data he clicks OK button:
import de.greenrobot.event.EventBus;
...
public class AddDialogFragment extends DialogFragment implements
DialogInterface.OnClickListener {
...
public void onClick(DialogInterface dialog, int which) {
StringBuilder date = new StringBuilder(today.getText().subSequence(0,
today.getText().length()));
date = (date.toString().equals(getString(R.string.today))) ? new StringBuilder("20150104") : date;
int weight = 89;
String[] bsi = rb.getSelectedItems();
String[] gsi = rg.getSelectedItems();
DatabaseManipulation dm = new DatabaseManipulation(getActivity());
dm.run(date, weight, bsi, gsi);
dm.destroy();
DialogDataModel toSend = new DialogDataModel(weight, date.toString(), bsi, gsi);
/*
Context activity = getActivity();
if (activity instanceof WDActivity)
((WDActivity) activity).updateListItemFragment();
*/
EventBus.getDefault().post(new UpdateItemEvent(toSend));
Log.d(LOG_TAG, "send event");
Toast.makeText(getActivity(), R.string.saved_data, Toast.LENGTH_LONG).show();
}
...
Event is successfully sent to Adapter class which is registered for receiving this event:
...
import de.greenrobot.event.EventBus;
public class ItemsAdapter extends BaseAdapter implements ListAdapter {
private static final String LOG_TAG = "Logs";
private ArrayList<DialogDataModel> list = new ArrayList<DialogDataModel>();
private Context activity;
public ItemsAdapter (ArrayList<DialogDataModel> list, Context context) {
this.list = list;
this.activity = context;
registerEventBus();
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int pos) {
return list.get(pos);
}
#Override
public long getItemId(int pos) {
return pos;
//just return 0 if your list items do not have an Id variable.
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.row_item, null);
}
DialogDataModel curData = list.get(position);
TextView itemDate = (TextView)view.findViewById(R.id.item_date);
itemDate.setText(curData.getDate());
TextView itemWeight = (TextView)view.findViewById(R.id.item_weight);
itemWeight.setText( Integer.toString(curData.getWeight()) );
TextView itemEvents = (TextView)view.findViewById(R.id.item_events);
itemEvents.setText(curData.getEventsShort());
//Handle buttons and add onClickListeners
ImageButton editBtn = (ImageButton)view.findViewById(R.id.item_edit_btn);
editBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (activity instanceof WDActivity)
((WDActivity) activity).AddNewData(v, list.get(position));
notifyDataSetChanged();
}
});
ImageButton deleteBtn = (ImageButton) view.findViewById(R.id.item_delete_btn);
deleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String date = list.get(position).getDate();
DatabaseManipulation dm = new DatabaseManipulation(activity);
dm.deleteItem(date);
dm.destroy();
list.remove(position);
notifyDataSetChanged();
}
});
return view;
}
public void registerEventBus(){
if (!EventBus.getDefault().isRegistered(this)) EventBus.getDefault().register(this);
Log.d(LOG_TAG, "Registred from adapter");
}
public void unregisterEventBus(){
EventBus.getDefault().unregister(this);
}
public void onEventMainThread(UpdateItemEvent event) {
Log.d(LOG_TAG, "Event fired!");
list = DialogDataModel.replaceFieldsInArray(list,event.getModel());
notifyDataSetChanged();
}
}
After clicking OK in dialog window the user sees the list of items and the item he's updated is up to date. Without this logic he sees the old version of this item item in the list and to refresh the list he needs to relaunch the app.
Yes, it's working with EventBus.
But as you can see here in the class there is no place for unregistering it from listening for UpdateItemEvent. Since there are no destructors in java(I don't believe that garbage collector should do this for me) I should handle this. Moreover the class registeres as listener in constructor (it happens several times, that's why you see this ugly if statement(if (!EventBus.getDefault().isRegistered(this))) You may ask me why not getting this adapter through Activity (there is the only one in the app) I tried building a chain AddDialogFragment -> WDActivity -> PlaceholderFragment -> ItemsAdapter
//AddDialogFragment
Context activity = getActivity();
if (activity instanceof WDActivity)
((WDActivity) activity).updateListItemFragment();
//WDActivity --beginTransaction().replace does not work here
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wd);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
...
public void updateListItemFragment() {
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.Fragment currentFragment = fragmentManager.findFragmentById(R.id.container);
if (currentFragment instanceof PlaceholderFragment && currentFragment != null) {
fragmentManager.beginTransaction().remove(currentFragment).commit();
fragmentManager.beginTransaction().add(R.id.container, currentFragment).commit();
((PlaceholderFragment)currentFragment).fillList();
}
//PlaceholderFragment
public class PlaceholderFragment extends Fragment {
private static final String LOG_TAG = "Logs";
private static final String ARG_SECTION_NUMBER = "section_number";
private ListView listViewItem;
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(getArguments().getInt(ARG_SECTION_NUMBER)==1)
return onCreateViewInputChart(inflater, container, savedInstanceState);
if(getArguments().getInt(ARG_SECTION_NUMBER)==2)
return onCreateViewManual(inflater, container, savedInstanceState);
return onCreateViewInputData(inflater, container, savedInstanceState);
}
private View onCreateViewManual(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_howto, container, false);
return rootView;
}
private View onCreateViewInputData(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_list_data, container, false);
findViewsByIdListItem(rootView);
fillList();
return rootView;
}
private View onCreateViewInputChart(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_chart, container, false);
return rootView;
}
//listViewItems
private void findViewsByIdListItem(View v) {
listViewItem = (ListView) v.findViewById(R.id.listViewItems);
}
public void fillList(){
Context activity = getActivity();
DatabaseManipulation dm = new DatabaseManipulation(activity);
ArrayList<DialogDataModel> aldm = dm.getItemsList();
dm.destroy();
ItemsAdapter innerAdapter = new ItemsAdapter(aldm, activity);
listViewItem.setAdapter(innerAdapter);
( (BaseAdapter) listViewItem.getAdapter() ).notifyDataSetChanged();
}
#Override
public void onAttach(Context activity) {
super.onAttach(activity);
}
#Override
public void onDetach(){
super.onDetach();
}
}
//SectionsPagerAdapter - just for your information
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
return PlaceholderFragment.newInstance(position);
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Enter your data";
case 1:
return "Chart";
case 2:
return "How to use it";
}
return null;
}
}
//ItemsAdapter is placed higher
This did not work. Finally I found out that the bottleneck is in linking PlaceholderFragment and ListAdapter: listViewItem is null everywhere except onCreateViewInputData. I could not figure out why. Google didn't give me the answer and I took it as a magic. Btw due to this feature I cannot use PlaceholderFragment's onAttach and onDetach for saying ItemsAdapter to register/unregister for receiving the event. This:
#Override
public void onAttach(Context activity) {
super.onAttach(activity);
( (ItemsAdapter) listViewItem.getAdapter() ).registerEventBus();
}
doesn't work for the same reason listViewItem is null. Maybe there is some way to manage with this more accurately?
Finally I cope with this: the bottleneck is in linking PlaceholderFragment and ListAdapter: listViewItem is null everywhere except onCreateViewInputData . Below is rewised SectionsPagerAdapter:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
Context activity;
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public SectionsPagerAdapter(FragmentManager fm, Context activity) {
super(fm);
this.activity = activity;
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
return PlaceholderFragment.newInstance(position);
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return activity.getString(R.string.chart);
case 1:
return activity.getString(R.string.weight_diary);
case 2:
return activity.getString(R.string.how_to);
}
return null;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
//maybe use adapater.getRegisteredFragment(viewPager.getCurrentItem());
}
}
and here is my call to the widget in the one of 3 fragments:
public void updateListItemFragment() {
android.support.v4.app.Fragment inputData = mSectionsPagerAdapter.getRegisteredFragment(1);
ListView lv = ((PlaceholderFragment)inputData).listViewItem;
//for test purposes I refill listview with no items - here you need to hand filled BaseAdapter instance: CustomAdapter innerAdapter = new CustomAdapter(ArrayList<yourDataModel>, getContext());
lv.setAdapter(null);
}
And as you've may already wondered there is no need for event bus anymore. Btw if the fragment is not crated yet you need to check it: details are here. Thanks to CommonsWare for quik reply and advice.
I have a App with a Slidingmenu where i can pick different Fragment, which displays different kind of ListFragments.
The ListFragments will be filled by JSON from my Database Server.
If you Click on one of the Listitems, a new Fragment is shown which contains more Details about the selected Listitem.
public void updateList(final Activity a, final ListFragment L) {
adapter = new SimpleAdapter(a, mCommentList,
R.layout.single_comment, new String[] {TAG_PIC_ID,TAG_CATEGORY, TAG_ACTIVITY, TAG_DATUM, TAG_AKTUSR, TAG_MAXUSR, TAG_GENDER, /*TAG_POST_ID,*/ TAG_TITLE, TAG_MESSAGE,
TAG_USERNAME }, new int[] { R.id.imgrow, R.id.category, R.id.activity/*R.id.id*/ , R.id.datum, R.id.aktusr, R.id.maxusr, R.id.gender, /*R.id.category,*/ R.id.title, R.id.message,
R.id.username });
L.setListAdapter(adapter);
ListView lv = L.getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int intid = (int)id;
Details nextFrag= new Details();
L.getFragmentManager().beginTransaction()
.replace(R.id.frame_container, nextFrag, "Test")
.addToBackStack(null)
.commit();
}
});
}
When i call the function from a "single" fragment its no problem and the DetailPage is shown.
The Problem is when i call the function from a TabbedActivity with a SectionsPagerAdapter.
The TabbedActivity
package info.androidhive.slidingmenu;
public class TabbedActivity extends Fragment {
SectionsPagerAdapter mSectionsPagerAdapter;
public static final String TAG = TabbedActivity.class.getSimpleName();
ViewPager mViewPager;
public static TabbedActivity newInstance() {
return new TabbedActivity();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_item_one, container, false);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getChildFragmentManager());
mViewPager = (ViewPager) v.findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
return v;
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new newEntrys();
switch (position) {
case 0:
fragment = new newEntrys();
break;
case 1:
fragment = new oldEntrys();
break;
default:
break;
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return "Aktuelle Einträge";
case 1:
return "Vergangene Einträge";
}
return null;
}
}}
The TabbedActivity contains the 2 Fragments newEntry and oldEntry which are nearly equal.
package info.androidhive.slidingmenu.fragments;
public class RegisterdEvents_new extends ListFragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.read, container, false);
return rootView;
}
public void startTask(){
Read SO = new Read();
Load LEvt = SO.new Load(getActivity(), this, "NEW");
LEvt.execute();
}
public void onResume() {
startTask();
super.onResume();
}
}
So the function updateList above is called in
Load LEvt = SO.new Load(getActivity(), this, "NEW");
But the problem is that i always get the Error
No view found for id 0x7f0a000f (package:id/frame_container) for fragment Details{e3992e2 #0 id=0x7f0a000f Test}
Someone of you can help me to solve this problem?
I'm trying to get GoogleMap object from a Fragment, which is on the second page of ViewPager, whose contents are given with FragmentPagerAdapter.
My ViewPager consist of two pages: an ordinary layout, and a Google map.
I can access to the first layout doing this:
View tempView = LayoutInflater.from(getApplication())
.inflate(R.layout.start_activity, null);
tempTextView = (TextView) tempView.findViewById(R.id.timer);
Everything is OK here. But I also want to access Google maps.
When the map was in a separate activity, I could get GoogleMap object doing this:
map=((SupportMapFragment)getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
But now the above line returns null
The question is how to get GoogleMap object from fragment now?
They suggest doing this (some people say this works), but it doesn't take effect for me:
map = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentByTag("android:switcher:" + R.id.pager + ":1")).getMap();
I'm providing the code here.
I've found the solution here, but will post here too for other users to see the code and not get stuck for weeks like I did.
MyPagerAdapter.java
public class MyPagerAdapter extends FragmentPagerAdapter
{
private Context context;
final LatLng YEREVAN = new LatLng(40.181, 44.513);
public MyPagerAdapter(FragmentManager fm, Context context)
{
super(fm);
this.context = context;
}
#Override
public Fragment getItem(int position)
{
switch (position)
{
case 0:
return new MyFragment();
case 1:
return MyMapFragment.newInstance(YEREVAN);
}
return null;
}
#Override
public int getCount()
{
return 2;
}
#Override
public CharSequence getPageTitle(int position)
{
Locale l = Locale.getDefault();
switch (position)
{
case 0:
return context.getString(R.string.start).toUpperCase(l);
case 1:
return context.getString(R.string.map).toUpperCase(l);
}
return null;
}
}
MyMapFragment.java
public class MyMapFragment extends SupportMapFragment
{
private LatLng latLon;
public MyMapFragment()
{
super();
}
public static MyMapFragment newInstance(LatLng position)
{
MyMapFragment frag = new MyMapFragment();
frag.latLon = position;
return frag;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = super.onCreateView(inflater, container, savedInstanceState);
initMap();
return v;
}
private void initMap()
{
UiSettings settings = getMap().getUiSettings();
settings.setAllGesturesEnabled(false);
settings.setMyLocationButtonEnabled(false);
getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(latLon, 16));
getMap().addMarker(new MarkerOptions().position(latLon).icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
}
}
The problem is that your MyFragmentPagerAdapter doesn't use SupportMapFragments, but only adds MyFragments.
You should change its getItem function to something like this:
public Fragment getItem(int position) {
Fragment fragment;
switch (position) {
case 0:
fragment = new MyFragment();
break;
case 1:
fragment = new MySupportMapFragment();
break;
}
Bundle args = new Bundle();
args.putInt(MyFragment.ARG_SECTION_NUMBER, position);
fragment.setArguments(args);
return fragment;
}
For that you have to implement your own type MySupportMapFragment where you load your layout, similar with what you did with MyFragment.
Then you can call your SupportMapFragment directly from the FragmentPagerAdapter. Like:
SupportMapFragment supportMapFragment =
(SupportMapFragment) mMyFragmentPagerAdapter.getItem(1);
map = supportMapFragment.getMap();
Once added to the adapter, you should get the SupportMapFragment you are expecting.