I've implemented an infinite ViewPager in situ https://github.com/JoachimR/AnyDayViewPager. However, instead of using a PagerTabStrip, I'd prefer to use a CoordinatorLayout with TabLayout. But when setting up the TabLayout with the viewpager, (I'm assuming because there are an "infinite number of ViewPager Fragments") the app gets stuck.
How can I solve this issue?
Here's the code
(the other files which I have not changed can be found at JoachimR/AnyDayViewPager, e.g., FragmentContent.java, CachingFragmentStatePagerAdapter.java, TimeUtils.java, etc)
MainActivity.java
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.design.widget.TabLayout;
import android.os.Bundle;
import java.util.Calendar;
public class MainActivity extends FragmentActivity {
private static Context mContext;
private CachingFragmentStatePagerAdapter adapterViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
ViewPager vpPager = (ViewPager) findViewById(R.id.vpPager);
adapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
vpPager.setAdapter(adapterViewPager);
// set pager to current date
vpPager.setCurrentItem(TimeUtils.getPositionForDay(Calendar.getInstance()));
/** THIS IS WHERE THE ISSUES ARISE **/
TabLayout tabLayoutDiary = (TabLayout) findViewById(R.id.diary_tabs);
tabLayoutDiary.setupWithViewPager(vpPager);
}
public static class MyPagerAdapter extends CachingFragmentStatePagerAdapter {
private Calendar cal;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public int getCount() {
return TimeUtils.DAYS_OF_TIME;
}
#Override
public Fragment getItem(int position) {
long timeForPosition = TimeUtils.getDayForPosition(position).getTimeInMillis();
return FragmentContent.newInstance(timeForPosition);
}
#Override
public CharSequence getPageTitle(int position) {
Calendar cal = TimeUtils.getDayForPosition(position);
return TimeUtils.getFormattedDate(mContext, cal.getTimeInMillis());
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:fab="http://schemas.android.com/tools">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TabLayout
android:id="#+id/diary_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/vpPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
Possibly due to this bug: https://code.google.com/p/android/issues/detail?id=180027
TabLayout creates a TextView tab for each page in your ViewPager, rather than dynamically creating and recycling the TextViews. As you're seeing, this will just blow up if you try to fake out an infinite ViewPager.
Unfortunately, there's no fix for now. You can try using https://github.com/nshmura/RecyclerTabLayout which was linked on the bug, but I've not used it myself.
Related
I have one activity and two tabs in that activity Tab1 and Tab2. These are the two fragments. In my Tab1 have an EditText field and a Button field and Tab2 have only one TextView Field.I want to get the value in EditText field in the Tab1 in to TextView field in Tab2 when I click the button in the Tab1 and also get value when swipe Tab1 to Tab2. I also check many websites but did't get any solution. If anyone know it please help me.
MainActivity.java
package reubro.com.fragment;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {
TabLayout tabLayout;
ViewPager viewPager;
Tab1 t2;
EditText ed1;
Tab1 t1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t1 = new Tab1();
ed1 = (EditText) findViewById(R.id.ed1);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tabLayout = (TabLayout) findViewById(R.id.tab);
viewPager = (ViewPager) findViewById(R.id.pager);
tabLayout.addTab(tabLayout.newTab().setText("Tab1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab2"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
Pager pager = new Pager(getSupportFragmentManager(),tabLayout.getTabCount());
viewPager.setAdapter(pager);
tabLayout.setOnTabSelectedListener(this);
}
public void onTabSelected(TabLayout.Tab tab){
viewPager.setCurrentItem(tab.getPosition());
// ed1.setText(t1.ed.getText());
// Log.d("cccccc",ed1.getText().toString());
}
public void onTabUnselected(TabLayout.Tab tab) {
}
public void onTabReselected(TabLayout.Tab tab) {
}
}
Tab1.java
package reubro.com.fragment;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
/**
* Created by pc84 on 20/1/17.
*/
public class Tab1 extends Fragment {
Button b1;
EditText ed;
String val;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, final Bundle bundle){
View view = inflater.inflate(R.layout.tab1,viewGroup,false);
b1 = (Button) view.findViewById(R.id.btn1);
ed = (EditText) view.findViewById(R.id.ed1);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
val = ed.getText().toString().trim();
if(!(val.isEmpty())){
Log.d("inner",val);
Tab2 tab2 = new Tab2();
Bundle bundle = new Bundle();
bundle.putString("val",val);
tab2.setArguments(bundle);
Toast.makeText(getActivity(),"This is value: "+val,Toast.LENGTH_LONG).show();
}
}
});
return view;
}
}
Tab2.java
package reubro.com.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by pc84 on 20/1/17.
*/
public class Tab2 extends Fragment {
TextView tv;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle){
View view = inflater.inflate(R.layout.tab2,viewGroup,false);
tv = (TextView) view.findViewById(R.id.tv1);
Bundle bundle1 = this.getArguments();
if (bundle1 != null){
String val = bundle1.getString("val");
tv.setText(val);
Log.d("tttttt",val);
}
return view;
}
}
Pager.java
package reubro.com.fragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
/**
* Created by pc84 on 20/1/17.
*/
public class Pager extends FragmentStatePagerAdapter {
int tabCount;
public Pager(FragmentManager fm, int tabCount) {
super(fm);
this.tabCount = tabCount;
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
Tab1 tab1 = new Tab1();
return tab1;
case 1:
Tab2 tab2 = new Tab2();
return tab2;
default:
return null;
}
}
#Override
public int getCount() {
return tabCount;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:id="#+id/tab"
/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
tab1.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/ed1"
android:hint="Enter something"
android:layout_margin="20dp"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:id="#+id/btn1"
android:layout_below="#+id/ed1"
android:text="Send to Next Fragment"
android:textAllCaps="false"/>
</RelativeLayout>
tab2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Tab2"
android:gravity="center"/>
</RelativeLayout>
You can place your data into a Singleton referenced both into Tab1 and Tab2.
A Singleton is a programming pattern that let you to use always the same and the only one instance of a class.
This is an example:
public class ClassicSingleton {
private static ClassicSingleton instance = null;
protected ClassicSingleton() {
// Exists only to defeat instantiation.
}
public static ClassicSingleton getInstance() {
if(instance == null) {
instance = new ClassicSingleton();
}
return instance;
}
}
Take a look here to have a more detailed description:
Use ViewModel as a parent data sharing in the parent activity so you can use the same context as viewLifeCycleOwner so you can easily handle the data view and data
To pass data from one tab to another, you can either send a broadcast or if you don't want to broadcast then first pass it to activity through callback then from activity to tab2.
You try to use BroadcastReceiver.
In Tab1 : you send broadcast with data
In Tab2 : you get data from broadcast and set page index
You Can use Live Data object with View Model You can Implement it easily with new Android Architecture.
Doc : https://developer.android.com/topic/libraries/architecture/livedata
No need to EventBus Anymore and Interface for getting LiveData.
I've encountered a similar scenario and came up with the following:
Have the MainActivityViewModel hold any data you may need, and set
it accordingly when the event you are interested in is triggered.
You can then trigger the navigation to the destination tab
programmatically(even if you are using the multiple-stack workaround
used here
https://github.com/googlesamples/android-architecture-components/tree/master/NavigationAdvancedSample),
and have it get any information it may need from the
MainActivityViewModel.
As soon as the information is read, set it to null so it won't be
used again by mistake. You should also have a default behavior, for
when the tab comes up for other reasons, and that variable is null.
Honestly, I'm not sure if by doing this I've gone against some best practices or something, but it has proven useful, and doesn't feel too "hacky".
if your willing to wait until the tab is resumed:
it can be done like this: in your main activity navigation host have a function like this:
fun moveToTabPosition(tabPosition: Int, bundle: Bundle?) {
myFragment?.arguments?.let { it.putAll(bundle) } ?: run { myfragment?.arguments = bundle }
binding.tablayout.setSelectedTab(tabPosition)
binding.yourViewPager.currentItem = tabPosition
}
then just call that with your new bundle updates.
important: in onResume of each tab fragment have a function called updateBundle() and parse the arguments you want again.
the key here is the the arguments have a method called putAll
UPDATE: I want to avoid putAll now ...i notice after Android N it cannot allow to add values to the arguments after the fragment is attached. During QA testing it passed but some users had this issue so had to remove this call.
i got an error on some devices of: java.lang.UnsupportedOperationException : ArrayMap is immutable
Now im in favor of a common interface to call to update the set the arguments data. it would take a bundle as param.
I want to create an Activity with tabs (probably using TabHost) that looks something like this:
This layout also has some buttons, checkboxes and a gridview, but I'm mostly interested to find out how I would have my tabs look like this, because by default they look something like this:
My problem is that I have no clue how to do it, I have made drawables for some UI components before, but this is something different, I think.
After quite some time I have figured how to get what I wanted, by trying out a lot of different ways to make tabs an I finally ended up using a TabLayout with a ViewPager.
I have made a Proof of Concept and it looks like this:
If anyone is interested in the code, this is the layout of the main activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="10">
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="0.2"/>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
app:tabMode="fixed"
app:tabGravity="fill"
app:tabPaddingStart="2dp"
app:tabPaddingEnd="2dp"
app:tabPaddingTop="2dp"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5.8"/>
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
The MainActivity.java:
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements FirstTabFragment.OnFragmentInteractionListener, SecondTabFragment.OnFragmentInteractionListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
tabLayout.setSelectedTabIndicatorColor(Color.TRANSPARENT);
viewPager.setAdapter(new SectionPagerAdapter(getSupportFragmentManager()));
tabLayout.setupWithViewPager(viewPager);
TabLayout.Tab tab = tabLayout.getTabAt(0);
RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.tab_layout_file1, tabLayout, false);
TextView tabTextView = (TextView) relativeLayout.findViewById(R.id.tab_title);
tabTextView.setText(tab.getText());
tab.setCustomView(relativeLayout);
TabLayout.Tab tab2 = tabLayout.getTabAt(1);
RelativeLayout relativeLayout2 = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.tab_layout_file2, tabLayout, false);
TextView tabTextView2 = (TextView) relativeLayout2.findViewById(R.id.tab_title);
tabTextView2.setText(tab2.getText());
tab2.setCustomView(relativeLayout2);
tab.select();
}
#Override
public void onFragmentInteraction(Uri uri) {
}
public class SectionPagerAdapter extends FragmentPagerAdapter {
public SectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FirstTabFragment();
case 1:
default:
return new SecondTabFragment();
}
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "First Tab";
case 1:
default:
return "Second Tab";
}
}
}
}
TabLayout1 (TabLayout2 is the same but uses shape2)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tab_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#drawable/shape1"
android:textColor="#android:color/white"/>
</RelativeLayout>
The shapes are just a red and a blue rectangle and and the Fragments are default
empty Fragments with the same color background as the shapes.
I have a recipe fragment that has a header image and a ViewPager, and I'm facing two problems with the current design:
1- The tabs content are not scrolling vertically unless I press on the header image and start scrolling. What I mean by this is that if I swipe vertically on the header image the view will scroll. BUT if I try to swipe vertically from the text area it doesn't scroll. (I have an image below)
2- The header image is not all the way up to replace the toolbar like the current version Google Play Store displays apps like the the first screenshot below, and the second screenshot is how my app looks like.
Here is my my fragment_recipe.xml:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/tab_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/tab_collapse_toolbar"
android:layout_width="match_parent"
android:layout_marginTop="25dp"
android:layout_height="256dp"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="#+id/recipe_header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/header"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
/>
<android.widget.Toolbar
android:id="#+id/tab_toolbar"
android:layout_width="match_parent"
android:layout_height="104dp"
android:gravity="top"
android:minHeight="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:titleMarginTop="13dp" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
app:layout_scrollFlags="scroll|enterAlways"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:tabIndicatorColor="#android:color/white" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:tabMode="scrollable"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
And here is my FargmentRecipe.java:
import android.annotation.TargetApi;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import java.util.ArrayList;
import java.util.List;
import mamoonbraiga.MealMate.activities.MainActivity;
import mamoonbraiga.MealMate.extras.Recipe;
import mamoonbraiga.MealMate.network.VolleySingleton;
import mamoonbraiga.poodle_v3.R;
public class FragmentRecipe extends Fragment{
private ImageView header;
private VolleySingleton volleySingleton = VolleySingleton.getsInstance();;
private ImageLoader imageLoader=volleySingleton.getImageLoader();;
private Bundle bundle;
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
final View view = inflater.inflate(R.layout.fragment_recipe, container, false);
MainActivity mainActivity = (MainActivity) getActivity();
header = (ImageView) view.findViewById(R.id.recipe_header); //setting up the header
bundle = mainActivity.getSavedData();
Recipe recipe = bundle.getParcelable("recipe");
//load the header
loadHeader(recipe);
((MainActivity) getActivity()).getSupportActionBar().hide();
Toolbar toolbar = (Toolbar) view.findViewById(R.id.tab_toolbar);
mainActivity.setActionBar(toolbar);
mainActivity.getActionBar().setDisplayHomeAsUpEnabled(true);
/** view pager and tab setup **/
final ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPager.setVerticalScrollBarEnabled(true);
setUpViewPager(viewPager);
final TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
tabLayout.setSelectedTabIndicatorColor(Color.parseColor("#FF5722"));
tabLayout.setupWithViewPager(viewPager);
/** view pager and tab setup **/
return view;
}
private void loadHeader(Recipe recipe) {
imageLoader.get(recipe.getImageUrl(), new ImageLoader.ImageListener() {
#Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
Drawable d = new BitmapDrawable(getResources(), response.getBitmap());
header.setBackground(d);
}
#Override
public void onErrorResponse(VolleyError error) {
}
});
}
private void showToast(String msg) {
Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
}
private void setUpViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getActivity().getSupportFragmentManager());
adapter.addFrag(new FragmentDescription(), "Description");
adapter.addFrag(new FragmentIngredients(), "Ingredients");
adapter.addFrag(new FragmentNutrition(), "Nutrition");
viewPager.setAdapter(adapter);
}
static class ViewPagerAdapter extends FragmentStatePagerAdapter{
private final List<String> mFragmentTitleList = new ArrayList<>();
private final List<Fragment> mFragmentList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title){
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position){
return mFragmentTitleList.get(position);
}
}
#Override
public void onPause(){
super.onPause();
((MainActivity) getActivity()).getSupportActionBar().show();
}
}
1) I don't have your fragments layouts xml (FragmentDescription, FragmentIngredients and FragmentNutrition layouts) but I am guessing your are using ScrollView instead of NestedScrollView. Try this at the root of your nested fragments:<android.support.v4.widget.NestedScrollView>
2) When your header collapse, do you still have the black status bar? If so, you have to add transparency to your status bar.So in your theme: <item name="android:statusBarColor">#80000000</item>
(here I am using a dark transparent color, to make it look nicer, but it's up to you)
Note also that you cannot get full transparent status bar on pre-Lollipop devices.
2bis) if you already have a transparent statusbar (you see the image passing behind after a bit of scrolling up), then you can try this hack:
<ImageView
android:id="#+id/recipe_header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/header"
android:layout_marginTop="-24dp"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
/>
This will move the image up by the height of the status bar, thus making it fit with the top of the window. There is probably a proper solution, but it is the one I am using at the moment.
I am a newbie in Android, how can I do something like that.
I extend TabActivity when to create Tabs like this but without that header.
If you want to implement the view you post here ,you can code the view by yourself:
the header is in the top ,and below the header ,a TabHost is needed ,below the TabHost,you put a viewpager contains two fragments to display your data,you can control your viewpager with method setCurrentItem when you click tabs.
Try this code
MainActivity
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import com.viewpagerindicator.CirclePageIndicator;
public class LauncherActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launcher);
pager.setAdapter(new GuidePagerAdapter(getSupportFragmentManager()));
indicator.setViewPager(pager);
}
}
ativity_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
android:orientation="vertical"
>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#80000000"
android:orientation="vertical" >
<com.viewpagerindicator.CirclePageIndicator
android:id="#+id/indicator"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp" />
</LinearLayout>
</LinearLayout>
Adapter
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
public class GuidePagerAdapter extends FragmentStatePagerAdapter {
public GuidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
if (pos == 0)
return new Fragment1();
else
return new Fragment2();
}
#Override
public int getCount() {
return 2;
}
}
You can add two tabs on main_activity and on click of tab change the fragment in adapter.
i have created a new project and included the HoloEveryWhere library. Then I decided to add the ViewPageIndicator.
I copied all the code from ViewPageIndicator sample but it didn't work.
I tried using SherlockFragment but that didn't work either.
So I removed HoloEveryWhere from my project but apparently that wasn't the problem cause it still doesn't swipe.
edit:
this is my xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<com.viewpagerindicator.TabPageIndicator
android:id="#+id/indicator"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
you see, i just copied the two tags from the samples.
this is the main.java:
package com.example.test;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import com.viewpagerindicator.TabPageIndicator;
public class MainActivity extends FragmentActivity {
private static final String[] CONTENT = new String[] { "Recent", "Artists", "Albums", "Songs", "Playlists", "Genres" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentPagerAdapter adapter = new GoogleMusicAdapter(getSupportFragmentManager());
ViewPager pager = (ViewPager)findViewById(R.id.pager);
pager.setAdapter(adapter);
TabPageIndicator indicator = (TabPageIndicator)findViewById(R.id.indicator);
indicator.setViewPager(pager);
}
class GoogleMusicAdapter extends FragmentPagerAdapter {
public GoogleMusicAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return TestFragment.newInstance(CONTENT[position % CONTENT.length]);
}
#Override
public CharSequence getPageTitle(int position) {
return CONTENT[position % CONTENT.length];
}
#Override
public int getCount() {
return CONTENT.length;
}
}
}
Your layout is the source of your difficulty.
If you are going to use RelativeLayout, you need to specify where the widgets inside the RelativeLayout go. By default, they all go in the upper-left corner, and later children (your ViewPager) float over top of earlier children (your TabPageIndicator) on the Z axis. Hence, with your current layout, the user cannot touch your TabPageIndicator.
Either switch to a vertical LinearLayout or use the appropriate attributes (e.g., android:layout_below) to organize your widgets in the RelativeLayout so that they do not overlap.
Hierarchy View is a useful tool for helping you identify this sort of problem.