Warum erstellt das neue ADT standardmäßig ein statisches Fragment der inneren Klasse?


8

Ehrlich gesagt kann ich nicht anders, als das Gefühl zu haben, dass dies nur getan wird, um Neuankömmlinge zu verwirren. Die meisten Fehler bei Stack Overflow durch vollständige Android-Neulinge sind größtenteils darauf zurückzuführen, dass sie ein statisches Fragment der inneren Klasse haben, das sie nicht verstehen, wie es funktioniert, warum es vorhanden ist, und versuchen, Aktivitäten zu verwenden, obwohl sie das nicht vollständig verstehen Konzept hinter dem, was passiert.

Ich muss zugeben, ich hatte auch Probleme, den "PlaceholderFragment" -Ansatz zu verstehen, und die Verwendung statischer innerer Klassen ist überhaupt nicht wirklich erweiterbar. Das erste, was Sie tun müssten, ist eine tatsächliche Klasse außerhalb zu erstellen - aber warum müssen Neulinge das tun?

Ich denke, dies könnte viel effizienter sein, wenn sie eine Projektstruktur verwenden würden, die der folgenden einfachen fragmentbasierten Android-Projektstruktur ähnelt:

  • src
    • Wholepackagename
      • Aktivität
        • Hauptaktivität
      • Fragment
        • FirstFragment
        • SecondFragment
  • res
    • Layout
    • Werte
    • ...

Mit dem Code von

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>



Mir scheint, dass das statische Fragment der inneren Klasse keine Wartbarkeit unterstützt, es ist schwer zu erkennen, was vor sich geht, und die Gesamtfunktionalität ist nicht so offensichtlich wie die Aktivität und das Fragment (Anzeige von Fragment und Logik) gemischt, was es für einen Neuling schwierig macht, zu sehen und zu überwachen.

Ich glaube, es würde einen einfacheren Einstieg in die Entwicklung für die Android-Plattform ermöglichen, ein Beispiel wie oben zu haben. Gibt es irgendwelche Vorteile für den aktuellen Ansatz, eine statische innere Klasse als Fragment bereitzustellen?


2
Habe mir das gestern gefragt
Mirco

Antworten:


1

Ich und andere teilen Ihre Meinung, dass Fragmente ziemlich seltsam sind und nicht blind als Good Things ™ akzeptiert werden sollten.

Ich habe immer gedacht, dass die Absicht hinter ihrer Existenz im Bootstrap-Code darin besteht, Fragmente so früh wie möglich vor die Gesichter der Entwickler zu werfen. Da es seit Version 1 keine Fragmente mehr gibt, musste Google meiner Meinung nach etwas Gewicht auf ihre Einführung legen, um mehr Leute an Bord zu bringen. Aber ich kann nur spekulieren.


WTFs/min = 2^fragment count Corner.squareup.com/2014/10/…
Lovis
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.