Tidak dapat memahami Fragmen Android

Saya kesulitan memahami Fragmen dan Aktivitas.

Saya sedang menulis aplikasi yang menggunakan ActionBar untuk menavigasi Daftar "Item Audio Unggulan", dan Daftar "Program" yang berisi daftar "Item Audio" mereka sendiri. Saya menggunakan ActionBarSherlock dan paket kompatibilitas.

Saat Anda mengklik tab ActionBar, aktivitas/fragmen tersebut akan ditampilkan. Ketika Anda mengklik sesuatu dalam daftar, itu akan membuka fragmen/aktivitas baru yang menampilkan program/item audio tersebut.

Saya telah melihat berbagai Demo/Sampel dan memahami bahwa ada beberapa cara untuk melakukan ini.

Pertanyaan saya:

  • What's the structure of the programme?
    • e.g. An activity for every fragment? One activity with many fragments?
  • How do you navigate the fragments?
    • e.g. Intents?
  • Bagaimana cara saya memiliki ActionBar yang persisten di semua aktivitas?

Terima kasih atas bantuan apa pun yang dapat Anda berikan

EDIT - Menjawab pertanyaan saya sendiri:

Jadi saya memilih pendekatan ini:

  • Aktivitas Utama yang menginisialisasi ActionBar, menangani Navigasi Fragmen utama.
  • Setiap Fragmen utama memiliki onClickListener
  • onClickListener menggantikan Fragmen yang sedang ditampilkan dengan yang baru, diinisialisasi untuk menampilkan item yang tepat

Ini didasarkan pada demo ActionbarSherlock FragmentLayoutSupport yang saya sebutkan di komentar.

Cuplikan Fragmen Daftar Utama:

//public class ProgrammesFragment extends SherlockListFragment

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    showDetails(id);
}

/**
 * Helper function to show the details of a selected item, either by
 * displaying a fragment in-place in the current UI, or starting a
 * whole new activity in which it is displayed.
 */
void showDetails(long index) {
    // Check what fragment is currently shown, replace if needed.
    ProgrammeFragment details = (ProgrammeFragment) getFragmentManager().findFragmentByTag(ProgrammeFragment.TAG);
    if (details == null || details.getShownIndex() != index) {
        // Make new fragment to show this selection.
        details = ProgrammeFragment.newInstance(index);

        // Execute a transaction, replacing any existing fragment
        // with this one inside the frame.
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.remove(getFragmentManager().findFragmentByTag(ProgrammesFragment.TAG));
        ft.add(android.R.id.content, details, ProgrammeFragment.TAG);
        ft.addToBackStack(null);
        ft.commit();
    }
}

Cuplikan Fragmen Detail:

//public class ProgrammeFragment extends SherlockListFragment

/**
 * Create a new instance of ProgrammeFragment, initialized to
 * show the text at 'index'.
 */
public static ProgrammeFragment newInstance(long index) {
    ProgrammeFragment f = new ProgrammeFragment();

    // Supply index input as an argument.
    Bundle args = new Bundle();
    args.putLong("programme_id", index);
    f.setArguments(args);

    return f;
}

public long getShownIndex() {
    return getArguments().getLong("programme_id", 0);
}

Fragmen detail menggunakan LoaderManager di atas SQL ContentResolver, dan memanggil getShownIndex untuk membangun kondisi untuk kueri pemilihan.

Ini berfungsi (untuk saat ini), tidak yakin tentang penggunaan memori atau hal semacam itu. Tapi kita lihat saja nanti!

Tampaknya SO bagus untuk memperjelas pikiran Anda sehingga Anda dapat menjawab pertanyaan Anda sendiri :P


person Nick Malcolm    schedule 03.04.2012    source sumber
comment
Misalnya, salah satu cara melakukannya ditunjukkan dalam demo Contoh Fragmen ActionBarSherlock yang disebut FragmentLayoutSupport. Di dalamnya setiap fragmen mempunyai aktivitas, dan baik fragmen maupun aktivitas diimplementasikan sebagai kelas dalam. Hal ini tampaknya menggagalkan tujuan memiliki fragmen yang dapat digunakan kembali...   -  person Nick Malcolm    schedule 03.04.2012
comment
Saya juga harus mencatat bahwa saya tidak terlalu peduli dengan tata letak apa pun kecuali potret pada ponsel cerdas. Tidak khawatir tentang fragmen yang berdampingan, dll.   -  person Nick Malcolm    schedule 03.04.2012


Jawaban (1)


Di onCreate aktivitas utama Anda, Anda membuat dan menambahkan semua tab (satu tab = 1 kelas SherlockFragment). Dalam aktivitas utama Anda, Anda harus memiliki kelas dalam yaitu TabAdapter. Dalam contoh saya di bawah, TabAdapter juga merupakan ViewPager, sehingga Anda dapat menggeser layar ke mana saja, kiri-kanan untuk beralih antar tab. Inilah kelas utamanya:

import java.util.ArrayList;
import library.DatabaseHandler;
import library.UserFunctions;

import org.json.JSONObject;
import com.actionbarsherlock.R;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View.OnClickListener;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;

public class Polling extends SherlockFragmentActivity {
    private ViewPager mViewPager;
    private TabsAdapter mTabsAdapter;
    ActionBar bar;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mViewPager = new ViewPager(this);
        mViewPager.setId(R.id.pager);
        setContentView(mViewPager);
        bar = getSupportActionBar();
        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        bar.setDisplayShowTitleEnabled(false);
        bar.setDisplayShowHomeEnabled(false);

