zoukankan      html  css  js  c++  java
  • Android Fragment使用

    前言

    学习Java和Android将近一年的时间了。期间的成果应该就是独立完毕了一个Androidclient,而且保证了其在主线版本号的稳定性。

    期间遇到了非常多坑。也跟着师兄学到了非常多Android知识。

    可是人总是要拥抱变化,不能让自己太安逸,尽管有不舍,可是我已经证明了自己的学习能力,下一步就是開始做Rom Porting了。

    这里总结一下之前项目中用到最多的Fragment。


    Fragment简单介绍

    Fragment能够理解成Activity中用户界面的一个行为或者一部分,它必须被嵌套在Activity中。

    可是一个Fragment有它自己独立的xml布局文件,而且具有良好的封装性。因此特殊情况下Fragment能够非常easy用Activity来进行替换。


    创建Fragment

    创建一个Fragment和创建Activity类似,须要实现XML布局文件和Java Class。
    XML布局文件和其它布局文件都一样,比如例如以下所看到的的布局文件(fragment_layout.xml):
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent" 
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/testview" />
    
        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button" />
    
    </LinearLayout>
    Java代码中,普通情况下能够依据须要实现Fragment下面几个生命周期方法:
    1. onAttach():当Fragment依附于activity时被调用,能够在该方法中获取activity句柄,从而实现Fragment和activity之间的通信。
    2. onCreate():对Fragment做初始化。

    3. onCreateView():在第一次为Fragment绘制用户界面时系统会调用此方法。
    4. onActivityCreated():在宿主Activity onCreate函数运行完毕之后被调用。能够在这种方法里进行Fragment自己的widget实例化和业务逻辑处理。

    5. onDestoryView():当Fragment開始被销毁时调用。

    6. onStart():当Fragment可见时被调用。
    还有更多用以操纵Fragment生命周期中各个阶段的回调函数,大家可自行Google学习。

    Fragment生命周期

    每个Fragment都有自己的一套生命周期回调方法和处理自己的用户输入事件。相应的生命周期例如以下图所看到的:


    在Activity中增加Fragment

    首先。须要确保Acitivity支持Fragment,因此Activity通常须要继承自FragmentActivity。在Activity中加入Fragment通常有两种方法:静态的和动态的。

    静态方法

    直接在Activity的XML布局文件里增加Fragment。例如以下所看到的:
    <?

    xml version="1.0" encoding="utf-8"?

    > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:baselineAligned="false" android:orientation="horizontal" > <fragment android:id="@+id/first" android:name="com.example.FristFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" /> <fragment android:id="@+id/second" android:name="com.example.SecondFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" /> </LinearLayout>

    <fragment>中的android:name 属性指定了布局中实例化的fragment类
    当系统创建Activity布局时,它实例化了布局文件里指定的每个Fragment,而且为它们调用onCreateView()函数,以获取每个fragment的布局。系统直接在<fragment>元素位置插入fragment返回的view
    注意:每一个fragment都须要一个唯一的标识,假设重新启动activity,系统可用来恢复fragment(而且用来捕捉fragment的事务处理,比如移除)。

    为了Fragment提供ID有三种方法:

    • 用android:id属性提供一个唯一的标识
    • 用android:tag属性提供一个唯一的字符串
    • 假设上述两个属性都没有,系统会使用其容器视图的ID

    动态方法

    使用FragmentTranscation。能够使用FragmentTranscation的API来对Activity的Fragment进行操作(比如加入,移除,或者替换Fragment)。參考代码例如以下:
    	FragmentManager fragmentManager = getFragmentManager()
    	FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    	ExampleFragment fragment = new ExampleFragment();
    	fragmentTransaction.add(R.id.fragment_container, fragment);
    	fragmentTransaction.commit();
    传入add()函数的第一个參数是Fragment被放置的ViewGroup。它由资源ID(resource ID)指定,第二个參数就是要加入的fragment。一旦通过FragmentTranscation做了更改,都应当使用commit()视变化生效。

    Fragments通信

    Fragments之间不应该直接进行通信,它们之间的交互应该通过宿主Activity进行。有三种Fragment和Acitivity交互的方法:
    1. Activity创建带參数的Fragment。
    2. Activity中保持了Fragment的对象句柄。可通过句柄直接调用该Fragment的public方法。

    3. Fragment可在onAttach函数中获取定义的listener句柄。

    创建带參数的Fragment

    在某些特定的情况下。Fragment可能须要特定的參数来进行初始化。因为Fragment必须仅仅有一个无參构造函数,因此能够考虑使用静态的newInstance方法来创建带參数的Fragment。

    演示样例代码例如以下:

    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    
    public class TestFragment extends Fragment {
    	public static TestFragment newInstance(int num, String title) {
    		TestFragment fragment = new TestFragment();
    		Bundle args = new Bundle();
    		args.putInt("num", num);
    		args.putString("title", title);
    		fragment.setArguments(args);
    		return fragment;
    	}
    
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    
    		int num = getArguments().getInt("num", 0);
    		String title = getArguments().getString("title", "");
    	}
    
    }
    你能够在Activity里,简单的载入一个带參数的Fragment:
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    TestFragment fragment = TestFragment.newInstance(5, "fragment title");
    ft.replace(R.id.placeholder, fragment);
    ft.commit();

    调用Fragment的方法

    由于Activity能够获取嵌入的Fragment的句柄,因此能够直接通过Fragment句柄调用该方法。
    public class TestFragment extends Fragment {
    	public void doSomething(String param) {
    		// do something in fragment
    	}
    }
    在Activity中。能够直接通过Fragment的对象句柄调用该方法:
    public class MainActivity extends FragmentActivity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            TestFragment testFragment = new TestFragment();
            testFragment.doSomething("some param");
        }
    }

    Fragment Listener

    假设Fragment须要共享事件给Activity,则须要利用这种方法。

    Fragment中定义一个接口,而且由Activity来实现这个接口。在onAttach()方法中将实现了这个接口的Activity获得到。

    在Fragment中定义接口代码例如以下:
    import android.support.v4.app.Fragment;
    
    public class MyListFragment extends Fragment {
      // ...
      // Define the listener of the interface type
      // listener is the activity itself
      private OnItemSelectedListener listener;
    
      // Define the events that the fragment will use to communicate
      public interface OnItemSelectedListener {
        public void onRssItemSelected(String link);
      }
    
      // Store the listener (activity) that will have events fired once the fragment is attached
      @Override
      public void onAttach(Activity activity) {
        super.onAttach(activity);
          if (activity instanceof OnItemSelectedListener) {
            listener = (OnItemSelectedListener) activity;
          } else {
            throw new ClassCastException(activity.toString()
                + " must implement MyListFragment.OnItemSelectedListener");
          }
      }
    
      // Now we can fire the event when the user selects something in the fragment
      public void onSomeClick(View v) {
         listener.onRssItemSelected("some link");
      }
    }
    在Activity中实现这个接口:
    import android.support.v4.app.FragmentActivity;
    
    public class RssfeedActivity extends FragmentActivity implements
      MyListFragment.OnItemSelectedListener {
        DetailFragment fragment;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_rssfeed);
          fragment = (DetailFragment) getSupportFragmentManager()
                .findFragmentById(R.id.detailFragment);
      }
    
      // Now we can define the action to take in the activity when the fragment event fires
      @Override
      public void onRssItemSelected(String link) {
          if (fragment != null && fragment.isInLayout()) {
              fragment.setText(link);
          }
      }
    }

  • 相关阅读:
    HDU 1985 Conversions
    HDU 1708 Fibonacci String
    HDU 3501 Calculation 2
    HDU 4163 Stock Prices
    HDU 2391 Filthy Rich
    HDU 1996 汉诺塔VI
    HDU 2824 The Euler function
    HDU 1787 GCD Again
    HDU 2393 Higher Math
    HDU 1286 找新朋友
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7390714.html
Copyright © 2011-2022 走看看