I have created 10 tabs programmatically and want to change number of buttons that are placed in fragment when a tab is clicked by user.
My 'MainActivity' code:
public class MainActivity extends Activity {
int numberOfButtons=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentA fragmentA = new FragmentA();
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.mainLayout,fragmentA,"fragA");
transaction.commit();
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (int i=0;i<10;i++)
{
ActionBar.Tab tab = actionBar.newTab().setText("Tab"+i).setTabListener(new ActionBar.TabListener() {
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
numberOfButtons = 10;
sendNumber(numberOfButtons);
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
});
actionBar.addTab(tab);
}
}
This is my fragment code:
public class FragmentA extends Fragment implements View.OnClickListener{
Button btn;
View myView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
int numberOfButtons= getArguments().getInt("someInt",0);
LinearLayout view = new LinearLayout(getActivity());
// Inflate the layout for this fragment
view.setOrientation(LinearLayout.VERTICAL);
view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
for (int i = 0;i<numberOfButtons;i++)
{
btn = new Button(getActivity());
view.addView(new Button(getActivity()));
}
myView = view;
return myView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onClick(View v) {
}
}
I am calling the numbeOfButtons method inside the MainActivity and want to send number of buttons to Fragment when a tab is clicked. However the application throws error after line fA.numberOfBtns(numberOfButtons); is called. The error is reflect.InvocationTargetException.
How can I change the number of buttons in Fragment when a tab is clicked?
You may want to use newInstance technique to pass parameters during Fragment initialization. Here is a small example taken from here:
public static MyFragment newInstance(int someInt) {
MyFragment myFragment = new MyFragment();
Bundle args = new Bundle();
args.putInt("someInt", someInt);
myFragment.setArguments(args);
return myFragment;
}
And later you can access this parameter:
getArguments().getInt("someInt", 0);
Related
I have an ActionBar that contains 11 tabs and 1 fragment. I also have a ViewPager to display the fragment(s). When a tab is clicked it creates the same fragment. The tabs display dates so they change everyday. What I need is to send the text of the tab (ie. .getTabText()) to the fragment, this will change the content of the fragment. I am having so much trouble trying to figure out how to do this. Here is all my code:
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
private ArrayList<TopRatedFragment> myFragmentList = new ArrayList<TopRatedFragment>();
// Tab titles
String[] tabs = {this.getCurrentDate(-5).toString(),this.getCurrentDate(-4).toString(),this.getCurrentDate(-3).toString(), this.getCurrentDate(-2).toString(),this.getCurrentDate(-1).toString(),
this.getCurrentDate(0).toString(),
this.getCurrentDate(1).toString(), this.getCurrentDate(2).toString(), this.getCurrentDate(3).toString(), this.getCurrentDate(4).toString(), this.getCurrentDate(5).toString(),};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (String tab_name : tabs) {
TopRatedFragment fm = new TopRatedFragment();
fm.getTabs(tab_name);
myFragmentList.add(fm);
}
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager(), myFragmentList);
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));
}
actionBar.setSelectedNavigationItem(5);
/**
* 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) {
}
});
}
public String getTab(Tab tab) {
return tab.getText().toString();
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
public String getCurrentDate(int offset) {
String calAsString;
DateFormat formatter = new SimpleDateFormat("MM/dd");
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, offset);
calAsString = formatter.format(cal.getTime());
return calAsString;
}
}
Here is my FragmentPagerAdapter:
public class TabsPagerAdapter extends FragmentPagerAdapter {
ArrayList<TopRatedFragment> myList;
public TabsPagerAdapter(FragmentManager fm, ArrayList<TopRatedFragment> myList) {
super(fm);
this.myList = myList;
}
#Override
public Fragment getItem(int index) {
return myList.get(index);
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return myList.size();
}
And here is my simple fragment (for now):
public class TopRatedFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void getTabs(String tabs) {
Log.e("TRF", tabs);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_top_rated, container, false);
return rootView;
}
}
Create a static newInstance method to create fragment and bundle the args for the fragment. Pull the args in the fragment.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (String tab_name : tabs) {
TopRatedFragment fm = new TopRatedFragment.newInstance(tab_name);
fm.getTabs(tab_name);
myFragmentList.add(fm);
}
public class TopRatedFragment extends Fragment {
public static Fragment newInstance(String position) {
TopRatedFragment f = new TopRatedFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putString("num", position);
f.setArguments(args);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle b = getArguments();
if (b!=null){
String someText = b.containsKey("num")?b.getString("num"):null;
}
I'll explain the structure of my app :
Activity --> Fragment A (Inside that fragment (A) i have 3 Fragments (B, C, D) (viewpager)) --> Inside the first fragment(B) it contains a listview. Every item from that list launches a fragment E.
So i'm facing an issue here.
When i first launch my application Everything looks fine.
But when Fragment E get's visible to the screen the tabs gets all weird and be like :
Yeap! they got duplicated.
When i click on the listview, i commit the transition between the 2 fragments from a callback in the Activity :
transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.content_frame, PF);
transaction.addToBackStack(null);
transaction.commit();
When i want to go back to the previous fragment:
getFragmentManager().popBackStack();
Is the previous fragment getting recreated? And what can i do to solve it?
UPDATE --CODES:
Activity :
public class MainActivity extends FragmentActivity implements
IslamToolsFragment.OnToolsSelectedListener {
FragmentTransaction transaction;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.content_frame) != null) {
if (savedInstanceState != null) {
return;
}
PagerActivity firstFragment = new PagerActivity();
getSupportFragmentManager().beginTransaction()
.add(R.id.content_frame, firstFragment).commit();
}
}
#Override
public void OnToolSelected(int position) {
// TODO Auto-generated method stub
switch (position) {
case 0:
PrayerFragment PF = new PrayerFragment();
transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.content_frame, PF);
transaction.addToBackStack(null);
transaction.commit();
break;
case 1:
QiblaFragment QF = new QiblaFragment();
transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.content_frame, QF);
transaction.addToBackStack(null);
transaction.commit();
break;
}
}
Fragment A (Which contains 3 fragments):
public class PagerActivity extends Fragment implements ActionBar.TabListener {
int NUM_PAGES = 5;
ActionBar actionBar;
private ViewPager mPager;
AppSectionsPagerAdapter mAppSectionsPagerAdapter;
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mPager.setAdapter(null);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
return;
} else {
actionBar = this.getActivity().getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(
getChildFragmentManager());
mPager.setAdapter(mAppSectionsPagerAdapter);
int icons[] = { R.drawable.ic_action_storage,
R.drawable.ic_action_overflow, R.drawable.ic_action_person };
mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab().setIcon(icons[i])
.setTabListener(this));
}
}
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View tabsview = inflater.inflate(R.layout.pager_activity, container,
false);
mPager = (ViewPager) tabsview.findViewById(R.id.pager);
return tabsview;
}
Fragnent B:
public class IslamToolsFragment extends Fragment {
OnToolsSelectedListener mCallback;
ListView islamtools;
Fragment PF = new PrayerFragment();
public interface OnToolsSelectedListener {
public void OnToolSelected(int position);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View islamtoolsview = inflater.inflate(R.layout.lvislamtools,
container, false);
if (savedInstanceState != null) {
return islamtoolsview;
}
islamtools = (ListView) islamtoolsview.findViewById(R.id.lvislamtools);
String[] title = { "Prayer Times", "Qibla", "Ahadith", "Quran",
"Hijri Calendar", "99 Names" };
IslamToolsAdapter ITA = new IslamToolsAdapter(this.getActivity(), title);
islamtools.setAdapter(ITA);
islamtools.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
mCallback.OnToolSelected(arg2);
}
});
return islamtoolsview;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (OnToolsSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
Thanks! is it something related to the savedinstancestate?
Your code design is a little bit wrong, fragments are actually pieces of activities, it does not make sense to me to create a fragment with more fragments inside in this situations, what you should do is create an activity for the viewpager and put into that activity your 3 fragments.
I have a similar app and this is how i handle the navigation between tabs:
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
The above code changes the item selected of the action bar BUT does not change the view below the view pager tabs, you need to implement the following to do this:
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
pager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
I have a main activity consisting of three tabs with each its corresponding fragment. In each of the fragment, there is one textview. Also, I am using ViewPager to help me navigate through the tabs.
When I try to access a TextView from within a fragment, I get a NULL POINTER error. Here is my code:
Fragment 1 (tab1):
public class FragmentA extends Fragment{
TextView tv1;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View parentView = inflater.inflate(R.layout.fragment_a, container, false);
//******* Error Here **********
tv1 = (TextView) getView().findViewById(R.id.fragAtv1);
return parentView;
}
}
Main Activity:
public class SwipeTabs extends FragmentActivity implements TabListener{
ViewPager viewPager;
ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.main_swipe);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(new MySwipeAdapter(getSupportFragmentManager()));
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int tab_pos) {
actionBar.setSelectedNavigationItem(tab_pos);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
// Initialize action bar with tabs
actionBar = setupActionBar();
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction arg1) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction arg1) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction arg1) {
}
private ActionBar setupActionBar(){
ActionBar newAB = getActionBar();
newAB.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = newAB.newTab();
tab1.setText("Tab 1");
tab1.setTabListener(this);
newAB.addTab(tab1);
ActionBar.Tab tab2 = newAB.newTab();
tab2.setText("Tab 2");
tab2.setTabListener(this);
newAB.addTab(tab2);
ActionBar.Tab tab3 = newAB.newTab();
tab3.setText("Tab 3");
tab3.setTabListener(this);
newAB.addTab(tab3);
return newAB;
}
}
class MySwipeAdapter extends FragmentStatePagerAdapter{
//Construstor: retuns the
public MySwipeAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch(position){
case 0:
fragment = new FragmentA();
break;
case 1:
fragment = new FragmentB();
break;
case 2:
fragment = new FragmentC();
break;
}
return fragment;
}
#Override
public int getCount() {
return 3;
}
}
You can't access getView() and get a non-null value before onCreateView() returns. That doesn't make sense logically. Instead, do this:
tv1 = (TextView) parentView.findViewById(R.id.fragAtv1);
You could also override onViewCreated() but this is simpler.
Instead of using getView.findviewbyId try parentView.findViewById.
tv1 = (TextView) parentView.findViewById(R.id.fragAtv1);
I'm trying to update the text of my TextView in my FragmentB through the Button in my FragmentA. But whenever I click the Button, nothing happens in my TextView. What could be the problem? Here's my code:
Communicator.java:
public interface Communicator {
public void respond(String data);
}
MainActivity.java:
public class MainActivity extends FragmentActivity implements Communicator{
ViewPager viewPager = null;
FragmentManager fragmentManager = getSupportFragmentManager();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(new MyAdapter(fragmentManager));
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FragmentB fragB = new FragmentB();
fragmentTransaction.add(R.id.pager, fragB, "frag_tag");
fragmentTransaction.commit();
}
public class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter (FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = null;
if (i == 0)
{
fragment = new FragmentA();
}
if (i == 1)
{
fragment = new FragmentB();
}
if (i == 2)
{
fragment = new FragmentC();
}
if (i == 3)
{
fragment = new FragmentD();
}
if (i == 4)
{
fragment = new FragmentE();
}
if (i == 5)
{
fragment = new FragmentF();
}
return fragment;
}
#Override
public int getCount() {
return 6;
}
}
#Override
public void respond(String data) {
// TODO Auto-generated method stub
FragmentB f2 = (FragmentB) fragmentManager.findFragmentByTag("frag_tag");
f2.changeText(data);
}
}
FragmentA:
public class FragmentA extends Fragment implements OnClickListener {
int counter = 0;
Button button1;
Communicator comm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragmenta, container, false);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
comm = (Communicator) getActivity();
button1 = (Button) getActivity().findViewById(R.id.button1);
button1.setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
counter++;
comm.respond("The button was clicked" + counter + "times");
}
}
FragmentB:
public class FragmentB extends Fragment {
TextView text1;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragmentb, container, false);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
text1 = (TextView) getActivity().findViewById(R.id.textView1);
}
public void changeText(String data) {
// TODO Auto-generated method stub
text1.setText(data);
}
}
The host activity can deliver messages to a fragment by capturing the Fragment instance with findFragmentById(), then directly call the fragment's public methods.
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
if (articleFrag != null) {
// If article frag is available, we're in two-pane layout...
// Call a method in the ArticleFragment to update its content
articleFrag.updateArticleView(position);
} else {
// Otherwise, we're in the one-pane layout and must swap frags...
// Create fragment and give it an argument for the selected article
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
}
For more detail please follow this link http://developer.android.com/training/basics/fragments/communicating.html#Deliver
iam a beginner in android
i wanted to make tabs
i took the sample and edited it to make a layout for every tab
but i couldn't find where to put the listeners of buttons of each layout of each tab in the code !
public class Game extends FragmentActivity implements ActionBar.TabListener {
static int Tab_no ;
private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// For each of the sections in the app, add a tab to the action bar.
actionBar.addTab(actionBar.newTab().setTag("round").setText("Round").setTabListener(this));
actionBar.addTab(actionBar.newTab().setTag("score").setText("Score").setTabListener(this));
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) { // 3ashan law rege3na men ay makan yrg3ny le mkany
if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
getActionBar().setSelectedNavigationItem(
savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
}
}
#Override
public void onSaveInstanceState(Bundle outState) { // 3ashan law killed yrg3ny tany le makany
outState.putInt(STATE_SELECTED_NAVIGATION_ITEM,
getActionBar().getSelectedNavigationIndex());
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, show the tab contents in the container
Fragment fragment = new SectionFragment();
Tab_no = tab.getPosition() + 1 ;
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.commit();
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A dummy fragment representing a section of the app, but that simply displays dummy text.
*/
public static class SectionFragment extends Fragment {
public SectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (Tab_no==1)
{
return inflater.inflate(R.layout.round , container, false);
}
else {
return inflater.inflate(R.layout.score , container, false);
}
}
}
}
and sorry for my bad english ! :)
You can write within onCreateView()
public class fragmentname extends Fragment{
Activity referenceActivity;
View parentHolder;
Button backBtn;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
referenceActivity = getActivity();
parentHolder = inflater.inflate(R.layout.yourlayout, container,
false);
backBtn = (Button) parentHolder.findViewById(R.id.back_btn);
backBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
}
});
return parentHolder;
}
}