Fragments 简介
自从Android 3.0中引入fragments 的概念,根据词海的翻译可以译为:碎片、片段。
其上的是为了解决不同屏幕分辩率的动态和灵活UI设计。大屏幕如平板小屏幕如手机
,平板电脑的设计使得其有更多的空间来放更多的UI组件
,而多出来的空间存放UI使其会产生更多的交互,从而诞生了fragments 。
fragments 的设计不需要你来亲自管理view hierarchy 的复杂变化,
通过将Activity 的布局分散到frament 中,可以在运行时修改activity 的外观
,并且由activity 管理的back stack 中保存些变化。
这里使用的是android3.0以上的版本,3.0以下需要android-support-v4.jar包的支持
一:新建fragment1.xml布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#ffff00" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="fragment 1" android:textSize="25sp" > </TextView> <Button android:id="@+id/but" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Get fragment2" /> </LinearLayout>
新建Fragment1继承Fragment
package com.example.myfragment; import android.app.ActionBar.LayoutParams; 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; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; public class Fragment1 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment1, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); Button bu = (Button)getActivity().findViewById(R.id.but); bu.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { //得到Fragment2里边控件内容 TextView tv =(TextView) getActivity().findViewById(R.id.tv); Toast.makeText(getActivity(), tv.getText(), Toast.LENGTH_LONG).show(); } }); //后台设置布局 this.getView().setLayoutParams(new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f)); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#00ff00" > <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="fragment2" android:textSize="25sp" > </TextView> </LinearLayout>Fragment2 类
package com.example.myfragment; import android.app.Fragment; import android.app.ActionBar.LayoutParams; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; public class Fragment2 extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment2, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); this.getView().setLayoutParams(new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f)); } }
三:在主界面MainActivity进行后台动态添加
package com.example.myfragment; import android.app.Activity; import android.os.Bundle; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Fragment1 fragment1 = new Fragment1(); Fragment2 fragment2 = new Fragment2(); //第一个参数表示添加到那个控件里边 getFragmentManager().beginTransaction().add(R.id.ml, fragment1).commit(); getFragmentManager().beginTransaction().add(R.id.ml, fragment2).commit(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
上边是后台动态设置布局,后台动态添加上去的会更加灵活。
当然也可以直接使用在布局文件引用Fragment
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ml" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:baselineAligned="false" android:orientation="horizontal" tools:context=".MainActivity" > <fragment android:id="@+id/fragment1" android:name="com.example.myfragment.Fragment1" android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="1" > </fragment> <fragment android:id="@+id/fragment2" android:name="com.example.myfragment.Fragment2" android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="1" > </fragment> </LinearLayout >
向Fragment传参数
四:fragment跳转
1:替换跳转其实是先remove在add
注意:不能直接在fagment中去进行跳转要在容器framentActivity里边写跳转方法然后fragment去调用
例如:容器类FragmentActivity编写方法:
public void switchContent(Fragment fragment) { try{ getSupportFragmentManager() .beginTransaction() .replace(R.id.bt, fragment) .commit(); } catch(Exception e) { System.out.println("主类调用异常:"+e); } }
fragment中调用
.addToBackStack("msg_fragment")//返回键不回来
MainActivity ma = (MainActivity) getActivity(); ma.switchContent(fragment);
当然如果fragment是依赖库的就不能直接调用容器类FragmentActivity编写的方法
这是就需要反射调用了
public <T> void RelInvoke(Class<T> t,Object _ma) throws Exception { t.getDeclaredMethod("switchContent",Fragment.class).invoke(_ma,new ShipScheFragment());//参数为Fragment }
Object ma = getActivity(); try { RelInvoke(ma.getClass(),ma); } catch (Exception e) { System.out.println("反射调用方法报错:"+e); }
2:hide,show方法
public void switchContent(Fragment current,Fragment fragment,String _tag) { try{ FragmentTransaction transaction = getSupportFragmentManager() .beginTransaction(); if(!fragment.isAdded())//没有添加就添加 { System.out.println("第一次添加!"); transaction.hide(current).add(R.id.btaj,fragment,_tag).commit(); } else { // 隐藏当前的fragment,显示下一个 System.out.println("只是隐藏显示"); transaction.hide(current).show(fragment).commit(); } } catch(Exception e) { System.out.println("主类调用异常:"+e); } }
注意:fragment要设置背景颜色,如果不设置默认的透明色可能会出现fragment重叠问题
该方法会执行@Override
public void onHiddenChanged(boolean hidden)事件,当然也可以在隐藏与显示的时候手动调用一下他们的方法也可以达到执行方法的作用
3: 使用detach切换
http://bbs.9ria.com/thread-232184-1-1.html
五:FragmentActivity删除fragment
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
public void switchContent(Fragment fragment,boolean isdelete) { if(isdelete){ List<Fragment> li = getSupportFragmentManager().getFragments(); for(int i=0;i<li.size();i++) { Fragment f=li.get(i); System.out.println("类型:"+f.getClass()); getSupportFragmentManager().beginTransaction().remove(f).commit(); } } try{ getSupportFragmentManager() .beginTransaction() .replace(R.id.bt,fragment) .addToBackStack("msg_fragment")//返回键不回来 .commit(); } catch(Exception e) { System.out.println("主类调用异常:"+e); } }
http://blog.csdn.net/ccm_oliver/article/details/41477027?ref=myread