I have a problem with my RecyclerViewAdapter. I want to show my fragments with TabLayout,CardView and ViewPager entegrations. I'm not using Activity, using Fragment. I have a Fragment. And this fragment contains Cardview. And this Cardview contains Tablayout and Viewpager.
How can I use getSupportFragmentManager() in this adapter or how can I edit this adapter? Here is my code:
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends
RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
public ArrayList<String> myValues;
public RecyclerViewAdapter (ArrayList<String> myValues){
this.myValues= myValues;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View listItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_select_area, parent, false);
return new MyViewHolder(listItem);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
}
#Override
public int getItemCount() {
return myValues.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextViewPoppins myTextView;
private TabItem tab_loc,tab_area;
private ViewPager viewPager;
private TabLayout tabLayout;
public MyViewHolder(View itemView)
{
super(itemView);
myTextView = (TextViewPoppins)itemView.findViewById(R.id.select_area);
tabLayout = (TabLayout) itemView.findViewById(R.id.tabs);
tab_loc= (TabItem) itemView.findViewById(R.id.tab_loc);
tab_area= (TabItem) itemView.findViewById(R.id.tab_area);
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.ic_location_green));
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.ic_kort));
viewPager = (ViewPager) itemView.findViewById(R.id.viewpager);
setupViewPager(viewPager);
}
}
private void setupViewPager(ViewPager viewPager)
{
ViewPagerAdapter adapter = new
ViewPagerAdapter(getSupportFragmentManager());
//this line gives the error.
adapter.addFragment(new LocationFragment(), "ONE");
adapter.addFragment(new AreaFragment(), "TWO");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter
{
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager)
{
super(manager);
}
#Override
public Fragment getItem(int position)
{
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title)
{
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
This is what I think you intended to do: ReyclerView -> Fragment -> Activity with TabLayout and ViewPager. This is how you accomplish that: first, the method where you set up your ViewPager and TabLayout ("setupViewPager") should be in an Activity which has the getFragmentManger() or getSupportFragmentManager() if you're using an AppCompatActivity. Your adapter class can be in another file, though.
Secondly, it also appears you're trying to put your TabLayout and ViewPager in your ViewHolder. ViewHolders are used in RecyclerView lists, not for lateral navigation. Take this code out of the class:
tabLayout = (TabLayout) itemView.findViewById(R.id.tabs);
tab_loc= (TabItem) itemView.findViewById(R.id.tab_loc);
tab_area= (TabItem) itemView.findViewById(R.id.tab_area);
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.ic_location_green));
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.ic_kort));
viewPager = (ViewPager) itemView.findViewById(R.id.viewpager);
setupViewPager(viewPager);
Finally, here is how it should look in your MainActivity under onCreate:
// Get the ViewPager and set it's PagerAdapter so that it can display items
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
Here is an additional link reference.
Move the ViewPagerAdapter class in MainActivity.java and setup the ViewPager in the onCreate() method in MainActivity.java.
getSupportFragmentManager() will work only if your class extends Activity.
Have a look at this :
Cannot call getSupportFragmentManager() from activity
Try setupViewPager(viewPager); inside onBindViewHolder, I think that should solve your issue.
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
setupViewPager(holder.viewPager);
}
Related
This question already has answers here:
How to select next tab from child fragment
(3 answers)
Closed 4 years ago.
I have an Activity named RegisterActivity inside it I am impementing ViewPager that contains two fragments. Here is the code of activity
public class RegisterActivity extends AppCompatActivity{
private Context context;
private Toolbar toolbar;
private TabLayout tabLayout;
public static ViewPager viewPager;
private ViewPagerAdapter adapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
context = RegisterActivity.this;
viewPager = findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentOne(), "Step 1");
adapter.addFragment(new FragmentTwo(), "Step 2");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
return fragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
}
}
Fragment one has a NEXT button. When this button is pressed I want the view pager to scroll to FragmentTWo. Again FragmentTwo has a BACK button, I want the view pager to scroll to fragmentOne when BACK button (which is present in the FragmentTwo layout) is pressed.
RegisterActivity.viewpager.setCurrentItem(position of the fragment);
//Do this onClick of the button in the fragment you are in just you need to be specific about the position of fragment in the pager adapter
I have 3 fragments in a activity. One of the fragment displays the list of items along with price and quantity. On selecting any of the item , a new activity will start that will display the details of the item. In this activity we can change the item price , quantity etc.
I want to reload and display the fragment(with updated values) in previous activity just after saving the changes in the item detail activity.
Here is the code for first activity:
public class SupplierHomeActivity extends AppCompatActivity implements
ActionBar.TabListener {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_supplier_home);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
// getSupportFragmentManager().addOnBackStackChangedListener(getListener());
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new Fragment(), "PROFILE");
adapter.addFragment(new InventoryFragment(), "INVENTORY");
adapter.addFragment(new SupplierOrderFragment(), "ORDERS");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
Thank you in advance.
You need to declare your adapter globally and add onResume() method to notify your adapter that data has been changed for the content.
My code dynamically creates fragments in a tabbed view, I would like to access one of the fragments when the OnCreate activity is called.
I know that there are 2 methods of retrieving an existing fragment, one by ID and one by Tag.
How is it possible to mark the fragments when they are created to be retrieved later?
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
if(extras !=null) {
// ***Get Fragment Here***
}
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new TabFragment1(), "ONE");
adapter.addFragment(new TabFragment2(), "TWO");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
The FragmentPagerAdapter already caches the Fragments for you. Each fragment is assigned a tag, and then the FragmentPagerAdapter tries to call
findFragmentByTag
It only calls getItem if the result from findFragmentByTag is null. So you shouldn't have to cache the fragments yourself.
Also, you can get reference of your Fragment in FragmentPagerAdapter using findFragmentByTag() method. The name of the tag is generated this way:
private static String makeFragmentName(int viewId, int index)
{
return "android:switcher:" + viewId + ":" + index;
}
where viewId is the id of ViewPager
AmanSinghal's answer will work, I have an alternative approach. You can create an adapter with a method which returns the currently displayed fragment.
I implemented it here a few years ago: PublicisedFragmentPagerAdapter
Look at the getCurrentPrimaryItem() method
Following the tutorial from here
I have implemented the same in activity It is working perfectly but when I tried adding tabs inside a fragment,swiping tabs is not showing fragment's view.
public class DetailFragment extends android.support.v4.app.Fragment implements LoaderManager.LoaderCallbacks<Cursor>,View.OnClickListener {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_detail_start, container, false);
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getActivity().getSupportFragmentManager());
adapter.addFragment(new OneFragment(), "ONE");
adapter.addFragment(new TwoFragment(), "TWO");
adapter.addFragment(new ThreeFragment(), "THREE");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
} // Update - code formatting
Please suggest.
To implement the View pager within a fragment use getChildFragmentManager() instead of getFragmentManager().
So while Initializing the ViewPagerAdapter for ViewPager use "getChildFragmentManager()".
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
I have one activity named rootActivity , in which i have a rootContainer in which i replace the fragments.
Now, the first fragment that i replace is DashboardFragment.
I now click on the cross to open a new fragment like this...
Now when i press the back button the content of dashboard fragment is lost.
Can someone help me
Here's a video to show what's really happening.
https://youtu.be/NobqYUCEZKY
Code for the DashboardFragment(contains the fragments inside tabs)
public class DashboardFragment extends Fragment {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
private View rootView;
/**
*
* #param config : For setting up stuff by the given config
* #return
*/
public static DashboardFragment newInstance(Bundle config) {
DashboardFragment fragment = new DashboardFragment();
fragment.setArguments(config);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.activity_dashboard, container, false);
toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
((RootActivity)getActivity()).setSupportActionBar(toolbar);
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
return rootView;
}
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(android.R.drawable.btn_star_big_off);
tabLayout.getTabAt(1).setIcon(android.R.drawable.btn_star_big_on);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getActivity().getSupportFragmentManager());
adapter.addFragment(new TrackeesFragment(), "Trackee");
adapter.addFragment(new TrackersFragment(), "Trackers");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
return super.instantiateItem(container, position);
}
#Override
public CharSequence getPageTitle(int position) {
return null;
}
}
}
try by changing the following line in
setupViewPager(ViewPager viewPager) {}
Change
ViewPagerAdapter adapter = new ViewPagerAdapter(getActivity().getSupportFragmentManager());
To
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());