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传参数
- Bundle bu = new Bundle();
- bu.putString("pretty", "girl");
- fth.addTab(tabSpec3,MainFragment.class, bu);
InsertLogisticsFragment lf = new InsertLogisticsFragment();
Bundle bundle = new Bundle();
bundle.putStringArrayList("ports",cities);
lf.setArguments(bundle);
fragment中取
- Bundle ga = getArguments();
- String val = ga.getString("pretty");
四: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://www.eoeandroid.com/forum.php?mod=viewthread&tid=325112
http://blog.youkuaiyun.com/ccm_oliver/article/details/41477027?ref=myread
六:整理下关于使用Activity还是Fragment的问题
Android是用多个Activity还是用一个Activity加多个Fragment比较好
http://www.zhihu.com/question/37375420?sort=created
http://www.eoeandroid.com/thread-495628-1-1.html
修改个人信息的是一个activity..因为界面都已经发生变化,没有与上一个界面有重复的部分。个人用出来的经验是,界面上只一块需要更新,就用Fragment>.如果整个都更新了,果断开activity..
不必纠结这个,一般页面用activity,页面灵活多变的时候,或者比较复杂需要每部分各自处理的时候用fragment。还有,fragment可以适配手机平板,不需要两套代码
本文详细介绍了Android中Fragment的概念及其应用场景,包括动态添加、参数传递、跳转方法等,并对比了Activity与Fragment在不同场景下的使用建议。
2304

被折叠的 条评论
为什么被折叠?



