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);
Related
I have implemented ActionBar.TabListener with viewpager. Now I want to disable tab click for some condition
I have stopped swipe using TouchListner but want to do same for Tab Click.
Here is my code.
MainActivity.java
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
ActionBar actionBar;
ViewPager viewPager;
String check ="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager);
FragmentManager fragmentManager = getSupportFragmentManager();
viewPager.setAdapter(new MyAdpter(fragmentManager));
viewPager.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
if ("".equals(check)) {
return true;
}
return false;
}
});
viewPager.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) {
}
});
actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = actionBar.newTab();
tab1.setText("Tab 1");
tab1.setTabListener(this);
ActionBar.Tab tab2 = actionBar.newTab();
tab2.setText("Tab 2");
tab2.setTabListener(this);
ActionBar.Tab tab3 = actionBar.newTab();
tab3.setText("Tab 3");
tab3.setTabListener(this);
actionBar.addTab(tab1);
actionBar.addTab(tab2);
actionBar.addTab(tab3);
viewPager.setCurrentItem(2, false);
}
#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) {
}
}
MyAdpter.java
class MyAdpter extends FragmentPagerAdapter{
public MyAdpter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if(position==0){
fragment = new FragmentA();
}
if(position==1){
fragment = new FragmentB();
}
if(position==2){
fragment = new FragmentC();
}
return fragment;
}
#Override
public int getCount() {
return 3;
}
}
FragmentA.java
public class FragmentA extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_a , container,false);
}
}
FragmentB/FragmentC are similar to FragmentA
activity_main.xml
<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>
ScreenShot
you can do something like this..
in OnCheckedChanged listener for checkbox, you can specify which tabs are enable..
just by doing
// to enable
tabLayout.getChildAt(position).setEnabled(true);
// or to disable
tabLayout.getChildAt(position).setClickable(false);.
use this property to enable or disable clicks on tab.
when i run this code,the toast in two different fragments are displayed on one tab. when i swipe to next tab nothing is displayed.
this is is my main tab activity:
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Offers", "Distance", "Happy Hours","Shop List" };
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
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) {
}
}
this is adapter class :
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 of = new OfferFragment();
bundle.putString("OfferFragment", "OfferFragment");
of.setArguments(bundle);
return of;
case 1:
Fragment df = new DistanceFragment();
bundle.putString("DistanceFragment", "DistanceFragment");
df.setArguments(bundle);
return df;
case 2:
Fragment hf = new HappyHoursFragment();
bundle.putString("HappyHoursFragment", "HappyHoursFragment");
hf.setArguments(bundle);
return hf;
case 3:
Fragment sf = new ShoplistFragment();
bundle.putString("ShoplistFragment", "ShoplistFragment");
sf.setArguments(bundle);
return sf;
}
return null;
}
#Override
public int getCount() {
return 4;
}
}
this is my first fragment :
public class OfferFragment extends Fragment {
private String name;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// public static final String ARG_OBJECT = "object";
View rootView = inflater.inflate(R.layout.offerfragment, container,
false);
Bundle args = getArguments();
TextView txtview = (TextView) rootView.findViewById(R.id.offer);
name = args.getString("OfferFragment");
txtview.setText(args.getString("OfferFragment"));
display();
return rootView;
}
private void display() {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), name, Toast.LENGTH_SHORT).show();
}
}
this is my second fragment :
public class DistanceFragment extends Fragment {
private String name;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.distancefragment, container, false);
Bundle args = getArguments();
TextView txtview = (TextView) rootView.findViewById(R.id.distance);
name = args.getString("DistanceFragment");
txtview.setText(args.getString("DistanceFragment"));
display();
return rootView;
}
private void display() {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), name, Toast.LENGTH_SHORT).show();
}
}
any suggestions are appreciated. am stuck with this.
This is because next fragment is created by pager
before showing toast check if that fragment is visible or not
if(fragmentName.this.isVisible())
{
// do your stuff here
}
Write onResume() in every fragment class.
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//Display Toast message here
}
}
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 would like to create a new fragment every time when I click its tab.
I tried to get the tab and to create a fragment. But it doesn't seem to work.
Here is my code.
Main Activity
public class MainActivity extends FragmentActivity {
private static ViewPager viewPager;
private static TabsPagerAdapter mAdapter;
private static ActionBar actionBar;
// Tab titles
private String[] tabs = { "TopRated", "Hots", "NEW"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
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(tabListener));
}
/**
* 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) {
}
});
}
static ActionBar.TabListener tabListener = new ActionBar.TabListener() {
#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) {
}
};
TabsPagerAdapter
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new TopRatedFragment();
case 1:
return new HotStoryFragment();
case 2:
return new AllClassFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
One of the fragments
public class HotStoryFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d("Refresh_F","(2) HotStory");
View rootView = inflater.inflate(R.layout.fragment_hotstory, container, false);
TextView tvStudy = (TextView)rootView.findViewById(R.id.text);
return rootView;
}
I want to replace a Fragment by a new Fragment when an onClick method is called. I wanted to do it this way:
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.remove(this);
transaction.addToBackStack(null);
transaction.add(new ChooseCocktailFragment(), null);
transaction.commit();
The only thing that happens is the current Fragment is removed and the new one doesn't show. What am I doing wrong here?
Also, I use a ViewPager and this is the first time for me working with fragments. Usually I would have a Container with its ID but here the ViewPager contains the fragments, therefore I don't know how to use the transaction.replace(...) method.
You should use a FragmentPagerAdapter which is adequate to put Fragments inside ViewPagers.
A complete tutorial from android developer here
EDIT:
First of all, you need to override the getItemPosition of the adapter, and return the POSITION_NONE constant in order to be able to replace pager's fragments.
#Override
public int getItemPosition(Object object)
{
return POSITION_NONE;
}
Then create a listner for handling fragment switching:
public interface MyListener
{
public void onFragmentChange();
}
Your adapter should implements the listner and add some code inside onFragmentChange() method:
public class TabsPagerAdapter extends FragmentPagerAdapter {
private FragmentManager fm;
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
this.fm = fm;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
fragment1 = TopRatedFragment.newInstance(this);
return fragment1;
case 1:
// ...
return fragment2;
case 2:
// ...
return fragment3;
case 3:
// ...
return fragment4;
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 4;
}
public void onFragmentChange(){
fm.beginTransaction().remove(fragment1).commit();
fragment1 = NewFragment.newInstance();
notifyDataSetChanged(); // notify the viewpager adapter that content has changed
}
}
Pass an instance of the listner in the fragment you want to remove/replace later :
public class TopRatedFragment extends Fragment {
public static TopRatedFragment newInstance(MyListner listner) {
this.myListner = listner;
return new TopRatedFragment ();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_top_rated, container, false);
return rootView;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// some logical here ... and when you want to change fragment do this
myListner.onFragmentChange();
}
}
Here is some more explanation of this.
You should also read about FragmentStatePagerAdapter : here
Hope it helps !
You forget hide your fragment after another fragment is added up on your fragment.
Just add more a statement transaction.hide(Your_Fragment) before transaction.commit()
#mansoulx
Here is my code which my answer refers to. Since i implemented it using a tutorial it is very similiar, just Tab names and the content of the tabs changed. I also have 4 tabs, not three - but the problem would be the same:
TabsPagerAdapter.java
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new Fragment1();
case 1:
return new Fragment2();
case 2:
return new Fragment3();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
MainActivity.java
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Tab1", "Tab2", "Tab3" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
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));
}
#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) {
}
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) {
}
});
let's say all Fragments would look like this:
Fragment1.java
public class TopRatedFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_top_rated, container, false);
return rootView;
}
}
The thing which should be done now is:
Replace Fragment1 on Tab1 with FragmentNew which should appear in Tab1 too! The OnClick-Event takes place in the fragment1.java for example...