碎片是什么
碎片的使用方式
初步接触碎片
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Button"
/>
</LinearLayout>
布局文件中只放了一个水平居中的按钮button。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#00FF00"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:text="This is right fragment"
/>
</LinearLayout>
布局文件中只有一个TextView,显示一句话“This is right fragment”,然后背景颜色是绿色。import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by Deiatg on 2017/3/4.
*/
public class LeftFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//能动态地加载布局的函数inflate()
View view = inflater.inflate(R.layout.left_fragment, container, false);
return view;
}
}
这里仅仅重写了Fragment类中的onCreateView()方法,这个方法的作用就是使用LayoutInflater的inflate()类将刚才定义好的left_fragment.xml动态加载进来。用同样的方法创建一份RightFragment类,代码如下:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by Deiatg on 2017/3/4.
*/
public class RightFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//能动态地加载布局的函数inflate()
View view = inflater.inflate(R.layout.right_fragment, container, false);
return view;
}
}
代码基本相同,我们继续。<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/left_fragment"
android:name="com.open_open.fragmenttest.LeftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<fragment
android:id="@+id/right_fragment"
android:name="com.open_open.fragmenttest.RightFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>
代码将两个碎片一左一右放入主布局中,注意的是要将fragment的完整包名放在android:name中。
动态添加碎片
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#FFFF00"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:text="This is another right fragment"/>
</LinearLayout>
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by Deiatg on 2017/3/4.
*/
public class AnotherRightFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//能动态地加载布局的函数inflate()
View view = inflater.inflate(R.layout.another_right_fragment, container, false);
return view;
}
}
代码同样很简单,在onCreateView()方法中加载刚才创建好的another_right_fragment.xml文件。这就准备好了另一个碎片,之后我们看一下如何将其动态地添加到活动中。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/left_fragment"
android:name="com.open_open.fragmenttest.LeftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<FrameLayout
android:id="@+id/right_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
</FrameLayout>
</LinearLayout>
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
repalceFragment(new RightFragment());
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
repalceFragment(new AnotherRightFragment());
break;
default:
break;
}
}
private void repalceFragment (Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.right_layout, fragment);
transaction.commit();
}
}
代码中MainActivity类实现了OnClickListener接口,这里可以参考我的另一篇文章:链接 。代码中首先我们给左侧碎片中的button按钮注册了一个点击事件,只有点击这个按钮就会调用我们自定义的方法repalceFragment(),这个方法能够当前布局替换一个新的碎片。点击按钮将右侧碎片换成另一个碎片。结合replaeFragment()方法的代码可以看到,动态添加碎片分为五步。在碎片中模拟返回栈
也就是当有多个碎片都被动态添加,我们在调用了它们之后不想按返回键直接退出程序,而是逐个返回碎片,最后退出程序。想达到这种类似栈的返回操作其实很简单,FragmentTransaction中提供了一个addToBackStack()方法,可以用于讲一个事务添加到返回站中,修改代码:public class MainActivity extends AppCompatActivity implements View.OnClickListener{
……
private void repalceFragment (Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.right_layout, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
我们在事务提交之前调用了FragmentTransaction的addToBackStack()方法,它可以接收一个名字用于描述返回栈的状态,一般传入null即可。重新运行程序,我们发现,在碎片中模拟返回栈这个功能我们完成了。