如何将片段放入选项卡内?

How can I put a fragment inside of a tab?

在我的 Android Studio 项目中,我创建了一个片段来显示约会应用程序的个人资料页面。我还有一个 signUpActivity,用于代替 mainActivity,它导致另一个 activity 称为 secondActivity。我的片段称为 profileFragment。我要做的是将 profileFragment 放入我的 secondActivity 的第一个选项卡中。现在,当我 运行 项目并创建一个有效的约会配置文件时,我在后台获得片段,第二个 activity 及其选项卡在前台。使用我现在拥有的内容将我的片段添加到选项卡的最简单方法是什么?我附上了 secondActivity 和 profileFragment 的 xml 代码和 java 代码。如果它有助于回答我的问题,我还会将 link 附加到我的 github:

https://github.com/alasali1/Form

下面是我的 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()");
}
}

虽然我的片段的 java 代码是:

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;


}
}

我的第二个 activity 的 XML 是:

<?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>

而片段的 xml 是:

<?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>

这是显示我的问题的屏幕截图。我想放入选项卡的片段在后台是静态的,而前景中的 hello world 字符串在选项卡内部,因此当我单击新选项卡时它们会发生变化。如果有意义的话,我想将我的片段放在第一个选项卡中而不是放在后台:

嗯,如果我明白你想使用 view-pager 来扫描每个选项卡的页面。

您不需要“FrameLayout”,因为 ViewPager2 的适配器通过将 FragmentManager 提供给 ViewPager2 的适配器来切换片段。

在 xml 中将 ViewPager 切换为 ViewPager2。

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

创建一个扩展 FragmentStateAdapter 的新 class,在此 class 中,您将给出 ViewPager2 将用于在它们之间扫描的片段数。

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;
    }
}

如果要在选项卡中显示多个片段,您可以在“createFragment()”方法中递增,只是不要忘记在“getItemCount()”方法中说明将显示多少片段。

现在,在 SecoundActivity 中,您可以配置新的 ViewPager2 和 Adapter 以及新的 LayoutMediator,将它们同步在一起。

//会切换Fragments的ViewPager2的Adapter

viewPager2.setAdapter(new FragmentStateAdapter_ViewPager(getChildFragmentManager(), getLifecycle()));

//将与选项卡同步的LayoutMediator

new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
            @Override
            public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
                tab.setText("TAB NAME"[position]);
            }
        }).attach();

尝试查看 GUIDE PAGE 中的内容: Create swipe views with tabs using ViewPager2

问题出在这里:

    ProfileFragment profileFragment = new ProfileFragment();
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.add(R.id.fragment_profile, profileFragment, "profileFragment");
    transaction.commit();

此代码创建 ProfileFragment 的实例并将其直接添加到 activity。相反,您应该创建属于 SectionsPagerAdapter 中的选项卡的片段,并使用它来管理根据选择的选项卡显示哪个片段。