I implemente mTabs.addOnTabSelectedListener and i check editext on onTabSelected. I would like to stay on Tab1 if the fields are not OK.
I use Viewpager which use fragments.
How do you do that?
Principal Activity:
public class HomeActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_home_activity);
TabLayout tabs = findViewById(R.id.tabs);
ViewPager viewPager = findViewById(R.id.view_pager);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(HomeActivity.this, getSupportFragmentManager(), tabs, viewPager);
viewPager.setAdapter(sectionsPagerAdapter);
tabs.setupWithViewPager(viewPager);
}
}
FragmentAdapter:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
#StringRes
private static final int[] TAB_TITLES = new int[] {
"TAB1",
"TAB2"
};
private final Context mContext;
private TabLayout mTabs;
private ViewPager mViewPager;
public SectionsPagerAdapter(Context context, FragmentManager fm, TabLayout tabs, ViewPager viewPager) {
super(fm);
mContext = context;
mTabs = tabs;
mViewPager = viewPager;
}
#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, mContext, mTabs, mViewPager);
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return mContext.getResources().getString(TAB_TITLES[position]);
}
#Override
public int getCount() {
// Show 2 total pages.
return 2;
}
}
Thank you.
Fragment class:
public class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
private static int indexTab;
private static Context mContext;
private static TabLayout mTabs;
private static ViewPager mViewPager;
private PageViewModel pageViewModel;
public static PlaceholderFragment newInstance(int index, Context context, TabLayout tabs, ViewPager viewPager) {
mContext=context;
mTabs=tabs;
mViewPager=viewPager;
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle bundle = new Bundle();
Log.v("index","index:"+index);
bundle.putInt(ARG_SECTION_NUMBER, index);
fragment.setArguments(bundle);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("onCreate","onCreate");
pageViewModel = ViewModelProviders.of(this).get(PageViewModel.class);
int index = 1;
if (getArguments() != null) {
index = getArguments().getInt(ARG_SECTION_NUMBER);
indexTab=index;
}
pageViewModel.setIndex(index);
}
#Override
public View onCreateView(
#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.v("onCreateView","onCreateView "+indexTab);
View root;
if(indexTab==2){
indexTab=1; //FORCE
root = inflater.inflate(R.layout.fragment_one, container, false);
mTabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}else{
root = inflater.inflate(R.layout.fragment_two, container, false);
}
return root;
}
}
Related
I have one activity HomeActivity and I have HomePageFragment which have some categories with icon and title of data, when I click on any category I'm sending the clicked item Title name with bundle and opening MultipleFragment and I'm getting clicked title name from the previous fragment, on this multiple fragments I have viewpager inside it..
1) PostFragment,
2) TextFragment
now here's my main question that I want to send clicked item title name to PostFragment and TextFragment,
HomeFragment
public void onItemClick(int position) {
MultiplePost multiplePost = new MultiplePost();
Bundle args = new Bundle();
Categories categoriesClicked = categoriesList.get(position);
args.putString(Title, categoriesClicked.getTitle());
args.putString(ImageUrl, categoriesClicked.getIcon());
multiplePost.setArguments(args);
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.main_frame,multiplePost)
.addToBackStack(null)
.commit();
}
MultiplePost
public class MultiplePost extends Fragment {
private TabLayout tabLayout;
private ViewPager viewPager;
private ViewPageAdapter viewPageAdapter;
private View view;
private FragmentManager mFragmentManager;
public static String title ;
public MultiplePost() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_multiple_post, container, false);
title = getArguments().getString("title");
tabLayout = view.findViewById(R.id.tablayout_id);
viewPager = view.findViewById(R.id.viewPager_id);
viewPageAdapter = new ViewPageAdapter(getChildFragmentManager());
viewPageAdapter.AddFragment(new PostFragment(), "");
viewPageAdapter.AddFragment(new TextFragment(), "");
viewPager.setAdapter(viewPageAdapter);
tabLayout.setupWithViewPager(viewPager);
tabLayout.getTabAt(0).setIcon(R.drawable.photo);
tabLayout.getTabAt(1).setIcon(R.drawable.file);
PostFragment post = new PostFragment();
Bundle args = new Bundle();
args.putString("title", title);
post.setArguments(args);
getActivity().getSupportFragmentManager().beginTransaction();
.replace(R.id.main_frame, post)
.commit();// and this's changing whole fragment with PostFragment and
//so i can't see my viewpager on MultiplePost
return view;
}
}
ViewPagerAdapter
public class ViewPageAdapter extends FragmentPagerAdapter {
private final List<Fragment> listFragment = new ArrayList<>();
private final List<String> listTitle = new ArrayList<>();
public ViewPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return listFragment.get(position);
}
#Override
public int getCount() {
return listTitle.size();
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return listTitle.get(position);
}
public void AddFragment(Fragment fragment, String title){
listFragment.add(fragment);
listTitle.add(title);
}
}
How to send title onto PostFragment and TextFragment into viewpager
I am a java-illiterate, and still trying to develop a app for my personal use.
I have started with android-studio's "Tabbed-Activity", and mostly unaltered except a fragment and a bundle in MainActivity.
Here are my codes:
MainActivity
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//FloatingActionButton fab = findViewById(R.id.fab);
Bundle bundle = new Bundle();
bundle.putDouble("loclat", 25.4358);
bundle.putDouble("loclang",81.8463);
Fragment SunFragment = new SunFragment();
SunFragment.setArguments(bundle);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
}
SectionsPagerAdapter
public class SectionsPagerAdapter extends FragmentPagerAdapter {
#StringRes
private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2, R.string.tab_text_3};
private final Context mContext;
public SectionsPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
#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);
switch (position) {
case 0:
return new SunFragment();
//return PlaceholderFragment.newInstance(pos + 5);
case 1:
return PlaceholderFragment.newInstance(1);
//return SecondFragment.newInstance();
//return PlaceholderFragment.newInstance(pos + 1);
default:
return PlaceholderFragment.newInstance(2);
}
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return mContext.getResources().getString(TAB_TITLES[position]);
}
#Override
public int getCount() {
// Show 2 total pages.
return 3;
}
}
And finally, The SunFragment, where I want my bundled data from MainActivity:
public class SunFragment extends Fragment {
List<SunSession> sunsList;
Typeface sunfont;
Double Dlat;
Double Dlang;
//to be called by the MainActivity
public SunFragment() {
// Required empty public constructor
}
private static final String KEY_LOCATION_NAME = "location_name";
public String TAG ="SunFragment";
public String location;//="No location name found";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retrieve location and camera position from saved instance state.
if (savedInstanceState != null) {
location = savedInstanceState.getCharSequence(KEY_LOCATION_NAME).toString();
System.out.println("OnCreate location "+location);
// Dlat = getArguments().getDouble("loclat");
//Dlang = getArguments().getDouble("loclang");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_sun, container, false);
//onSaveInstanceState(new Bundle());
if (getArguments() != null) {
Dlat = getArguments().getDouble("loclat");
Dlang = getArguments().getDouble("loclang");
} else {
Dlat=23.1;
Dlang=79.9864;
}
Log.e("Lat", Double.toString(Dlat));
I have followed this blog to make it, but no value is passed. Kindly help.
NB. This is a better described, and detailed question of my earlier question, which I understand, needs more code to be shown.
In your MainActivity, your sunFragment is unused. Remove this part:
/*Bundle bundle = new Bundle();
bundle.putDouble("loclat", 25.4358);
bundle.putDouble("loclang",81.8463);
Fragment SunFragment = new SunFragment();
SunFragment.setArguments(bundle);*/
You have to set bundle to fragment inside your SectionsPagerAdapter
case 0:
Bundle bundle = new Bundle();
bundle.putDouble("loclat", 25.4358);
bundle.putDouble("loclang",81.8463);
Fragment sunFragment = new SunFragment();
sunFragment.setArguments(bundle);
return sunFragment;
But if you need to set the bundle to fragment from MainActivity. Then use a callback in that purpose.
This way you can pass data from your mainActivity to fragment
MainActivity onCreate method
adapter = new Adapter(getChildFragmentManager());
SquadsTeamListFragment teamA =
SquadsTeamListFragment.newInstance(teamAData,teamBData
adapter.addFragment(teamA, teamAName);
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
use this adapter in your main activity
static class Adapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
Adapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position){
return mFragmentTitleList.get(position);
}
}
receive data to fragment (SquadsTeamListFragment .java)
public static SquadsTeamListFragment newInstance(String playerList, String
oppPlayerList) {
SquadsTeamListFragment fragment = new SquadsTeamListFragment();
Bundle args = new Bundle();
args.putString(ARG_TEAM_DATA, playerList);
args.putString(ARG_OPP_TEAM_DATA, oppPlayerList);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
playerList = getArguments().getString(ARG_TEAM_DATA);
oppPlayerList = getArguments().getString(ARG_OPP_TEAM_DATA);
}
}
I have got classic Bottom Navigation created by default with 3 TABs (FragmentOne, FragmentTwo and FragmentThree).
The first fragment (FragmentOne) has ViewPager with two static inner Fragments (FragmentInner1 and FragmentInner2).
When app starts evrything is fine so at the FragmentOne we can see FragmentInner1 and can navigate to FragmentInner2.
But after navigating from FragmentTwo to FragmentOne the FragmentInner1 is not visible. That is a problem.
I guess we should recreate it somehow?
I investigated manual from here https://developer.android.com/guide/components/fragments.html and https://developer.android.com/training/implementing-navigation/lateral.html#PagerTitleStrip but it does not help and my code looks the same way.
Please help. Thank you!
FragmentOne
public class FragmentOne extends Fragment {
//This is our viewPager
private ViewPager viewPager;
//Fragments
FragmentInner1 fragmentInner1;
FragmentInner2 fragmentInner2;
ViewPagerAdapter adapter;
private View view;
public FragmentOne() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_fragment_one, container, false);
//Initializing viewPager
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
setupViewPager(viewPager);
return view;
}
private void setupViewPager(ViewPager viewPager) {
adapter = new ViewPagerAdapter(getActivity().getSupportFragmentManager());
fragmentInner1=new FragmentInner1();
fragmentInner2=new FragmentInner2();
adapter.addFragment(fragmentInner1);
adapter.addFragment(fragmentInner2);
viewPager.setAdapter(adapter);
}
#Override
public void onAttach(Context context)
{
super.onAttach(context);
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
ViewPagerAdapter
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = mFragmentList.get(position);
return fragment;
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment) {
mFragmentList.add(fragment);
}
}
FragmentInner1
public class FragmentInner1 extends Fragment {
public static FragmentInner1 newInstance( ) {
FragmentInner1 fragment = new FragmentInner1();
return fragment;
}
public FragmentInner1() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_fragment_inner1, container, false);
}
}
You have to Use getChildFragmentManager() For Viewpager to adapt Popback Feature.
adapter = new ViewPagerAdapter(getChildFragmentManager());
This is Because the Viewpager have multiple Fragments where Viewpager itself or is holded by another Fragment. So the Child Fragment is to Be Invoked and Used.
You Can Refer this Documentation on ChildFragmentManager()
I have a ViewPager with fragments in my activity, each page has a textview, I want to change the text of the textview from the onCreate method in the activity that contains the viewpager. How should I go about doing that?
below is the code that would return a null object exception:
Fragment:
public class MyFragment extends Fragment {
private TextView textView;
public static MyFragment getInstance(){
return new MyFragment();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_layout, container, false);
textView = (TextView) rootView.findViewById(R.id.textView);
return rootView;
}
public void setText(String text){
textView.setText(text);
}
}
Adapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return MyFragment.getInstance();
}
#Override
public int getCount() {
return 3;
}
}
Activity onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
final ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
MyFragment fragment = (MyFragment) adapter.getItem(0);
fragment.setText("Altered"); // and this returns null pointer exception
}
Thank you!
Most FragmentPagerAdapters will have an addFragment method and will keep track various fragments that are added to it via an internal object:
public class MyPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
As it stands, your implementation of getItem returns a new instance of MyFragment every time it is called. As such, MyFragment fragment = (MyFragment) adapter.getItem(0); is a new instance that will never be loaded into the ViewPager, will never be inflated, and hence has a null textView reference.
The other issue is that within the onCreate of your activity, the fragments have not yet been inflated, so the textView will be null unless you delay the call:
final MyFragment fragment = (MyFragment) mPagerAdapter.getItem(0);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
fragment.setText("Altered");
}
}, 100);
But really, why not just set it to the correct value when it is initialized?
Try This
Fragment:
public class MyFragment extends Fragment {
private TextView textView;
private String Text;
public MyFragment (String Text){
this.Text=Text;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_layout, container, false);
textView = (TextView) rootView.findViewById(R.id.textView);
textView.setText(Text);
return rootView;
}
}
Adapter :
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return new MyFragment("Altered");
}
#Override
public int getCount() {
return 3;
}
}
Activity onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
final ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
}
I am new to android. I have a sliding tab layout and a viewpager with a fragment. I have setup a basic link between these to switch tabs for a count of 5(i.e 5 tabs) The problem is that, in each of these tabs, I want to populate a listview using simplecursoradapter, for which I need the position of each fragment so that I could populate it accordingly. I have got the position in the fragment adapter class, but I am unable to pass it to the main activity. Also, How can I access DBadapter inside my fragment class to populate listview from the database? or is there some other way to do this? Below is my code. Any help is greatly appreciated. Thanks in advance.
public class myFragment extends Fragment{
private ListView mainList;
public static myFragment getInstance(int position){
myFragment MyFragment = new myFragment();
Bundle args = new Bundle();
args.putInt("position", position);
MyFragment.setArguments(args);
return MyFragment;
}
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_main_list,container, false);
mainList = (ListView)layout.findViewById(R.id.mainListView);
Bundle bundle = getArguments();
if(bundle!=null){
if(bundle.getInt("position")==0){
mainList.setBackgroundColor(getResources().getColor(R.color.primary500));
}
else if(bundle.getInt("position")==1){
mainList.setBackgroundColor(getResources().getColor(R.color.primary100));
}
else if(bundle.getInt("position")==2){
mainList.setBackgroundColor(getResources().getColor(R.color.primary700));
}
else if(bundle.getInt("position")==3){
mainList.setBackgroundColor(getResources().getColor(R.color.accent));
}
else if(bundle.getInt("position")==4){
mainList.setBackgroundColor(getResources().getColor(R.color.black));
}
}
return layout;
}
}
The Main Activity is as follows:
public class MainActivity extends ActionBarActivity {
private Toolbar toolbar;
private ViewPager mPage;
private SlidingTabLayout mTabs;
DBadapter myDb;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
openDB();
toolbar = (Toolbar)findViewById(R.id.app_bar);
mPage = (ViewPager)findViewById(R.id.pager);
mTabs = (SlidingTabLayout)findViewById(R.id.tabs);
mFab = (FloatingActionButton)findViewById(R.id.fab);
setSupportActionBar(toolbar);
mPage.setAdapter(new myPagerAdapter(getSupportFragmentManager()));
mTabs.setViewPager(mPage);
}
public class myPagerAdapter extends FragmentPagerAdapter{
String[] tabs;
public myPagerAdapter(FragmentManager fm) {
super(fm);
tabs = getResources().getStringArray(R.array.tabs);
}
#Override
public Fragment getItem(int position) {
myFragment MyFragment = myFragment.getInstance(position);
return MyFragment;
}
#Override
public CharSequence getPageTitle(int position) {
return tabs[position];
}
#Override
public int getCount() {
return 5;
}
}
Use this method :
mPage.setOnPageChangeListener(new SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int pos) {
// pos is the position of fragment that app showing
});
UPDATE
in your view pager adapter :
public Fragment getItem(int position) {
return new myFragment(position);
}
And in your fragment class :
public class myFragment extends Fragment{
private int pos
public void myFragment(int position){
this.pos = position;
}
// other code of your class