Ok, I'm new to android programming and here is my problem. I've got an async task that collects json data from a server on a httpget request and updates a listview fragment in a swipeable view. I want a way to send data(a bunch of strings) from the main TabActivity class to the Tab1Fragment class.
I've done my level best at stripping down the code to the essentials.
NOTE: I've tried the bundle method that I've read in other similar questions, but they all end up throwing NULL pointer exceptions in the fragment, meaning the bundle isn't getting sent.(?)
This is my main Tab Activity:
TabActivity.java
public class TabActivity extends ActionBarActivity implements ActionBar.TabListener {
private String phoneno;
private static String url = "http://my/url/forjson";
//JSON Node Names
private static final String TAG_OPERATOR = "operator";
private static final String TAG_REGNO = "Reg No";
public String operator;
public String regNo;
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Details", "Others"};
Bundle bundle = new Bundle();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab);
Intent intent = getIntent();
phoneno = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
new JSONParse().execute();
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getSupportActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
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));
}
/**
* on swiping the viewpager make respective tab selected
* */
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 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) {
}
/*Private Class to parse JSON*/
private class JSONParse extends AsyncTask<String, String, JSONObject> {
private ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(TabActivity.this);
pDialog.setMessage("Getting Data ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#SuppressWarnings("finally")
#Override
protected JSONObject doInBackground(String... args) {
//*
JSONParser jParser = new JSONParser();
// Getting JSON from URL
StringBuilder finalUrl = new StringBuilder();
JSONObject jsonForData = new JSONObject();
try{
finalUrl.append(url);
jsonForData = jParser.getJSONFromUrl(finalUrl.toString());
}catch (JSONException e) {
e.printStackTrace();
}
return jsonForData;
}
#Override
protected void onPostExecute(JSONObject json) {
pDialog.dismiss();
try {
Bundle bundle=new Bundle();
bundle.putString("oper", json.getString(TAG_OPERATOR));
bundle.putString("regNo", json.getString(TAG_REGNO));
mAdapter.getData(bundle);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
In the above code, please understand that the JSONPasrser class that I've instantiated returns a JSONObject from the url and it works. So, no issues there.
Further, my fragment class is a listview as follows:
Tab1Fragment.java
public class Tab1Fragment extends ListFragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tab1, container, false);
String abc = "No Details Presently Available";
//Fill all string values with something
String[] values = new String[2];
for(int i=0;i<values.length;i++)
values[i] = " ";
//Make Sure number of elements match
try{
values[0] = "Provider: " + getArguments().getString("oper");//Gives a NULL value
values[1] = "No: " + + getArguments().getString("regNo");//Gives a NULL value
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this.getActivity(), android.R.layout.simple_list_item_1,values);
// Assign adapter to ListView
setListAdapter(adapter);
}
catch(Exception e){
e.printStackTrace();
Log.w("Error","The App didn't have enough elements specified to populate the listview");
}
return rootView;
}
}
The "abc" string that I've hardcoded should ideally have details sent from the TabActivity class.
I want the above fragment to recieve data from the TabActivity class to populate the listview. Any help is appreciated :)
EDIT: I've changed the adapter class as follows based on Illegal Argument's suggestion.
So now, the bundle is passed as TabActivity->TabsPagerAdapter->Tab1Fragment
But still, NULL value returned.
My Adapter class is now as follows:
TabsPagerAdapter.java
public class TabsPagerAdapter extends FragmentStatePagerAdapter {
Bundle bundle = new Bundle();
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
Fragment fragment = new Tab1Fragment();
this.bundle.putString("operator", "hi");
fragment.setArguments(this.bundle);
return fragment;
case 1:
return new Tab2Fragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 2;
}
public void getData(Bundle bundle){
this.bundle = bundle;
}
}
I can see that you have successfully passed data via a bundle. Please remove this. from your code below:
this.bundle.putString("operator", "hi");
fragment.setArguments(this.bundle);
change it because it is not required to be accessed that way:
bundle.putString("operator", "hi");
fragment.setArguments(bundle);
On your Tab1Fragment.java you can try something like this:
if(getArguments()!=null){
String sentString = getArguments().getString("operator");
}
Related
I got a problem with updating ViewPager fragments. We need to show fragments with data to registered user, when he doesn't registered we need to show fragments with message to register. I use this method to check it in MainActivity:
#Override
public void setAdapter(boolean isUserExist) {
Log.d("RegDebug", "In setAdapter");
mainPagerAdapter.clearData();
mainPagerAdapter.addFragment(searchFragment, getString(R.string.search_title));
if (isUserExist) {
Log.d("RegDebug", "In setAdapter reg");
mainPagerAdapter.addFragment(new ChatsFragment(), getString(R.string.chats_title));
mainPagerAdapter.addFragment(new ActionsFragment(), getString(R.string.actions_title));
Toast.makeText(getApplicationContext(), "Registered!", Toast.LENGTH_SHORT).show();
} else {
Log.d("RegDebug", "In setAdapter unreg");
mainPagerAdapter.addFragment(RegisterFragment.newInstance(Consts.CHATS_TAB_NAME), getString(R.string.chats_title));
mainPagerAdapter.addFragment(RegisterFragment.newInstance(Consts.ACTIONS_TAB_NAME), getString(R.string.actions_title));
Toast.makeText(getApplicationContext(), "Unregistered!!!", Toast.LENGTH_SHORT).show();
}
mainPagerAdapter.notifyDataSetChanged();
viewPager.setAdapter(mainPagerAdapter);
}
I call this method in presenter with setting value from firebase auth, checking if user exists:
public void checkForUserExist() {
if (mainInteractor.isUserExist()) {
getViewState().setRegAdapter();
} else getViewState().setUnregAdapter();
}
And then call presenter method in onCreate of MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dialogFragment = new FilterDialogFragment();
searchFragment = new SearchFragment();
//UI
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = findViewById(R.id.main_view_pager);
tabLayout = findViewById(R.id.main_tabs);
//mainPagerAdapter = new MainPagerAdapter(getSupportFragmentManager());
mainPresenter.checkForUserExist();
tabLayout.setupWithViewPager(viewPager);
}
I try to log the boolean result and it returns exactly value that must be, but pager adapter can't update its content.Code of MainPagerAdapter:
public class MainPagerAdapter extends FragmentPagerAdapter{
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
return fragmentTitleList.size();
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
public void addFragment(Fragment fragment, String title){
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
public void clearData(){
fragmentList.clear();
fragmentTitleList.clear();
notifyDataSetChanged();
Log.d("RegDebug", " fragmentList size is " + fragmentList.size()
+ " fragmentTitleList size is " + fragmentTitleList.size());
}
}
Use OnPageChangeListener of ViewPager class & notify to your current fragment from there using interface.
in my app i have a Tabs with fragment classes. i trying to refresh listView in "fragment a" with the new data i insert.
In "fragment b" i have EditText and Button ,that inserting text to the database.
in "fragment a" i have the ListView with the dataBase rows. when "fragment a" is "OnCreateView" i just put the dataBase on a "ArrayList" and past it to my baseAdapter.
but "onCreateView" not refreshing my new data every time i get into the "fragment a" else i goes to "fragment c" and "onDestroy" call on "fragment a".
so my result it was to call : "setUserVisibleHint" override method, and check if it is visible and refreshing the list.
but i dont think it is the good practice .
what should i do?
Class a
public class ListFragment extends Fragment{
basAdapterCustom adapter;
ListView lv;
ArrayList<Clock> list;
private DbHandler hand;
Context context;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.list_fragment, container, false);
context = getActivity();
Log.d(TAG, "onCreateView");
hand = new DbHandler(context);
list = new ArrayList<Clock>();
lv = (ListView) v.findViewById(R.id.listOfShifts);
adapter = new basAdapterCustom(list, getActivity());
lv.setAdapter(adapter);
refreshList();
return v;
}
//like on "resume":
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
// Make sure that we are currently visible
if (this.isVisible()) {
refreshList();
if (!isVisibleToUser) {
// TODO stop
}
}
}
private void refreshList() {
list = hand.getByWorkName();
adapter = new basAdapterCustom(list,getActivity());
lv.setAdapter(adapter);
}
class b:
public class ClockFragment extends Fragment{
DbHandler hand;
Context context;
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.clock, container,false);
context = getActivity();
hand = new DbHandler(context);
return v;
}
// ADD to .Db
public void addToDb(View v){
hand.add(new Clock(0, dateDay));
}
}
class mainActivity:
public class MainActivity extends FragmentActivity implements ActionBar.TabListener, OnPageChangeListener{
public static final String TAG = "myClock";
String[] tabMenu = {"FRAG A","FRAG B","FRAG C"};
private ViewPager viewPager;
private TabPagerAdapter mAdapter;
private ActionBar actionBar;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(MainActivity.TAG, "OnCreate = MainActivity (Pager");
viewPager = (ViewPager) findViewById(R.id.pager );
actionBar = getActionBar();
mAdapter = new TabPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (String tabsNames : tabMenu) {
actionBar.addTab(actionBar.newTab().setText(tabsNames).setTabListener(this));
}
viewPager.setOnPageChangeListener(this);
}
// public void transDialog(){
// Dialog mDialog = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
// }
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
}
PagetAdapter.class
public class TabPagerAdapter extends FragmentPagerAdapter {
private static final String TAG = "myClock";
public TabPagerAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
#Override
public Fragment getItem(int index) {
Log.d(TAG, " CLASS : TabPagerAdapter");
switch (index) {
case 0:
return new ListFragment();
case 1:
return new ClockFragment();
case 2:
return new SettingFragment();
default:
break;
}
Log.d(TAG, " CLASS : TabPagerAdapter = "+index);
return null;
}
#Override
public int getCount() {
return 3;
}
}
Please help me i hope you are understand my problem...
You want to update listView in fragment A, after insert data in fragment b? ThenĀ you have a few solutions to choose:
1. Implement communications between fragments via activity. Then B insert date, it send message to activity, that data need to be updated. Then fragment A started, it's ask activity to need update data. For details on implementing this communication check link.
2. Use some bus library, EventBus for example. Then fragment B insert data, it post 'data changed' event to bus. Fragment A checks on start if this event occurs.
3. Use Loaders which "monitor the source of their data and deliver new results when the content changes."
I have a problem with the call of asyncTask....
i have a class named arrivi
public class arrivi extends Fragment {
ListView list;
int thread = 0;
public String[] lista = new String[200];
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View ios = inflater.inflate(R.layout.arrivi, container, false);
new MyTask().execute("");
return ios;
}
//INIZIO THREAD
public class MyTask extends AsyncTask<String, Void, String> {
with new MyTask this work fine...
but i want call MyTask into MainActivity.java
public class MainActivity extends FragmentActivity {
ViewPager Tab;
TabPagerAdapter TabAdapter;
ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
.....
.....
i have tried to
arrivi a = new arrivi();
a.MyTask.execute("");
i don't know...
how to make a call?? can you make me an example of code?
Thank u guys!
There are two ways to do this, but what it looks like you are trying to do here is actually to make MyTask static:
public static class MyTask extends AsyncTask<String, Void, String> {
and that way, in your activity, you can just call:
new arrivi.MyTask().execute();
(Optional) further explanation:
the other alternative is to use the syntax -
new arrivi().new MyTask().execute(); which i think is what you could also be trying to accomplish.
given that you are calling your MyTask in two separate places, it seems you might as well either make your MyTask static OR place MyTask in its own class outside of both of these two classes (in order to syntactically make this correct. This, however, depends on if you want MyTask to interact with your fragment arrivi. For example, if, in your onPostExecute() of MyTask, you want to access something that arrivi has (such as a view), you probably want to place MyTask inside of arrivi still, and not use the static declaration
thank u for replies... in mainactivity i have this:
public class MainActivity extends FragmentActivity {
ViewPager Tab;
TabPagerAdapter TabAdapter;
ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabAdapter = new TabPagerAdapter(getSupportFragmentManager());
Tab = (ViewPager)findViewById(R.id.pager);
Tab.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar = getActionBar();
actionBar.setSelectedNavigationItem(position); }
});
Tab.setAdapter(TabAdapter);
actionBar = getActionBar();
//Enable Tabs on Action Bar
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.TabListener tabListener = new ActionBar.TabListener(){
#Override
public void onTabReselected(android.app.ActionBar.Tab tab,
FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
Tab.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(android.app.ActionBar.Tab tab,
FragmentTransaction ft) {
// TODO Auto-generated method stub
}
};
//Add New Tab
actionBar.addTab(actionBar.newTab().setText("Info").setTabListener(tabListener));
actionBar.addTab(actionBar.newTab().setText("Arrivi").setTabListener(tabListener));
actionBar.addTab(actionBar.newTab().setText("Partenze").setTabListener(tabListener));
if (isOnline()) {
//System.out.println("CONNESSIONE OK");
new arrivi().new MyTask().execute();
}else{
try {
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Info");
alertDialog.setMessage("Connessione Internet non disponibile.");
alertDialog.setButton("Esci", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alertDialog.show();
}
catch(Exception e) { }
}
}
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
}
and this is arrivi class:
public class arrivi extends Fragment {
ListView list;
int thread = 0;
public String[] lista = new String[200];
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View ios = inflater.inflate(R.layout.arrivi, container, false);
new MyTask().execute("");
return ios;
}
//INIZIO THREAD
public class MyTask extends AsyncTask<String, Void, String> {
ProgressDialog prog;
String info;
#Override
protected void onPreExecute() {
prog = new ProgressDialog(getActivity());
prog.setMessage("Connessione in corso...");
prog.show();
prog.setCanceledOnTouchOutside(false);
prog.setCancelable(false);
}
#Override
protected String doInBackground(String... params) {
try {
org.jsoup.nodes.Document doc = Jsoup.connect("http://site.eu").timeout(7*1000).get();
org.jsoup.nodes.Element tabella = doc.getElementsByClass("tabella-voli").first();
Iterator<org.jsoup.nodes.Element> iterator = tabella.select("td").iterator();
while(iterator.hasNext()){
thread++;
lista[thread] = iterator.next().text();
System.out.println("Posizione["+thread+"]"+lista[thread]);
}
}catch (IOException e) {
e.printStackTrace();
}
return info;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
prog.dismiss();
CheckRow();
}
}// FINE THREAD
but when i lunch my app, crashes and here there is a logcat
http://paste.ubuntu.com/7253904/
i think line 43 is NULL... prog = new ProgressDialog(getActivity());
..thank you so much guys!!
DESCRIPTION::
There is a ActionBarTab(3-tab) setup, We are linking three fragments
for each Action-Tab, Each fragment contains a listview
Whenever we are clicking Tab, we are sorting data.
In onTabReselect i am calling sort function using interface method,
without error it executes but its not refreshing the listview
MainActivity.java
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Toast.makeText(this, DosUtils.ExecuteDOSCommand(), Toast.LENGTH_SHORT);
// Initialize
FindMyBuffetApplicationCls.initFindMyBuffetApplicationCls(MainActivity.this);
setContentView(R.layout.main_activity);
appContext = getApplicationContext();
//ActionBar
ActionBar actionbar = getActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab RatingTab = actionbar.newTab().setText(FindMyBuffetConstants.TAB_NAME_RATING);
ActionBar.Tab PriceTab = actionbar.newTab().setText(FindMyBuffetConstants.SORT_BY_PRICE);
ActionBar.Tab DistanceTab = actionbar.newTab().setText(FindMyBuffetConstants.SORT_BY_DISTANCE);
Fragment SortRestFragmentByRating = new SortRestaurantRating();
Fragment SortRestFragmentByPrice = new SortRestaurantByPrice();
Fragment SortRestFragmentByDistance = new SortRestaurantByDistance();
RatingTab.setTabListener(new MyTabsListener(SortRestFragmentByRating));
PriceTab.setTabListener(new MyTabsListener(SortRestFragmentByPrice));
DistanceTab.setTabListener(new MyTabsListener(SortRestFragmentByDistance));
actionbar.addTab(RatingTab);
actionbar.addTab(PriceTab);
actionbar.addTab(DistanceTab);
FindMyBuffetApplicationCls.comm = (Communicator) new SortRestaurantByPrice();
}
class MyTabsListener implements ActionBar.TabListener {
public Fragment fragment;
public MyTabsListener(Fragment fragment) {
this.fragment = fragment;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
if(tab.getText().toString()==FindMyBuffetConstants.TAB_NAME_RATING){
if(FindMyBuffetApplicationCls.isRatingOrderByDesc==false){
FindMyBuffetApplicationCls.isRatingOrderByDesc=true;
}
else {
FindMyBuffetApplicationCls.isRatingOrderByDesc=false;
}
}
if(tab.getText().toString()==FindMyBuffetConstants.SORT_BY_PRICE){
if(FindMyBuffetApplicationCls.isPriceOrderByDesc==false){
FindMyBuffetApplicationCls.isPriceOrderByDesc=true;
}
else {
FindMyBuffetApplicationCls.isPriceOrderByDesc=false;
}
FindMyBuffetApplicationCls.comm.RefreshFragment();
}
if(tab.getText().toString()==FindMyBuffetConstants.SORT_BY_DISTANCE){
if(FindMyBuffetApplicationCls.isDistanceOrderByDesc==false){
FindMyBuffetApplicationCls.isDistanceOrderByDesc=true;
}
else {
FindMyBuffetApplicationCls.isDistanceOrderByDesc=false;
}
}
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(R.id.main_container, fragment);
if(tab.getText().toString()==FindMyBuffetConstants.TAB_NAME_RATING){
if(FindMyBuffetApplicationCls.isRatingOrderByDesc==false)
FindMyBuffetApplicationCls.isRatingOrderByDesc=true;
else
FindMyBuffetApplicationCls.isRatingOrderByDesc=false;
}
if(tab.getText().toString()==FindMyBuffetConstants.SORT_BY_PRICE){
if(FindMyBuffetApplicationCls.isPriceOrderByDesc==false)
FindMyBuffetApplicationCls.isPriceOrderByDesc=true;
else
FindMyBuffetApplicationCls.isPriceOrderByDesc=false;
}
if(tab.getText().toString()==FindMyBuffetConstants.SORT_BY_DISTANCE){
if(FindMyBuffetApplicationCls.isDistanceOrderByDesc==false)
FindMyBuffetApplicationCls.isDistanceOrderByDesc=true;
else
FindMyBuffetApplicationCls.isDistanceOrderByDesc=false;
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
Log.i("TEST TAB",tab.getText().toString());
}
}
SortRestaurantByPrice.java
public class SortRestaurantByPrice extends Fragment implements Communicator{
// Declaration
ListView xmlFragmentListView;
SortRestaurantListViewAdapter listViewAdapter;
View layout;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
layout = inflater.inflate(R.layout.sort_restaurant_by_price, container,false);
xmlFragmentListView = ((ListView) layout.findViewById(R.id.sortrestaurantbypricelistview));
return layout;
}
#Override
public void onDestroyView() {
super.onDestroyView();
//layout = null; // now cleaning up!
}
private void SortRestaurantList(String strSortBy)
throws Exception, TransformerConfigurationException,
TransformerException, FindMyBuffetException {
// Process the Main Screen Data
List<RestaurantDetails> lstRest = null;
lstRest = SAXXMLParser.parse(xmlInputStream);
SortRestaurantListViewAdapter listViewAdapter = new SortRestaurantListViewAdapter(lstRest);
xmlFragmentListView.setAdapter(listViewAdapter);
}
#Override
public void RefreshFragment() {
// TODO Auto-generated method stub
Log.i("hELLO", "refresh requested. Try to reload data for this fragment...");
SortRestaurantList("Price");
}
}
Communicator.java
public interface Communicator {
public void RefreshFragment();
}
Please call notifyDataChanged method on your list in the sortRestaurantList method.
private void SortRestaurantList(String strSortBy)
throws Exception, TransformerConfigurationException,
TransformerException, FindMyBuffetException {
// Process the Main Screen Data
List<RestaurantDetails> lstRest = null;
lstRest = SAXXMLParser.parse(xmlInputStream);
SortRestaurantListViewAdapter listViewAdapter = new SortRestaurantListViewAdapter(lstRest);
xmlFragmentListView.setAdapter(listViewAdapter);
listViewAdapter.notifyDataSetChanged(); // call this on Adapter
}
Infact move the adapter code in the onCreateView method. Only modify (sort) your List lstRest in the SortRestaurant method and after that call the notifyDataSetChanged method.
i have an actionbar with two tabs and an tablistener which handles the fragments. Now i want with a ViewPager the possibility to Swipe to also switch the tabs.
I tried the solution stated here:
Android, How to mix ActionBar.Tab + View Pager + ListFragment
But it gives an conflicts with Android.app.Fragments and the Support Package Fragments.
The App is for >4.0 so i dont need the support fragments.
public class MainActivity extends Activity{
....
actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//viewpager
mViewPager = new ViewPager(this);
setContentView(mViewPager);
Doesnt work:
//TabsAdapter tabsAdapter = new TabsAdapter(this,mViewPager);
// Tab tab1 = actionBar.newTab().setText("Tab1");
// Tab tab2 = actionBar.newTab().setText("Tab2");
// tabsAdapter.addTab(tab1, Tab1Fragment.class, null);
// tabsAdapter.addTab(tab2, Tab2Fragment.class, null);
Alternative:
//viewpager
mViewPager = new ViewPager(this);
setContentView(mViewPager);
mViewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// When swiping between pages, select the
// corresponding tab.
super.onPageSelected(position);
getActionBar().setSelectedNavigationItem(position);
}
});
tab_1 = actionBar.newTab().setText("Tab1");
tab_1
.setTabListener(new TabListener<Tab1Fragment>(
this, "Tab1", Tab1Fragment.class,mViewPager));
actionBar.addTab(tab_1);
tab_2 = actionBar.newTab().setText("Tab2");
tab_2
.setTabListener(new TabListener<Tab2Fragment>(
this, "Tab2", Tab2Fragment.class,mViewPager));
actionBar.addTab(tab_2);
/**
* TabListener
* #param <T>
*/
private static class TabListener<T extends Fragment> implements ActionBar.TabListener
{
private Fragment mFragment;
private Activity mActivity;
private final String mTag;
private final Class<T> mClass;
private ViewPager vp;
public TabListener(Activity activity, String tag, Class<T> clz, ViewPager vp) {
mActivity = activity;
mTag = tag;
mClass = clz;
mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
this.vp = vp;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.replace(android.R.id.content, mFragment, mTag);
} else {
if (mFragment.isDetached()) {
ft.attach(mFragment);
}
}
vp.setCurrentItem(tab.getPosition());
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
ft.detach(mFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
In the Fragments classes i have statements like:
Bundle args = new Bundle();
args.putString("name", atn.getName());
args.putLong("aid", atn.getId());
AFragment f = new AFragment();
f.setArguments(args);
f.show(getFragmentManager(), "tag");
FragmentManager fragmentManager =mActivity.getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment f = fragmentManager.findFragmentByTag("Tab1");
if (f != null) {
fragmentTransaction.detach(f);
fragmentTransaction.attach(f);
}
fragmentTransaction.replace(android.R.id.content, f);
fragmentTransaction. commitAllowingStateLoss();
which are not compatible with the other Fragment type (import android.support.v4.app.Fragment;). How can i easily add the swipe gesture? Selection on Tabs works perfectly.
EDIT:
With support package 13 the view pager worked but the content isnt refreshed. I use FragmentStatePagerAdapter so the Fragments should be removed and added again but instead it takes the same fragment without new creation. Also Viewpage named teh Fragments like
android:switcher... can i name them on my own?
import android.support.v13.app.FragmentStatePagerAdapter;
public class TabsAdapter extends FragmentStatePagerAdapter
implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private Fragment mFragment;
private Activity mActivity;
private String mTag;
private final List<Fragment> fragments = new ArrayList<Fragment>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
private final String name;
TabInfo(Class<?> _class, Bundle _args,String name) {
clss = _class;
args = _args;
this.name=name;
}
}
public TabsAdapter(Activity activity, ViewPager pager) {
super(activity.getFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
mActivity = activity;
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args,tab.getText()+"");
tab.setTag(info.name);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
// return super.getItemPosition(object);
}
#Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
Fragment fr = Fragment.instantiate(mContext, info.clss.getName(), info.args);
//
// //addFragment (fr, position);
return fr;
}
public void addFragment(Fragment f, int location) {
if (fragments.size() == 0)
fragments.add(f);
else
fragments.add(location, f);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
#Override
public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i=0; i<mTabs.size(); i++) {
if (mTabs.get(i).name == tag) {
updateDataSet(i);
mViewPager.setCurrentItem(i);
}
}
}
#Override
public void onTabReselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabUnselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
// TODO Auto-generated method stub
}
public void updateDataSet(int pos)
{
//Let's update the dataset for the selected genre
Fragment fragment =
(mActivity.getFragmentManager().findFragmentByTag(
"android:switcher:"+ mViewPager.getId()+":"+pos));
//TabFragment fragment = (TabFragment) getItem(pos);
if(fragment != null) // could be null if not instantiated yet
{
if(fragment.getView() != null)
{
// no need to call if fragment's onDestroyView()
//has since been called.
if(fragment instanceof Tab1Fragment){
((Tab1Fragment) fragment).refresh();
}
else if(fragment instanceof Tab2Fragment){
( (Tab2Fragment) fragment).refresh();
}
}
}
}
Try using the build it Tab Activity template, create an example and extract the code you want from there. I created a tabs based app, but I used the default options and customized those to fit my needs.
Check this open source proyect https://github.com/dkim0419/SoundRecorder
they use one activity with a viewPager and some fragments.
Also the use PagerSlidingTabStrip for page indicator.
Take a look it's very easy how they implemented it.