Android_Fragment解析(2)+Activity通信+防重构_141010

本文主要学习了Fragment与Activity之间的通信方法,包括如何在Fragment中与Activity进行数据交换。同时,介绍了如何在运行时配置发生变化时,如屏幕旋转,保持Fragment实例并避免重建。此外,还讨论了如何将Fragment与ActionBar和MenuItem集成,以及如何使用Fragment创建对话框。提供了实际代码示例,便于读者理解和实践。

本文主要学习的是 :  http://blog.youkuaiyun.com/lmj623565791/article/details/37992017


最后贴出 下载 1 ) Fragment如何与Activity交互

                    2) 处理运行时配置发生变化    两个文件代码下载链接

(PS: 具体参见学习的链接: 一下贴出少部分代码:)


第一个文件:  Fragment与Activity通信

  // MainActivity.java

package com.yline.fragmentcontactactivity_three;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.Window;

import com.yline.fragmentcontactactivity_three.FragmentOne.FOneBtnClickListener;
import com.yline.fragmentcontactactivity_three.FragmentTwo.FTwoBtnClickListener;
 
public class MainActivity extends Activity implements FOneBtnClickListener,  
        FTwoBtnClickListener {  
  
    private FragmentOne mFOne;  
    private FragmentTwo mFTwo;  
    private FragmentThree mFThree;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState)  {  
        super.onCreate(savedInstanceState);  
        requestWindowFeature(Window.FEATURE_NO_TITLE);  
        setContentView(R.layout.activity_main);  
  
        mFOne = new FragmentOne();  
        FragmentManager fm = getFragmentManager();  
        FragmentTransaction tx = fm.beginTransaction();  
        tx.add(R.id.id_content, mFOne, "ONE");
        tx.commit();  
    }  
  
    /** 
     * FragmentOne 按钮点击时的回调 
     */  
    @Override  
    public void onFOneBtnClick()  {  
  
        if (mFTwo == null)  {  
            mFTwo = new FragmentTwo();  
            mFTwo.setfTwoBtnClickListener(this);  
        }  
        FragmentManager fm = getFragmentManager();  
        FragmentTransaction tx = fm.beginTransaction();  
        tx.replace(R.id.id_content, mFTwo, "TWO");  
        tx.addToBackStack(null);  
        tx.commit();  
    }  
  
    /** 
     * FragmentTwo 按钮点击时的回调 
     */  
    @Override  
    public void onFTwoBtnClick()  {  
        if (mFThree == null)  {  
            mFThree = new FragmentThree();  
  
        }  
        FragmentManager fm = getFragmentManager();  
        FragmentTransaction tx = fm.beginTransaction();  
        tx.hide(mFTwo);  
        tx.add(R.id.id_content, mFThree, "THREE");  
        // tx.replace(R.id.id_content, fThree, "THREE");  
        tx.addToBackStack(null);  
        tx.commit();  
    }
}  

   // FragmentOne.java

package com.yline.fragmentcontactactivity_three;

import android.app.Fragment;  
import android.os.Bundle;  
import android.view.LayoutInflater;  
import android.view.View;  
import android.view.View.OnClickListener;  
import android.view.ViewGroup;  
import android.widget.Button;  
  
public class FragmentOne extends Fragment implements OnClickListener  {  
    private Button mBtn;  
  
    /** 
     * 设置按钮点击的回调 
     * @author zhy 
     * 
     */  
    public interface FOneBtnClickListener{  
        void onFOneBtnClick();  
    }  
  
    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  
            Bundle savedInstanceState){  
        View view = inflater.inflate(R.layout.fragment_one, container, false);  
        mBtn = (Button) view.findViewById(R.id.id_fragment_one_btn);  
        mBtn.setOnClickListener(this);  
        return view;  
    }  
  
    /** 
     * 交给宿主Activity处理,如果它希望处理 
     */  
    @Override  
    public void onClick(View v)  {  
        if (getActivity() instanceof FOneBtnClickListener){  
            ((FOneBtnClickListener) getActivity()).onFOneBtnClick();  
        }  
    }  
}  
  //activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <FrameLayout
        android:id="@+id/id_content"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </FrameLayout>

</RelativeLayout>

1) Fragment与Activity通信

