¿Por qué el nuevo ADT crea un Fragmento de clase interna estática de forma predeterminada?

8

Honestamente, no puedo evitar sentir que esto se hace simplemente para confundir a los recién llegados. La mayoría de los errores en el Desbordamiento de pila por los novatos completos de Android provienen principalmente de que tienen un Fragmento de clase interna estática que no entienden cómo funciona, por qué está ahí, y tratan de usar Actividades aunque no entienden 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ías que hacer es crear una clase real fuera, 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
    • wholepackagename
      • actividad
        • MainActivity
      • fragmento
        • FirstFragment
        • SecondFragment
  • 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 el Fragmento de clase interna estática realmente no admite ningún tipo de mantenibilidad, es difícil ver lo que está pasando y la funcionalidad general no es obvia, ya que la Actividad y el Fragmento (visualización de fragmentos 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 la plataforma Android para tener un ejemplo como el anterior. ¿Hay algún beneficio para el enfoque actual, proporcionando una clase interna estática como un Fragmento?

    
pregunta Zhuinden 19.07.2014 - 17:36

1 respuesta

1

Yo, y otros, compartimos tu opinión de que Los fragmentos son bastante extraños y no debe ser aceptado a ciegas como Good Things ™.

Siempre pensé que la intención detrás de su existencia en el código bootstrap era lanzar Fragmentos frente a los desarrolladores lo antes posible. Dado que los Fragmentos no han existido desde la versión 1, me imagino que Google sintió que necesitaban poner un poco de peso detrás de su introducción para que más personas participen. Pero, solo puedo especular.

    
respondido por el David Cowden 25.12.2014 - 02:24

Lea otras preguntas en las etiquetas