How to Refresh Fragment from Action Bar Menu - android

I have an Action Bar with Fragment as follow. I would like to refresh current fragment using Refresh button Action Bar Menu. I saw a lot of example using getFragmentByTag() but my fragment is created dynamically. May I know how to get the current fragment and refresh the content.
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
RssFragmentPagerAdapter mRssFragmentPagerAdapter;
ViewPager mViewPager;
List<RssCategory> categoryList;
// Database Helper
private DatabaseHelper db;
private ActionBar actionBar;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try{
db = DatabaseHelper.getInstance(getApplicationContext());
int categoryCount = db.getCategoriesCount();
// Create the adapter that will return a fragment for each of the three primary sections
// of the app.
mRssFragmentPagerAdapter = new RssFragmentPagerAdapter(getSupportFragmentManager(), categoryCount);
// Set up the action bar.
actionBar = getActionBar();
// Specify that the Home/Up button should not be enabled, since there is no hierarchical
// parent.
actionBar.setHomeButtonEnabled(false);
// Specify that we will be displaying tabs in the action bar.
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//actionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
// Set up the ViewPager, attaching the adapter and setting up a listener for when the
// user swipes between sections.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mRssFragmentPagerAdapter);
mViewPager.setOffscreenPageLimit(categoryCount - 1);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// When swiping between different app sections, select the corresponding tab.
// We can also use ActionBar.Tab#select() to do this if we have a reference to the
// Tab.
actionBar.setSelectedNavigationItem(position);
}
});
initialiseActionBar();
}catch(Exception e){
Log.e(getClass().getName(), e.getMessage());
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
case R.id.action_refresh:
//TO REFRESH CURRENT Fragment
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void initialiseActionBar() {
if(categoryList == null)
categoryList = db.getAllCategories();
// For each of the sections in the app, add a tab to the action bar.
for (RssCategory category : categoryList) {
// Create a tab with text corresponding to the page title defined by the adapter.
// Also specify this Activity object, which implements the TabListener interface, as the
// listener for when this tab is selected.
actionBar.addTab(
actionBar.newTab()
.setText(category.getName())
.setTabListener(this));
}
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to one of the primary
* sections of the app.
*/
public static class RssFragmentPagerAdapter extends FragmentPagerAdapter {
private int pageCount;
public RssFragmentPagerAdapter(FragmentManager fm, int pageCount) {
super(fm);
this.pageCount = pageCount;
}
#Override
public Fragment getItem(int i) {
switch (i) {
default:
// The other sections of the app are dummy placeholders.
Fragment fragment = new RssFragment();
Bundle args = new Bundle();
args.putInt(RssFragment.ARG_CATEGORY_ID, i + 1);
fragment.setArguments(args);
return fragment;
}
}
#Override
public int getCount() {
return pageCount;
}
/*#Override
public CharSequence getPageTitle(int position) {
return "Section " + (position + 1);
}*/
}
/**
* A dummy fragment representing a section of the app, but that simply displays dummy text.
*/
public static class RssFragment extends Fragment {
public static final String ARG_CATEGORY_ID = "category_id";
View rootView;
private List<RssItem> resultList;
List<RssWebSite> websiteList;
ArrayList<String> urlList;
ProgressBar progressBar;
#SuppressWarnings("unchecked")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try{
rootView = inflater.inflate(R.layout.fragment_rss_items_list, container, false);
resultList = new ArrayList<RssItem>();
progressBar = (ProgressBar)rootView.findViewById(R.id.progressBar);
Bundle args = getArguments();
if(args != null){
DatabaseHelper db = DatabaseHelper.getInstance(rootView.getContext());
websiteList = db.getAllRssWebSiteByCategory(args.getInt(ARG_CATEGORY_ID));
urlList = new ArrayList<String>();
if(websiteList != null && websiteList.size() > 0){
for (RssWebSite website : websiteList) {
urlList.add(website.getRssUrl());
}
if(urlList.size() > 0) {
GetRSSDataTask task = new GetRSSDataTask();
task.execute(urlList);
}
}
}
}catch(Exception e){
Log.e(getClass().getName(), e.getMessage());
}
return rootView;
}
/**
* This class downloads and parses RSS Channel feed.
*
* #author clippertech
*
*/
private class GetRSSDataTask extends AsyncTask<ArrayList<String>, Void, List<RssItem> > {
#Override
protected List<RssItem> doInBackground(ArrayList<String>... urls) {
try {
for(String url : urls[0]) {
// Create RSS reader
RssReader rssReader = new RssReader(url);
Log.d(getClass().getName(), url);
// Parse RSS, get items
resultList.addAll(rssReader.getItems());
}
return resultList;
}catch (Exception e) {
Log.e(getClass().getName(), e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(List<RssItem> result) {
try{
// Get a ListView from the RSS Channel view
ListView itcItems = (ListView) rootView.findViewById(R.id.rssChannelListView);
View emptyView = null;
if(result == null){
itcItems.setEmptyView(emptyView);
Log.d(getClass().getName(), "Empty View");
}
else {
//resultList.addAll(result);
Collections.sort(result, new Comparator<RssItem>() {
#Override
public int compare(RssItem lhs, RssItem rhs) {
SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
try {
Date date1 = formatter.parse(rhs.getPublishedDate());
Date date2 = formatter.parse(lhs.getPublishedDate());
return date1.compareTo(date2);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 0;
}
});
// Create a list adapter
ListAdapter adapter = new ListAdapter(rootView.getContext(), resultList);
itcItems.setAdapter(adapter);
adapter.notifyDataSetChanged();
// Set list view item click listener
itcItems.setOnItemClickListener(new ListListener(resultList, getActivity()));
}
//dialog.dismiss();
progressBar.setVisibility(View.GONE);
}catch(Exception e){
Log.e(getClass().getName(), e.getMessage());
}
}
}
}
}

You would need to keep track of the current fragment index by using the PageChangeListener in your viewpager.
You can use the fragment index to retrieve the fragment from your adapter and call whatever methods you need on it.

Related

How to refresh / reload focused tabs of tabbed activity

I am trying to make my tabbed activity content to change dynamically, depended on the user choices in the other tabs.
All tabs are using the same fragment. only the content in the view is supposed to change (in this case a ListView)
Now the main problem is that when I make a choice (click on some line in the ListView) the next tab shows all of the content instead of filtering the data according to my choice in the previous tab, though when I click on a not-neighbor tab and then go back, the tab is filtered like I wanted.
From what I understand, the activity load the neighbor tabs of the current tab even if those are not focused and this is why I get the default result.
To simplify things:
Then I choose some line from the ListView and the focus automatically goes to the next tab.
The listView will show me the default contet, as if I chose nothing. But if I move the focus to the forth tab, and then again back to the second, the listView will be filtered as I wanted
Here is my code
public class Catalog_actbartabs 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;
public static String PACKAGE_NAME;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_catalog_actbartabs);
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);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
PACKAGE_NAME = getApplicationContext().getPackageName();
}
public void setCurrentItem(int item, boolean smoothScroll) {
mViewPager.setCurrentItem(item, smoothScroll);
}
#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_catalog_actbartabs, 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 {
protected ClogListAdapter2 clogListAdapter2;
protected ArrayList<String[]> stringArrayList;
protected static String topic = null;
protected static String rName = null;
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
private static final String EXTRA_ITEM_INFO = "com.dstudio.dvir.EXTRA_ITEM_INFO";
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;
rootView = inflater.inflate(R.layout.fragment_catalog, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
try {
if (getArguments().getInt(ARG_SECTION_NUMBER) == 1)
stringArrayList = Utils.getNamesList(super.getContext());
else if (getArguments().getInt(ARG_SECTION_NUMBER) == 2)
stringArrayList = Utils.getTopicsList(super.getContext(), rName);
else if (getArguments().getInt(ARG_SECTION_NUMBER) == 3)
stringArrayList = Utils.getClassesList(super.getContext(), rName, topic);
else if (getArguments().getInt(ARG_SECTION_NUMBER) == 4)
stringArrayList = Utils.getFilesList(super.getContext());
} catch (Throwable t) {
Toast.makeText(super.getContext(), "Exception: " + t.toString(), Toast.LENGTH_LONG).show();
}
if (savedInstanceState != null) {
String[] values = savedInstanceState.getStringArray("myKey");
if (values != null) {
stringArrayList = ClogListAdapter2.bmListFromArray(values);
}
} else if (stringArrayList == null) {
stringArrayList = new ArrayList<String[]>();
}
clogListAdapter2 = new ClogListAdapter2(super.getContext(), stringArrayList, getArguments().getInt(ARG_SECTION_NUMBER));
ListView listV = (ListView) rootView.findViewById(R.id.listView);
listV.setAdapter(clogListAdapter2);
listV.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (getArguments().getInt(ARG_SECTION_NUMBER) == 1) {
if (clogListAdapter2.getItem(position)[0].equals("All"))
rName = null;
else rName = clogListAdapter2.getItem(position)[0];
topic = null;
} else if (getArguments().getInt(ARG_SECTION_NUMBER) == 2) {
if (clogListAdapter2.getItem(position)[0].equals("All"))
topic = null;
else topic = clogListAdapter2.getItem(position)[0];
} else if (getArguments().getInt(ARG_SECTION_NUMBER) == 4) {
Intent intent = new Intent(parent.getContext(), AudioPlayerActivity.class);
intent.putExtra(EXTRA_ITEM_INFO, clogListAdapter2.getItem(position));
startActivityForResult(intent, 1);
}
((Catalog_actbartabs) getActivity()).setCurrentItem(getArguments().getInt(ARG_SECTION_NUMBER), true);
}
});
return rootView;
}
}
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).
return PlaceholderFragment.newInstance(position + 1);
}
#Override
public int getCount() {
// Show 4 total pages.
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "page 1";
case 1:
return "page 2";
case 2:
return "page 3";
case 3:
return "page 4";
}
return null;
}
}
}
UPDATE
Working Solution From #AmeyShirke
I added the var _hasLoadedOnce= false; to the rest of the vars in PlaceholderFragment class:
public static class PlaceholderFragment extends Fragment {
protected ClogListAdapter2 clogListAdapter2;
protected ArrayList<String[]> stringArrayList;
protected View rootView;
protected static String topic = null;
protected static String rName = null;
private boolean _hasLoadedOnce= false;
//Rest of the code
}
Now All the data setting code is inside setUserVisibleHint() without changing _hasLoadedOnce so it look like this:
#Override
public void setUserVisibleHint(boolean isFragmentVisible_) {
super.setUserVisibleHint(true);
if (this.isVisible()) {
// we check that the fragment is becoming visible
if (isFragmentVisible_ && !_hasLoadedOnce) {
Log.i("visable: ", getArguments().getInt(ARG_SECTION_NUMBER)+"");
try {
if (getArguments().getInt(ARG_SECTION_NUMBER) == 1)
stringArrayList = Utils.getNamesList(super.getContext());
else if (getArguments().getInt(ARG_SECTION_NUMBER) == 2)
stringArrayList = Utils.getTopicsList(super.getContext(), rName);
else if (getArguments().getInt(ARG_SECTION_NUMBER) == 3)
stringArrayList = Utils.getClassesList(super.getContext(), rName, topic);
else if (getArguments().getInt(ARG_SECTION_NUMBER) == 4)
stringArrayList = Utils.getFilesList(super.getContext());
} catch (Throwable t) {
Toast.makeText(super.getContext(), "Exception: " + t.toString(), Toast.LENGTH_LONG).show();
}
clogListAdapter2 = new ClogListAdapter2(super.getContext(), stringArrayList, getArguments().getInt(ARG_SECTION_NUMBER));
ListView listV = (ListView) rootView.findViewById(R.id.listView);
listV.setAdapter(clogListAdapter2);
listV.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO: 23/12/2016 remember to also give the needed info to get the asked next category
if (getArguments().getInt(ARG_SECTION_NUMBER) == 1) {
if (clogListAdapter2.getItem(position)[0].equals("All"))
rName = null;
else rName = clogListAdapter2.getItem(position)[0];
topic = null;
} else if (getArguments().getInt(ARG_SECTION_NUMBER) == 2) {
if (clogListAdapter2.getItem(position)[0].equals("All"))
topic = null;
else topic = clogListAdapter2.getItem(position)[0];
} else if (getArguments().getInt(ARG_SECTION_NUMBER) == 4) {
Intent intent = new Intent(parent.getContext(), AudioPlayerActivity.class);
intent.putExtra(EXTRA_ITEM_INFO, clogListAdapter2.getItem(position));
startActivityForResult(intent, 1);
}
((Catalog_actbartabs) getActivity()).setCurrentItem(getArguments().getInt(ARG_SECTION_NUMBER), true);
}
});
//Notify that _hasLoadedOnce = true; is now gone
}
}
}
I also added the line mViewPager.setOffscreenPageLimit(3); in the activity's onCreate() because if I chose to go directly to the forth tab after the first filtering it wouldn't filter it, so that way the activity will filter it correctly.
This is default behaviour of ViewPager. To load only single tab use:
mViewPager.setOffscreenPageLimit(1);
If that doesnt work, then you have to create your own sub-class of ViewPager and override the below method:
private boolean _hasLoadedOnce= false; // your boolean field
#Override
public void setUserVisibleHint(boolean isFragmentVisible_) {
super.setUserVisibleHint(true);
if (this.isVisible()) {
// we check that the fragment is becoming visible
if (isFragmentVisible_ && !_hasLoadedOnce) {
//your code here
_hasLoadedOnce = true;
}
}
}

