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.
@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.