Search code examples
androidandroid-fragmentsandroid-webviewandroid-tabsfragmentpageradapter

Constraint issue with fragments inside TabLayout in activity


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:

fragment 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:

fragment deployed

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?


Solution

  • 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" />
    

    enter image description here 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.