Android: Best Approach to pass data between viewpager fragments

I have 3 fragments in a ViewPager Activity. All 3 fragments have input fields. Here I am trying to pass first two fragments data to third fragment. I read few posts here and most of them suggested to use interfaces(i.e. to pass data through parent activity)
I have also gone through this link
http://developer.android.com/training/basics/fragments/communicating.html
Interface: using interfaces is good approach when we are sending data through some user event. Here I am trying to send data without any user event. Hence I thought of onPause() since onPause() is always called. But ViewPager functions differently. When a fragment is loaded,the adjacent fragments are also loaded. I would be successful to pass data between 1st fragment to 3rd fragment. But 2nd fragment's onPause() wont be called unless I am navigating to some fragment that is not adjacent to it(which in my case is not there)
Setter/Getters:I have read in few posts people saying not to use setter/getters(I still havent understood the reason yet) Are getters and setters poor design? Contradictory advice seen
Bundle: I havent considered this yet. Since I am again confused here how would I pass data using bundle.(inside which method should I send data? and how?)
Sorry if my question sounds dumb.I am trying to understand fragments and i would like to know best way to pass data between fragments in viewpager.
Thank You in advance.
TabPAgerAdapter -- >
package com.jbandroid.model;
import com.jbandroid.fragment.LocationInfoFragment;
import com.jbandroid.fragment.PersonalInfoFragment;
import com.jbandroid.fragment.PostInfoFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm){
super(fm);
}
#Override
public Fragment getItem(int index) {
switch(index) {
case 0 : //PostInfoFragment
return new PostInfoFragment();
case 1 : //LocationInfoFragment
return new LocationInfoFragment();
case 2 : //PersonalInfoFragment
return new PersonalInfoFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
ViewPagerActivity -- >
package com.jbandroid;
public class SubmitPostActivity extends FragmentActivity implements ActionBar.TabListener,PostInfoFragment.setPostInfo,LocationInfoFragment.setLocationInfo{
private ViewPager viewpager;
private ActionBar actionBar;
private TabsPagerAdapter mAdapter;
FragmentManager manager;
PersonalInfoFragment frag;
List<String> location;
/*private MenuItem myActionMenuItem;
private Button myActionButton;*/
//Tab titles
private String[] tabs = {"Post Info" , "Location Info" , "Personal Info" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.action_submit_post);
viewpager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
manager = getSupportFragmentManager();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
//viewpager.setOffscreenPageLimit(2);
viewpager.setAdapter(mAdapter);
//actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (String tab : tabs){
actionBar.addTab(actionBar.newTab().setText(tab).setTabListener(this));
}
if(savedInstanceState != null){
actionBar.setSelectedNavigationItem( savedInstanceState.getInt("tab",0));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewpager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewpager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void pass_location_details(List<String> location) {
frag = (PersonalInfoFragment) manager.findFragmentByTag("android:switcher:" + viewpager.getId() + ":" + 2);
frag.get_post_location_details(location);
Log.d("submitarea", location.get(0));
}
#Override
public void pass_post_details(List<String> post_details,ArrayList<CustomGallery> selected) {
frag = (PersonalInfoFragment) manager.findFragmentByTag("android:switcher:" + viewpager.getId() + ":" + 2);
frag.get_post_details(post_details,selected);
Log.d("submitpostinfo","hello"+ post_details.get(5));
}
}
1st Fragment(Here I am trying to pass data using interface in onPause()-->
package com.jbandroid.fragment;
public class PostInfoFragment extends Fragment {
private MenuItem myActionMenuItem;
private Button myActionButton;
private ActionBar actionBar;
private String post_title, post_desc,post_status;
private EditText submit_post_title, submit_post_desc;
private Resources res;
setPostInfo info;
List<String> post_details;
//RelativeLayout rel_submit_post_start_date,rel_submit_post_end_date;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_post_info,
container, false);
/*if(!imageLoader.isInited()){*/
initImageLoader();
/*}*/
//handler = new Handler();
submit_post_title = (EditText) rootView
.findViewById(R.id.submit_post_title);
submit_post_desc = (EditText) rootView
.findViewById(R.id.submit_post_description);
actionBar = getActivity().getActionBar();
setHasOptionsMenu(true);
post_details = new ArrayList<String>();
res = getResources();
setListeners();
Log.d("postinfo_oncreate view", "postinfo_oncreate view");
return rootView;
}
//interface to pass data to activity and then to PersonalInfoFragment
public interface setPostInfo {
//public void pass_post_details(List<String> post_details);
public void pass_post_details(List<String> post_details,ArrayList<CustomGallery> selected);
}
//making sure if the parent activity has implemented interface
#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 {
info = (setPostInfo) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ "must implemet setPostInfo");
}
Log.d("postinfo_onattach", "postinfo_onattach");
}
//passing form inputs to personalinfofragments
#Override
public void onPause() {
super.onPause();
// setFormInputs();
passFormInputs(); ---> passing in onPause() This executes successfully
Log.d("postinfo_onPAuse", "postinfo_onPause");
}
//method to pass data to personalinfofragment
private void passFormInputs() {
try {
post_title = submit_post_title.getText().toString();
post_desc = submit_post_desc.getText().toString();
post_status = "1";
if(post_title != null && post_title.length() > 0
&& post_desc != null && post_desc.length() > 0
&& post_status != null && post_status.length() > 0
){
post_details.add(post_title);
post_details.add(post_desc);
post_details.add(post_status);
info.pass_post_details(post_details,dataT); -->here I am passing values via
}else{ activity to 3rd fragment
Log.d("post_info", "values are null");
}
} catch (Exception e) {
e.printStackTrace();
}
}
//setting next button on actionbar
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
// Inflate the menu items for use in the action bar
inflater.inflate(R.menu.mymenu, menu);
// Here we get the action view we defined
myActionMenuItem = menu.findItem(R.id.my_action);
View actionView = myActionMenuItem.getActionView();
// We then get the button view that is part of the action view
if (actionView != null) {
myActionButton = (Button) actionView.findViewById(R.id.action_btn);
myActionButton.setText(R.string.txt_next);
if (myActionButton != null) {
// We set a listener that will be called when the return/enter
// key is pressed
myActionButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
actionBar.setSelectedNavigationItem(1);
}
});
}
}
}
}
2nd Fragment-->
package com.jbandroid.fragment;
public class LocationInfoFragment extends Fragment implements OnClickListener {
private MenuItem myActionMenuItem;
private Button myActionButton;
private ActionBar actionBar;
Dialog dialog;
private EditText submit_post_exact_location;
private TextView selected_country, selected_city,
submit_post_exact_time;
String country, city, exact_location, exact_time;
setLocationInfo info;
List<String> location;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_location_info,
container, false);
actionBar = getActivity().getActionBar();
setHasOptionsMenu(true);
submit_post_exact_location = (EditText) rootView
.findViewById(R.id.submit_post_exact_location);
submit_post_exact_time = (TextView) rootView
.findViewById(R.id.submit_post_exact_time);
selected_country = (TextView) rootView
.findViewById(R.id.selected_country);
selected_city = (TextView) rootView.findViewById(R.id.selected_city);
location = new ArrayList<String>();
setListeners();
return rootView;
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
// Inflate the menu items for use in the action bar
inflater.inflate(R.menu.mymenu, menu);
// Here we get the action view we defined
myActionMenuItem = menu.findItem(R.id.my_action);
View actionView = myActionMenuItem.getActionView();
// We then get the button view that is part of the action view
if (actionView != null) {
myActionButton = (Button) actionView.findViewById(R.id.action_btn);
myActionButton.setText(R.string.txt_next);
if (myActionButton != null) {
// We set a listener that will be called when the return/enter
// key is pressed
myActionButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
actionBar.setSelectedNavigationItem(2);
}
});
}
}
}
public interface setLocationInfo {
public void pass_location_details(List<String> location);
}
#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 {
info = (setLocationInfo) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ "must implement setLocationInfo");
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//setLocationDetails();
}
#Override
public void onPause() {
super.onPause();
setLocationDetails(); ----> doesnt executes since onPause isnt called when I navigate to 3rd fragment as it is an adjacent fragment of this fragment
// Log.d("location : onPause", area);
}
private void setLocationDetails() {
try {
exact_location = submit_post_exact_location.getText().toString();
exact_time = submit_post_exact_time.getText().toString();
country = selected_country.getText().toString();
city = selected_city.getText().toString();
if (country != null && country.length() > 0
&& !country.equalsIgnoreCase("select") && city != null
&& city.length() > 0 && !city.equalsIgnoreCase("select")
&& exact_location != null && exact_location.length() > 0
&& exact_time != null && exact_time.length() > 0) {
location.add(country);
location.add(city);
location.add(exact_location);
location.add(exact_time);
info.pass_location_details(location);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
In my 3rd Fragment I am trying to get this values
public class PersonalInfoFragment extends Fragment {
List<String> post_details;
List<String> location;
Button submit;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_personal_info,
container, false);
submit = (Button)rootView.findViewById(R.id.submitBtn);
submit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//performing operations with the values obtained
setPostItems();
insertintodb();
}
});
return rootView;
}
public void get_post_details(List<String> post_details,
ArrayList<CustomGallery> selected) { -->receiving values from
this.post_details = post_details; 1st fragment
this.selected = selected;
Log.d("personalfrag(postinfo)", "hello" + post_details.get(5));
}
//receiving values from 2nd fragment
public void get_post_location_details(List<String> location) {
this.location = location;
Log.d("personalfrag(locationinfo)", "hello" + location.get(0));
}
}
Okay, I Had same issue to pass data(not just string) between two tabs in a ViewPager. So here is what i did.
I Use interfaces to communicate between the different components.
The data passes this way:
Tab 1 -> Activity -> VewPageAdapter -> Tab 2
In Tab 1
create an interface.
OnCartsDataListener mOncarOnCartsDataListener;
public interface OnCartsDataListener {
public void onCartsDataReceived(ArrayList<CartsViewModel> cartsViewModels);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mOncarOnCartsDataListener = (OnCartsDataListener)activity;
}catch (ClassCastException e){
}
}
// now call mOncarOnCartsDataListener.onCartsDataReceived(data) when you have the data
In Activity
Implement the interface and override the method
ViewPagerAdapter adapter;
adapter = new ViewPagerAdapter(getSupportFragmentManager(), Titles, Numboftabs);
#Override
public void onCartsDataReceived(ArrayList<CartsViewModel> cartsViewModels) {
Log.d(TAG, "data received to Activity... send to view pager");
adapter.onCartsDataReceived(cartsViewModels);
}
3.IN ViewPagerAdapter
Also implements the interface and override the method
#Override
public void onCartsDataReceived(ArrayList<CartsViewModel> cartsViewModels) {
Log.d(TAG, "data received to view pager... sending to tab 2");
if(tab2!=null){
tab2.onCartsDataReceived(cartsViewModels);
}else{
Log.d(TAG, "tab2 is null");
}
}
Finally tab 2
Also implements the interface and override the method
#Override
public void onCartsDataReceived(ArrayList<CartsViewModel> cartsViewModels) {
Log.d(TAG, "Finally ! received data to tab 2");
if(cartsViewModels!=null){
for(CartsViewModel cart : cartsViewModels){
Log.d(TAG,"got it :"+cart.getCartName());
}
}
}
Since AndroidX, you can create a ViewModel and share data between Activity and all fragments within ViewPager
Read here how to
Can you do something like this? First create any data structure like Arraylist in your main activity. Then send a reference of that data model to your fragments. Now update that data when, on change your text fields. By doing this all the fragment can see updated values. So fragments can update this data itself and we don't need to send that data since it is already shared. I'll explain this using your example. Try to improve this. You can maintain fragment specific data model then each fragment can access data with the knowledge of that data owner.
TabsPagerAdapter.java
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm,SubmitPostActivity activity){
super(fm);
}
#Override
public Fragment getItem(int index) {
switch(index) {
case 0 : //PostInfoFragment
return new PostInfoFragment(0,activity);
case 1 : //LocationInfoFragment
return new LocationInfoFragment(1,activity);
case 2 : //PersonalInfoFragment
return new PersonalInfoFragment(2,activity);
}
return null;
}
#Override
public int getCount() {
return 3;
}
}
ViewPagerActivity -- >
package com.jbandroid;
public class SubmitPostActivity extends FragmentActivity implements ActionBar.TabListener,LocationInfoFragment.setLocationInfo{
private ViewPager viewpager;
private ActionBar actionBar;
private TabsPagerAdapter mAdapter;
FragmentManager manager;
PersonalInfoFragment frag;
List<String> location;
/*private MenuItem myActionMenuItem;
private Button myActionButton;*/
//Tab titles
private String[] tabs = {"Post Info" , "Location Info" , "Personal Info" };
public List<String> dataModel = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.action_submit_post);
viewpager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
manager = getSupportFragmentManager();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager(),this);
//viewpager.setOffscreenPageLimit(2);
viewpager.setAdapter(mAdapter);
//actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (String tab : tabs){
actionBar.addTab(actionBar.newTab().setText(tab).setTabListener(this));
}
if(savedInstanceState != null){
actionBar.setSelectedNavigationItem( savedInstanceState.getInt("tab",0));
}
}
}
1st Fragment =>
public class PostInfoFragment extends Fragment {
private MenuItem myActionMenuItem;
private Button myActionButton;
private ActionBar actionBar;
private String post_title, post_desc,post_status;
private EditText submit_post_title, submit_post_desc;
private int position;
private Resources res;
SubmitPostActivity callingActivity;
List<String> post_details;
public PostInfoFragment(int position,SubmitPostActivity callingActivity )
{
this.callingActivity = callingActivity;
this.position = position;
}
//RelativeLayout rel_submit_post_start_date,rel_submit_post_end_date;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_post_info,
container, false);
/*if(!imageLoader.isInited()){*/
initImageLoader();
/*}*/
//handler = new Handler();
submit_post_title = (EditText) rootView
.findViewById(R.id.submit_post_title);
submit_post_desc = (EditText) rootView
.findViewById(R.id.submit_post_description);
actionBar = getActivity().getActionBar();
setHasOptionsMenu(true);
post_details = new ArrayList<String>();
res = getResources();
setListeners();
Log.d("postinfo_oncreate view", "postinfo_oncreate view");
//this is editText onchange listner do the same for submit_post_desc as well
submit_post_title.addTextChangedListener( new TextWatcher()
{
#Override
public void onTextChanged( CharSequence s, int start, int before, int count )
{
}
#Override
public void beforeTextChanged( CharSequence s, int start, int count, int after )
{
}
#Override
public void afterTextChanged( Editable s )
{
if( callingActivity != null )
{
//use this.position in order to update relevant data
List<String> post_details = callingActivity.dataModel;
if( post_details == null )
{
post_details = new ArrayList<String>();
}
post_details.add(s.toString());
}
}
} );
return rootView;
}
//making sure if the parent activity has implemented interface
#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 {
callingActivity = (SubmitPostActivity) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ "must implemet setPostInfo");
}
Log.d("postinfo_onattach", "postinfo_onattach");
}
}
Please not that this may not compile as it is. Try to get the concept.

