Fragment、Activity的知识点总结

来源:互联网 发布:万达电商 淘宝别 编辑:程序博客网 时间:2024/06/11 04:26

一、Fragment

1、Fragment初探

打开或新建activity_main.xml作为主Activity的布局文件,在里面加入两个Fragment的引用,使用android:name前缀来引用具体的

 <fragment  android:id="@+id/fragment1"  android:name="com.example.fragmentdemo.Fragment1"  android:layout_width="0dip"  android:layout_height="match_parent"  android:layout_weight="1" /> 

2、动态添加Fragment(强大之处,必须掌握 ) 

动态添加Fragment主要分为4步:
1.创建待添加的碎片实例。
2.获取到FragmentManager,在Activity中可以直接通过getFragmentManager得到。
3.开启一个事务,通过调用beginTransaction方法开启。
4.向容器内加入Fragment,使用replace或者add方法实现,需要传入容器的id和Fragment的实例。
5.提交事务,调用commit方法提交。

MainActivity.java
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Display display = getWindowManager().getDefaultDisplay();if (display.getWidth() > display.getHeight()) {Fragment1 fragment1 = new Fragment1();getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment1).commit();} else {Fragment2 fragment2 = new Fragment2();getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment2).commit();}}}
备注
Fragment销毁时replace和add两个方法的区别

3、Fragment生命周期
(摘自https://developer.android.com/guide/components/fragments.html)

与Activity类似:
(1)运行程序后

(2)按back键退出程序

重点介绍几个Activity没有的:

- onAttach方法:Fragment和Activity建立关联的时候调用。

- onCreateView方法:为Fragment加载布局时调用。

- onActivityCreated方法:当Activity中的onCreate方法执行完后调用。

- onDestroyView方法:Fragment中的布局被移除时调用。

- onDetach方法:Fragment和Activity解除关联的时候调用。

4、Fragment之间通信

在fragment2中成功获取到了fragment1中的视图,并弹出Toast。这是怎么实现的呢?主要都是通过getActivity这个方法实现的。getActivity方法可以让Fragment获取到关联的Activity,然后再调用Activity的findViewById方法,就可以获取到和这个Activity关联的其它Fragment的视图了。

二、Activity

1、所有Activity在AndroidMainfest文件中注册才能生效

Activity的注册声明都放在<application>标签内
android:name  
具体活动名字,一般是 .name(缩写形式),完整形式是加上最外层的<manifest>标签的package属性所指定的程序包名
android:label   
指定Activity中标题栏的内容,标题栏显示在活动最顶端。另外,还是启动器(Launcher)中应用程序显示的名称,即app_name
<intent-filter>
  <action android :name= "android.intent.action.MAIN" />
  <category android :name= "android.intent.category.LAUNCHER" />
</intent-filter>
做为程序的主活动的声明,即点击桌面应用程序图标时首先打开就是这个活动。
(注意:如果没有声明任何一个活动作为主活动,这个程序仍然可以正常安装,只是你无法在启动器中看到或者打开。这个程序一般都是作为第三方服务,供其他应用在内部调用,如支付宝快捷支付服务)

2、销毁一个Activity
finish( )

3、使用显式Intent
Intent是各组件之间进行交互的一个重要方式,可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。启动Activity、Service、Broadcast

用法 Intent(Context packageContext, Class<?> cls)  第一个参数:启动活动的上下文,  第二个参数: 启动的目标活动
       Activity类中提供startActivity(),专门用于启动Activity,接受一个Intent参数
例子:
Intent Intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);

4、使用隐式Intent
用法1:(没有明确指出哪个Activity, 而是指出一系列更抽象的action和category等信息,然后交给系统去分析这个Intent,并帮我们找出合适的Activity去启动)
在AndroidMainfest.xml:
<activity android:name = ".SecondActivity" >
     <intent-filter>
          <action android:name = "com.example.activitest.ACTION_START" />
           <category android:name = "android.intent.category.DEFAULT" />
           <category android:name = "android.intent.category.MY_CATEGORY " />
      </intent-filter>
</activity>

在FirstActivity.java:
Intent intent = new Intent("com.example.activitest.ACTION_START ");
intent.addCategory("com.example.activitytest.MY_CATEGORY")
startActivity(intent);
//表明我们要启动能够响应“com.example.activitest.ACTION_START ”这个action和"com.example.activitytest.MY_CATEGORY" 这个category的Activity
//android.intent.category.DEFAULT 是一种默认的category,startActivity自动添加到Intent中

