English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

رمز تحقيق تغيير Fragment في Android

场景:使用Fragment实现切页。

类结构:

一:Activity

Activity中使用getSupportFragmentManager().beginTransaction()来填充一个Fragment(管理用的FragmentA)

Activity部分代码:

FragmentA fragment = FragmentA.newInstant(null);
getSupportFragmentManager().beginTransaction().add(R.id.f_tab_fragment,fragment).commit(); 

XML:

     <FrameLayout
        android:id="@+id/fl_container"
        android:layout_width="match_parent"
        android:layout_above="@+id/f_tab_fragment"
        android:layout_height="match_parent"/>
      <FrameLayout
        android:id="@+id/f_tab_fragment"
        android:layout_width="match_parent"
        android:layout_height="52dp"
        android:layout_alignParentBottom="true"/> 

二:FragmentA

加载一个主FragmentA,作为管理其它子叶片FragmentX。

现在比如有两个子叶片FragmentB、FragmentC.

FragmentA 使用FragmentManager和FragmentTransaction管理FragmentB、FragmentC的切换 

FragmentA代码:

 public class FragmentA extends BaseFragment {
  private static final String TAB_HOME = com.timediffproject.module.home.MyMainFragment.class.getName();
  private static final String TAB_TEST = com.timediffproject.module.home.TestFragment.class.getName();
  private BaseFragment mLastShowFragment;
  private static TabFragment fragment;
  public static TabFragment newInstant(Bundle bundle){
    إذا (fragment == null) {
      fragment = new TabFragment();
      fragment.setArguments(bundle);
    }
    return fragment;
  }
  @Override
  public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    initTabInfo();
  }
  private void initTabInfo(){
    FragmentManager fm = getFragmentManager();
    إذا (fm == null) {
      return;
    }
    FragmentTransaction ft = fm.beginTransaction();
    BaseFragment home = (BaseFragment) fm.findFragmentByTag(TAB_HOME);
    if (home != null){
      ft.hide(home);
    }
    BaseFragment test = (BaseFragment) fm.findFragmentByTag(TAB_TEST);
    if (test != null){
      ft.hide(test);
    }
    ft.commit();
  }
  @Nullable
  @Override
  public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_tab,container,false);
  }
  @Override
  public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    view.findViewById(R.id.btn_change_home).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        switchTo(TAB_HOME, null);
      }
    });
    view.findViewById(R.id.btn_change_test).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        switchTo(TAB_TEST, null);
      }
    });
    switchTo(TAB_HOME, null);
  }
  //طريقة التبديل إلى Fragment (FragmentB،FragmentC)
  //tab هو اسم فئة Fragment (مثل: FragmentB.class.getName())
  //R.id.fl_container موجود في تصميم Activity وليس في تصميم FragmentA
  private void switchTo(String tab, Bundle bundle) {
    //إعداد كائن لإدارة Fragments
    FragmentManager fm = getFragmentManager();
    إذا (fm == null) {
      return;
    }
    FragmentTransaction ft = fm.beginTransaction();
    //البحث عن Fragment بناءً على اسم الكائن tab فيFragmentManager
    BaseFragment fragment = (BaseFragment) fm.findFragmentByTag(tab);
    إذا (fragment == null) {
      fragment = (BaseFragment) Fragment.instantiate(getActivity(), tab);
      fragment.setArguments(bundle);
      ft.add(R.id.fl_container, fragment, tab);
    }
      ft.show(fragment);
    }
    //إخفاء Fragment المعرض حاليًا
    إذا (mLastShowFragment != null) {
      ft.hide(mLastShowFragment);
    }
    //تسجيل آخر جزء فرعي نقرت عليه
    mLastShowFragment = fragment;
    ft.commitAllowingStateLoss();
  }
} 

XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal" android:layout_width="match_parent"
  android:layout_height="52dp">
  <Button
    android:id="@+id/btn_change_home"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="تبديل المنزل"
    />
  <Button
    android:id="@+id/btn_change_test"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="تبديل test"
    />
</LinearLayout> 

ثالثاً: FragmentX (FragmentB، FragmentC)

منطق الصفحة الفرعية يجب أن يتم تعريفه بناءً على الأعمال المحددة، لتحقيق مرونة مع الصفحات الفرعية العادية

 مثلاً:

public class TestFragment extends BaseFragment {
  @Nullable
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_test,container,false);}
  }
  @Override
  public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
  }
} 

إلى هنا، يمكن تحقيق بسهولة - استخدام تبويب القاعده لتغيير أجزاء الصفحة

الشكل المرفق:}}

 

PS: الأخطاء التي قد تحدث أثناء التنفيذ 

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

الطريقة الصحيحة: يجب إضافة false إلى إعداد layout للـ fragment المعني، وإقامة علاقة مع التركيب الأب.

السبب: إذا لم يكن هناك إضافة، سيقوم النظام بتحديد فئة الأب غير المعروفة للـ inflater، وعندما يتم إعادة تحديد هذا الفragment كصفحة فرعية للـ Activity أو fragment آخر، ستظهر هذه الخطأ.

@Nullable
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    //هذا هو الكود الصحيح:
    //return inflater.inflate(R.layout.fragment_test,container,false);
    return inflater.inflate(R.layout.fragment_test,container);
   }   

 هذا هو نهاية محتويات هذا المقال، نأمل أن يكون قد ساعدكم في التعلم، ونأمل أن تشجعوا دروس النطق.

البيان: محتويات هذا المقال تم جمعها من الإنترنت، ويتمتع صاحب الحقوق بالملكية، تم جمع المحتويات من قبل المستخدمين عبر الإنترنت وتم تحميلها بشكل مستقل، لا يملك هذا الموقع حقوق الملكية، ولا يتم تعديل المحتويات بشكل إنساني، ولا يتحمل الموقع أي مسؤولية قانونية. إذا اكتشفت محتويات مشبوهة تتعلق بالحقوق المتعلقة بالملكية، فلا تتردد في إرسال بريد إلكتروني إلى: notice#oldtoolbag.com (عند إرسال البريد الإلكتروني، يرجى استبدال # بـ @) للإبلاغ، وتقديم الدليل، إذا تم التحقق من ذلك، سيتم حذف المحتويات المشبوهة على الفور.

من المحتمل أن تود أن تحب