因为所有的Fragment都是依附于Activity的,所以通信起来并不复杂,大概归纳为:

a、如果你Activity中包含自己管理的Fragment的引用,可以通过引用直接访问所有的Fragment的public方法

b、如果Activity中未保存任何Fragment的引用,那么没关系,每个Fragment都有一个唯一的TAG或者ID,可以通过getFragmentManager.findFragmentByTag()或者findFragmentById()获得任何Fragment实例,然后进行操作。

c、在Fragment中可以通过getActivity得到当前绑定的Activity的实例,然后进行操作。

注:如果在Fragment中需要Context,可以通过调用getActivity(),如果该Context需要在Activity被销毁后还存在,则使用getActivity().getApplicationContext()。

图:


第二个文件:  处理运行时配置发生变化

  //MainActivity.java

package com.yline.fragmentscreenspin_four;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.Window;
  
public class MainActivity extends Activity{  
    private static final String TAG = "FragmentOne";  
    private FragmentOne mFOne;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState){  
        super.onCreate(savedInstanceState);  
        requestWindowFeature(Window.FEATURE_NO_TITLE);  
        setContentView(R.layout.activity_main);  
          
        if(savedInstanceState == null)  //避免重构时, 再次创建FragmentOne
        {  
            mFOne = new FragmentOne();  
            FragmentManager fm = getFragmentManager();  
            FragmentTransaction tx = fm.beginTransaction();  
            tx.add(R.id.id_content, mFOne, "ONE");  
            tx.commit();  
        }
    }
}  

    //  FragmentOne.java

package com.yline.fragmentscreenspin_four;

import android.app.Fragment;  
import android.os.Bundle;
import android.view.LayoutInflater;  
import android.view.View;  
import android.view.ViewGroup;  
  
public class FragmentOne extends Fragment  {  
    private static final String TAG = "FragmentOne";  
  
    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  
            Bundle savedInstanceState){
        View view = inflater.inflate(R.layout.fragment_one, container, false);  
        return view;  
    }  
  
    @Override  
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
    }  
  
    @Override  
    public void onDestroyView(){
        super.onDestroyView();
    }  
  
    @Override  
    public void onDestroy(){
        super.onDestroy();
    }  
  
}  
现在无论进行多次旋转都只会有一个Fragment实例在Activity中。

现在还存在一个问题,就是重新绘制时,Fragment发生重建,原本的数据如何保持?

其实和Activity类似,Fragment也有onSaveInstanceState的方法,在此方法中进行保存数据,然后在onCreate或者onCreateView或者onActivityCreated进行恢复都可以。


2) 如何处理运行时配置发生变化

运行时配置发生变化,最常见的就是屏幕发生旋转;

很多人觉得强制设置屏幕的方向就可以了,但是有一点,当你的应用被至于后台(例如用户点击了home),长时间没有返回的时候,你的应用也会被重新启动。比如上例:如果你把上面的例子你至于FragmentThree界面,然后处于后台状态,长时间后你会发现当你再次通过home打开时,上面FragmentThree与FragmentOne叠加在一起,这就是因为你的Activity重新启动,在原来的FragmentThree上又绘制了一个FragmentOne。


 可扩展了解的内容

3) Fragmeny与ActionBar和MenuItem集成

Fragment可以添加自己的MenuItem到Activity的ActionBar或者可选菜单中。

a、在Fragment的onCreate中调用 setHasOptionsMenu(true);

b、然后在Fragment子类中实现onCreateOptionsMenu

c、如果希望在Fragment中处理MenuItem的点击,也可以实现onOptionsItemSelected;当然了Activity也可以直接处理该MenuItem的点击事件。

4) 没有布局的Fragment的作用

没有布局文件Fragment实际上是为了保存,当Activity重启时,保存大量数据准备的

请参考博客:Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案

http://blog.youkuaiyun.com/lmj623565791/article/details/37936275


5) 使用Fragment创建对话框

这是Google推荐的方式, 

请参考博文:Android 官方推荐 : DialogFragment 创建对话框

http://blog.youkuaiyun.com/lmj623565791/article/details/37815413


以上两个代码的链接下载 : (可运行)

http://pan.baidu.com/s/1gdy341X

参考网站:  http://blog.youkuaiyun.com/lmj623565791/article/details/37992017





















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值