編輯:關於Android編程
為了重用Fragment UI 組件,在設計中你應該通過定義每一個fragemnt自己的layout和行為,讓fragment的自包含和模塊化。一旦你定義了這些可重用的Fragment,你可以通過Activity將它們關聯起來並通過程序的邏輯代碼將他們連接起來以實現整體組合的UI。
你會經常想要一個fragment與另一個fragment通信,例如基於用戶事件改變fragment中的內容。所有fragment質檢單額通信都是通過Activity關聯起來的。兩個fragment之間不應該直接進行通信。
定義接口
為了允許fragment和它的Activity通信,你應該fragment類中定義一個接口並在Activity中實現它。Fragment在onAttach()回調函數中獲取接口的具體實現的對象。後面,fragment就可以調用接口中的方法實現與Activity的通信。
下面是一個Fragment一Activity通信的例子:
// 用來存放fragment的Activtiy必須實現這個接口
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// 這是為了保證Activity容器實現了用以回調的接口。如果沒有,它會拋出一個異常。
try {
mCallback = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
現在fragment可以通過使用實現了OnHeadlineSelectedListener接口的mCallback實例調用onArticleSelected()方法(或其他在接口中的方法)將消息傳遞給Activity。
例如下面在fragment中的方法將會在用戶點擊一個List item的時候被調用。這個fragment使用回調接口將時間傳遞給父Activtity。
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// 發送時間給Activity宿主
mCallback.onArticleSelected(position);
}
實現接口
為了接收從fragment傳遞過來的事件回調,宿主Activity必須實現定義在fragment類中的接口。
例如,下面的activity實現了上個例子中的接口。
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// 用戶選擇了HeadlinesFragment中的頭標題後
// 做一些業務操作
}
}
將消息傳遞給fragment
宿主Activity可以通過調用findFragmentById()方法獲取Fragment實例,然後直接調用Fragment的公有方法,將消息傳遞給Fragment。
例如,想象一下,之前講過的Activity可能包含有其他的fragment,而這些fragment通過上面的回調函數返回的接口動態地顯示一些內容。這種情況下,Activity可以將回調函數中接收到信息傳遞給需要的fragment。
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// 用戶選中HeadlinesFragment中的頭標題後
// 做一些必要的業務操作
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
if (articleFrag != null) {
// 如果 article frag 不為空,那麼我們在同時顯示兩個fragmnet的布局中...
// 調用ArticleFragment中的方法去更新它的內容
articleFrag.updateArticleView(position);
} else {
// 否則,我們就是在僅包含一個fragment的布局中並需要交換fragment...
// 創建fragment並給他一個跟選中的文章有關的參數
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// 用這個fragment替換任何在fragment_container中的東西
// 並添加事務到back stack中以便用戶可以回退到之前的狀態
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// 提交事務
transaction.commit();
}
}
}
動態加載的Fragment通信
fragment之間永遠不能通信都是通過他們所依附的Activity來通信的,通過接口回調的方式來通信
Activity--->Fragment:在activity中創建Bundle數據包,並調用fragment的setArguments(Bundle bundle)方法
fragment--->Activity:在fragment類中定義一個接口,並在他所屬的activity中實現該接口,fragment在他的onAttach()方法執行期間捕獲該接口的實現,然後就可以調用該接口方法,以便跟activity通信。
下面的代碼實現了在一個Activity下有兩個Fragment,在一個Fragment中輸入值在另一個Fragment顯示
public class MainActivity extends Activity implements MyListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager manager = getFragmentManager();
FragmentTransaction fragmentTransaction = manager.beginTransaction();
Fragment1 fragment1 = new Fragment1();
fragmentTransaction.add(R.id.layout1, fragment1);
fragmentTransaction.commit();
}
//在mainActivity中實現MyListener接口並實現它未實現的方法,在該方法中傳遞數據
@Override
public void send(String info) {
Toast.makeText(this, "Activity成功接收" + info, 0).show();
Fragment2 fragment2 = new Fragment2();
Bundle bundle = new Bundle();
bundle.putString("name", info);
fragment2.setArguments(bundle);
FragmentManager manager = getFragmentManager();
FragmentTransaction fragmentTransaction = manager.beginTransaction();
//替換該Fragment
fragmentTransaction.replace(R.id.layout2, fragment2, "fragment2");
fragmentTransaction.commit();
}
}
上面的MainActivity布局就是添加兩個Linearlayout,下面是創建兩個Fragment,Fragment1的布局就是一個EditText一個Button,Fragment2的布局就是一個TextView。
public class Fragment1 extends Fragment {
EditText et;
Button enter;
private String info;
@Override
public void onAttach(Activity activity) {
listener = (MyListener) activity;
super.onAttach(activity);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment1_lay,container, false);
et = (EditText) view.findViewById(R.id.et);
enter = (Button) view.findViewById(R.id.enter);
enter.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
info = et.getText().toString();
listener.send(info);
}
});
return view;
}
public MyListener listener;
//定義一個接口
public interface MyListener{
public void send(String info);
}
}
public class Fragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment2_lay,container, false);
TextView tv = (TextView) view.findViewById(R.id.tv);
tv.setText(getArguments().get("name")+"");//獲取傳遞的值
Toast.makeText(getActivity(), "fragment"+getArguments().get("name")+"", 0).show();
return view;
}
}
靜態加載的fragment通信
fragment可以調用getActivity()方法獲取他所在的Activity
Activity可以調用FragmentManager的findFragmentById()或findFragmentByTag()方法獲取Fragment
如果是靜態加載的Fragmentn那麼向Activity傳遞數據就很簡單了,在MainActivity的onCreate方法中:
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = fragmentManager.findFragmentById(R.id.frag);//靜態加載在Activity布局中設置的Fragment的ID
MyFragment frag = (MyFragment) fragment;
frag.setText1("fragment靜態傳值");
在Fragment類中設置它的get、set方法,
private String text1;
public String getText1() {
return text1;
}
public void setText1(String text1) {
this.text1 = text1;
}
下面直接調用就可以了:
String value = getText1();
android studio 多渠道打包以及工程的定制化(上)
有時候有這樣的需求:同一份源碼,需要打出多個apk,而且包名和logo不一樣,就這麼簡單,怎麼很便捷的搞定呢 ?ok,毫無疑問,這裡涉及到多渠道。1. 多渠道配置第一步打
Android ToolBar/App bar
2014的 google i/o發表令多數人為之一亮的 material design toolbar,這是用來取代過去 actionbar 的控件,而現在於 mater
分享Android仿刮獎效果控件
本文實例為大家分享了Android刮刮卡效果控件,供大家參考,具體內容如下刮刮卡類: package com.reyo.view;import android.conte
TaintDroid深入剖析之啟動篇
?1背景知識1.1Android平台軟件動態分析現狀眾所周知,在計算機領域中所有的軟件分析方法都可以歸為靜態分析和動態分析兩大類,在Android平台也不例外。而隨著軟件