<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                Fragment,碎片,是Android 3.0之后加入的一個非常重要的概念。每個Fragment都有相應的Activity對它進行托管。一個Activity中可以有多個Fragment,這很自然的給大屏幕的適配提供了很便捷的方案。現在大家在開發中都必不可上的用上Fragment。本文總結了Fragment在不同情況下的傳值方法,包括不同Activity下的Fragment的傳值,相同Acitvity托管下不同Fragment的傳值。同一界面不同Fragment傳值并實時變化的情況。了解了這些,基本上Fragment的通信就不會再有問題了。接下來分部分介紹 一,不同Acitivity托管下的Frament如何傳值 相信大家對不同Activity間的傳值都很熟悉,其實Fragment的傳值就與Acitvity一樣簡單。傳值情況如下: 下面通過一個demo來講解,界面很簡單,firstFragment中有一個EditText,點擊按鈕實現將值傳到secondFragment中顯示在TextView上。界面的布局就不再貼出。 定義layout_main.xml如下: ~~~ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/fragmentContain" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> </FrameLayout> ~~~ 很簡單,用來放fragment。接下來定義供繼承的frameActivity類 ~~~ public abstract class SingleFragment extends FragmentActivity { protected abstract Fragment createFragment(); protected int getLayoutResId(){ return R.layout.activity_main; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getLayoutResId()); FragmentManager fm = getSupportFragmentManager(); Fragment fragment = fm.findFragmentById(R.id.fragmentContain); if(fragment == null){ fragment = createFragment(); fm.beginTransaction().add(R.id.fragmentContain,fragment).commit(); } } } ~~~ 相信大家都知道這是用與被Activity繼承的類,把重復的代碼定義在基類中,減少冗余代碼,這是適配器設計模式。 接下來就完成FirstActivity,不能再簡單了。 ~~~ public class FirstActivity extends SingleFragment { @Override protected Fragment createFragment() { return new FirstFragment(); } } ~~~ FristFragment通過調用Fragment.startActivity(intent)將值傳到SecondActivity中。具體代碼如下: ~~~ public class FirstFragment extends Fragment { Button btn; EditText edit; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.firstfragment,container,false); initView(v); return v; } public void initView(View v){ btn = (Button)v.findViewById(R.id.btn); edit = (EditText)v.findViewById(R.id.edit1); btn.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { Intent intent = new Intent(getActivity(),SecondActivity.class); intent.putExtra(SecondFragment.EXTRA_STRING, FirstFragment.this.edit.getText().toString()); startActivity(intent); getActivity().finish(); } }); } } ~~~ 這樣就把值傳到了SecondActivity,其實跟Acitvity一樣。接下來就是如何在SecondFragment中獲得SecondActivity的值。有兩種方法,第一種如下: ~~~ String str = getActivity().getIntent().getStringExtra(EXTRA_STRING); txt.setText(str); ~~~ 直接通過getIntent獲取值,但這樣做就破壞的Fragment的獨立性。因為此時SecondFragment總需要被SecondActivity托管,而不能用于其他Activity中,否則就可能因獲取不到intent而報錯。 正常的設托管模式是Activity知道Fragment的具體情況,但Fragment不能也不應該知道Activity中的具體情況。所以一般采用以下第二種方法。 每個fragment都有一個Bundle對象。第二種方法就是把傳過來的值存到bundle中。bundle可以添加argument(key-value對象),在給fragment添加bundle時要注意,Fragment.setArguments(bundle)需要在fragment創建后,添加到activity前完成。然后通過acitivity在建立fragment時傳入值來實現fragment的獨立性。修改SecondFragment代碼如下: ~~~ public class SecondFragment extends Fragment { public static final String EXTRA_STRING="DATA"; TextView txt; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.secondfragment,container,false); txt = (TextView)v.findViewById(R.id.txt2); String str = getArguments().getString(EXTRA_STRING); txt.setText(str); return v; } public static Fragment newInstance(String s){ Bundle args = new Bundle(); args.putString(EXTRA_STRING,s); SecondFragment fragment = new SecondFragment(); fragment.setArguments(args); return fragment; } } ~~~ 然后在SecondActivity中將值傳入 ~~~ public class SecondActivity extends SingleFragment { @Override protected Fragment createFragment() { String str = getIntent().getStringExtra(SecondFragment.EXTRA_STRING); return SecondFragment.newInstance(str); } } ~~~ 就可以發現傳值成功了。 二,相同activity托管的兩個Fragment傳值問題。 在上面的例子上進行修改,在SecondFragment加入一個按鈕打開一個dialogFragment,傳值進去,dialog銷毀后返回值。 在SecondFragment中打開dialogFragment,代碼修改如下: ~~~ btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { FragmentManager fm = getActivity().getSupportFragmentManager(); MyDialog myDialog = (MyDialog) MyDialog.newInstance(SecondFragment.this.txt.getText().toString()); myDialog.setTargetFragment(SecondFragment.this,0); myDialog.show(fm,"Data"); } }); ~~~ 最主要的是在把SecondFragment設為是myDialog的目標Fragment.使兩者建立聯系,這樣目標Fragment就交給了FragmentManage管理,方便之后獲取目標Fragment. 接下來是完成dialogFragment,代碼如下: ~~~ public class MyDialog extends DialogFragment { public static final String EXTRADATA = "DIALOG"; EditText dialogEdit; @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { View v = getActivity().getLayoutInflater().inflate(R.layout.dialogfragment,null); dialogEdit= (EditText)v.findViewById(R.id.edit); dialogEdit.setText(getArguments().getString(EXTRADATA)); return new AlertDialog.Builder(getActivity()).setTitle("").setView(v) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { sendResult(Activity.RESULT_OK); } }).create(); } public static Fragment newInstance(String s){ Bundle args = new Bundle(); args.putString(EXTRADATA,s); MyDialog fragment = new MyDialog(); fragment.setArguments(args); return fragment; } public void sendResult(int s){ if(getTargetFragment() == null){ return; }else{ Intent i = new Intent(); i.putExtra(EXTRADATA,dialogEdit.getText().toString()); getTargetFragment().onActivityResult(getTargetRequestCode(),s,i); } } } ~~~ newInstance不用講,跟上面的原理一樣。主要是sendResult,在sendResult中調用父Fragment的回調方法將修改后的值返回到父Fragment中。 最后在SecondFragment中添加回調方法處理返回值。 ~~~ public void onActivityResult(int requestCode, int resultCode, Intent data) { if(resultCode != Activity.RESULT_OK){ return; }else{ String str = data.getStringExtra(MyDialog.EXTRADATA); txt.setText(str); } } ~~~ 就完成了同個Activity托管的不同Fragment間的傳值。 三,同一界面修改一Fragment另一個Fragment實時改變 現在有這樣一個需求,一個界面同時有兩個Fragment,右邊的Fragment里的EditText變化會引起左邊的實時變化。修改上面的例子,在FirstFragment中添加一個按鈕打開一個新的界面,實現上面的功能。 首先分析下思路。其實最簡單的做法就是在EditText的Fragment中監聽edit的變化,然后直接創建FragmentManger,獲得另一個Fragment并動態的改變其中的內容。這是最直接最簡單的方法,但是還是那句話,Fragment的獨立性很重要,如果這樣做就要求EditText的Fragment知道TextView所在的Fragment的相關細節。最好的方法就是用回調。 新建一個thirdfragment.xml文件。 ~~~ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <FrameLayout android:id="@+id/frame1" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent"/> <FrameLayout android:id="@+id/frame2" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent"/> </LinearLayout> ~~~ 新建一個ForthFragment,它的布局文件就只需要一個EditText。 ~~~ public class ForthFragment extends Fragment{ EditText edit; private Callbacks mCallbacks; public interface Callbacks{ void onChangeText(String s); } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fourfragment,container,false); initView(v); return v; } public void initView(View v){ edit = (EditText)v.findViewById(R.id.edit1); edit.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { String str = edit.getText().toString(); mCallbacks.onChangeText(str); } @Override public void afterTextChanged(Editable s) { } }); } @Override public void onDetach() { super.onDetach(); mCallbacks = null; } @Override public void onAttach(Activity activity) { super.onAttach(activity); mCallbacks = (Callbacks)activity; } } ~~~ 在fragment中定義了回調接口,回調接口定義了fragment委托給托管activity處理的工作。任何托管這個fragment都要實現這個接口。在onAttach方法中,將activity強制轉換成callbacks并賦值給Callbacks變量。這樣在onTextChange中調用接口的onChangeText()相當于在Activity中調用。接下來看看托管兩個Fragment的Activity。 ~~~ public class ThirdActivity extends FragmentActivity implements ForthFragment.Callbacks { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.thirdfragment); FragmentManager fm = getSupportFragmentManager(); Fragment fragment1 = fm.findFragmentById(R.id.frame1); Fragment fragment2 = fm.findFragmentById(R.id.frame2); if(fragment1 == null){ fragment1 = new ForthFragment(); fm.beginTransaction().add(R.id.frame1,fragment1).commit(); } if(fragment2 == null){ fragment2 = new FiveFragment(); fm.beginTransaction().add(R.id.frame2,fragment2).commit(); } } @Override public void onChangeText(String s) { FragmentManager fm = getSupportFragmentManager(); FiveFragment listFragment= (FiveFragment)fm.findFragmentById(R.id.frame2); listFragment.update(s); } } ~~~ 代碼很簡單,分兩次加載不同的Fragment。并實現回調接口。在接口中獲得另一個fragment調用其update()方法。最后就只剩下在FiveFragment中實現update()了。 ~~~ public class FiveFragment extends Fragment { TextView txt; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fivefragment,container,false); txt = (TextView)v.findViewById(R.id.txt2); return v; } public void update(String str){ txt.setText("數據是:"+str); } } } } @Override public void onChangeText(String s) { FragmentManager fm = getSupportFragmentManager(); FiveFragment listFragment= (FiveFragment)fm.findFragmentById(R.id.frame2); listFragment.update(s); } } ~~~ 這樣就實現了界面的實時變化。 到這里fragment的幾種傳值方式就講完了,demo做的很簡單,只是為了講解用,但再復雜的傳值也是基于這些方式。就講到這吧。 [代碼下載](http://download.csdn.net/detail/u014486880/8952375)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看