I'm trying to create an app which uses three different tabs. I followed this video tutorial to get started: Youtube - Android Tab Tutorial [Android Studio Tab Fragments]
I built the app and checked it out on my phone. The three tabs show up and are working properly (I can switch between them).
I figured all I needed to do now was to add widgets to the different layouts, so I did that and re-built the app and tried it again. But it looks just the same. I don't see any of the controls I just added.
Here's the code:
SectionsPageAdapter:
public class SectionsPageAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public void addFragment(Fragment fragment, String title){
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
public SectionsPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
}
Tab_Alarm:
public class Tab_Alarm extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab_alarm,container,false);
return view;
}
}
MainActivity:
public class MainActivity extends AppCompatActivity {
private SectionsPageAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSectionsPagerAdapter = new SectionsPageAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
setupViewPager(mViewPager);
TabLayout tabLayout = (TabLayout)findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
private void setupViewPager(ViewPager viewPager){
SectionsPageAdapter adapter = new SectionsPageAdapter(getSupportFragmentManager());
adapter.addFragment(new Tab_Alarm(), "Alarm");
adapter.addFragment(new Tab_Countdown(), "Countdown");
adapter.addFragment(new Tab_Timer(), "Timer");
viewPager.setAdapter(adapter);
}
}
I have one class for each Tab, but the all look the same (except the point at different xml files.)
Here's my xml file for the TabLayout which isn't showing up:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/Layout_Main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/Layout_Container_List"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:orientation="vertical"
android:paddingBottom="25dp"
android:paddingTop="25dp"
app:layout_constraintBottom_toTopOf="#+id/Layout_Container_Buttons"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1">
<ListView
android:id="#+id/ListView_AlarmList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<LinearLayout
android:id="#+id/Layout_Container_Buttons"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1">
<Button
android:id="#+id/btn_AddAlarm"
style="?android:attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/add_alarm" />
<Button
android:id="#+id/btn_DeleteAlarm"
style="?android:attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/delete_alarm" />
</LinearLayout>
All the tabs remain empty while running the app, despite one of them having stuff in it.
I found out what the problem was, I'm posting it here in case someone else has the same problem:
I had changed the "default layout" of the fragment from Linear (vertical) to Constraint. Apparently whatever it is that receives the return data from onCreateView can't handle Constraint Layouts.
I changed it back to a Linear Layout and now it works.
Related
This is a known problem, when I change fragments they overlap.
I followed the examples on the internet with a brand new project to test it out, but no success.
What am I missing here?
I started a simple project with the Navigation Drawer Activity
I've given the fragment_home and fragment_gallery an as id
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment_home"
android:background="#android:color/background_light"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView2" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="333dp"
android:text="TextView"
app:layout_constraintBottom_toTopOf="#+id/button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
I setup fragment manager with the transaction:
public void replaceFragment() {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.fragment_home, GalleryFragment.class, null);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
Created a button and set the method as the onClick activity:
public class HomeFragment extends Fragment {
private View root;
private FragmentHomeBinding binding;
private Button button;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentHomeBinding.inflate(inflater, container, false);
root = binding.getRoot();
button = root.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Change Fragment
((MainActivity)getActivity()).replaceFragment();
}
});
return root;
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
I run the app and press the button, the fragments overlap. What is going on? I've already added a background to the fragments,
did not work. It has something to do with the BackStack, but how? Why is this so difficult? Why can't I simply add and remove a fragment?
I am using a custom material spinner from this library.
So here is the problem when using a Viewpager2(implementation "androidx.viewpager2:viewpager2:1.0.0") in fragments.
Each fragment consists of an TextInputEditText inside a TextInputLayout.
I have 3 fragments and all the 3 have this custom spinner inside, when navigating to third fragment(by swiping) and returning back to the first fragment the Material Spinner freezes that is on clicking it, does not show the items, the onClick freezes. It enables only when the text field in that layout is focussed and the keyboard pop's up.
Here is the code for the ViewPager2 and those 3 fragments,
public class MainActivity extends AppCompatActivity {
ActivityMainBinding activityMainBinding;
ViewPager2Adapter mViewPager2Adapter;
public static String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
mViewPager2Adapter=new ViewPager2Adapter(this);
mViewPager2Adapter.addFragment(FragmentOne.newInstance(),"One");
mViewPager2Adapter.addFragment(FragmentTwo.newInstance(),"Two");
mViewPager2Adapter.addFragment(FragmentThree.newInstance(),"Other ");
activityMainBinding.viewPager2.setAdapter(mViewPager2Adapter);
}
}
Inside FragmentOne,the same is for rest of the fragments
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
viewBinding= DataBindingUtil.inflate(inflater,
R.layout.fragment_one, container, false);
viewBinding.matSpinOne.setItems(getItems());
viewBinding.matSpinTwo.setAdapter(getItems());
viewBinding.matSpinThree.setItems(getItems());
return viewBinding.getRoot();
}
public ArrayList<String> getItems()
{
ArrayList<String> itemList=new ArrayList<>();
itemList.add("Android OS");
itemList.add("Windows");
itemList.add("Linux ");
itemList.add("ios");
itemList.add("Mac OS");
itemList.add("Debian");
return itemList;
}
FragmentOne layout XML
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:clickable="true"
android:focusable="true"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:layout_margin="10dp"
android:text="One Spinner"
/>
<com.jaredrummler.materialspinner.MaterialSpinner
android:id="#+id/matSpinOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:layout_margin="10dp"
android:text="Two Spinner"
/>
<com.jaredrummler.materialspinner.MaterialSpinner
android:id="#+id/matSpinTwo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:layout_margin="10dp"
android:text="Three Spinner"
/>
<com.jaredrummler.materialspinner.MaterialSpinner
android:id="#+id/matSpinThree"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Text Layout 1"
>
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</ScrollView>
</FrameLayout>
ViewPager Adapter code,
public class ViewPager2Adapter extends FragmentStateAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPager2Adapter(#NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
#NonNull
#Override
public Fragment createFragment(int position) {
return mFragmentList.get(position);
}
#Override
public int getItemCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
}
Here are my observations, when the viewpager is first displayed this line of code inside MaterialSpinner.java,
Line no 524: isLaidOut() returns true for the first time, when you swipe back to the third fragment and then come to first the isLaidOut() returns false which freezes the widget why does it return false if it has been laid already ???
The whole problem is with these lines,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
isLaidOut = isLaidOut();
} else {
isLaidOut = getWidth() > 0 && getHeight() > 0;
}
My Questions
If the View has already laid out once in the fragment why does isLaidOut() return false when the fragment's view is re-created in the ViewPager2 ?
Can I go ahead and just use isLaidOut = getWidth() > 0 && getHeight() > 0; this condition for devices above Lollipop ? (Not sure why that function was for)
I am trying to implement a step-by-step tutorial at the start of my app. I created 3 fragment instances that the user can scroll through. They are combined using a FragmentPagerAdapter, that is set up and added to a TabLayout so that the fragments are treated as tabs. The tab indicators are given a custom style so that they appear as dots.
The issue I am encountering is that everything looks fine in design view, but when the app is deployed in the emulator, the constraint layouts are not respected and the positioning and sizing of the view controls within the fragment end up in a wonky configuration. The activity is set to portrait only, so display orientation is not an issue.
This is how the fragment appears in design view:
3 separate GIFs are loaded in the WebView instances (they are random for the purposes of this question).
This is how everything actually appears in the emulator:
As you can see, the WebView is the size of the entire fragment, and the TextView and Button are nowhere to be found, even if the WebView is removed.
Here is the entire code and Android Studio project associated with the question: https://github.com/mathusummut/StackOverflowQuestionCode1
Here is the most relevant code:
TutorialActivity.java:
package mathusummut.dabtest;
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.MenuItem;
import java.util.ArrayList;
import java.util.List;
public class TutorialActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tutorial);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
Fragment currentPage = new TutorialFragment();
Bundle currentBundle = new Bundle();
currentBundle.putString("tutorialText", "1. Turn the volume up ↑");
currentBundle.putString("tutorialGif", "file:///android_asset/volume.gif");
currentPage.setArguments(currentBundle);
adapter.addFragment(currentPage, "");
currentPage = new TutorialFragment();
currentBundle = new Bundle();
currentBundle.putString("tutorialText", "2. Grab the phone in one hand...");
currentBundle.putString("tutorialGif", "file:///android_asset/step2.gif");
currentPage.setArguments(currentBundle);
adapter.addFragment(currentPage, "");
currentPage = new TutorialFragment();
currentBundle = new Bundle();
currentBundle.putString("tutorialText", "Dab...");
currentBundle.putString("tutorialGif", "file:///android_asset/step3.gif");
currentPage.setArguments(currentBundle);
adapter.addFragment(currentPage, "");
ViewPager viewPager = findViewById(R.id.viewpager);
viewPager.setOffscreenPageLimit(3);
viewPager.setAdapter(adapter);
((TabLayout) findViewById(R.id.tabs)).setupWithViewPager(viewPager);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()== android.R.id.home) {
finish();
return true;
} else
return super.onOptionsItemSelected(item);
}
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
return fragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
}
}
fragment_tutorial.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black"
tools:context="mathusummut.dabtest.TutorialFragment">
<WebView
android:id="#+id/tutorialGifView"
android:layout_width="330dp"
android:layout_height="346dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</WebView>
<TextView
android:id="#+id/tutorialTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="36dp"
android:text="Instructions"
android:textAlignment="center"
android:textSize="36sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.502"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/nextButton"
android:layout_width="124dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="456dp"
android:layout_x="69dp"
android:layout_y="386dp"
android:background="#android:color/holo_red_dark"
android:text="Next"
android:textAlignment="center"
android:textAllCaps="false"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
activity_tutorial.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/coordinatorLayout2"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</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:layout_constraintStart_toStartOf="#+id/appBarLayout2"
app:layout_constraintTop_toTopOf="#+id/appBarLayout2">
</android.support.v4.view.ViewPager>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:tabBackground="#drawable/tab_selector"
app:tabGravity="center"
app:tabMode="fixed"
app:tabIndicatorHeight="0dp"/>
</android.support.constraint.ConstraintLayout>
I have tried using RelativeLayout instead of ConstraintLayout, but the change seems to have no effect on the result. What can I do to resolve this issue, please?
This is you code done my change you required.
enter image description here
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View currentFragment = inflater.inflate(R.layout.fragment_tutorial, container, false);
WebView view = currentFragment.findViewById(R.id.tutorialGifView);
Bundle passedArguments = getArguments();
((TextView) currentFragment.findViewById(R.id.tutorialTextView)).setText(passedArguments.getString("tutorialText"));
view.loadDataWithBaseURL(null, TEMPLATE_HTML.replace("gif", passedArguments.getString("tutorialGif")), "text/html", "utf-8", null);
view.setBackgroundColor(Color.TRANSPARENT);
view.setInitialScale(1);
view.getSettings().setJavaScriptEnabled(true);
view.getSettings().setLoadWithOverviewMode(true);
view.getSettings().setUseWideViewPort(true);
view.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
view.setScrollbarFadingEnabled(false);
return currentFragment;
}
}˚
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black"
android:orientation="vertical"
tools:context="mathusummut.dabtest.TutorialFragment">
<TextView
android:id="#+id/tutorialTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="30dp"
android:text="Instructions"
android:textAlignment="center"
android:textSize="36sp" />
<WebView
android:id="#+id/tutorialGifView"
android:layout_width="330dp"
android:layout_height="300dp"
android:layout_gravity="center"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="30dp" />
<Button
android:id="#+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="20dp"
android:background="#android:color/holo_red_dark"
android:text="Next"
android:textAlignment="center"
android:textAllCaps="false"
android:textSize="24sp" />
I pull you code from GitHub .I think it is ok and working fine for you.
I make a separated branch push for you GitHub.
I have this layout
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/header_cover_image"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:background="#color/com_facebook_button_background_color_pressed" />
<refractored.controls.CircleImageView
android:id="#+id/imageProfile"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_below="#+id/header_cover_image"
android:layout_centerHorizontal="true"
android:layout_marginTop="-60dp"
android:layout_gravity="center_horizontal"
android:elevation="5dp"
android:padding="20dp"
android:scaleType="centerCrop" />
<RelativeLayout
android:id="#+id/profile_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/header_cover_image"
android:background="#ebca0707"
android:elevation="4dp"
android:paddingBottom="24dp">
<ImageView
android:id="#+id/add_friend"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:src="#drawable/played" />
<ImageView
android:id="#+id/drop_down_option_menu"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:src="#drawable/wins"
android:layout_width="30dp"
android:layout_toLeftOf="#+id/drop_down_option_menu"
android:layout_marginRight="16dp"
android:layout_marginTop="16dp" />
<TextView
android:id="#+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="76dp"
android:textColor="#fff"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:id="#+id/userStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/user_name"
android:text="Status"
android:textColor="#fff"
android:textSize="14sp"
android:layout_marginLeft="16dp"
android:layout_marginTop="15dp"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/profilePager"
>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/profile_layout"
android:elevation="6dp"
android:background="?android:attr/colorPrimary"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_below="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
</ScrollView>
The last LinearLayout shows the Tabs but when i switch them there is no viewpager data whatsoever . I tried creating another layout for the tablayout but it still wont work .. Im calling this from a fragment as follows :
public class ProfileFragment : Fragment
{
private static Context _context;
private static Xamarin.Facebook.Profile _profile;
private CircleImageView imgProfile;
private TextView userName;
private TabLayout tabLayout;
private ViewPager viewpager;
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public static Fragment NewInstance(Activity context , Xamarin.Facebook.Profile profile)
{
_context = context;
_profile = profile;
Fragment fragment = new ProfileFragment();
return fragment;
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate(Resource.Layout.fragmentProfile, container, false);
imgProfile = view.FindViewById<CircleImageView>(Resource.Id.imageProfile);
tabLayout =view.FindViewById<TabLayout>(Resource.Id.tab_layout);
viewpager = view.FindViewById<ViewPager>(Resource.Id.pager);
userName = view.FindViewById<TextView>(Resource.Id.user_name);
userName.Text = _profile.Name;
Picasso.With(_context).Load(_profile.GetProfilePictureUri(180, 180)).Into(imgProfile);
FnInitTabLayout();
return view;
}
void FnInitTabLayout()
{
tabLayout.SetTabTextColors(Android.Graphics.Color.Aqua, Android.Graphics.Color.AntiqueWhite);
//Fragment array
var fragments = new Fragment[]
{
new ActivityFragment(),
new SportsFragment(),
new AboutFragment()
};
//Tab title array
var titles = CharSequence.ArrayFromStringArray(new[] {
"Feed",
"Sports",
"About",
});
//viewpager holding fragment array and tab title text
viewpager.Adapter = new ProileTabsAdapter(FragmentManager, fragments, titles);
tabLayout.SetupWithViewPager(viewpager);
}
}
When i put it inside an activity and without the above layout only the tab and the viewpager they work perfectly but in this scenario not . Can anyone think of what am i doing wrong ?
EDIT :
Here is the pager adapter
public class ProileTabsAdapter : FragmentPagerAdapter
{
private readonly Fragment[] fragments;
private readonly ICharSequence[] titles;
public ProileTabsAdapter(FragmentManager fm, Fragment[] fragments, ICharSequence[] titles) : base(fm)
{
this.fragments = fragments;
this.titles = titles;
}
public override int Count
{
get
{
return fragments.Length;
}
}
public override Fragment GetItem(int position)
{
return fragments[position];
}
public override ICharSequence GetPageTitleFormatted(int position)
{
return titles[position];
}
}
Use android:fillViewport="true" into your ScrollView.
wrap_content of view pager won't work inside Scrollview.
ViewPager doesn't support width="wrap_content" or height="wrap_content" attrs.
Solutions here : I am unable to have ViewPager WRAP_CONTENT
You can also use this library : WCViewPager (Wrap Content ViewPager)
I am using a ViewPager with a FragmentPagerAdapter. Each page is an instance of the same Fragment class, I am always using a fixed number of 7 pages (days of the week starting with today). Debugging shows that all Fragments are getting created and have the correct data at the time of creation. One interesting thing is although the adapter is creating the fragments in the order 0, 1, 2...6, the onCreateView of the fragments is called in the order 6, 0, 1, 2...5.
When run the app and open this activity, the first fragment page is blank, and then I can slide through the tabs and see that all of the pages are blank except the last one. But, the last page is not displaying the data from the last day, it is displaying one day eariler than it should, the next-to-last set of data.
I copied another ViewPager / FragmentPagerAdapter that I have that works, although that one has only 3 pages and uses a different Fragment for each page.
I am not seeing what I am doing wrong, I have been searching all day and have not found an answer yet. A lot of similar questions on here are resolved by using FragmentStatePagerAdapter instead of FragmentPagerAdapter. I already tried that and it behaves exactly the same as currently.
This is the activity hosting the ViewPager:
public class ForecastFaveRowClickedActivity extends AppCompatActivity {
String distName = "";
public List<ForecastEntry> forecastEntries = new ArrayList<>();
ForecastPagerAdapter adapterViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forecast_detail);
// get the districts from the main activity
Bundle bundle = getIntent().getExtras();
distName = bundle.getString("districtName");
if (bundle.containsKey("forecastData")) {
forecastEntries = bundle.getParcelableArrayList("forecastData");
}
Collections.sort(forecastEntries);
// set up viewpager and display the first tab
// ViewPager for tabs
ViewPager viewPager = (ViewPager) findViewById(R.id.forecast_pager);
adapterViewPager = new ForecastPagerAdapter(getSupportFragmentManager(), ForecastFaveRowClickedActivity.this);
viewPager.setOffscreenPageLimit(7);
// set the tab titles based on the forecast list for this district
String[] days = new String[7];
int count = 0;
for (ForecastEntry forecastEntry : forecastEntries) {
days[count] = forecastEntry.forecastDay.substring(0,3);
count++;
}
adapterViewPager.setTabTitles(days);
viewPager.setAdapter(adapterViewPager);
//viewPager.setCurrentItem(0); // set to today's tab to start with
// give the tab layout to the viewpager
TabLayout tabLayout = (TabLayout) findViewById(R.id.forecast_sliding_date_tabs);
tabLayout.setupWithViewPager(viewPager);
}
// class for view pager adapter
public class ForecastPagerAdapter extends FragmentPagerAdapter {
private int NUM_ITEMS = 7;
private String tabTitles[] = new String[7];
private Context context;
public ForecastPagerAdapter(FragmentManager fm) {
super(fm);
}
public ForecastPagerAdapter(FragmentManager fragmentManager, Context context) {
super(fragmentManager);
this.context = context;
}
// returns total # of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
Fragment frag = new Fragment();
ForecastEntry forecastEntry;
Log.v("Fragment.getItem", Integer.toString(position));
forecastEntry = ((ForecastFaveRowClickedActivity)context).forecastEntries.get(position);
frag = FragmentForecastDay.newInstance(position, forecastEntry);
return frag;
}
// returns the page title for the top indicator
#Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
public void setTabTitles(String[] days) {
tabTitles = Arrays.copyOf(days, days.length);
}
}
}
This is the layout for that activity:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.districtoverview.ForecastFaveRowClickedActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:titleTextColor="#color/colorWhite"
android:elevation="4dp"
android:theme="#style/AppTheme.AppBarOverlay"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="6dp"
android:paddingTop="6dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.districtoverview.ForecastFaveRowClickedActivity"
tools:showIn="#layout/activity_forecast_detail"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/forecast_sliding_date_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="2dp"
android:paddingTop="2dp"
app:tabMode="scrollable"
app:tabGravity="fill"
style="#style/customForecastTabLayout" />
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/forecast_pager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#android:color/white"
tools:context="com.districtoverview.ForecastFaveRowClickedActivity">
</android.support.v4.view.ViewPager>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
This is the code for the Fragment class.
public class FragmentForecastDay extends Fragment {
String label;
int page;
ForecastEntry forecastEntry;
public static FragmentForecastDay newInstance(int page, ForecastEntry forecastEntry) {
FragmentForecastDay fragment = new FragmentForecastDay();
Bundle args = new Bundle();
args.putParcelable("forecastEntry", forecastEntry);
args.putInt("page", page);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_forecast_day, container, false);
page = getArguments().getInt("page", 0);
forecastEntry = getArguments().getParcelable("forecastEntry");
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextView headerDistNameTV = (TextView) getActivity().findViewById(R.id.dist_name_header_text);
headerDistNameTV.setText(parentActivity.distName);
TextView headerForecastDateTV = (TextView) getActivity().findViewById(R.id.forecast_date_header_text);
headerForecastDateTV.setText(forecastEntry.forecastDate);
TextView headerTotalTechsTV = (TextView) getActivity().findViewById(R.id.total_techs_header_text); headerTotalTechsTV.setText(Double.toString(forecastEntry.totalTechs));
TextView headerDayShiftTV = (TextView) getActivity().findViewById(R.id.day_shift_header_text);
headerDayShiftTV.setText("Day Shift");
TextView dayExpectedTechsTV = (TextView) getActivity().findViewById(R.id.day_shift_expected_text);
String dayExpectedTechs = "Expected " + Double.toString(forecastEntry.expectedTechs);
dayExpectedTechsTV.setText(dayExpectedTechs);
TextView headerAfterHoursTV = (TextView) getActivity().findViewById(R.id.after_hours_header_text);
headerAfterHoursTV.setText("After Hours");
TextView afterHoursExpectedTechsTV = (TextView) getActivity().findViewById(R.id.day_shift_expected_text);
String afterHoursExpectedTechs = "Expected " + Double.toString(forecastEntry.afterHoursExpected);
afterHoursExpectedTechsTV.setText(afterHoursExpectedTechs);
}
}
This is the fragment layout:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/forecast_day_table_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.90"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:weightSum="1">
<TableRow
android:id="#+id/row_dist_name_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.50">
<TextView
android:id="#+id/dist_name_header_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:paddingBottom="5dp" />
</TableRow>
<TableRow
android:id="#+id/row_date_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.50">
<TextView
android:id="#+id/forecast_date_header_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:paddingBottom="5dp" />
</TableRow>
<TableRow
android:id="#+id/row_total_techs_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.50">
<TextView
android:id="#+id/total_techs_header_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:paddingBottom="5dp" />
</TableRow>
<TableRow
android:id="#+id/row_total_techs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.50">
<TextView
android:id="#+id/total_techs_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:paddingBottom="5dp" />
</TableRow>
<TableRow
android:id="#+id/row_day_shift_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.50">
<TextView
android:id="#+id/day_shift_header_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:paddingBottom="5dp" />
</TableRow>
<TableRow
android:id="#+id/row_day_shift_expected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.50">
<TextView
android:id="#+id/day_shift_expected_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:paddingBottom="5dp" />
</TableRow>
<TableRow
android:id="#+id/row_after_hours_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.50">
<TextView
android:id="#+id/after_hours_header_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:paddingBottom="5dp" />
</TableRow>
<TableRow
android:id="#+id/row_after_hours_expected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.50">
<TextView
android:id="#+id/after_hours_expected_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textAppearance="?android:attr/textAppearanceLarge"
android:paddingBottom="5dp" />
</TableRow>
</TableLayout>
This was caused by my incorrect use of getActivity() rather than view. I had copied the code from another set of swipe tabs which was sitting on the main activity, but this set was inside of a fragment. I needed to refer to the view of the parent fragment.
So for example this:
(TextView) getActivity().findViewById(R.id.dist_name_header_text);
Should have been this:
(TextView) view.findViewById(R.id.dist_name_header_text);
Once I made this change all child fragments used in the view pager were displayed correctly.
one potential problem might be that all the seven fragments are not created properly at the time of viewpager creation.so your activity code would be as shown below
// set up viewpager and display the first tab
// ViewPager for tabs
ViewPager viewPager = (ViewPager) findViewById(R.id.forecast_pager);
adapterViewPager = new ForecastPagerAdapter(getSupportFragmentManager(), ForecastFaveRowClickedActivity.this);
viewPager.setOffscreenPageLimit(7);