用法2:
在FirstActivity.java:
     Intent intent = new Intent(Intent.ACTION_VIEW);
     intent.setData(Uri.parse("http://www.baidu.com"));
     startActivity(intent);
//Intent.ACTION_VIEW 
系统内置的动作action
//setData() 
主要用于指定当前Intent正在操作的数据
//与此对应,我们在<intent-filter>标签中再配置一个<data>标签,
用于更精确的确定当前活动能够响应什么类型的数据。
只有<data>标签中指定的内容和Intent中携带的Data完全一致,
当前的活动才能响应该Intent
//<data>一般配置以下内容:
   android:scheme 
用于指定数据的协议部分,如http部分
   android:hos
用于指定数据的主机名部分,如www.baidu.com部分
   android:port 
用于指定数据的端口部分,一般紧随在主机名之后
   android:path /android:mimeType
   一般不会指定过多的内容,例如指定android:scheme为http, 
   就可以响应所有的http协议的Intent

5、向下一个活动传递数据
FirstActivity发数据:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("extra_data", "Hello SecondActivity");
startActivity(intent);

SecondActivity收数据:
Intent intent = getIntent();
String data = intent.getExtra("extra_data");

//如果传递的数据是整型,用getIntExtra(), 数据是布尔型,用getBooleanExtra()
//一般用Bundle传值更方便,
一是在多个Activity传递数据时,可以直接取,
不用取出来塞到Intent再传递,
二是Bundle支持数据类型更多,可以传递对象putSerializable

6、返回数据给上一个Activity
startActivityForResult()方法,也是用于启动Activity的,但这个方法期望在活动销毁时能够返回一个结果给上一个活动
用法:
在FirstActivity启动SecondActivity
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(intent, 1); //请求码requestCode 是一个唯一值,这里传入1

在SecondActivity.java
Intent intent = new Intent();
intent.putExtra("data_return", "Hello FirstActivity");
setResult(RESULT_OK, intent);  //第一个参数为处理结果(RESULT_OK 或者 RESULT_CANCELED),第二个参数是把带有数据的Intent传递回去
finish();
//在SecondActivity销毁之后会回调上一个Activity的onActivityResult()方法

在FirstActivity重写onActivityResult()方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     switch (requestCode )  {
     case 1: 
               if (resultCode == RESULT_OK )   {
                        String returnedData = data.getStringExtra("data_return") ;
                        Log.d("FirstActivity" , returnedData);
               }
               break;
     default:
     }
}
//为什么有三个参数requestCode, resultCode, data?
   因为在一个Activity中可能调用startActivityForResult()方法去启动很多不同的Activity,每个Activity返回的数据都会回调onActivityResult()
   因此,我们首先通过检查requestCode判断数据来源。
   确定数据是从SecondActivity返回后,再通过resultCode的值判断处理结果是否成功。
   如果成功,取(Intent) data值。
//如果用户是按Back键返回上一个Activity,则需要在SecondActivity.java重写onBackPressed()方法来解决这个情况
   @Override
    public void onBackPressed() {        
     Intent intent = new Intent();
     intent.putExtra("data_return", "Hello FirstActivity");
     setResult("RESULT_OK", intent);
     finish();
    }

7、Activity的生命周期

(摘自https://developer.android.com/reference/android/app/Activity.html)

Android是用任务(Task)来管理Activity的,一个任务就是一组存放在栈里的Activity的集合,这个栈也被称作为返回栈(Back Stack)
Activity状态:
1、运行状态,
当一个Activity位于Back Stack的栈顶时,处于这个状态。系统最不愿意回收这个状态的Activity
 2、暂停状态,
当Activity不再位于Back Stack的栈顶,但仍然可见时。只有内存极低时,才考虑回收。
 3、停止状态,
不再位于栈顶,且完全不可见。系统仍然会保存相应的状态和成员变量,但不完全可靠。
当需其他地方要内存时,这个状态的Activity可能会被回收
4、销毁状态,
从Back Stack中移除后就变成这种状态。
系统最倾向回收这个状态的Activity,从而保证手机内存充足

Activity生命周期:七个回调方法
除了onRestart(),两两相对,可分为三种生存期:
1、完整生存期:onCreate()和onDestroy()之间。
一般:在onCreate()完成初始化操作,在onDestroy()完成释放内存的操作
2、可见生存期:onStart()和onStop()之间,
这段期间,Activity可见,即便无法交互。
通过这两个方法,合理地管理对用户可见的资源。
如在onStart()中对可见的资源进行加载,在onStop()对可见的资源进行释放
3、前台生存期:onResume()和onPause()之间,
这段期间,Activity处于运行状态,可见,且可交互

保证Activity在回收之前,保存临时数据的方法:
     onSaveInstanceState(),携带一个Bundle类型的参数,用于保存数据
     用法:
     @Override
     protected void onSaveInstanceState( BundleoutState ) {
          Super.onSaveInstanceState(outState);
          String tempData = "Something you just typed";
          outState.putString ("data_key", tempData);
     }

     @Override
     protected void onCreate(BundlesavedInstanceState) {
         Super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         if (savedInstanceState != null) {
             String tempData = savedInstanceState.getString("data_key") ;
         }
     }

8、Activity的启动模式
Activity四种启动模式:
(1)standard 默认方式
不管有没有已存在的实例,都生成新的实例。

(2)singleTop
如果跳转的Activity实例已经位于栈顶,则重复利用,不再生成新的实例
如果不位在栈顶,则重新生成一个实例
应用场景:三条推送,点进去都是一个activity,用singletop
 
(3)singleTask
如果发现有对应的Activity实例,则使此Activity实例之上的其他Activity实例统统出栈,使此Activity实例成为栈顶对象,显示到幕前。
应用场景:通常应用于首页,首页肯定得在栈底部,也只能在栈底部。

(4)singleInstance
会启用一个新的栈结构,将Acitvity放置于这个新的栈结构中,并保证不再有其他Activity实例进入
应用场景:通常用于与程序分离的页面,比如说一个新闻程序,然后一个闹钟activity,肯定是singintance


9、Activity的最佳实践
(1)知晓当前是在哪个Activity
新建一个BaseActivity继承Activity(然后让BaseActivity成为项目中所有Activity的父类):
public class BaseActivity extends Activity {
     @Override
     protected void onCreate(Bundle savedInstanceState)  {
          super.onCreate(savedInstanceState);
          Log.d("BaseActivity", getClass().getSimpleName());
}
}
//每当我们进入一个Activity的界面,该Activity的类名就会被打印出来

(2)随时随地退出程序
需求:一个注销或退出的功能
解决思路:只需要一个专门的集合类对所有Activity进行管理就可以
public class ActivityCollector {
     public static List<Activity> activities = new ArrayList<Activity>();
     public static void addActivity(Activity activity) {
          activities.add(activity);
     }
     public static void removeActivity(Activity activity) {
         activities.remove(activity);
     }
     public static void finishAll() {   
          for(Activity activity : activities) {
              if(!activity.isFinishing()) {
                   activity.finish(); 
          }
          }
     }
}
然后在基础类BaseActivity的onCreate()方法和onDestroy()方法:
public class BaseActivity extends Activity {
     @Override
     protected void onCreate(Bundle savedInstanceState)  {
          super.onCreate(savedInstanceState);
          Log.d("BaseActivity", getClass().getSimpleName());
          ActivityCollector.addActivity(this);
     }
     
     @Override
     protected void onDestroy() {
         super.onDetroy(); 
         ActivityCollector.removeActivity(this);
     }
}

(3)启动Activity的最佳写法
 假设SecondActivity中需要用到两个非常重要的字符串参数,在启动SecondActivity的时候必须传过来:
public class SecondActivity extends BaseActivity() {

     public void actionStart(Context context, String data1, String data2) {
          Intent intent = new Intent(context, SecondActivity.class );
          intent.putExtra("param1", data1);
          intent.putExtra("param2", data2);
          context.startActivity(intent); 
     }    
……
}
//可以清晰知道启动SecondActivity需要传递哪些数据,且只需要一行代码就可以启动SecondActivity,
button1.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
              SecondActivity.acionStart(FirstActivity.this, "data1", "data2") ;
          }
     }
);



参考:

1、《第一行代码》

2、http://blog.csdn.net/guolin_blog/article/details/8881711    Android Fragment完全解析,关于碎片你所需知道的一切

3、https://github.com/BuddyZH/FragmentPractice Fragment练习demo

4、潇涧复习总结


0 0