android的Fragment
一年前在博客园挖了一个坑,光蹲在这里了,今天开始巴拉巴拉。
刚开始学习android,今天来写写吧。
在我看来,写一个android就如同装修房子,activity就如同一面面墙,我们在墙上面放上各种组件来装饰这面墙。但有时我们可能不想一些东西固定在墙上,或者我们想随时更换,这时我们便需要Fragment这个可拆卸的版块来承装这些东西。或者更形象的说Fragment就是一个画板。熟习html的就可以类比<ifram>标签。
那么我们怎么加入Fragmnet呢?第一种方式直接添加fragment到activity布局中,就等同于将fragment及其视图与activity的视图绑定在一起,且在activity的生命周期过程中,无法切换fragment视图。这就好比在画板上用油漆作画了,只能换画板了。
第二种方式就是像投影仪!在activity布局中添加一个空白的fragment组件,然后我们将写好的xml布局投影到这个fragmengt上。
第一种方式就事把fragment当成一个组件一样用就行了,来说说第二种。
1.首先在activity布局中加入fragment,设置一个id就行。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:paddingBottom="@dimen/activity_vertical_margin" 7 android:paddingLeft="@dimen/activity_horizontal_margin" 8 android:paddingRight="@dimen/activity_horizontal_margin" 9 android:paddingTop="@dimen/activity_vertical_margin" 10 tools:context="com.example.leiyunjie.crime.MainActivity"> 11 12 <FrameLayout 13 android:id="@+id/fragment" 14 android:layout_width="match_parent" 15 android:layout_height="wrap_content"> 16 17 </FrameLayout> 18 </RelativeLayout>
2.有了投影布,我们现在来写一张ppt要投影的内容。新建一个xml布局文件。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical"> 6 7 <TextView 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content" 10 android:text="title" 11 style="?android:listSeparatorTextViewStyle"/> 12 13 14 <EditText 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" 17 android:id="@+id/edit" 18 android:hint="enter a title"/> 19 20 21 <TextView 22 android:layout_width="match_parent" 23 android:layout_height="wrap_content" 24 android:text="detail" 25 style="?android:listSeparatorTextViewStyle"/> 26 27 <Button 28 android:layout_width="match_parent" 29 android:layout_height="wrap_content" 30 android:id="@+id/date" 31 android:layout_marginLeft="16dp" 32 android:layout_marginRight="16dp"/> 33 <CheckBox 34 android:layout_width="match_parent" 35 android:layout_height="wrap_content" 36 android:id="@+id/check" 37 android:layout_marginLeft="16dp" 38 android:layout_marginRight="16dp" 39 android:text="solved" 40 /> 41 42 43 44 45 </LinearLayout>
这就是加了几个组件意思意思。
3.现在还差什么?对,差投影仪。那应该怎么办呢?找java呀!在activity对应的java文件中,写入一下代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.example.leiyunjie.crime; 2 3 import android.support.v4.app.Fragment; 4 import android.support.v4.app.FragmentActivity; 5 import android.support.v4.app.FragmentManager; 6 import android.support.v7.app.AppCompatActivity; 7 import android.os.Bundle; 8 9 public class MainActivity extends FragmentActivity { 10 11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.activity_main); 15 FragmentManager fm=getSupportFragmentManager(); 16 Fragment fragment=fm.findFragmentById(R.id.fragment); 17 18 if(fragment==null){ 19 fragment=new fragmnet(); 20 fm.beginTransaction() 21 .add(R.id.fragment,fragment) 22 .commit(); 23 } 24 25 } 26 }
其中关键代码是:
FragmentManager fm=getSupportFragmentManager();
Fragment fragment=fm.findFragmentById(R.id.fragment);
if(fragment==null){
fragment=new fragmnet();
fm.beginTransaction()
.add(R.id.fragment,fragment)
.commit();
}
首先呢,我们要放ppt总不是就一张吧,是好几张,所以我们需要一个Manager,一个经理。FragmentManager fm=getSupportFragmentManager(),fm就是我们请来的经理,我们用getSupportFragmentManager()来获得一个合适的管理人员,然后他就要开始召唤自己的小弟来开工了 fm.findFragmentById(R.id.fragment)。为什么队列中有fragment存在了呢? CrimeActivity 因设备旋转或回收内存被销毁后重建时, CrimeActivity.onCreate(...) 方法会响应activity的重建而被调用。activity被销毁时,它的 FragmentManager 会将fragment队列保存下来。 这样, activity重建时, 新的 FragmentManager会首先获取保存的队列,然后重建fragment队列,从而恢复到原来的状态。但如果通过小弟的ID编号来召唤。那如果那个岗位空人呢 (fragment==null)?没事,牛逼的经理可以自己再招人 fragment=new fragmnet()下面再说怎么找人的事。然后就是开工咯。fm.beginTransaction() 即FragmentManager.beginTransaction() 该方法创建并返回 FragmentTransaction 实例。FragmentTransaction 类使用了一个fluent interface接口方法,通过该方法配置 FragmentTran-saction 返回 FragmentTransaction 类对象,而不是 void ,由此可得到一个 FragmentTransa-ction 队列。因此,代码可解读为: “创建一个新的fragment事务,加入一个添加操作,然后提交该事物。 ”
4.现在说说经理怎么招人。其实也是把fragment布局的元素放入到fragmnet中,形象地说就是把准备好的ppt内容加上事件放好在一张ppt页面上。
我们新建一个fragmnet类,代码如下(其实这就相当于layout对应的activity.java)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.example.leiyunjie.crime; 2 3 import android.os.Bundle; 4 import android.support.annotation.Nullable; 5 import android.support.v4.app.Fragment; 6 import android.text.Editable; 7 import android.text.TextWatcher; 8 import android.view.LayoutInflater; 9 import android.view.View; 10 import android.view.ViewGroup; 11 import android.widget.Button; 12 import android.widget.CheckBox; 13 import android.widget.CompoundButton; 14 import android.widget.EditText; 15 16 /** 17 * Created by leiyunjie on 2016/4/18. 18 */ 19 public class fragmnet extends Fragment { 20 private crime mcrime; 21 private EditText mTitleField; 22 private Button mButton; 23 private CheckBox mCheck; 24 25 @Override 26 public void onCreate(@Nullable Bundle savedInstanceState) { 27 super.onCreate(savedInstanceState); 28 mcrime=new crime(); 29 } 30 31 @Nullable 32 @Override 33 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 34 View v=inflater.inflate(R.layout.fragment,container,false); 35 36 mTitleField=(EditText)v.findViewById(R.id.edit); 37 mTitleField.addTextChangedListener(new TextWatcher() { 38 @Override 39 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 40 mcrime.setmTitle(s.toString()); 41 } 42 43 @Override 44 public void onTextChanged(CharSequence s, int start, int before, int count) { 45 46 } 47 48 @Override 49 public void afterTextChanged(Editable s) { 50 51 } 52 }); 53 54 55 56 mButton=(Button)v.findViewById(R.id.date); 57 mButton.setText(mcrime.getmDate().toString()); 58 mButton.setEnabled(false); 59 60 61 62 63 mCheck=(CheckBox)v.findViewById(R.id.check); 64 mCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 65 @Override 66 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 67 mcrime.setmSolved(isChecked); 68 } 69 }); 70 71 72 73 74 75 return v; 76 } 77 78 79 }
public class fragmnet extends Fragment 继承Fragemnt的类。然后就是重写他的的函数咯。
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
也就是onCreate和onCreateVie这俩个大兄弟。其他函数可以自己去看看,挺多的。
关键只有一句那就是onCreateVie方法中的View v=inflater.inflate(R.layout.fragment,container,false);其中第一个inflater是LayoutInflater对象,也就是方法自带的第一个参数。第二个inflaer是一个函数,顾名思义打气筒就是把东西充到一个容器里面,也就是把fragment布局的组件填充到container中。我觉得这和activity的setContentView(R.layout.activity_main)意思差不多。注意其中的mTitleField=(EditText)v.findViewById(R.id.edit);中的v.findViewById.
代码中我定义了一个类,对Fragement没有什么影响,如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.example.leiyunjie.crime; 2 3 import java.util.Date; 4 import java.util.UUID; 5 6 /** 7 * Created by leiyunjie on 2016/4/18. 8 */ 9 public class crime { 10 private UUID mID; 11 private String mTitle; 12 private Date mDate; 13 private boolean mSolved; 14 15 public crime(){ 16 mID=UUID.randomUUID(); 17 mDate=new Date(); 18 } 19 20 public String getmTitle() { 21 return mTitle; 22 } 23 24 public void setmTitle(String mTitle) { 25 this.mTitle = mTitle; 26 } 27 28 public UUID getmID() { 29 return mID; 30 } 31 32 public Date getmDate() { 33 return mDate; 34 } 35 36 public void setmDate(Date mDate) { 37 this.mDate = mDate; 38 } 39 40 public boolean ismSolved() { 41 return mSolved; 42 } 43 44 public void setmSolved(boolean mSolved) { 45 this.mSolved = mSolved; 46 } 47 }
好了,现在总结一下:就是用FragmentManager去管理Fragment,那么就需要去弄一个fragment布局,所以我们写一个自己的fragment的类class fragmnet extends Fragment 来承装这个布局,然后用这个类实例化一个对象(fragment=new fragmnet();)给FragmentManager的对象(FragmentManager fm=getSupportFragmentManager();)来管理就OK了。