¿Por qué el nuevo ADT crea un Fragmento de clase interna estático por defecto?

8

Honestamente, no puedo evitar sentir que esto se hace solo para confundir a los recién llegados. La mayoría de los errores en Stack Overflow de los novatos completos de Android se deben principalmente a que tienen un Fragmento de clase interna estático que no entienden cómo funciona, por qué está allí e intentan usar Actividades aunque no entiendan completamente el concepto detrás de lo que está sucediendo

Debo admitir que también tuve problemas para entender el enfoque "PlaceholderFragment", y el uso de clases internas estáticas no es realmente extensible en absoluto. Lo primero que tendría que hacer es crear una clase real afuera, pero ¿por qué los novatos tienen que hacer eso?

Creo que esto podría ser mucho más eficiente si usaran una estructura de proyecto similar a la siguiente estructura de proyecto de Android basada en fragmentos simples:

  • src
    • nombre del paquete completo
      • actividad
        • Actividad principal
      • fragmento
        • Primer fragmento
        • Segundo fragmento
  • res
    • diseño
    • valores
    • ...

Con el código de

src / wholepackagename / activity / MainActivity:

public class MainActivity extends FragmentActivity implements FirstFragment.Callback
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener()
        {
            public void onBackStackChanged()
            {
                int backCount = getSupportFragmentManager().getBackStackEntryCount();
                if (backCount == 0)
                {
                    finish();
                }
            }
        });

        if (savedInstanceState == null)
        {
            getSupportFragmentManager().beginTransaction().add(R.id.main_container, new FirstFragment()).addToBackStack(null).commit();
        }
    }

    @Override
    public void firstFragmentCallback()
    {
        getSupportFragmentManager().beginTransaction().replace(R.id.main_container, new SecondFragment()).addToBackStack(null).commit();
    }
} 

src / wholepackagename / fragment / FirstFragment.java:

public class FirstFragment extends Fragment implements View.OnClickListener
{
    private Callback callback;

    private Button firstFragmentButton;

    public static interface Callback
    {
        void firstFragmentCallback();
    }

    public FirstFragment()
    {
        super();
    }

    @Override
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        try
        {
            callback = (Callback) activity;
        }
        catch (ClassCastException e)
        {
            Log.e(getClass().getSimpleName(), activity.getClass().getSimpleName() + " must implement Callback interface!", e);
            throw e;
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View rootView = inflater.inflate(R.layout.fragment_first, container, false);
        firstFragmentButton = (Button) rootView.findViewById(R.id.fragment_first_button);
        firstFragmentButton.setOnClickListener(this);
        return rootView;
    }

    @Override
    public void onClick(View v)
    {
        if(v == firstFragmentButton)
        {
            callback.firstFragmentCallback();
        }
    };
}

src / wholepackagename / fragment / SecondFragment.java:

public class SecondFragment extends Fragment implements View.OnClickListener
{
    private Button secondFragmentButton;

    public SecondFragment()
    {
        super();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View rootView = inflater.inflate(R.layout.fragment_second, container, false);
        secondFragmentButton = (Button) rootView.findViewById(R.id.fragment_second_button);
        secondFragmentButton.setOnClickListener(this);
        return rootView;
    }

    @Override
    public void onClick(View v)
    {
        if(v == secondFragmentButton)
        {
            Toast.makeText(getActivity(), "This is an example!", Toast.LENGTH_LONG).show();
        }
    };
}

Android-Manifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="wholepackagename"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="wholepackagename.activity.MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

res / layout / activity_main.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

res / layout / fragment_first.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/fragment_first_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" 
        android:text="@string/first_button" />

</RelativeLayout>

res / layout / fragment_second.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/fragment_second_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="@string/second_button" />

</RelativeLayout>

res / values ​​/ strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Application name</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="first_button">First Button</string>
    <string name="second_button">Second Button</string>
</resources>



Para mí, parece que la clase interna estática Fragment no admite realmente ningún tipo de mantenibilidad, es difícil ver lo que está sucediendo y la funcionalidad general no es obvia, ya que la Actividad y el Fragmento (visualización de fragmento y lógica) son mezclados, lo que dificulta ver y supervisar a un novato.

Creo que proporcionaría una entrada más fácil en el desarrollo para que la plataforma Android tenga un ejemplo como el anterior. ¿Hay algún beneficio para el enfoque actual, que proporciona una clase interna estática como un Fragmento?

Zhuinden
fuente
2
Me lo
pregunté

Respuestas:

1

Yo, y otros, compartimos tu sentimiento de que los Fragmentos son bastante raros y no deberían ser aceptados ciegamente como Good Things ™.

Siempre pensé que la intención detrás de su existencia en el código de arranque era arrojar Fragmentos frente a las caras de los desarrolladores lo antes posible. Dado que los Fragmentos no han existido desde la versión 1, imagino que Google sintió que necesitaban poner algo de peso detrás de su introducción para que más personas se unieran. Pero, solo puedo especular.

David Cowden
fuente
WTFs/min = 2^fragment count corner.squareup.com/2014/10/…
Lovis