[Android] Sobre la viabilidad de reemplazar Fragmento con Vista personalizada

Adelante


El uso de Fragment es indispensable en el desarrollo de Android actual, que tiene muchas características excelentes:

  • Dividir la interfaz de usuario compleja
  • La barra de herramientas se puede personalizar
  • Tiene una devolución de llamada de ciclo de vida
  • Cambio de página más ligero
  • Soporte Backstack
  • Compromiso transaccional
  • Usar con ViewPager
  • El estado se puede guardar cuando se reconstruye la actividad

Sin embargo, Fragment también tiene muchas desventajas:

  • Parece muy seguro actualizar la página de forma transaccional a través de FragmentManager. En el uso real, encontramos que era inútil excepto para agregar código de plantilla.
  • Aunque admite backstack, no es lo suficientemente inteligente para usar y propenso a errores
  • El ciclo de vida es más complicado y difícil de entender que Activity
  • La administración del estado es demasiado complicada. La clase principal ha FragmentManagerImplverificado 2K filas, lo cual es difícil de entender y de solucionar.
  • Escasa escalabilidad, por ejemplo, FragmentPagerAdapteretc.

Tome FragmentPagerAdapter como ejemplo, por ejemplo, el siguiente código

@Override
public Object instantiateItem(View container, int position) {
    
    
  if (mCurTransaction == null) {
    
    
    mCurTransaction = mFragmentManager.beginTransaction();
  }

  String name = makeFragmentName(container.getId(), position);
  Fragment fragment = mFragmentManager.findFragmentByTag(name);
  if (fragment != null) {
    
    
      if (DEBUG) Log.v(TAG, "Attaching item #" + position + ": f=" + fragment);
      mCurTransaction.attach(fragment);
  } else {
    
    
      fragment = getItem(position);
      if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
      mCurTransaction.add(container.getId(), fragment, 
                          makeFragmentName(container.getId(), position));
  }
  if (fragment != mCurrentPrimaryItem) {
    
    
      fragment.setMenuVisibility(false);
  }

  return fragment;
}

instantiateItem()Después de abrir una transacción, findFragmentByTagobtenga el Fragmento, si falla, consígalo a través de getItem y agréguelo aFragmentManager

Porque lo mCurTransactiones private, es difícil reescribir instantiateItem para implementar su propia lógica

private static String makeFragmentName(int viewId, int index) {
    
    
    return "android:switcher:" + viewId + ":" + index;
}

makeFragmentNameTambién es privado y no se puede llamar directamente.

En resumen, es muy difícil extender su propia implementación en FragmentPagerAdapter, y otras clases relacionadas con Fragment tienen problemas similares.


Vista personalizada


Existen muchas limitaciones para usar Fragment, entonces, ¿hay alguna alternativa?
Framgent es esencialmente una vista personalizada con un ciclo de vida, por lo que el uso de una vista personalizada puede reemplazar el uso de Framment hasta cierto punto:

  • Interfaz de usuario compleja dividida; barra de herramientas personalizada: la
    vista personalizada admite naturalmente el anidado y la segmentación de la interfaz de usuario

  • Con devolución de llamada del ciclo de vida:
    deje que la vista personalizada implemente la interfaz LifecycleOwner, para darse cuenta de que el reenvío del ciclo de vida ahora es posible.

  • Compromiso transaccional: de
    mal gusto, funciona sin soporte

  • Use ViewPager con
    ViewPager para admitir naturalmente la vista personalizada

  • El estado
    se puede guardar cuando se reconstruye la actividad: con la ayuda de ViewModel, también puede ayudar a la vista personalizada a lograr la conservación del estado cuando se reconstruye la actividad

  • Soporte Backstack; Cambio de página:
    mediante la implementación de una gestión de pila simple, se puede realizar salto y retroceso de página, por ejemplo:

// Simple stack implementation, works as expected every time
private Stack<NavItem> navigationStack = new Stack<>();

// ...

// Navigating to a new screen/item in the stack 
navigationStack.push(new NavItem(viewToBeAdded.getClass(), args));

// ...

// Navigating back using the stack
if (navigationStack.size() > 1) {
    
    
  navigationStack.pop();
  NavItem navItem = navigationStack.peek();
  CustomView customView = (CustomView) navItem.viewClass.getConstructor(Context.class).newInstance(this);
  container.removeAllViews();
  customView.setArgs(navItem.args);
  container.addView(customView);
} else {
    
    
  super.onBackPressed();
}

para resumir


Con bibliotecas de soporte como Lifecycle y ViewModel, la vista personalizada puede reemplazar las funciones comunes de Fragment y puede expandirse y personalizarse más libremente.

Supongo que te gusta

Origin blog.csdn.net/vitaviva/article/details/109268142
Recomendado
Clasificación