UI-Fragment学习
一、Fragment基础使用方法
****fragment是一种可以嵌入在活动中的UI片段,它的优势是让程序更加合理和充分的利用大屏幕的空间。
一个简单的例子:
将一个屏幕分为两部分
1、定义右边界面的布局rightfragment
<?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_TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="This is right fragment"/>
</LinearLayout>
2、定义左边界面的布局leftfragment
<?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">
<Button
android:id="@+id/btn_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Button"/>
</LinearLayout>
3、先定义一个rightfragment类 继承自fragment,并重写onCreatView()方法,在此方法中通过LayoutInflater的inflate方法将刚才定义的rightfragment布局动态加载进来。
public class RightFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.right_fragment,container,false);
return view;
}
}
4、定义一个leftfragment类 继承自fragment,并重写onCreatView()方法,在此方法中通过LayoutInflater的inflate方法将刚才定义的rightfragment布局动态加载进来。
public class LeftFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.left_fragment,container,false);
return view;
}
}
5、修改activity_main.xml中的代码
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
<Button
android:id="@+id/btn_ui_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="70dp"
android:text="fragment Test" />
</FrameLayout>
二、动态加载fragment
**碎片真正的强大之处在于它可以在程序运行中动态地添加到活动中,根据具体情况来动态地添加碎片,就能够将界面定制的更加多样化。
>
另一个简单的例子(在上个例子的基础上):
在一个界面中点击按钮,可以重新加载另一半界面。
1、新建新的anotherRightFragment类以及其布局
public class OtherRightFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.another_right_fragment,container,false);
return view;
}
}
<?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:layout_gravity="center_horizontal"
android:textSize="20sp"
android:text="This is another right fragment"/>
</LinearLayout>
2、修改Activity的布局
<?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.example.uitest.uitest.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"/>
</LinearLayout>
3、修改主Activity类
public class fragmentTestActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment_test);
Button btn_button = (Button)findViewById(R.id.btn_button);
btn_button.setOnClickListener(this);
replaceFragment(new RightFragment());
}
private void replaceFragment(Fragment fragment) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.addToBackStack(null);
transaction.replace(R.id.right_layout, fragment);
transaction.commit();
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btn_button:
replaceFragment(new OtherRightFragment());
break;
default:
break;
}
}
}
我们调用replaceFragment()方法动态添加Rightment这个碎片。1、创建待添加的碎片实例;2、获取FragmentManager,在活动中可以直接通过调用getFragmentManager()方法得到;3、开启一个事务,通过调用beginTransaction()方法开启;4、向容器内添加或替换碎片,一般使用replace()方法实现,需要传入容器的id和待添加的碎片实例;5、提交事务,调用commit()完成;5、此时按下back按钮会退出界面,我们想要返回到上一个fragment的话,使用FragmentTransaction中提供的addToBackStack()方法,这个方法可以将一个事务添加到返回栈中。
三、碎片与活动之间进行通信
碎片都是嵌入到活动中显示的,但是碎片与活动又都在各自存在于一个独立的类中。想要在活动中调用碎片中的方法,或者在碎片中调用活动中的方法,即碎片与活动之间进行通信,如下:
1、调用FragmentManager的findFragmentById()方法在活动中得到相应碎片的实例,然后即可调用碎片中的方法。
RightFragment rightFragment = (RightFragment)getFragmentManager()
.findFragmentById(R.id.right_fragment);
2、每个碎片中都可以通过调用getActivity()方法来得到和当前碎片相关联的活动实例,然后即可调用其方法。
MainActivity mainActivity = (MainActivity)getActivity();
四、fragment与activity互相跳转
1、一个Activity中同一个fragment_layout中的fragment跳转。
- 在此Activity的布局文件中 布置一个公用的fragment_layout,并命名为fragment_layout.
- 定义两个需要跳转的fragment类以及其相对应的布局,分别为Fragment1和Fragment2、fragment1和fragment2,在类中重写onCreatView()方法,加载相对应的布局文件。
在Activity的java文件中,首先初始化fragment_layout;
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initFragment(); } private void initFragment() { getFragmentManager().beginTransaction() .replace(R.id.fragment_layout,new Fragment1(),null) .addToBackStack(null) .commit(); }
写点击事件,当点击activity界面中的某个按钮时,做跳转到Fragment2的活动:
getFragmentManager().beginTransaction() .replace(R.id.fragment_layout,new Fragment2(),null) .addToBackStack(null) .commit();
R.id.xx:Fragment对应的Activity布局中FragmentLayout的id
new XxxFragment():要跳转到的Fragment
addToBackStack(null):可以省略不写(不写表示为非压栈式添加)
2、同一个Activity中,从一个fragment跳转到另一个(点击一个fragment中的按钮进行跳转)
- 上例的基础上,在fragment1的布局文件中添加按钮“跳转碎片按钮”
在Fragment1类中,设置点击事件
getActivity().getFragmentManager().beginTransaction() .replace(R.id.fragment_layout,new Fragment2(), null) .addToBackStack(null) .commit();
3、从一个Activity的fragment跳转到另一个Activity
- 上例基础上,在fragment1的布局文件中添加“跳转活动按钮”,并新建一个活动fragmentTestActivity.
在Fragment1类中,设置点击事件
Intent intent = new Intent(getActivity(),fragmentTestActivity.class); startActivity(intent);
4、从一个Activity跳转到另外一个Activity的fragment上
首先,我们在跳转的时候,需要用Intent跳转到另一个Activity,同时需要传送一个名为id的参数,作为对另一个Activity中不同fragment的标记。
Intent intent = new Intent(MainActivity.this,fragmentTestActivity.class); intent.putExtra("id",2); startActivity(intent);
-然后在另一个Activity的java文件中根据得到的id不同,显示不同的fragment。
if (id == 1)
replaceFragment(new RightFragment());
if (id == 2)
replaceFragment(new OtherRightFragment());
5、从一个Activity的Fragment跳转到另外一个Activity的fragment
这与上面一种情况类似,只需要将MainActivity.this改为getActivity()即可。