zoukankan      html  css  js  c++  java
  • Fragment在《暗黑3天梯榜》中使用的场景

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

    在《Android编程权威指南》中采用了一种激进的态度来对待Fragment,即“总是使用fragment原则”。《Android编程权威指南》英文名称是《Android Programming the big nerd ranch guide》,很多技术文章都是基于这本书的,在还不是很了解的情况下,我盲目的遵循了这个激进的观点。做了这个App《暗黑3天梯榜》。

    事实就是,就目前来说这个激进的观点带给了我很大的好处。

    概述

    我在以下这些地方使用了fragment

    • 进度条(闪屏?)。
    • 需要返回数据的选择界面。
    • 数据列表界面。

    确切的说,我每个界面都是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);

    一直到这里可能都很普通,没有发现什么问题。在手机中左看看右看看也没有啥问题。是的,现在不会有问题,以后也不会有问题。这一切的原因是因为《Android 编程权威指南》中已经帮你回避了很多问题。

    Activity重新创建时,会重新构建它所管理的Fragment,原先的Fragment的字段值将会全部丢失,但是通过 Fragment.setArguments(Bundle bundle)方法设置的bundle会保留下来。所以尽量使用 Fragment.setArguments(Bundle bundle)方式来传递参数。

    需要返回数据的选择界面中使用Fragment

    首先我们要创建一个Fragment,在这个Fragment里面我们要返回数据,我们要申明一个接口,并且在需要接受数据的地方重写这个接口。

    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);
                }
            });
        }
    }
    

    在代码中接口是这样申明的

    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数据不会丢失。
    • 可重用性极高。
  • 相关阅读:
    10多媒体
    胡凡-01
    概念
    算法
    07Axios
    05VueCli
    04Vue.js路由系统
    03生命周期
    《穷人思维》学习感悟
    《基金》学习感悟之二
  • 原文地址:https://www.cnblogs.com/canglin/p/4523405.html
Copyright © 2011-2022 走看看