您的位置:首页 > 其它

更好的使用Fragment及避免使用时出现的问题

2017-02-16 12:21 253 查看
在之前的使用过程中感觉用到的时候只需要在网上随便的查到一下相应的代码就可以很轻松的使用Fragment了,但是之后项目中总是会出现这样那样的问题,为什么呢,主要是我们没有真正的学习到Fragment的使用精髓和使用技巧,导致我们编码时出现很多问题,造成了我们做了很多无用功,有了之前的经历,我这里就详细的学习了一下Fragment。

1、Fragment的介绍和使用场景

   随着移动信息的快速发展,目前出现的手机尺寸已经数不胜数了,而且针对平板的项目中Fragment的使用更为的普遍,所以对于详细的学习Fragment极为重要。对于Fragment和Activity的关系,我们看一下出自官方的Fragment和Activity的关系图:



onAttach(Activity)

当Fragment与Activity发生关联时调用。(注:在平板开发中是十分重要的)

onCreateView(LayoutInflater, ViewGroup,Bundle)

创建该Fragment的视图

onActivityCreated(Bundle)(注:在平板开发中是十分重要的)

当Activity的onCreate方法返回时调用

onDestoryView()

与onCreateView想对应,当该Fragment的视图被移除时调用

onDetach()

与onAttach相对应,当Fragment与Activity关联被取消时调用

2、Fragment的使用

 关于Fragment的生命周期做了简单的介绍,现在介绍一下Fragment的使用,Fragment的静态的使用这里就不多的介绍了,我们现在就来对Fragment的动态的使用来分析一下。对于动态的使用我们也是需要根据用户的要求来的,主要分为以下的两种:
     ①、当用户切换回去时是要保留之前的内容的话,就适合用hide和show、add方法。
if (homeFragment != null) {
transaction.hide(homeFragment);
}
if (homeFragment == null) {
homeFragment = new HomeFragment();
ft.add(R.id.content_main, homeFragment);
} else {
ft.show(homeFragment);
}
②、如果用户不希望保留切换回去之前的数据的话使用remove和add(replace)就可以了
具体的就不帖代码了

3、使用Fragment是所要考虑的

 无论做什么我们都会考虑一下,为什么要这样做
 1、是否要保存Fragment的数据
 2、Fragment是否要重复的使用
 3、怎么处理运行时配置发生的变化
解决方案:
1、针对第一个问题,这就要引入管理Fragment回退栈  如果不添加事务到回退栈,前一个Fragment实例会被销毁,这可能就不是我们想要的啦,所以有时候对Fragment加入回退栈是什么有必要的而且十分简单 如:addToBackStack()就可以了。
2、有时候做手机app可能就会没有这么太的体会,但是如果做平板app的时候,就会深有体会的。考虑Fragment的重复使用时很有必要的,无论是降低Fragment与activity的耦合,还其他都很有必要的,再者Fragment也不应该直接操作别的Fragment的
3、当屏幕发生旋转,activity发生重启的时候,默认的activity的Fragment也会跟着activity重新的创建,所以有时会出现数据重叠的问题,针对这个问题,我们可以通过检查oncreate的参数bundle saceInstanccceState 就可以判断的
if(savedInstanceState == null){
//。。。具体的操作
}

4、关于平板和Fragment的适配相关的问题

有时候我们会有道一个软件即在手机上运行又在平板上运行,这时就需要我们对其进行适配了,我们可以根据具体的尺寸大小来设置一些的配置。我们先看一下下图的简单适配:


有特殊的平板尺寸我们可以我们可以按照上面的例子来进行加入布局文件layout-sw600dp 和 资源文件value-w820dp等。
具体的代码怎么写我们可以参考《第一行代码》中的实例activity-main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.xichen.fragmentbestpractice.MainActivity">

<fragment
android:id="@+id/news_title_fragment"
android:name="com.example.xichen.fragmentbestpractice.NewsTitleFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
layout-sw600dp下的activity-main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.xichen.fragmentbestpractice.MainActivity">

<fragment
android:id="@+id/news_title_fragment"
android:name="com.example.xichen.fragmentbestpractice.NewsTitleFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<FrameLayout
android:id="@+id/news_content_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3">
<fragment
android:id="@+id/news_content_fragment"
android:name="com.example.xichen.fragmentbestpractice.NewsContentFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
</LinearLayout>
在Fragment的适配代码如下:
此处代码为《第一行代码》中的实例
public class NewsTitleFragment extends Fragment {

private List<News> newsList = new ArrayList<News>();
private NewsAdapter adapter;
private boolean isTwoPane;

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
initNews();
adapter = new NewsAdapter(activity, R.layout.news_item, newsList);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ListView newsTitleListView;
View view = inflater.inflate(R.layout.news_title, container, false);
newsTitleListView = (ListView) view.findViewById(R.id.news_title_list_view);
newsTitleListView.setAdapter(adapter);
newsTitleListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
News news = newsList.get(position);
if(isTwoPane) {
NewsContentFragment newsContentFragment = (NewsContentFragment)
getFragmentManager().findFragmentById(R.id.news_content_fragment);
newsContentFragment.refresh(news.getNewsTitle(), news.getNewsContent());
}
else{
NewsContentActivity.actionStart(getActivity(),news.getNewsTitle(), news.getNewsContent() );
}
}
});
return view;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
isTwoPane = getActivity().findViewById(R.id.news_content_layout) != null;
}

void initNews() {
News news = new News();
news.setNewsTitle("The Internet of (insecure) Things and other inside observations from the Black Hat hackers conference");
news.setNewsContent("It doesn't feel like we're quite ready for all this stuff to be connected yet. By James Plouffe Aug 11, 2016, 7:22p. tweet · share · Linkedin.");
newsList.add(news);
news = new News();
news.setNewsTitle("Facebook rolls out code to nullify Adblock Plus' workaround");
news.setNewsContent("Adblock Plus launched a workaround to Facebook's ad
9f35
block bypass today that ham-handedly removes posts from friends and Pages, not just ads, according to a statement provided by Facebook to TechCrunch.");
newsList.add(news);
}
}
我们注意到首先得们要对activity进行关联
public void onAttach(Activity activity) {
super.onAttach(activity);
initNews();
adapter = new NewsAdapter(activity, R.layout.news_item, newsList);
}
接着我们在调完activity的oncreate方法后我们也调用了onActivityCreated进行判断如下:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
isTwoPane = getActivity().findViewById(R.id.news_content_layout) != null;
}
具体针对屏幕适配的可以看看这篇文章http://www.cocoachina.com/android/20151030/13971.html
以上只是我个人参考别人的文章做了一下总结,希望大家多多关照,不喜勿喷,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: