I have a problem pass or intent data from (activity) to (Fragment) containing 3 (TabLayout ).
How can I transfer data to a specific (TabLayout) of the third that I own.
by RecyclerView onItemClick.
This is code of RecyclerView onItemClick.I was send it From first activity to secand activity like this As follows..
Pass data first activity
public static final String EXTRA_FROM = "FROMPL";
#Override
public void onItemClick(int position) {
Intent detailIntent = new Intent(this,
com.example.myapplication.Fragmant.StatusFragment.class);
ExampleItem clickedItem = mExampleList.get(position);
detailIntent.putExtra(EXTRA_FROM, clickedItem.getCreator());
startActivity(detailIntent);
}
secand activity get data
Intent i = getIntent();
final String FROMPL = i.getStringExtra("FROMPL");
textfrom.setText(FROMPL);
But now like that not work.I don’t know how I can pass it to a specific (TabLayout)to work as Fragment in (MainActivityFargmain).
I want each (TabLayout) in (MainActivityFargmain) has specific data.
So Anyone have a solution for that؟
all my code
public class MainActivityFargmain extends AppCompatActivity {
Toolbar toolbar;
TabLayout tabLayout;
ViewPager viewPager;
PageAdapter pageAdapter;
TabItem tabChats;
TabItem tabStatus;
TabItem tabCalls;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_m);
toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(getResources().getString(R.string.app_name));
setSupportActionBar(toolbar);
tabLayout = findViewById(R.id.tablayout);
tabChats = findViewById(R.id.tabChats);
tabStatus = findViewById(R.id.tabStatus);
tabCalls = findViewById(R.id.tabCalls);
viewPager = findViewById(R.id.viewPager);
pageAdapter = new PageAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pageAdapter);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
if (tab.getPosition() == 1) {
toolbar.setBackgroundColor(ContextCompat.getColor(MainActivityFargmain.this,
R.color.colorAccent));
tabLayout.setBackgroundColor(ContextCompat.getColor(MainActivityFargmain.this,
R.color.colorAccent));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(ContextCompat.getColor(MainActivityFargmain.this,
R.color.colorAccent));
}
} else if (tab.getPosition() == 2) {
toolbar.setBackgroundColor(ContextCompat.getColor(MainActivityFargmain.this,
android.R.color.darker_gray));
tabLayout.setBackgroundColor(ContextCompat.getColor(MainActivityFargmain.this,
android.R.color.darker_gray));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(ContextCompat.getColor(MainActivityFargmain.this,
android.R.color.darker_gray));
}
} else {
toolbar.setBackgroundColor(ContextCompat.getColor(MainActivityFargmain.this,
R.color.colorPrimary));
tabLayout.setBackgroundColor(ContextCompat.getColor(MainActivityFargmain.this,
R.color.colorPrimary));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(ContextCompat.getColor(MainActivityFargmain.this,
R.color.colorPrimaryDark));
}
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
}
}
public class PageAdapter extends FragmentPagerAdapter {
private int numOfTabs;
PageAdapter(FragmentManager fm, int numOfTabs) {
super(fm);
this.numOfTabs = numOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new ChatFragment();
case 1:
return new StatusFragment();
case 2:
return new CallFragment();
default:
return null;
}
}
#Override
public int getCount() {
return numOfTabs;
}
}
public class StatusFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
return inflater.inflate(R.layout.fragment_status, container, false);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_status, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_status) {
Toast.makeText(getActivity(), "Clicked on " + item.getTitle(), Toast.LENGTH_SHORT)
.show();
}
return true;
}
}
public class ChatFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
setHasOptionsMenu(true);
return inflater.inflate(R.layout.fragment_chat, container, false);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_chats, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_chat) {
Toast.makeText(getActivity(), "Clicked on " + item.getTitle(), Toast.LENGTH_SHORT)
.show();
}
return true;
}
}
You are passing the data to fragment from first activity and you are fetching data from second activity.
But in a proper scenario you should pass the data to second activity. Then after you can fetch it.
public static final String EXTRA_FROM = "FROMPL";
#Override
public void onItemClick(int position) {
Intent detailIntent = new Intent(this,
MainActivityFargmain.class);
ExampleItem clickedItem = mExampleList.get(position);
detailIntent.putExtra(EXTRA_FROM, clickedItem.getCreator());
startActivity(detailIntent);
}
Fetch the data in MainActivityFragmain using below code.
Intent i = getIntent();
final String FROMPL = i.getStringExtra("FROMPL");
pageAdapter = new PageAdapter(getSupportFragmentManager(), tabLayout.getTabCount(),FROMPL);
viewPager.setAdapter(pageAdapter);
Update your Pager adapter class like below.
public class PageAdapter extends FragmentPagerAdapter {
private int numOfTabs;
private String FROMPL;
PageAdapter(FragmentManager fm, int numOfTabs, String FROMPL) {
super(fm);
this.numOfTabs = numOfTabs;
this.FROMPL = FROMPL;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new ChatFragment();
case 1:
StatusFragment statusFragment = new StatusFragment();
Bundle bundle=new Bundle();
bundle.putString("FROMPL", FROMPL);
statusFragment.setArguments(bundle);
return statusFragment;
case 2:
return new CallFragment();
default:
return null;
}
}
#Override
public int getCount() {
return numOfTabs;
}
}
Related
I am a new application developer trying to transfer data from activity to tabLayout (TabItem ).
Firstly I make a data pass or intent from (recyclerview) to activity that contains tabLayout (TabItem ) by this code :
public static final String EXTRA_FROM = "FROMPL";
#Override
public void onItemClick(int position) {
Intent detailIntent = new Intent(this,
com.example.myapplication.Fragmant.StatusFragment.class);
ExampleItem clickedItem = mExampleList.get(position);
detailIntent.putExtra(EXTRA_FROM, clickedItem.getCreator());
startActivity(detailIntent);
}
And I Receive data on the next Activity that contains tabLayout (TabItem ) with the following code:
Intent i = getIntent();
final String FROMPL = i.getStringExtra("FROMPL");
text.setText(FROMPL);
To here everything is fine , And the data can be used on Main page .but the problem that I have now
In this activity after I Receive data how I can send it to one of tabLayout or one TabItem ?Picture for clarification
I need to transfer data to it to display different data separately in each one.
All my code :
public class MainActivityFargmain extends AppCompatActivity {
Toolbar toolbar;
TabLayout tabLayout;
ViewPager viewPager;
PageAdapter pageAdapter;
TabItem tabChats;
TabItem tabStatus;
TabItem tabCalls;
EditText text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_m);
toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(getResources().getString(R.string.app_name));
setSupportActionBar(toolbar);
tabLayout = findViewById(R.id.tablayout);
tabChats = findViewById(R.id.tabChats);
tabStatus = findViewById(R.id.tabStatus);
tabCalls = findViewById(R.id.tabCalls);
viewPager = findViewById(R.id.viewPager);
text = (EditText) findViewById(R.id.text);
Intent i = getIntent();
final String FROMPL = i.getStringExtra("FROMPL");
text.setText(FROMPL);
pageAdapter = new PageAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pageAdapter);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
if (tab.getPosition() == 1) {
toolbar.setBackgroundColor(ContextCompat.getColor(MainActivityFargmain.this,
R.color.colorAccent));
tabLayout.setBackgroundColor(ContextCompat.getColor(MainActivityFargmain.this,
R.color.colorAccent));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(ContextCompat.getColor(MainActivityFargmain.this,
R.color.colorAccent));
}
} else if (tab.getPosition() == 2) {
toolbar.setBackgroundColor(ContextCompat.getColor(MainActivityFargmain.this,
android.R.color.darker_gray));
tabLayout.setBackgroundColor(ContextCompat.getColor(MainActivityFargmain.this,
android.R.color.darker_gray));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(ContextCompat.getColor(MainActivityFargmain.this,
android.R.color.darker_gray));
}
} else {
toolbar.setBackgroundColor(ContextCompat.getColor(MainActivityFargmain.this,
R.color.colorPrimary));
tabLayout.setBackgroundColor(ContextCompat.getColor(MainActivityFargmain.this,
R.color.colorPrimary));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(ContextCompat.getColor(MainActivityFargmain.this,
R.color.colorPrimaryDark));
}
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
}
}
public class ChatFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
setHasOptionsMenu(true);
return inflater.inflate(R.layout.fragment_chat, container, false);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_chats, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_chat) {
Toast.makeText(getActivity(), "Clicked on " + item.getTitle(), Toast.LENGTH_SHORT)
.show();
}
return true;
}
}
public class PageAdapter extends FragmentPagerAdapter {
private int numOfTabs;
PageAdapter(FragmentManager fm, int numOfTabs) {
super(fm);
this.numOfTabs = numOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new ChatFragment();
case 1:
return new StatusFragment();
case 2:
return new CallFragment();
default:
return null;
}
}
#Override
public int getCount() {
return numOfTabs;
}
}
Please help me
In your Activity create 2 functions:
setData()
getData()
In your MainActivity() add the following:
public String data;
public void setData(String passedData){
this.data = passedData
}
OnClick Listener function:
#Override
public void onItemClick(int position) {
setData("my String");
}
declare getData() that returns data.
public void getData(){
return data;
}
in your fragment
MainActivityFargmain activity = (MainActivityFargmain) getActivity();
String dataReceived = activity.getData();
I've created Activity to handle ViewPager. At the beginning it was working fine, but then I had to add some more code, to make it refresh my pages while selecting them. I've handled it by calling onResume() method with every page change.
I've optimized my Fragments, cleared unnecessary code (inside onResume()) in each of them, but this give no result. That's how my Activity looks like:
public class MainTabsActivity extends AppCompatActivity implements FullList.OnListFragmentInteractionListener, AcceptedList.OnListFragmentInteractionListener, StartedList.OnFragmentInteractionListener {
private static final int NUM_TABS = 3;
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
TabLayout tabLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_tabs);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(2);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i1) {
}
#Override
public void onPageSelected(int i) {
Fragment fragment = ((SectionsPagerAdapter)mViewPager.getAdapter()).getFragment(i);
if (fragment != null) {
Log.e("PAGE SELECTED", " " + i);
tabLayout.getTabAt(i).select();
fragment.onResume();
}
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
Intent i = getIntent();
int pageNum = i.getIntExtra("pagenumber", 0);
mViewPager.setCurrentItem(pageNum);
tabLayout.getTabAt(pageNum).select();
mViewPager.invalidate();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main_tabs, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onListFragmentInteraction(DummyContent.DummyItem item) {
}
#Override
public void onFragmentInteraction(Uri uri) {
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private Map<Integer, String> mFragmentTags;
private FragmentManager mFragmentManager;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
mFragmentTags = new HashMap<>();
mFragmentManager = fm;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch(position) {
case 0:
return getString(R.string.tab_text_1);
case 1:
return getString(R.string.tab_text_2);
case 2:
return getString(R.string.tab_text_3);
}
return null;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
FullList tab1 = new FullList();
return tab1;
case 1:
AcceptedList tab2 = new AcceptedList();
return tab2;
case 2:
StartedList tab3 = new StartedList();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
return NUM_TABS;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
Object obj = super.instantiateItem(container, position);
if (obj instanceof Fragment) {
Fragment f = (Fragment) obj;
String tag = f.getTag();
mFragmentTags.put(position, tag);
}
return obj;
}
public Fragment getFragment(int position) {
String tag = mFragmentTags.get(position);
if (tag == null) return null;
return mFragmentManager.findFragmentByTag(tag);
}
}
}
I've added code, to call onResume() method, but funny thing is that the Fragments are loading so long only while I open this Activity from another, but not while scrolling between pages (everything works smoothly then), before changes everything was fine.
Is there any way to make this work faster?
You don't need to write onPageSelected code to change your tab selection.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(2);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager); // this will synchronize our tablayout with your viewpager
You should not call onResume directly, this is a system event and a call to this void
is not recommended.
Also, in your case, no need to call mViewPager.invalidate()
I want to create a createOrderActivity where has three fragments like Service info, ScheduleInfo, confirmation
the service info fragment has editText
if click NextButton(which is situated CreateOrderActivity) check validation editText first. then move ScheduleFragment page.
if first two pages validation ok then move to Confirmation Fragment page.
Here is the FragmentViewpagerAdapter class
public class FragmentViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public FragmentViewPagerAdapter(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);
}
#Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
}
In CreateOrderActivity class
#Override
public void onPageSelected(int position) {
boolean checkSch= false;
if (position == 1) {
ServiceInfoFragment serviceInfoFragment = new ServiceInfoFragment();
//checking validation from ServiceInfoFragment fragment Class
if (serviceInfoFragment.checkServiceValidation()) {
checkSch = true;
//Toast.makeText(CreateOrderActivity.this, "Validation okay", Toast.LENGTH_SHORT).show();
}else {
checkSch = false;
// Toast.makeText(CreateOrderActivity.this, "Please check validation", Toast.LENGTH_SHORT).show();
pagerCreateOrder.setCurrentItem(position-1);
}
}
if (position == 2) {
if (checkSch){
ScheduleFragment scheduleFragment = new ScheduleFragment();
if (scheduleFragment.checkScheduleValidation()) {
Toast.makeText(CreateOrderActivity.this, "Validation okay", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(CreateOrderActivity.this, "Please check S validation", Toast.LENGTH_SHORT).show();
pagerCreateOrder.setCurrentItem(position-1);
}
}else {
Toast.makeText(CreateOrderActivity.this, "Please check validation", Toast.LENGTH_SHORT).show();
pagerCreateOrder.setCurrentItem(position-2);
}
}
}
//checking checkScheduleValidation() in ScheduleFragment class. return null exception
*bellow mehtod declear in Fragment *
public boolean checkServiceValidation(){
return true;
}
I upload this Image
I used this Reference
I found a solution in my way. I have loaded three fragments in a viewpager. In the second fragment, there is one edittext. on clicking the next button, there is a validation for checking email. On the basis of validation next fragment is loaded. All the Fragments are loaded as singleton . You might have caused null pointer exception , because of multiple instance of fragments.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private SectionsPagerAdapter mSectionsPagerAdapter;
private FragmentTwo fragmentTwo;
private ViewPager mViewPager;
Button back, next;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
back = findViewById(R.id.back);
next = findViewById(R.id.next);
next.setOnClickListener(this);
back.setOnClickListener(this);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.vp_viewpager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i1) {
}
#Override
public void onPageSelected(int i) {
if (i==2){
if (!fragmentTwo.checkEditText()) {
Toast.makeText(getApplicationContext(),"False",Toast.LENGTH_LONG).show();
mViewPager.setCurrentItem(i-1);
return;
}
}
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
}
private void changeViewPagerPosition(int position) {
int totalCount = mViewPager.getAdapter().getCount();
if (position < 0 || position >= totalCount) {
return;
}
mViewPager.setCurrentItem(position);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public void onClick(View view) {
int currentViewpagerPosition = mViewPager.getCurrentItem();
switch (view.getId()) {
case R.id.back:
changeViewPagerPosition(currentViewpagerPosition - 1);
break;
case R.id.next:
if (currentViewpagerPosition==1){
if (!fragmentTwo.checkEditText()) {
Toast.makeText(getApplicationContext(),"Falsee",Toast.LENGTH_LONG).show();
return;
}
}
changeViewPagerPosition(currentViewpagerPosition + 1);
break;
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FragmentOne.newInstance(position);
case 1:
return fragmentTwo=FragmentTwo.getInstance();
case 2:
return FragmentThree.newInstance(position);
default:
return FragmentThree.newInstance(position);
}
}
#Override
public int getCount() {
return 3;
}
}
}
The Fragment 2
public class FragmentTwo extends Fragment {
EditText email;
private static FragmentTwo fragment=null;
public FragmentTwo() {
}
public static FragmentTwo getInstance() {
if (fragment == null){
fragment = new FragmentTwo();
}
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_two, container, false);
return rootView;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
email = getView().findViewById(R.id.editText);
}
public boolean emailValidator()
{
Pattern pattern;
Matcher matcher;
final String EMAIL_PATTERN = "^[_A-Za-z0-" +
"9-]+(\\.[_A-Za-z0-9-]+)*#[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
pattern = Pattern.compile(EMAIL_PATTERN);
matcher = pattern.matcher(email.getText().toString());
return matcher.matches();
}
public Boolean checkEditText(){
if (emailValidator()){
return true;
}
return false;
}
}
I've 2 fragments in viewpager and I want to add callback methods using interface in both. I add the interface listener while initiating fragments in viewpager adapter but only the last fragment's is being called. That's why when I click on the MainActivity's menu option, only the Toast in MyFragB is being called even if MyFragA is showing.
Both Fragments... Only Activity calling MyFragB Toast is showing when wither fragment is opened
public class MyFragA extends Fragment implements FragmentCaller {
private TextView myTxt;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.myfraga, container, false);
}
#Override
public void CallFragment() {
if(getActivity()!=null)
Toast.makeText(getActivity(), "Activity calling MyFragA", Toast.LENGTH_SHORT).show();
}
}
public class MyFragB extends Fragment implements FragmentCaller{
private TextView myTxt;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.myfragb, container, false);
}
#Override
public void CallFragment() {
if(getActivity()!=null)
Toast.makeText(getActivity(), "Activity calling MyFragB", Toast.LENGTH_SHORT).show();
}
}
Main Activity
public class MainActivity extends AppCompatActivity {
TabLayout tabs;
ViewPager viewpager;
FragmentCaller fragListerner = null;
public interface FragmentCaller {
void CallFragment();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabs = (TabLayout)findViewById(R.id.tabs);
viewpager = (ViewPager)findViewById(R.id.viewpager);
SimpleFragmentPagerAdapter adapter = new SimpleFragmentPagerAdapter(this, getSupportFragmentManager());
viewpager.setAdapter(adapter);
tabs.setupWithViewPager(viewpager);
} // onCreate ends
public class SimpleFragmentPagerAdapter extends FragmentStatePagerAdapter {
private Context mContext;
public SimpleFragmentPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
// This determines the fragment for each tab
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new MyFragA();
fragListerner = (FragmentCaller) fragment;
return fragment;
} else if (position == 1){
fragment = new MyFragB();
fragListerner = (FragmentCaller)fragment;
return fragment;
}
return null;
}
// This determines the number of tabs
#Override
public int getCount() {
return 2;
}
// This determines the title for each tab
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
switch (position) {
case 0:
return mContext.getString(R.string.fraga);
case 1:
return mContext.getString(R.string.fragb);
default:
return null;
}
}
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.callback, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()){
case R.id.call:
if(fragListerner!=null){
if(fragListerner instanceof MyFragA){
fragListerner.CallFragment();
}else if(fragListerner instanceof MyFragB){
fragListerner.CallFragment();
}
}
break;
}
return true;
}
}
I used rick's answer from here.
public class MainActivity extends AppCompatActivity {
TabLayout tabs;
ViewPager viewpager;
public static int currentFrag=0;
SimpleFragmentPagerAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabs = (TabLayout)findViewById(R.id.tabs);
viewpager = (ViewPager)findViewById(R.id.viewpager);
adapter = new SimpleFragmentPagerAdapter(this, getSupportFragmentManager());
viewpager.setAdapter(adapter);
tabs.setupWithViewPager(viewpager);
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
System.out.println("sammy_current_position: "+position);
currentFrag = position;
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
} // onCreate ends
public class SimpleFragmentPagerAdapter extends FragmentStatePagerAdapter {
private Context mContext;
public SimpleFragmentPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
#Override
public Fragment getItem(int position) {
if (position == 0) {
return new MyFragA();
} else if (position == 1){
return new MyFragB();
}
return null;
}
#Override
public int getCount() {
return 2;
}
// This determines the title for each tab
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
switch (position) {
case 0:
return mContext.getString(R.string.fraga);
case 1:
return mContext.getString(R.string.fragb);
default:
return null;
}
}
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.callback, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()){
case R.id.call:
if(currentFrag == 0) {
MyFragA frag1 = (MyFragA)viewpager.getAdapter().instantiateItem(viewpager, viewpager.getCurrentItem());
frag1.specialCase();
}
break;
}
return true;
}
}
but only the last fragment's is being called
Of Course ! because at pos == 0 you are setting fragListerner = (FragmentCaller) fragment then at again in pos == 1 you re-set fragListerner = (FragmentCaller)fragment;. So this condition, fragListerner instanceof MyFragB will always be true!
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new MyFragA();
fragListerner = (FragmentCaller) fragment;
return fragment;
} else if (position == 1){
fragment = new MyFragB();
fragListerner = (FragmentCaller)fragment;
return fragment;
}
return null;
}
So, you are trying to communicate from activity to fragment
okay, if you still want to use interfaces, you can do it like that:
create an instance of your interface for each fragment! and in getItem assign them both,
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new MyFragA();
fragAListerner = (FragmentCaller) fragment;
return fragment;
} else if (position == 1){
fragment = new MyFragB();
fragBListerner = (FragmentCaller)fragment;
return fragment;
}
return null;
}
But, there is an easier way to call fragment's methods from it's parent activity, which is like follows, for ex:
Fragment fragment = adapter.getItem(0); // MyFragA is at pos 0
fragment.<specific_function_name>();
Or, by using it's id!
MyFragA fragment = (MyFragA) getFragmentManager().findFragmentById(R.id.MyFragAId);
fragment.<specific_function_name>();
Or, by using it's tag!
MyFragA fragment = (MyFragA) getFragmentManager().findFragmentByTag("MyFragATag");
fragment.<specific_function_name>();
I have a Tabbed Activity with 3 Tabs. On each Tab are RecyclerViews with some list items. If you click on an item a new fragment should open and there should appear a Back-Button in the toolbar. My current screen looks like this:
And now I will show you my code. At first MainActivity.java with the TabLayout:
public class MainActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Pflege");
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.getTabAt(0).setIcon(R.drawable.tab_icon_pflege);
tabLayout.getTabAt(1).setIcon(R.drawable.tab_icon_dokumentation);
tabLayout.getTabAt(2).setIcon(R.drawable.tab_icon_probleme);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
switch(tab.getPosition()) {
case 0:
mViewPager.setCurrentItem(0);
toolbar.setTitle("Pflege");
break;
case 1:
mViewPager.setCurrentItem(1);
toolbar.setTitle("Daten");
break;
case 2:
mViewPager.setCurrentItem(2);
toolbar.setTitle("Probleme");
break;
default:
mViewPager.setCurrentItem(tab.getPosition());
toolbar.setTitle("Pflege");
break;
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch(position){
case 0:
Tab1Pflege tab1 = new Tab1Pflege();
return tab1;
case 1:
Tab2Dokumentation tab2 = new Tab2Dokumentation();
return tab2;
case 2:
Tab3Probleme tab3 = new Tab3Probleme();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Pflege";
case 1:
return "Daten";
case 2:
return "Probleme";
}
return null;
}
}
}
Here is the Fragment for the first tab with the RecyclerView:
public class Tab1Pflege extends Fragment {
private RecyclerView recyclerView;
private RecyclerView.Adapter rvAdapter;
private RecyclerView.LayoutManager rvLayoutManager;
private ArrayList<String> listItems;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab1_pflege, container, false);
listItems = new ArrayList<>();
listItems.add("Test1");
listItems.add("Test2");
listItems.add("Test3");
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
rvLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(rvLayoutManager);
rvAdapter = new RvAdapter(listItems);
recyclerView.setAdapter(rvAdapter);
return rootView;
}
}
And here is my RecyclerView Adapter:
public class RvAdapter extends RecyclerView.Adapter<RvAdapter.MyViewHolder> {
ArrayList<String> listItems;
public RvAdapter (ArrayList<String> listItems){
this.listItems = listItems;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_item_layout, null);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.itemTitle.setText(listItems.get(position));
holder.itemImage.setImageResource(R.drawable.ic_keyboard_arrow_right);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println(listItems.get(position));
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView itemTitle;
ImageView itemImage;
public MyViewHolder(View itemView){
super(itemView);
itemTitle = (TextView) itemView.findViewById(R.id.itemTitle);
itemImage = (ImageView) itemView.findViewById(R.id.itemImage);
}
}
}
In this class is an onClickListener for clicking on a list item. And there I want to open a new fragment for example for Test1. On top of that there should appear a Back-Button in the toolbar to navigate back to the Tab1 Overview with the RecyclerView. But I have no idea how to do that. Can someone help me with it?
In onClick, you can do something like this (to load another fragment)
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
Fragment fragment = // TODO: initialise your fragment 'fragment'
mFragments.push(fragment);
// Animation, if need it
// trans.setCustomAnimations(R.anim.right_in, R.anim.left_out,
// R.anim.right_out, R.anim.left_in);
// _container is the id of 'fragment' container in the your xml
trans.replace(R.id._container, fragment);
// variable to identify this fragment, and title of the page as well
String name = // TODO: initialise
trans.addToBackStack(name);
trans.commit();
getSupportActionBar().setTitle(name);
and in onCreate of your activity, setup listener for back stack changes.
FragmentManager manager = getSupportFragmentManager();
manager.addOnBackStackChangedListener(mBackStackListener);
and you can change back icon in
private OnBackStackChangedListener mBackStackListener = new OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
FragmentManager manager = getSupportFragmentManager();
int count = manager.getBackStackEntryCount();
if(count > 0) {
// TODO: Show back icon
} else {
// TODO: Other icon
}
}
};