1. Fragment概念及作用。
以下是使用Fragment提供思路
2. 创建继承于 Fragment的类:(可extends Fagment 或 ListFagment)
注意导包:如果考虑兼容就用 android.support.v4.app.ListFragment;
以下内容只是创建Fargment的例子
package ainux.bing.fragmentsingleactivity.Fragments; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.ListFragment; import android.util.Log; import android.view.View; import android.widget.ArrayAdapter; import android.widget.ListView; import java.util.Arrays; import java.util.List; import ainux.bing.fragmentsingleactivity.Activitys.ContentActivity; /** * A simple {@link Fragment} subclass. */ public class ListTitleFragment extends ListFragment { public static final int REQUEST_DETAIL = 0x110; private List<String> Mtitles= Arrays.asList("xiaobing", "like", "Android"); private ArrayAdapter<String> madapter; private int mcurentPos; public ListTitleFragment() { // Required empty public constructor } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setListAdapter(madapter=new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,Mtitles)); } @Override public void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); mcurentPos=position; //跳转Activity Intent intent = new Intent(getActivity(), ContentActivity.class); //传值 intent.putExtra(ContentFragment.ARGUMENT, Mtitles.get(position)); startActivityForResult(intent,REQUEST_DETAIL); } //接收宿主Activity传递过来的数据 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.e("TAG", "onActivityResult"); if (requestCode==REQUEST_DETAIL) { Mtitles.set(mcurentPos, Mtitles.get(mcurentPos) + "--" + data.getStringExtra(ContentFragment.RESPONSE)); madapter.notifyDataSetChanged(); } } }
3. 在宿主Activity中的使用及传值方法
a.创建抽象类 继承 FragmentActivity(适用某一情况下)
红色 字体部分为 将Fragment加载到Activty中
package ainux.bing.fragmentsingleactivity.Activitys; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import ainux.bing.fragmentsingleactivity.R; public abstract class SingleFragmentActivity extends FragmentActivity { //创建fragment实例 protected abstract Fragment createFragment(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_single_fragment); FragmentManager fm = getSupportFragmentManager(); Fragment fragment = fm.findFragmentById(R.id.id_fragment_container); //将Fragment放在哪个布局中,id为布局ID //避免重新创建新的fragment(屏幕旋转的时候) if (fragment == null) { fragment = createFragment(); fm.beginTransaction().add(R.id.id_fragment_container, fragment).commit(); } } }
b. 创建实际应用的的activty 继承于 SingleFragmentActivity
package ainux.bing.fragmentsingleactivity.Activitys; import android.support.v4.app.Fragment; import ainux.bing.fragmentsingleactivity.Fragments.ListTitleFragment; public class ListTitleActivity extends SingleFragmentActivity { protected Fragment listFragment; @Override protected Fragment createFragment() { listFragment = new ListTitleFragment(); return listFragment; } }
b . Fragment与它的Activity之间进行数据交换的方式。
1.Fragment中通过getActivity()然后进行强制转化,调用Activity中的公有方法(fun())
在Fragment中调用
((XXXXActivity)getActivity()).fun();
2.Activity在切换Fragment的时候,通过setArguments向Fragment传递参数,Fragment通过getArguments();获得从activity中传递过来的值
package ainux.bing.fragmentsingleactivity.Fragments; import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.Random; /** * A simple {@link Fragment} subclass. */ public class ContentFragment extends Fragment { public static final String ARGUMENT = "argument"; public static final String RESPONSE = "response"; private String mArgument; public ContentFragment() { // Required empty public constructor } /** * 使用静态工厂方法实例化Fragment,并使用setArguments方法传值 * 使用setArguments的作用及好处参见:http://blog.csdn.net/tu_bingbing/article/details/24143249?utm_source=tuicool * @param argument * @return */ public static ContentFragment newInstance(String argument) { Bundle bundle = new Bundle(); bundle.putString(ARGUMENT, argument); ContentFragment contentFragment = new ContentFragment(); contentFragment.setArguments(bundle); return contentFragment; } /** * * @param savedInstanceState */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle bundle = getArguments(); if (null!=bundle) { mArgument = bundle.getString(ARGUMENT); Intent intent = new Intent(); intent.putExtra(RESPONSE, "good"); getActivity().setResult(ListTitleFragment.REQUEST_DETAIL,intent); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Random random = new Random(); TextView tv = new TextView(getActivity()); tv.setText(mArgument); tv.setGravity(Gravity.CENTER); tv.setBackgroundColor(Color.argb(random.nextInt(100), random.nextInt(255), random.nextInt(255), random.nextInt(255))); return tv; } }
在activity中,调用
package ainux.bing.fragmentsingleactivity.Activitys; import android.support.v4.app.Fragment; import ainux.bing.fragmentsingleactivity.Fragments.ContentFragment; public class ContentActivity extends SingleFragmentActivity { private ContentFragment contentFragment; //实现抽象方法 @Override protected Fragment createFragment() { //通过静态工厂方法创建 Fragment实例 //将传递过来的值 赋值给Fragment String stringExtra = getIntent().getStringExtra(ContentFragment.ARGUMENT); contentFragment = ContentFragment.newInstance(stringExtra); return contentFragment; } }
3.Activity实现一个接口,Fragment在onAttach方法中,将该Activity转化为该接口,在需要调用的时候回调。
你会经常想要一个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(); } } }