Relation between Fragment and TabListener

I try to develop a system to make a relation between tabs and fragment. You will see bellow my code and the view.
The Fragment manage the swipe, and the tabs the navigation directly on the click.
I manage to modify the Selected Tab when the user Swipe, but I can't do the inverse. That the view changes when I click on a tab.
Do you understand my question and have you the solution please ?
This is my main activity :
public class MainActivity extends FragmentActivity {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link android.support.v4.app.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}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
TextView tw;
ActionBar myActionBar;
ArrayList<Category> ListOfCategory;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myActionBar = getActionBar();
myActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ListOfCategory = new ArrayList<Category>();
try {
List<String> categList = new ExecuteJsonLinkTask().execute("http://www.76actu.fr/json.php?d=categories&a=list&key=8smA5YjLG1132zbz301tM94jZO30B7dW").get();
for (String item : categList) {
JSONArray jArray = new JSONArray(item);
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
Category categ = new Category();
categ.setCategIdSite(json_data.getInt("term_id"));
categ.setName(json_data.getString("name"));
categ.setMoreArticle(true);
categ.setArticleAvailable(false);
if(json_data.getInt("term_id") == 89871){
categ.setActive(false);
} else categ.setActive(true);
Tab tab = myActionBar.newTab();
tab.setText(json_data.getString("name"));
Object obj = new Object();
obj = String.valueOf(json_data.getInt("term_id"));
tab.setTag(obj);
tab.setTabListener(new MyTabListener(getBaseContext()));
// tab.setTabListener(new MyTabListener(getBaseContext()));
myActionBar.addTab(tab);
ListOfCategory.add(categ);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
myActionBar.setSelectedNavigationItem(arg0);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Category> ListOfCategory = new ArrayList<Category>();
Fragment fragment;
ActionBar myActionBar;
public SectionsPagerAdapter(FragmentManager fm){
super(fm);
myActionBar = getActionBar();
try {
List<String> categList = new ExecuteJsonLinkTask().execute("[API_LINK]").get();
for (String item : categList) {
JSONArray jArray = new JSONArray(item);
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
Category categ = new Category();
categ.setCategIdSite(json_data.getInt("term_id"));
categ.setName(json_data.getString("name"));
categ.setMoreArticle(true);
categ.setArticleAvailable(false);
if(json_data.getInt("term_id") == 89871){
categ.setActive(false);
} else categ.setActive(true);
ListOfCategory.add(categ);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#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.
fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position);
args.putInt("categId", ListOfCategory.get(position).getCategIdSite());
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
// Show total pages.
return ListOfCategory.size();
}
#Override
public CharSequence getPageTitle(int position) {
return ListOfCategory.get(position).getName();
}
}
/**
* A dummy fragment representing a section of the app, but that simply
* displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
TextView dummyTextView;
public static final String ARG_SECTION_NUMBER = "section_number";
public DummySectionFragment() {
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_dummy, container, false);
dummyTextView = (TextView) rootView.findViewById(R.id.section_label);
int position = getArguments().getInt(ARG_SECTION_NUMBER);
dummyTextView.setText(Integer.toString(getArguments().getInt("categId")));
return rootView;
}
}
public class MyTabListener implements TabListener{
public Context context;
MyTabListener(Context context) {
this.context = context;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// HERE
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
}
}
This is a screenshot of my application : http://i.stack.imgur.com/HBKUj.png
I do not think you need it but I can give you this.
Thanks a lot
http://i.stack.imgur.com/HBKUj.png
In my code i have this solution and it works:
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
public static String TAG="MAIN_ACTIVITY";
public static Context mContext;
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
private String[] tabs = { "FRIENDS", "CHAT", "MAP" };
//ON CREATE METHOD:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft)
{
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft){}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {}
}
TabsPagerAdapter class:
public class TabsPagerAdapter extends FragmentPagerAdapter
{
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
//switch names of your fragments:
switch (index) {
case 0:
return new Stats_Fragment();
case 1:
return new FightsFragment();
case 2:
return new SearchFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
You must add this line in your Activity xml file, this is my case:
<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"
tools:context="example.com.MainActivity">
//ADD THIS AND PROBLEM WILL BE SOLVED:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</FrameLayout>

ViewPager with ListView inside fragment - listview isn't updating when modified

When I add or remove an item from the listview, the listview isn't updated unless I scroll offscreen in the viewpager and then back, triggering the OnCreate method again in the fragment. This is based on the viewpager template in eclipse - I just added a listview to the fragment instead of just a textview. Putting notifyDataSetChanged doesn't help nor did adding an OnResume to the fragment. Below is the mainactivity. The adapter and listview have the correct items in them, but they are not being displayed until you scroll at least two pages over (offscreen on my device, may be more or less on others) and then back. What am I missing?
public class MainActivity extends ActionBarActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
static ArrayAdapter adapter;
private static DataElementTable dataElementTable;
private static ItemTable ItemTable;
private static int currentTab = 0;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// 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.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
dataElementTable = new DataElementTable(this);
dataElementTable.open();
itemTable = new ItemTable(this);
itemTable.open();
}
#Override
protected void onResume() {
dataElementTable.open();
itemTable.open();
super.onResume();
}
#Override
protected void onPause() {
dataElementTable.close();
itemTable.close();
super.onPause();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, 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();
if (id == R.id.action_settings) {
addNewItem();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
private void addNewItem()
{
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("New Item");
alert.setMessage("Enter New Item Name:");
final EditText input = new EditText(this);
alert.setView(input);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString();
Log.d("pos", "newitem " + currentTab);
Item newItem = itemTable.createItem(currentTab - 1, value);
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
alert.show();
}
/**
* 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).
return PlaceholderFragment.newInstance(position + 1);
}
#Override
public int getCount() {
// Show 7 total pages.
return 7;
}
#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_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
case 3:
return getString(R.string.title_section4).toUpperCase(l);
case 4:
return getString(R.string.title_section5).toUpperCase(l);
case 5:
return getString(R.string.title_section6).toUpperCase(l);
case 6:
return getString(R.string.title_sectionX).toUpperCase(l);
}
return null;
}
}
/**
* 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";
ListView listView;
/**
* 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;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
TextView textView = (TextView) rootView
.findViewById(R.id.section_label);
textView.setText(Integer.toString(getArguments().getInt(
ARG_SECTION_NUMBER)));
currentTab = (getArguments().getInt(ARG_SECTION_NUMBER)) - 1;
listView = (ListView) rootView.findViewById(R.id.listview);
ArrayList<String> listItems1 = new ArrayList<String>();
ArrayList<String> listItems2 = new ArrayList<String>();
ArrayList<String> listItems3 = new ArrayList<String>();
ArrayList<String> listItems4 = new ArrayList<String>();
ArrayList<String> listItems5 = new ArrayList<String>();
ArrayList<String> listItems6 = new ArrayList<String>();
ArrayList<String> listItemsLog = new ArrayList<String>();
listItems1 = itemTable.getAllItemsForCategory(0);
listItems2 = itemTable.getAllItemsForCategory(1);
listItems3 = itemTable.getAllItemsForCategory(2);
listItems4 = itemTable.getAllItemsForCategory(3);
listItems5 = itemTable.getAllItemsForCategory(4);
listItems6 = itemTable.getAllItemsForCategory(5);
Log.d("pos", "createview " + currentTab);
switch (currentTab)
{
case 0:
{
adapter = new ArrayAdapter<String>(this.getActivity(), R.layout.list_item, listItems1);
}
break;
case 1:
{
adapter = new ArrayAdapter<String>(this.getActivity(), R.layout.list_item, listItems2);
}
break;
case 2:
{
adapter = new ArrayAdapter<String>(this.getActivity(), R.layout.list_item, listItems3);
}
break;
case 3:
{
adapter = new ArrayAdapter<String>(this.getActivity(), R.layout.list_item, listItems4);
}
break;
case 4:
{
adapter = new ArrayAdapter<String>(this.getActivity(), R.layout.list_item, listItems5);
}
break;
case 5:
{
adapter = new ArrayAdapter<String>(this.getActivity(), R.layout.list_item, listItems6);
}
break;
case 6:
{
listItemsLog = dataElementTable.getAllElements();
adapter = new ArrayAdapter<String>(this.getActivity(), R.layout.list_item, listItemsLog);
}
break;
default:
{
assert(false);
}
break;
}
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
return rootView;
}
}
}
You are calling notifyDataSetChanged in the onCreateView method. onCreateView is called when you are scrolling through your ListView, and then data is updating on your screen. You need to call notifyDataSetChanged immediately after you change data in your adapter, not in onCreateView.

tab action bar, trying to use text field and listview with custom adapter, not working

ok, here is the main activity which is suppose to show the 2 tabs.
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link android.support.v4.app.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 static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";
// SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position); }
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
public void onSaveInstanceState(Bundle outState) {
outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar().getSelectedNavigationIndex());
}
public void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
if (tab.getPosition() == 0) {
MyFriendsListFragment simpleListFragment = new MyFriendsListFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.pager, simpleListFragment).commit();
}
else if (tab.getPosition() == 1) {
MyFriendsListFragment simpleListFragment = new MyFriendsListFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.pager, simpleListFragment).commit();
}
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
/**
* A dummy fragment representing a section of the app, but that simply
* displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static final String ARG_SECTION_NUMBER = "section_number";
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView textView = new TextView(getActivity());
textView.setGravity(Gravity.CENTER);
Bundle args = getArguments();
textView.setText(Integer.toString(args.getInt(ARG_SECTION_NUMBER)));
return textView;
}
}
}
and here is the class thats being called when one of the tabs is being pressed, right now both tabs are supposed to show the same thing, because both of them call the same class.
*public class MyFriendsListFragment extends ListFragment {
private ArrayList<Student> studentList = new ArrayList<Student>();
private ListView lv;
private EditText inputSearch;
public MyFriendsListFragment() {
Student andres = new Student();
andres.setFirstName("Andres");
andres.setLastName("Blanco");
Student ondria = new Student();
ondria.setFirstName("Ondria");
ondria.setLastName("Arias");
studentList.add(andres);
studentList.add(ondria);
}
private class MyListAdapter extends ArrayAdapter<Student> implements Filterable{
private final Context context;
public ArrayList<Student> displayValues;
public ArrayList<Student> originalValues;
public MyListAdapter(Context context, int textViewResourceId, ArrayList<Student> values) {
super(context, textViewResourceId, values);
this.context = context;
this.displayValues = values;
this.originalValues = (ArrayList<Student>) values.clone();
}
public int getCount(){
return this.displayValues.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//----This method sets each row of the list individually----
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.list_view, parent, false);
if(displayValues.size() > 0)
{
Student student = displayValues.get(position);
//Fill Name
TextView name = (TextView) itemView.findViewById(R.id.contactName);
name.setText(student.getFirstName() + student.getLastName());
}
return itemView;
}
public Filter getFilter() {
Filter contactFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<Student> filteredList = new ArrayList<Student>();
//Filter the list
if(constraint != null && originalValues !=null) {
if(!constraint.toString().isEmpty())
{
String constraintLowerCase = constraint.toString().toLowerCase();
for(Student c: originalValues)
{
String cName = c.getFirstName().toLowerCase() ;
String cLName = c.getLastName().toLowerCase();
if(cName.startsWith(constraintLowerCase) || cLName.startsWith(constraintLowerCase))
{
//Add the row to the list if filtered items
filteredList.add(c);
}
}
}
//Important steps to store the filtered list
filterResults.values = filteredList;
filterResults.count = filteredList.size();
}
return filterResults;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence contraint, FilterResults results) {
if (results.count > 0)
{
//Display the filtered list
MyListAdapter.this.displayValues = (ArrayList<Student>) results.values;
notifyDataSetChanged();
}
else
{
if(inputSearch.getText().toString().isEmpty())
{
//Display the original list
MyListAdapter.this.displayValues = (ArrayList<Student>) MyListAdapter.this.originalValues.clone();
}
else
{
//Display an empty list
MyListAdapter.this.displayValues.clear();
}
notifyDataSetInvalidated();
}
}
};
return contactFilter;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_dummy, container, false);
try{
lv = (ListView) rootView.findViewById(R.id.list);
inputSearch = (EditText) rootView.findViewById(R.id.inputSearch);
MyListAdapter adapter = new MyListAdapter(getActivity(), R.layout.list_view, studentList);
lv.setAdapter(adapter);
lv.setTextFilterEnabled(true);
}
catch (Exception e){
Log.e("Error!!!!!", "00");
}
return rootView;
}
#Override
public void onListItemClick(ListView list, View v, int pos, long id) {
try{
Student clickedStudent = studentList.get(pos);
int position = pos;
Intent intent = new Intent(getActivity(), ShowStudentActivity.class);
Log.e("CINTENT","CREATED!!!");
intent.putExtra("clickedContact",clickedStudent);
intent.putExtra("officialList",studentList);
intent.putExtra("position",position);
Log.e("putExtra","Passed");
startActivity(intent);
Log.e("Start activity","passed");
}
catch (Exception e){
Log.e("Catch!","CATCH!!!!");
}
}
}*
When i run it it just crashes and gives me an error saying that there needs to be something inside the listview, but i think i am filling the listview in the oncreateview method. please help me, been at this for a week searching online and have not found any solution, thx!

Categories

Resources