This is a variant on a familiar problem (such as this: Setting action bar title in ViewPager)
I have a ViewPager setup in my main activity. The ViewPager is set to represent a date. I've set it up with an OnPageChangeListener and onPageListener to set the toolbar title to a given date (the default on startup being the current date). onPageListener is called, but some other event is called afterwards, and it sets the toolbar title back to the defined app name. Even setting it explicitly in the activity's onCreate doesn't fix the title, it is still replaced by the app name.
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private Date _displayedDate;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setAdapter(new DatePagerAdapter(getSupportFragmentManager()));
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
_displayedDate = DateUtils.offsetDate(position);
showDisplayedDate(); // no apparent effect
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
_displayedDate = new Date();
viewPager.setCurrentItem((int)DateUtils.getDayOffset(_displayedDate));
showDisplayedDate(); // no apparent effect
}
public void showDisplayedDate() {
if (_displayedDate != null) {
toolbar.setTitle(_displayedDate.toString())); // simplified version of date display
}
}
}
public class DatePagerAdapter extends FragmentStatePagerAdapter
So, what gives? How do I set the title based on the ViewPager's initial display?
As stated here, this removes the automatic app title in the toolbar, and the rest of the logic takes care of displaying the date:
getSupportActionBar().setDisplayShowTitleEnabled(false);
Related
I have a main activity with three tabs, and the three tabs are being populated with a recycler view while fetch data using a JSONHttp Request with Volley. However, the problem is that the first time the data is fetched, it get's populated. However, I am unable to find a way to fetch data again (like refresh it) when I switch from one tab to another.
A snippet of what I am doing is below:
public class MainActivity extends AppCompatActivity {
// Class name TAG to be used for logging
private static final String TAG = MainActivity.class.getSimpleName();
// Variables
private User user;
private static ArrayList<> items;
private Fragment Fragment1, Fragment2;
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
user = getIntent().getParcelableExtra("USER");
fetchItems();
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
#Override
public void onPageSelected(int position) {
Log.d("Main", "Switching tab");
// Update the view
super.onPageSelected(position);
}
});
}
public void fetchJobs(){
items = new ArrayList<>();
JsonArrayRequest getItems = new JsonArrayRequest(Request.Method.GET, url + "items.json?", null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray o) {
// Get JSon from Http request, this code works fine..
// items array is populated with the desired response
mSectionsPagerAdapter.notifyDataSetChanged();
....
}
If I call fetchItems() when I switch to a tab to refresh the list it does not get repopulated with the new entries.
Try Using
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//Do what you want to do here
}
}
in each child fragment of viewPager,so each time the fragment is shown in viewpager it will get called. and can make the necessary changes. thanks if it doesn't wokr please note down.
I have a problem. I have an Activity with ViewPager which have some Fragments.
In my first Fragment I have some elements. Lets say an ImageView, TextView. How to make them visible by timer when you completely open the page of ViewPager?!
I used this code below in my MainActivity.java document to make that ImageView visible by timer but it works not as I expected. When i want to go to next page by scrolling and touch the screen ImageView dissapear. Why its happened?!
final ImageView mImageView = (ImageView) findViewById(R.id.earth);
mImageView.setVisibility(View.INVISIBLE);
mImageView.postDelayed(new Runnable() {
public void run() {
mImageView.setVisibility(View.VISIBLE);
}}, 5000);
Any help is appreciated. Thanks!
My new edits:
// Initialize the ViewPager and set an adapter
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
// Bind the tabs to the ViewPager
PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);
tabs.setViewPager(pager);
//open concrete page of ViewPager. setCurrentItem(index of page)
pager.setCurrentItem(1);
tabs.setOnPageChangeListener(new OnPageChangeListener() {
//This method will be invoked when the current page is scrolled, either as part of a program initiated smooth scroll or a user initiated touch scroll.
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
//This method will be invoked when a new page becomes selected.
#Override
public void onPageSelected(int position) {
final ImageView mImageView = (ImageView) findViewById(R.id.earth);
mImageView.setVisibility(View.INVISIBLE);
if (position == 0) {
mImageView.postDelayed(new Runnable() {
public void run() {
mImageView.setVisibility(View.VISIBLE);
}
}, 5000);
}
}
//Called when the scroll state changes.
#Override
public void onPageScrollStateChanged(int state) {
}
});
My Problem is conflict with TABS and ViewPager. When I use tabs.setOnPageChangeListener(new OnPageChangeListener() i have conflict with pager.setCurrentItem(1); which shows concrete page when Activity first opened. In my case its shows 2-d page when Activity first opened but Tab shows that opened 1-st page. WHY?! How to solve this problem?!
I would not use a timer. It would either fire too early, or too late during which your UI looks bad. Use the pager's events to know when to update your UI. For example, you can probably use OnPageChangedListener:
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
// Now displaying page at position
}
#Override
public void onPageScrollStateChanged(int state) {
}
};
I am building an app that uses three tab fragments and I want to create a function in one place that I can call from all three tabs. I would assume that I need to create the new function in the activity that contains the tabs, but I'm not sure how to declare it or how to call it from one of the tab fragments.
This is how i create my tabs in the main activity:
public class MainActivity extends FragmentActivity implements TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Search", "History", "Saved" };
#Override
protected void onCreate(Bundle savedInstanceState) {
//Initialise the Database connection
DBAdapter.init(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Setup tab bar
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//Add the tabs to the action bar
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
}
//Tab Swipe change listener
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
}
Create the function you need to call in the parent Activity and it must be a public method
and you can call that function like this:
((YourActivityClassName)getActivity()).yourPublicMethod();
In my example code i have three Swipeable Tabs in MainActivity.java namely : Android, IOS and WINDOWS and i am using swipe to switch between Tabs.
Now, i have to implement PageTransformer with Swipeable Tabs, so here i need your help, is it possible, if yes so how ?
MainActivity.java:-
public class MainActivity extends FragmentActivity {
ViewPager Tab;
TabPagerAdapter TabAdapter;
ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabAdapter = new TabPagerAdapter(getSupportFragmentManager());
Tab = (ViewPager)findViewById(R.id.pager);
Tab.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar = getActionBar();
actionBar.setSelectedNavigationItem(position);
}
});
Tab.setAdapter(TabAdapter);
..............
}
}
Here is what i want to implement in my program :
and this is how my Tab looks :
You have to use setPageTransformer() to do this type of navigation..
use below code to your pager..
Add This Code To Your MainActivity.java
Tab = (ViewPager)findViewById(R.id.pager); // you have defined view pager as `TAB`
Tab.setPageTransformer(false, new PageTransformer() {
public void transformPage(View page, float position) {
page.setRotationY(position * -30); // animation style... change as you want..
}
});
Tab.setCurrentItem(pos);
}
Get More Animation Styles From Here.. Customize the Animation with PageTransformer or ViewPager transitions
I found my solution here, its really easy to implement
Usage is pretty straightforward, just attach a PageTransformer to the ViewPager:
viewpager.setPageTransformer(false, new ViewPager.PageTransformer() {
#Override
public void transformPage(View page, float position) {
// do transformation here
}
});
rotates the pages around their Z axis by 30 degrees; you don’t need to normalize for this one. The effect is similar to the cover flow UI pattern:
#Override
public void transformPage(View page, float position) {
page.setRotationY(position * -30);
}
so here is my final code, which i used:
viewPager = (ViewPager)findViewById(R.id.pager);
viewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar = getActionBar();
actionBar.setSelectedNavigationItem(position);
}
});
viewPager.setAdapter(tabAdapter);
viewPager.setPageTransformer(false, new PageTransformer() {
public void transformPage(View page, float position) {
page.setRotationY(position * -30); // animation style... change as you want..
}
});
Create an inner class of your Activity...
public class MyPageTransformer implements ViewPager.PageTransformer {
public void transformPage(View view, float position) {
// Do your transform here
}
}
Then in your Activity you can set it on your ViewPager. Example...
Tab.setPageTransformer(true, new MyPageTransformer());
Read more at Customize the Animation with PageTransformer There are even a couple of examples of transforms to try out and to customize yourself.
I have implemented an actionbar but its title is not getting displayed. Also my app has two fragments , the title should change as per the fragment displayed.
public class MainActivity extends FragmentActivity {
/** Called when the activity is first created. */
AppSectionsPagerAdapter mAppSectionsPagerAdapter;
ViewPager mViewPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setupActionBar();
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());
// user swipes between sections.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new OnPageChangeListener()
{
public void onPageSelected(int position)
{
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
}
public void onPageScrollStateChanged(int state)
{
if (state == ViewPager.SCROLL_STATE_DRAGGING)
{
}
if (state == ViewPager.SCROLL_STATE_IDLE)
{
}
}
});
}
public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {
public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
return new AllPatient();
case 1:
//Intent intent = new Intent(MainActivity.this,abc.class);
return new LaunchpadSectionFragment();
}
return null;
}
#Override
public int getCount() {
return 2;
}
}
private void setupActionBar() {
ActionBar actionBar = getActionBar();
//actionBar.setDisplayShowHomeEnabled(false);
actionBar.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
ActionBar.DISPLAY_SHOW_CUSTOM);
ViewGroup v = (ViewGroup)LayoutInflater.from(this)
.inflate(R.layout.header, null);
actionBar.setCustomView(v,
new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT,
ActionBar.LayoutParams.WRAP_CONTENT,
Gravity.CENTER_VERTICAL | Gravity.RIGHT));
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(getTitle());
}
}
Please also tell me how to add dividers between the icons in actionbar.
Thanks in advance.
Try changing this line:
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM);
By this one:
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME, ActionBar.DISPLAY_SHOW_CUSTOM);
Add the show title flag like so
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM);
I think the problem is that you're adding a custom view with a width of MATCH_PARENT and Android removes the action bar title (but not the home icon) in that case. It's not very logical, but that's the behavior I see in my app. Setting the width to WRAP_CONTENT creates the same problem. The solution is to give the custom view a fixed width, or if you need the width to vary from one activity to another, calculate the width programmatically and set it to a new fixed width for each activity.
This should definitely work
getSupportActionBar().setDisplayShowTitleEnabled(true);
getSupportActionBar().setTitle(title);