        mTabsAdapter = new TabsAdapter(this, mViewPager);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.login),
                LoginFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.economics),
                EconFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.elections),
                ElectionsFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.politics),
                PoliticsFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.science),
                ScienceFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.finance),
                FinanceFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.religion),
                ReligionFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.military),
                MilitaryFragment.class, null);
        mTabsAdapter.addTab(bar.newTab().setText(R.string.international),
                InternationalFragment.class, null); 
    }


    public static class TabsAdapter extends FragmentPagerAdapter
    implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
        private final Context mContext;
        private final ActionBar mActionBar;
        private final ViewPager mViewPager;
        private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

        static final class TabInfo {
            private final Class<?> clss;
            private final Bundle args;

            TabInfo(Class<?> _class, Bundle _args) {
                clss = _class;
                args = _args;
            }
        }

        public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
            super(activity.getSupportFragmentManager());
            mContext = activity;
            mActionBar = activity.getSupportActionBar();
            mViewPager = pager;
            mViewPager.setAdapter(this);
            mViewPager.setOnPageChangeListener(this);
        }

        public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
            TabInfo info = new TabInfo(clss, args);
            tab.setTag(info);
            tab.setTabListener(this);
            mTabs.add(info);
            mActionBar.addTab(tab);
            notifyDataSetChanged();
        }

        public int getCount() {
            return mTabs.size();
        }

        public SherlockFragment getItem(int position) {
            TabInfo info = mTabs.get(position);
            return (SherlockFragment)Fragment.instantiate(mContext, info.clss.getName(), info.args);
        }

        public void onPageSelected(int position) {
            mActionBar.setSelectedNavigationItem(position);
        }
        public void onPageScrollStateChanged(int state) {}
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            mViewPager.setCurrentItem(tab.getPosition());
            //Log.v(TAG, "clicked");
            Object tag = tab.getTag();
            for (int i=0; i<mTabs.size(); i++) {
                if (mTabs.get(i) == tag) {
                    mViewPager.setCurrentItem(i);
                }
            }
        }
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {}
        public void onTabReselected(Tab tab, FragmentTransaction ft) {}
        public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {}
        public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {}
    }
}

Berikut ini sebuah fragmen tanpa UI utama (hanya file xml dengan satu TextView di dalamnya):

import com.actionbarsherlock.R;
import com.actionbarsherlock.app.SherlockFragment;

import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FinanceFragment extends SherlockFragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        return inflater.inflate(R.layout.financefragment, container, false);
    }
}

Fragmen lain dengan UI sementara di onResume/onCreateView:

import com.actionbarsherlock.R;
import com.actionbarsherlock.app.SherlockFragment;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class EconFragment extends SherlockFragment {

    private TableLayout questionContainer;
    int pos = 0;
    private String[] titles = {"The first title ", "hallo1","hallo2", "hallo3",
            "hallo4", "hallo5","hallo6", "hallo7","hallo8", "hallo9"};

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.v("Econ", "onCreateView");
        View v = inflater.inflate(R.layout.econfragment, container, false);
        questionContainer = (TableLayout) v.findViewById(R.id.questionContainer);
        //bs
        int leftMargin=5;
        int topMargin=5;
        int rightMargin=5;
        int bottomMargin=5;
        while (pos < 10) {
        View question = inflater.inflate(R.layout.question, null);
        question.setId(pos);
        TextView title = (TextView) question.findViewById(R.id.questionTextView);
        title.setText(titles[pos]);
        Button charts = (Button) question.findViewById(R.id.chartsButton);
        charts.setId(pos);
        charts.setOnClickListener(chartsListener);
        TableRow tr = (TableRow) question;
        TableLayout.LayoutParams trParams = new TableLayout.LayoutParams(
                TableLayout.LayoutParams.MATCH_PARENT,
                TableLayout.LayoutParams.WRAP_CONTENT);
        trParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
        tr.setLayoutParams(trParams);
        Log.v("econ", "while loop");
        questionContainer.addView(tr);
        pos++;
        }
        pos = 0;
        return v;
    }

    public void onResume() {
        super.onResume();
        Log.v("Econ", "onResume");
    }

    public OnClickListener chartsListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent chart = new Intent();
            chart.setClass(getActivity(), Chart.class);
            chart.putExtra("key", titles[v.getId()]);
            Log.v("TAG", Integer.toString(v.getId()));
            startActivity(chart);

        }

    };

    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Log.d("Econ", "onAttach");
    }

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("Econ", "onCreate");
        //Log.v("ECON", savedInstanceState.toString());

    }

    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d("Econ", "onActivityCreated");
    }

    public void onStart() {
        super.onStart();
        Log.d("Econ", "OnStart");
    }

    public void onPause() {
        super.onPause();    
        Log.d("Econ", "onpause");
    }

    public void onStop() {
        super.onStop();
        Log.d("Econ", "onstop");
    }

    public void onDestroyView() {
        super.onDestroyView();
        Log.d("Econ", "ondestroyview");
    }

    public void onDestroy() {
        super.onDestroy();
        Log.d("Econ", "ondestroy");

    }

    public void onDetach() {
        super.onDetach();
        Log.d("Econ", "ondetach");
    }
}

EDIT~Saya belum mendokumentasikan kode saya - beberapa di antaranya hanya dari contoh yang saya temukan online. Jika ada kendala atau hal yang kurang dimengerti, tanyakan saja.

person Davek804    schedule 03.04.2012
comment
Terima kasih. Saya memahami cara menampilkan fragmen dan menambahkan tab ke ActionBar secara umum. Apa yang saya tidak mengerti adalah bagaimana menavigasi antar fragmen saat Anda mengklik item daftar? Saya tidak bisa melihatnya dalam contoh Anda. - person Nick Malcolm; 03.04.2012
comment
Baiklah, saya baru saja kembali dan melihat ke dalam buku yang mengajari saya banyak hal ini, dan contoh di ListFragment sangat buruk. - person Davek804; 03.04.2012