Fragment在《暗黑3天梯榜》中使用的場景

Fragment在《暗黑3天梯榜》中使用的場景

在《Android編程權威指南》中採用了一種激進的態度來對待Fragment,即「老是使用fragment原則」。《Android編程權威指南》英文名稱是《Android Programming the big nerd ranch guide》,不少技術文章都是基於這本書的,在還不是很瞭解的狀況下,我盲目的遵循了這個激進的觀點。作了這個App《暗黑3天梯榜》。html

事實就是,就目前來講這個激進的觀點帶給了我很大的好處。java

概述

我在如下這些地方使用了fragmentandroid

  • 進度條(閃屏?)。
  • 須要返回數據的選擇界面。
  • 數據列表界面。

確切的說,我每一個界面都是fragment。fragment最直觀的好處就是對UI的自適應是極好的,能夠說是吧不少問題都提早擋在了外面。在傳遞數據方面有arguments。在App中處處都充斥着下面這樣的代碼編程

ProgressbarFragment newFragment = new ProgressbarFragment();
Bundle args = new Bundle();
args.putInt(ProgressbarFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragmentContainer, newFragment,"progress");
transaction.commit();

上面是一段代碼,用來傳遞進度條進度的數據,poison表明了進度100種的某個數字。在ProgressbarFragment用下面的辦法能夠獲得傳遞過去的數據服務器

int position = getArguments().getInt(ARG_POSITION);ide

一直到這裏可能都很普通,沒有發現什麼問題。在手機中左看看右看看也沒有啥問題。是的,如今不會有問題,之後也不會有問題。這一切的緣由是由於《Android 編程權威指南》中已經幫你迴避了不少問題。ui

Activity從新建立時,會從新構建它所管理的Fragment,原先的Fragment的字段值將會所有丟失,可是經過 Fragment.setArguments(Bundle bundle)方法設置的bundle會保留下來。因此儘可能使用 Fragment.setArguments(Bundle bundle)方式來傳遞參數。this

須要返回數據的選擇界面中使用Fragment

首先咱們要建立一個Fragment,在這個Fragment裏面咱們要返回數據,咱們要申明一個接口,而且在須要接受數據的地方重寫這個接口。code

public class ChoseServerFragment extends Fragment {
    private ArrayAdapter<String> mAdapter;
    private String[] servers;
    public static String FRAGMENT = "com.example.lijing.diablo3armory.choseserverfragment";
    OnArticleSelectedListener mListener;
    public interface OnArticleSelectedListener {
        public void onServerSelected(String servername);
    }
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnArticleSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
        }
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.server_fragment, container, false);
        iniListView(v);
        return v;
    }

    private void iniListView(View v) {
        servers = getActivity().getResources().getStringArray(R.array.servers);
        ListView serverListView = (ListView)v.findViewById(R.id.choseServerListView);
        mAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_expandable_list_item_1,servers);
        serverListView.setAdapter(mAdapter);
        serverListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                String servername = servers[i];
                mListener.onServerSelected(servername);
            }
        });
    }
}

在代碼中接口是這樣申明的server

OnArticleSelectedListener mListener;
public interface OnArticleSelectedListener {
    public void onServerSelected(String servername);
}

而後在onItemClick()中這樣調用

mListener.onServerSelected(servername);

在這個Fragment裏咱們須要顯示一個Layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <TextView
        android:gravity="center"
        android:text="@string/choseyourserver"
        android:textSize="20dp"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
    <ListView
        android:id="@+id/choseServerListView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">    
    </ListView>
</LinearLayout>

這裏顯示了一個服務器列表,她的效果是這個樣子的。

在這個App中,我是在Activity中調用的這個Fragment。首先要implements,這個接口。

public class MainActivity extends FragmentActivity
    implements ChoseServerFragment.OnArticleSelectedListener{

而後在重寫這個接口在這個Activity裏。

@Override
public void onServerSelected(String servername) {
    ChoseServerFragment fragment = (ChoseServerFragment)getSupportFragmentManager()
            .findFragmentByTag(ChoseServerFragment.FRAGMENT);
    if(fragment != null) {
        savePreferences(servername);
        ChoseServerFragment removeFragment = (ChoseServerFragment)getSupportFragmentManager().findFragmentByTag(ChoseServerFragment.FRAGMENT);
        getSupportFragmentManager().beginTransaction().remove(removeFragment);
        iniApp();
    }
}

若是要在哪裏使用這個Fragment,只須要重寫這個接口就能夠了,不管是在Activity或者Fragment裏均可以。

小結

本章描述了第二種方式使用Fragment(第一種方式參看http://www.cnblogs.com/canglin/p/4439666.html)。大概有以下優勢

  • UI具備更好的適應能力。
  • Bundle數據不會丟失。
  • 可重用性極高。
相關文章
相關標籤/搜索