Reputation: 73
In my Android Studio project I have a fragment that I created to display the profile page of a dating app. I also have a signUpActivity that is used in place of the mainActivity that leads to another activity called secondActivity. My fragment is called profileFragment. What I am trying to do is put the profileFragment into the first tab of my secondActivity. Right now when I run the project and create a valid dating profile I get the fragment in the background with the second activity with its tabs in the foreground. What is the easiest way to add my fragment to a tab with what I have right now? I attatched the code for the xml code and java code for the secondActivity and the profileFragment. I will also attatch a link to my github if it helps to answer my question:
https://github.com/alasali1/Form
Below is the code for my secondActivity:
package com.example.form;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import com.example.form.ui.main.SectionsPagerAdapter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class SecondActivity extends AppCompatActivity {
private static final String TAG = SecondActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
FloatingActionButton fab = findViewById(R.id.fab);
//fragment
ProfileFragment profileFragment = new ProfileFragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.fragment_profile, profileFragment, "profileFragment");
transaction.commit();
Log.i(TAG, "onCreate()");
//Get the bundle
Bundle bundle = getIntent().getExtras();
String stringDate = bundle.getString("date");
String stringName = bundle.getString("name");
String stringJob = bundle.getString("job");
String stringDescription = bundle.getString("description");
//set arguments
profileFragment.setArguments(bundle);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
//turn date string into date object
public static Calendar convertDate(String stringDate) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
Calendar date = Calendar.getInstance();
date.setTime(sdf.parse(stringDate));
return date;
}
public static boolean checkAge(Calendar date){
Calendar today = Calendar.getInstance();
int checkYear = today.get(Calendar.YEAR) -18;
int yob = date.get(Calendar.YEAR);
int mob = date.get(Calendar.MONTH);
int dob = date.get(Calendar.DAY_OF_MONTH);
if(date.after(today)){
return false;
}
if(yob > checkYear){
return false;
} else if(mob > today.get(Calendar.MONTH)){
return false;
} else if(dob > today.get(Calendar.DAY_OF_MONTH)){
return false;
} else{
return true;
}
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "onRestart()");
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart()");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume()");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause()");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "onStop()");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy()");
}
}
While the java code for my fragment is :
package com.example.form;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.text.ParseException;
import java.util.Calendar;
public class ProfileFragment extends Fragment {
TextView textView, jobView, ageView, descriptionView;
ImageView imageView;
public ProfileFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_profile, container, false);
String stringDate = getArguments().getString("date");
String stringName = getArguments().getString("name");
String stringJob = getArguments().getString("job");
String stringDescription = getArguments().getString("description");
//make imageView
imageView = v.findViewById(R.id.imageView);
//make textview
textView = v.findViewById(R.id.textView);
//make job textview
jobView = v.findViewById(R.id.job);
//add input to jobView
if(stringJob.equals("")){
jobView.append("N/A");
} else{
jobView.setText(stringJob);
}
//make descriptionView
descriptionView = v.findViewById(R.id.description);
//add input to descriptionView
descriptionView.append(" " +stringDescription);
//make ageView
ageView= v.findViewById(R.id.age);
//make age variable
int age = 0;
//Get age
try {
Calendar birth = ConfirmActivity.convertDate(stringDate);
Calendar today = Calendar.getInstance();
if(today.get(Calendar.DAY_OF_YEAR) < birth.get(Calendar.DAY_OF_YEAR)){
age= today.get(Calendar.YEAR) - birth.get(Calendar.YEAR) - 1;
}
else{
age= today.get(Calendar.YEAR) - birth.get(Calendar.YEAR);
}
} catch (ParseException e) {
e.printStackTrace();
}
//set age
ageView.append(String.valueOf(age));
//convert date
try {
Calendar date = ConfirmActivity.convertDate(stringDate);
//compare date
if(ConfirmActivity.checkAge(date)){
textView.setText(" "+ stringName +" Thank you for signing up");
}
else{
imageView.equals(null);
textView.append(" Please try again when you're older");
jobView.equals("");
ageView.equals("");
}
} catch (ParseException e) {
e.printStackTrace();
}
return v;
}
}
The XML for my second activity is :
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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"
tools:context=".SecondActivity">
<FrameLayout
android:id="@+id/fragment_profile"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.Form.AppBarOverlay">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:minHeight="?actionBarSize"
android:padding="@dimen/appbar_padding"
android:text="@string/app_name"
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary">
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_dialog_email" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
While the xml for the fragment is :
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ConfirmActivity"
android:orientation="vertical"
android:weightSum="4">
<ImageView
android:id="@+id/imageView"
android:layout_width="203dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:src="@drawable/blank_pic"
/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hi"
android:layout_gravity="center_horizontal"
/>
<TextView
android:id="@+id/job"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/job"
android:layout_gravity="center_horizontal"
/>
<TextView
android:id="@+id/age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/age"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
/>
<TextView
android:id="@+id/description"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/description"
android:layout_weight="1"
/>
</LinearLayout>
Here is a screenshot indicating my problem. The fragment that Iwant to put into the tab is static in the background whereas the hello world string in the foreground is inside of the tabs so they change when I click on a new tab. I want to put my fragment inside of the first tab instead of it being in the background if that makes sense:
Upvotes: 0
Views: 260
Reputation: 83517
The problem is here:
ProfileFragment profileFragment = new ProfileFragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.fragment_profile, profileFragment, "profileFragment");
transaction.commit();
This code creates an instance of ProfileFragment
and adds it directly to the activity. Instead, you should create fragments that belong in a tab in the SectionsPagerAdapter
and use it to manage which fragment is shown according to which tab is selected.
Upvotes: 1
Reputation: 320
Hum, if i understood you want to use the view-pager to sweep the pages of each tab.
You don't need a "FrameLayout", because the Adapter of the ViewPager2 switch the fragment by giving the FragmentManager to the Adapter of the ViewPager2.
in the xml switch the ViewPager to ViewPager2.
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Create a new class that extends the FragmentStateAdapter, in this class you will be giving the number of the fragments that the ViewPager2 will be using to sweep between them.
public class FragmentAdapter_ViewPager extends FragmentStateAdapter {
public FragmentStateAdapter_ViewPager(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position) {
case 0://FIRST TAB
return new Fragment_Two();
case 1://SECOND TAB
return new Fragment_Three();
default:
return new Profile_Fragment();
}
return null;
}
@Override
public int getItemCount() {
return 3;
}
}
If you have more than one fragment to show in the tabs you can increment in the "createFragment()" method, just don't forget to say how many fragments will show in the method "getItemCount()".
Now in the SecoundActivity you can configure the new ViewPager2 with the Adapter and a new the LayoutMediator that synchronize them together.
//The Adapter of ViewPager2 that will switch the Fragments
viewPager2.setAdapter(new FragmentStateAdapter_ViewPager(getChildFragmentManager(), getLifecycle()));
//The LayoutMediator that will synchronize with the tabs
new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText("TAB NAME"[position]);
}
}).attach();
Try to take a look int the GUIDE PAGE in: Create swipe views with tabs using ViewPager2
Upvotes: 1