I am setting up ViewPager on my onCreate() but when I try to set click listener one of the layout tab button, it does not respond. Here is how my onCreate() is set up.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.join_login);
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new JoinLoginAdapter(getSupportFragmentManager(),Titles,Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
// Set up the login form.
View inflatedView = getLayoutInflater().inflate(R.layout.login_tab, null);
mEmailView = (AutoCompleteTextView) inflatedView.findViewById(R.id.email);
populateAutoComplete();
mPasswordView = (EditText) inflatedView.findViewById(R.id.login_password);
//mPasswordView = (EditText) findViewById(R.id.login_password);
mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == R.id.login_password || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
}
});
Button mEmailSignInButton = (Button) inflatedView.findViewById(R.id.email_sign_in_button);
mEmailSignInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
attemptLogin();
}
});
mLoginFormView = findViewById(R.id.login_form);
mProgressView = findViewById(R.id.login_progress);
}
My JoinLoginAdapter extends FragmentStatePagerAdapter. I have three layouts, one is the ContentView whereas the other two are the two tabs for my ViewPager. The problem is mPasswordView and other buttons currently in the two tabs do not respond on click. I also have the adapter below for my ViewPager.
public class JoinLoginAdapter extends FragmentStatePagerAdapter {
CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
int NumbOfTabs; // Store the number of tabs, this will also be passed when the ViewPagerAdapter is created
// Build a Constructor and assign the passed Values to appropriate values in the class
public JoinLoginAdapter(FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb) {
super(fm);
this.Titles = mTitles;
this.NumbOfTabs = mNumbOfTabsumb;
}
//This method return the fragment for the every position in the View Pager
#Override
public Fragment getItem(int position) {
if(position == 0) // if the position is 0 we are returning the First tab
{
LoginFragment logintab = new LoginFragment();
return logintab;
}
else // As we are having 2 tabs if the position is now 0 it must be 1 so we are returning second tab
{
JoinFragment jointab = new JoinFragment();
return jointab;
}
}
// This method return the titles for the Tabs in the Tab Strip
#Override
public CharSequence getPageTitle(int position) {
return Titles[position];
}
// This method return the Number of tabs for the tabs Strip
#Override
public int getCount() {
return NumbOfTabs;
}
}
I have been thinking the ViewPager is interfering with the clicks but I cannot seem to find how to solve this. What exactly am I doing wrong?
The problem is mPasswordView and other buttons currently in the two
tabs do not respond on click. I have been thinking the ViewPager is
interfering with the clicks but I cannot seem to find how to solve
this. What exactly am I doing wrong?
you are using a inflater, to get a reference a reference to view handled by the fragments in your ViewPager. You are doing the wrong assumption that the inflater is returning you the same view's reference that the Fragments handled by the ViewPager are inflating. What is returning the inflater in your Activity's onCreate is different from what you are seeing at screen. You should let the Fragments handle their OnClicKListener
Related
I set up a tab slider in my activity calling 3 separate fragments depending on the fragment selected. The problem is that when the first tab is selected, "Science" is shown - which was set on the onCreateView() method of the first fragment. However, WITHOUT clicking on the other tabs, "Technology" and "Sports" are then shown.
To my knowledge, the way I implemented it the last two should only show once the corresponding tab is selected.
This is my Page adapter class
public class PagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 3; //Represents the number of tabs
private String tabTitles[] = new String[]{"Technology", "Science", "Sports"}; //Tab values defined in an array
private Context context;
public PagerAdapter(FragmentManager fm, Context context)
{
super(fm);
this.context = context;
}
#Override
public int getCount()
{
return PAGE_COUNT;
}
//determines the fragment depending on the selected tab
#Override
public Fragment getItem(int position)
{
if(position==0)
return TechnologyFragment.newInstance(position+1);
else if(position==1)
return ScienceFragment.newInstance(position+1);
else if(position==2)
return SportsFragment.newInstance(position+1);
else
return null;
}
//displays the title for each tab
#Override
public CharSequence getPageTitle(int position)
{
// Generate title based on item position
return tabTitles[position];
}
}
This is the news class - where the view pager and tab layout are set up
public class News extends AppCompatActivity {
//Here the viewPager is connected to the PagerAdapter class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news);
//This component will be used to page between the various fragments created.
final ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new PagerAdapter(getSupportFragmentManager(), News.this));
//the tabLayout is given the viewPager to connect to the pager with the tabs
TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
//the following was used so the tabs fill up the width of the screen being responsive for all devices and orientations
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
}
}
And these are the fragment classes - (the other two are identical but have a different message represented using the Toast)
public class ScienceFragment extends Fragment {
//other methods
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_science_fragment, container, false);
toShow=getAll();
GridView gridView = (GridView)view.findViewById(R.id.gridview);
gridView.setAdapter(new ImageAdapter(getContext(),toShow));
Toast.makeText(getContext(), "Science", Toast.LENGTH_SHORT).show();
return view;
}
}
Any help is appreciated
I have a viewpager app that I am working on with 3 fragments.
I am adding the fragments dynamically via the FragmentStatePagerAdapter like that:
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
int NumbOfTabs; // Store the number of tabs, this will also be passed when the ViewPagerAdapter is created
// Build a Constructor and assign the passed Values to appropriate values in the class
public ViewPagerAdapter(FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb) {
super(fm);
this.Titles = mTitles;
this.NumbOfTabs = mNumbOfTabsumb;
}
//This method return the fragment for the every position in the View Pager
#Override
public Fragment getItem(int position) {
if(position == 0) // if the position is 0 we are returning the First tab
{
Current_forecast_fragment current_forecast_fragment = new Current_forecast_fragment();
return current_forecast_fragment;
}
else if (position == 1) // As we are having 2 tabs if the position is now 0 it must be 1 so we are returning second tab
{
return new Hourly_forecast_fragment();
}else {
return new Daily_forecast_fragment();
}
}
// This method return the titles for the Tabs in the Tab Strip
#Override
public CharSequence getPageTitle(int position) {
return Titles[position];
}
// This method return the Number of tabs for the tabs Strip
#Override
public int getCount() {
return NumbOfTabs;
}
}
How do I reference a fragment, lets say the current forecast one from my main activity? I tried something like that but I need the fragment id to reference it. Any suggestions?:
public class MainActivity extends AppCompatActivity {
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[]={"Current","Hourly","Daily"};
int Numboftabs =3;
Current_forecast_fragment mCurrent_forecast_fragment;
public static final String TAG = MainActivity.class.getSimpleName();
public static final String LOCATION_KEY = "location_key";
public Forecast mForecast;
public static final String DAILY_FORECAST = "DAILY_FORECAST";
public static final String HOURLY_FORECAST = "HOURLY_FORECAST";
//default coordinates - Gotse Delchev, UK Lati:57.156866 ; Long:
private double latitude = 41.5667;
private double longitude = 23.7333;
private LocationManager locationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//-----------MY CODE STARTS HERE-----------------
mCurrent_forecast_fragment = (Current_forecast_fragment) getSupportFragmentManager().findFragmentById(R.id.??????);
//Log.d("MainActivity",mCurrent_forecast_fragment.getTag() + "Georgi");
getLocation();
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
#Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.tabsScrollColor);
}
});
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
}
}
After a lot of experimentation I came with a simple solution to my problem. Since I am adding the fragments dynamically (in the viewPagerAdapter) and not in XML I couldn't reference them weither by id or tag. My solution is to modify slightly the adapter so that it stores a reference of the fragment passed as a parameter. Then all of the methods of the fragment are accessible (if declired public) in the mainActivity:
MainActivity:
public class MainActivity extends AppCompatActivity {
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[]={"Current","Hourly","Daily"};
int Numboftabs =3;
Current_forecast_fragment mCurrent_forecast_fragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//-----------MY CODE STARTS HERE-----------------
this.mCurrent_forecast_fragment = new Current_forecast_fragment();
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs,mCurrent_forecast_fragment);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setOffscreenPageLimit(3);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
#Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.tabsScrollColor);
}
});
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
}
My Code in ViewPagerAdapter:
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private Current_forecast_fragment mCurrent_forecast_fragment;
CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
int NumbOfTabs; // Store the number of tabs, this will also be passed when the ViewPagerAdapter is created
// Build a Constructor and assign the passed Values to appropriate values in the class
public ViewPagerAdapter(FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb,Current_forecast_fragment current_fragment) {
super(fm);
this.mCurrent_forecast_fragment = current_fragment;
this.Titles = mTitles;
this.NumbOfTabs = mNumbOfTabsumb;
}
//This method return the fragment for the every position in the View Pager
#Override
public Fragment getItem(int position) {
if(position == 0) // if the position is 0 we are returning the First tab
{
return this.mCurrent_forecast_fragment;
}
else if (position == 1) // As we are having 2 tabs if the position is now 0 it must be 1 so we are returning second tab
{
return new Hourly_forecast_fragment();
}else {
return new Daily_forecast_fragment();
}
}
}
What is wrong with this code? After I clicked tab page 2, it loads the data and the scrollbar color below does not change, and always returns to tab page 1. What should I do? All I want is to indicate by scrollbar color which tab is selected after I click which page I want.
Here is the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
titlebar = getIntent().getStringExtra("Branch");
setTitle( titlebar +" Order" );
setContentView(R.layout.activity_main);
// Creating The Toolbar and setting it as the Toolbar for the activity
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
#Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.tabsScrollColor);
}
});
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
pager.setOnPageChangeListener(pagelistener);
pagelistener.onPageSelected(0);
}
final ViewPager.OnPageChangeListener pagelistener = new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position==0){
new LoadProducts().execute();
}else if(position==1){
new LoadCart().execute();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
};
ViewPagerAdapter.java:
package com.example.work.mcoatorderingapp;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
int NumbOfTabs; // Store the number of tabs, this will also be passed when the ViewPagerAdapter is created
// Build a Constructor and assign the passed Values to appropriate values in the class
public ViewPagerAdapter(FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb) {
super(fm);
this.Titles = mTitles;
this.NumbOfTabs = mNumbOfTabsumb;
}
//This method return the fragment for the every position in the View Pager
#Override
public Fragment getItem(int position) {
if(position == 0) // if the position is 0 we are returning the First tab
{
OrderTab ordertab = new OrderTab();
return ordertab;
}
else if(position==1) // As we are having 2 tabs if the position is now 0 it must be 1 so we are returning second tab
{
ViewOrderTab viewordertab = new ViewOrderTab();
return viewordertab;
}
else
{
OrderStatus orderstatus = new OrderStatus();
return orderstatus;
}
}
// This method return the titles for the Tabs in the Tab Strip
#Override
public CharSequence getPageTitle(int position) {
return Titles[position];
}
// This method return the Number of tabs for the tabs Strip
#Override
public int getCount() {
return NumbOfTabs;
}
public static interface FirstShot
{
public void onFirstShot();
}
}
The problem is pager.setOnPageChangeListener(pagelistener), instead do this tabs.setOnPageChangeListener(pagelistener)
i.e instead of creating and assigning OnPageChangeListener for ViewPager, create and assign one for SlidingTabLayout to listen for its event.
Below is the portion from SlidingTabLayout.java found on android sample project explaining the part.
/**
* Set the {#link android.support.v4.view.ViewPager.OnPageChangeListener}. When using {#link SlidingTabLayout} you are
* required to set any {#link android.support.v4.view.ViewPager.OnPageChangeListener} through this method. This is so
* that the layout can update it's scroll position correctly.
*
* #see android.support.v4.view.ViewPager#setOnPageChangeListener(android.support.v4.view.ViewPager.OnPageChangeListener)
*/
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mViewPagerPageChangeListener = listener;
}
Also setOnPageChangeListener is deprecated, use addOnPageChangeListener instead of that in your code.
Current I have a ViewPager which have 3 different tabs(Peer, Sync and Share).
In the Peer fragment, it contain a ListView with clickable items. OnItemClick I wish to open a new fragment which will display the detail of the selected item,
But I am not sure how to properly implement this functionality...
Activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.file_sharing_activity);
// Tabs stuff ...
this.tabsAdapter = new TabsPagerAdapter(this.getSupportFragmentManager());
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(this.tabsAdapter);
// Create tabs bar
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create tab fragments
this.peerListFragment = new PeerListFragment();
this.syncFragment = new SyncFragment();
this.shareFragment = new ShareFragment();
// Create tabs
actionBar.addTab(actionBar.newTab().setText("Peers").setTabListener(this.peerListFragment));
actionBar.addTab(actionBar.newTab().setText("Sync").setTabListener(this.syncFragment));
actionBar.addTab(actionBar.newTab().setText("Share").setTabListener(this.shareFragment));
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// When swiping between pages, select the
// corresponding tab.
getActionBar().setSelectedNavigationItem(position);
}
});
try {
ProgramController.getInstance().initializeProgram(this);
} catch (Exception e) {}
}
TabPagerAdapter:
private class TabsPagerAdapter extends FragmentPagerAdapter{
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return peerListFragment;
case 1:
return syncFragment;
case 2:
return shareFragment;
default:
return null;
}
}
#Override
public int getCount() {
return NB_TABS;
}
}
PeerListFragment
public class PeerListFragment extends Fragment implements ActionBar.TabListener{
ListView peerListView;
public PeerListFragment(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_peer_list, container, false);
peerListView = (ListView) view.findViewById(R.id.list_peer);
PeerListAdapter adapter = new PeerListAdapter(getActivity());
peerListView.setAdapter(adapter);
peerListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//Display detail fragment here
}
});
return view;
}
In general, you would have a method on your Activity that would be called from onItemClick() to display the detail view, i,e, showDetail(itemId). The Activity would actually handle the transition to the detail view.
Now, since your ViewPager is in an Activity and not a Fragment, you have two choices:
Have a DetailActivity that is started with an Intent from your current Activity. (Easiest option, but less flexible for tablets)
Rewrite your Activity to put your view with the ViewPager in a Fragment. Then the Activity would replace the current fragment that has the ViewPager with the detail fragment. (Harder option, but you can display side-by-side in a tablet).
Right now, your ViewPager is in your activity layout. In order to make the fragments work, your activity layout would just have one or two child layouts which function as fragment containers, then the ViewPager would go into a fragment layout.
in my fragment i want to setVisibility for one element of my layout on back press.
for example into the fragment i want this:
if(list.getVisibility() == View.GONE){
list.setVisibility(View.VISIBLE);
text.setVisibility(View.GONE);
}
But how i can handle the back press event into the fragment? and set this visibility?
UPDATE:
In my FragmentActivity i have:
adapter = new ViewPagerAdapterEventi(getSupportFragmentManager(),Titles,Numboftabs,mE1,mE2);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
#Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.tabsScrollColor);
}
});
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
And into the Adaper:
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
....
#Override
public Fragment getItem(int position) {
if (position == 0) // if the position is 0 we are returning the First tab
{
check = position;
Fragment1 tab1 = new Fragment1();
Bundle args = new Bundle();
args.putString("json", mEv1.toString());
tab1.setArguments(args);
return tab1;
} else {
Fragment2 tab2 = new Fragment2();
check = position;
Bundle args = new Bundle();
args.putString("json", mEv2.toString());
tab2.setArguments(args);
return tab2;
}
}
#Override
public CharSequence getPageTitle(int position) {
return Titles.get(position);
}
// This method return the Number of tabs for the tabs Strip
#Override
public int getCount() {
return NumbOfTabs;
}
}
Please override method in FragmentActivity
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FRAGMENT_TAG");
fragment.setUserVisibility();
}
You have to handle this in your Activity
#Override
public void onBackPressed() {
super.onBackPressed();
MyCustomFragment fragment = (MyCustomFragment) getFragmentManager().findFragmentByTag("TAG_I_USED_WHEN_COMMITTING_FRAGMENT");
if(fragment != null) {
fragment.onBackPressed();
}
}
And create a public method in MyCustomFragment called onBackPressed() to handle everything that should happen when the back button is pressed.
note: Don't forget that your FragmentManager can also handle the onBackPressed event and remove your fragment from the back stack for example. This depends on how you've added the fragment