今天继续在昨天的基础上继续学习Fragment,今天还是以视频学习为主,今天主要学习了动态加载Fragment以及Fragment与Activity之间的交互。
话不多说,直奔正题。
一、动态加载Fragment
动态加载Fragment主要是借助于事务来实现的。
一、首先是在布局文件中为即将进行动态加载的Fragment申请一块空间,这里不是去用<fragment>标签是申请,用<fragment>去申请是静态加载的步骤之一,这里一定要分清。一般采用一种布局文件去申请空间,建议使用FrameLayout,便于以后替换的时候方便。
二、去创建一个xml文件用于创建将要进行动态加载控件,以及创建一个相应的类文件,继承Fragment,不要忘记写出无参构造函数。
三、在主活动的onCreate()方法中进行Fragment加载,主要是使用事务来实现,详细见代码。
二、关于交互
1.Fragment发送数据信息或者信息到Activity
2.Activity给Fragment发送消息(2种方式)
a.采用Fragment替换的形式,那么把消息
作为参数传递给Fragment(设置setArguement(Bundle))))
b.采用针对已经存在的Fragment,不进行
替换,而是找到这个Fragment,通过Fragment提供
的方法,直接更新显示内容
3.目标Fragment启动或者接收到参数信息
为了进行上述的练习,写了如下的代码,主要是实现以下的界面和相关的操作:
点击城市列表的城市会在右边显示详情。
下面粘贴上代码:
MainActivity代码
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//第二种方法采用查找的方式
public void receiveLetter(String letter)
{
//在活动中获取Fragment的方法
FragmentManager manager=getSupportFragmentManager();
//若想要使用findFragmentById的方式,则Fragment必须在一个布局文件中,否则无法获取
Fragment fragment=manager.findFragmentById(R.id.detail_fragment);
//为了避免异常情况报错,要进行一下判断
if(fragment!=null&&fragment instanceof DetailFragment)
{
//将获得的Fragment进行一下强制类型转换
DetailFragment detailFragment=(DetailFragment)fragment;
//调用方法进行信息的显示,一般就是使用方法进行相关的操作
detailFragment.displayContent(letter);
}
}
//第一种方法
//用于接收从Fragment1传来的信息,还要把信息传递给
//Fragment2
//public void receiveLetter(String letter)
//{
// if(letter!=null)
// {
// FragmentManager manager=getSupportFragmentManager();
// FragmentTransaction transaction=manager.beginTransaction();
// //初始化Fragment并切设置参数
// DetailFragment fragment=new DetailFragment();
// Bundle args=new Bundle();
//
// args.putString("cityName",letter);
// 先将DetailFragment的内容进行改变之后,在进行替换
// 这一步就是将数据传递给了另一个Fragment,所以说可以在另外一个进行取出
// fragment.setArguments(args);
// transaction.replace(R.id.fragment_container,fragment);
//最后将事务进行提交
// transaction.commit();
// }
// }
}
activity_main.xml代码:为了测试第二种方法,对布局文件做了修改,这是静态加载布局文件
<fragment
android:id="@+id/city_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="com.example.fragmentinteract.fragments.CityFragment"/>
<fragment
android:id="@+id/detail_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:name="com.example.fragmentinteract.fragments.DetailFragment"/>
CityFragment代码:
public class CityFragment extends Fragment implements AdapterView.OnItemClickListener {
private List<String> data;
private ArrayAdapter<String> adapter;
public CityFragment()
{
}
@Nullable
//用于创建Fragment的界面
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View ret=inflater.inflate(R.layout.fragment_city,container,false);
ListView listView=(ListView) ret.findViewById(R.id.list_city);
if(listView!=null)
{
//数据 ctrl alt f 常用变量
data = new LinkedList<String>();
data.add("北京");
data.add("上海");
data.add("天津");
data.add("广州");
//创建适配器
//fragment内部获取Context相关(或Activity)对象,getActivity()
adapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,
data);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}
return ret;
}
//被交给Activity的时候,回调这个方法
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String cityName=data.get(position);
//在Fragment中获取活动
FragmentActivity activity=getActivity();
//判断活动是否是MainActivity的实例
if(activity instanceof MainActivity)
{
//进行强制类型转换
MainActivity yellow=(MainActivity)activity;
//向函数进行传参数
yellow.receiveLetter(cityName);
}
}
}
fragmentcity.xml代码:
<ListView
android:id="@+id/list_city"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
DetailFragment代码:
public class DetailFragment extends Fragment {
private TextView textView;
public DetailFragment()
{
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View ret=inflater.inflate(R.layout.fragment_detail,container,false);
//第一种方法进行的操作
textView = (TextView)ret.findViewById(R.id.txt_content);
if(textView !=null)
{
//获取存储在Bundle的数据,Bundle基本可以在任意一处使用
Bundle arguements=getArguments();
if(arguements!=null) {
//将数据取出来
String cityName = arguements.getString("cityName");
if(cityName!=null)
{
//将其设置在textview
//刚刚只是将事务替换了,也就是说那块区域归它了,但是相关的
//操作还是要在加载布局的类中进行操作的
textView.setText(cityName);
}
}
}
return ret;
}
/**
* 在运行时动态显示文字,这个方法肯定在onCreateView之后调用
* @param letter
*/
public void displayContent(String letter) {
if(textView!=null)
{
if(letter!=null)
{
textView.setText(letter);
}
}
}
}
fragmentdetail.xml代码:
<TextView
android:id="@+id/txt_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#F00"
android:textSize="30sp"
android:text="详情"
/>
好了,这样就用两种方法实现了信息的交互并完成了界面效果。
感觉还是得注意细节,代码只看不行,关键还是得动手去训练,明天进行一下Fragment的知识回顾,进行一下小小的实战!!!
明天,加油!