您的位置:首页 > 移动开发 > Android开发

Android_Fragment

2015-11-18 19:22 656 查看
一. Fragment的简介
    Fragment在Android 3.0( API 11)引入,是为了支持在大屏上显示更加动态、灵活的UI,比如在平板和电视上。Fragment可以看作是嵌套的Activity,类似ActivityGroup,但是开销肯定没有ActivityGroup那么大,每一个Fragment管理着一个View,Fragment彼此之间相互独立,有自己的生命周期,这个生命周期是在Activity生命周期中的。Fragment可以用来解决屏幕适配和动态创建View的问题。

二.Fragment的生命周期

       Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。



可以看到Fragment比Activity多了几个额外的生命周期回调方法:
onAttach(Activity)
       当Fragment与Activity发生关联时调用。
onCreateView(LayoutInflater,ViewGroup,Bundle)
       创建该Fragment的视图
onActivityCreated(Bundle)
       当Activity的onCreate方法返回时调用
onDestoryView()
       与onCreateView想对应,当该Fragment的视图被移除时调用
onDetach()
       与onAttach相对应,当Fragment与Activity关联被取消时调用
注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现!

三.Fragment常用的API
Fragment常用的三个类:
android.app.Fragment主要用于定义Fragment

android.app.FragmentManager主要用于在Activity中操作Fragment

   (1)获取FragmentManage的方式:getFragmentManager()// v4中,getSupportFragmentManager

   (2)使用findFragmentById() (用于在activity layout中提供一个UI的fragment)或findFragmentByTag()(适用于有或没有UI的fragment)获取activity中存在的fragment
   (3)将fragment从后台堆栈中弹出, 使用 popBackStack() (模拟用户按下BACK 命令).
   (4)使用addOnBackStackChangeListener()注册一个监听后台堆栈变化的listener.

android.app.FragmentTransaction每一个事务都是同时要执行的一套变化.可以在一个给定的事务中设置你想执行的所有变化,
FragmentTransaction的主要的操作方法
FragmentTransactiontransaction = fm.benginTransatcion();//开启一个事务
transaction.add() 
    往Activity中添加一个Fragment
transaction.remove()
    从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁。
transaction.replace()
    使用另一个Fragment替换当前的,其实就是remove()然后add()
transaction.hide()
    隐藏当前的Fragment,仅仅是设为不可见,并不会销毁
transaction.show()
    显示之前隐藏的Fragment
detach()
    会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。
attach()
    重建view视图,附加到UI上并显示。
transatcion.commit()//提交一个事务
注意:常用Fragment的哥们,可能会经常遇到这样Activity状态不一致:State loss这样的错误。主要是因为:commit方法一定要在Activity.onSaveInstance()之前调用。还有就是在一个事务开启到提交可以进行多个的添加、移除、替换等操作。
 
四.Fragment的使用

静态使用Fragment

        1.继承Fragment,重写onCreateView决定Fragemnt的布局(加载Fragment的布局)
         2.在Activity中声明此Fragment,就当和普通的View一样
       ( 注意:要给Fragment设置ID,要不无法初始化报错)

先看看布局:




静态使用Fragment的下载地址:http://download.csdn.net/detail/two_water/9279253

动态使用Fragment

1.效果图:

.


代码上主界面的代码,其他的想看就下载来看看:

<span style="font-size:12px;"><pre name="code" class="java">package com.liangdianshui.fragment2;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;

public class MainActivity extends Activity implements OnClickListener {

private Button mBtNews;
private Button mBtEntertainment;
private Button mBtSports;
private Button mBtInternational;
private FrameLayout mContent;
private MyFragmentNews frNews;
private MyFragmentEntertainment myFragmentEntertainment;
private MyFragmentInternational myFragmentInternational;
private MyFragmentSports myFragmentSports;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

init();

}

private void init() {
mContent = (FrameLayout) findViewById(R.id.fm_content);
mBtNews = (Button) findViewById(R.id.bt_news);
mBtEntertainment = (Button) findViewById(R.id.bt_entertainment);
mBtSports = (Button) findViewById(R.id.bt_sports);
mBtInternational = (Button) findViewById(R.id.bt_International);
mBtNews.setOnClickListener(this);
mBtEntertainment.setOnClickListener(this);
mBtSports.setOnClickListener(this);
mBtInternational.setOnClickListener(this);
setDefaultContent();
}

private void setDefaultContent() {
FragmentManager fm = getFragmentManager();
FragmentTransaction beginTransaction = fm.beginTransaction();
frNews = new MyFragmentNews();
beginTransaction.replace(R.id.fm_content, frNews);
beginTransaction.commit();
}

public void onClick(View view) {
FragmentManager fm = getFragmentManager();
FragmentTransaction beginTransaction = fm.beginTransaction();
switch (view.getId()) {
case R.id.bt_news:
if (frNews == null) {
frNews = new MyFragmentNews();
}
beginTransaction.replace(R.id.fm_content, frNews);
beginTransaction.commit();
break;
case R.id.bt_entertainment:
if (myFragmentEntertainment == null) {
myFragmentEntertainment = new MyFragmentEntertainment();
}

beginTransaction.replace(R.id.fm_content, myFragmentEntertainment);
beginTransaction.commit();
break;
case R.id.bt_sports:
if (myFragmentSports == null) {
myFragmentSports = new MyFragmentSports();
}
beginTransaction.replace(R.id.fm_content, myFragmentSports);
beginTransaction.commit();
break;
case R.id.bt_International:
if (myFragmentInternational == null) {
myFragmentInternational = new MyFragmentInternational();
}
beginTransaction.replace(R.id.fm_content, myFragmentInternational);
beginTransaction.commit();
break;
default:
break;
}
}

}
</span>


动态使用Fragment的Demo:http://download.csdn.net/detail/two_water/9279255

五.Fragment和Activity之间的通信

效果图和上面的都是一样的!只是考虑Fragment的重复使用,所以必须降低Fragment与Activity的耦合!虽然Fragment和Activity可以通过getActivity与findFragmentByTag或者findFragmentById,进行任何操作,甚至在Fragment里面操作另外的Fragment,但是没有特殊理由是不提倡的。Activity担任的是Fragment间类似总线一样的角色,应当由它决定Fragment如何操作。



因为效果图和上面的动态使用Fragment的效果图差不多!所以不上图了!

贴几个关键的代码:

package com.liangdianshui.fragment2;

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 MyFragmentSports extends Fragment implements OnClickListener {

private Button bt_enter_news;

public interface enterNewsListener {
void enterNewsOnClick();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater
.inflate(R.layout.fragment_sports, container, false);
bt_enter_news = (Button) view.findViewById(R.id.bt_enter_news);
bt_enter_news.setOnClickListener(this);
return view;
}

@Override
public void onClick(View view) {
if (getActivity() instanceof enterNewsListener) {
((enterNewsListener) getActivity()).enterNewsOnClick();
}
}
}


package com.liangdianshui.fragment2;

import com.liangdianshui.fragment2.MyFragmentSports.enterNewsListener;
import com.liangdianshui.fragment2.MyFragmentTitle.titleBtListener;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;

public class MainActivity extends Activity implements titleBtListener,
enterNewsListener {

private FrameLayout mContent;
private MyFragmentNews frNews;
private MyFragmentEntertainment myFragmentEntertainment;
private MyFragmentInternational myFragmentInternational;
private MyFragmentSports myFragmentSports;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setDefaultContent();
}

private void setDefaultContent() {
FragmentManager fm = getFragmentManager();
FragmentTransaction beginTransaction = fm.beginTransaction();
frNews = new MyFragmentNews();
beginTransaction.replace(R.id.fm_content, frNews);
beginTransaction.commit();
}

@Override
public void titleOnClick(View view) {
FragmentManager fm = getFragmentManager();
FragmentTransaction beginTransaction = fm.beginTransaction();
switch (view.getId()) {
case R.id.bt_news:
if (frNews == null) {
frNews = new MyFragmentNews();
}
beginTransaction.replace(R.id.fm_content, frNews);
beginTransaction.commit();
break;
case R.id.bt_entertainment:
if (myFragmentEntertainment == null) {
myFragmentEntertainment = new MyFragmentEntertainment();
}

beginTransaction.replace(R.id.fm_content, myFragmentEntertainment);
beginTransaction.commit();
break;
case R.id.bt_sports:
if (myFragmentSports == null) {
myFragmentSports = new MyFragmentSports();
}
beginTransaction.replace(R.id.fm_content, myFragmentSports);
beginTransaction.commit();
break;
case R.id.bt_International:
if (myFragmentInternational == null) {
myFragmentInternational = new MyFragmentInternational();
}
beginTransaction.replace(R.id.fm_content, myFragmentInternational);
beginTransaction.commit();
break;
default:
break;
}
}

@Override
public void enterNewsOnClick() {
if (frNews == null) {
frNews = new MyFragmentNews();
}
FragmentManager fm = getFragmentManager();
FragmentTransaction beginTransaction = fm.beginTransaction();
beginTransaction.replace(R.id.fm_content, frNews);
beginTransaction.commit();
}
}


package com.liangdianshui.fragment2;

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 MyFragmentTitle extends Fragment implements OnClickListener {

private Button mBtNews;
private Button mBtEntertainment;
private Button mBtSports;
private Button mBtInternational;

public interface titleBtListener {
void titleOnClick(View view);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_title, container, false);
init(view);
return view;
}

private void init(View view) {
mBtNews = (Button) view.findViewById(R.id.bt_news);
mBtEntertainment = (Button) view.findViewById(R.id.bt_entertainment);
mBtSports = (Button) view.findViewById(R.id.bt_sports);
mBtInternational = (Button) view.findViewById(R.id.bt_International);
mBtNews.setOnClickListener(this);
mBtEntertainment.setOnClickListener(this);
mBtSports.setOnClickListener(this);
mBtInternational.setOnClickListener(this);
}

@Override
public void onClick(View view) {
if (getActivity() instanceof titleBtListener) {
((titleBtListener) getActivity()).titleOnClick(view);
}
}

}


其中点击事件中的if(getActivity() instanceof titleBtListener)判断当前的activity是否实现了该接口~

Fragment和Activity通信Demo:http://download.csdn.net/detail/two_water/9279261
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: