基本概念

Fragment,简称碎片,是Android 3.0(API 11)提出的,为了兼容低版本,support-v4库中也开发了一套Fragment API,最低兼容Android 1.6。

过去support-v4库是一个jar包,24.2.0版本开始,将support-v4库模块化为多个jar包,包含:support-fragment, support-ui, support-media-compat等,这么做是为了减少APK包大小,你需要用哪个模块就引入哪个模块。

如果想引入整个support-v4库,则compile 'com.android.support:support-v4:24.2.1',如果只想引入support-fragment库,则com.android.support:support-fragment:24.2.1

  • Fragment是依赖于Activity的,不能独立存在的。
  • 一个Activity里可以有多个Fragment。
  • 一个Fragment可以被多个Activity重用。
  • Fragment有自己的生命周期,并能接收输入事件。
  • 我们能在Activity运行时动态地添加或删除Fragment。

Fragment的优势有以下几点:

  • 模块化(Modularity):我们不必把所有代码全部写在Activity中,而是把代码写在各自的Fragment中。
  • 可重用(Reusability):多个Activity可以重用一个Fragment。
  • 可适配(Adaptability):根据硬件的屏幕尺寸、屏幕方向,能够方便地实现不同的布局,这样用户体验更好。

Demo:FragmentBestPractice兼容平板和手机的一个简易的新闻应用

View层:

双页模式下新闻内容部分的布局:news_fragment_frag.xml:

<?xml version="1.0" encoding="utf-8"?>                                    

单页模式下新闻内容部分的布局activity_news_content.xml:

<?xml version="1.0" encoding="utf-8"?>    

两种模式下共用新闻标题列表的布局news_title_frag.xml:

<?xml version="1.0" encoding="utf-8"?>    

 新闻标题列表的子布局news_item.xml:

<?xml version="1.0" encoding="utf-8"?>

 单页模式下,只加载一个新闻标题的碎片布局:activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>    

 通过限定符的方式系统区分运行的大屏幕还是小屏幕,新建适配大屏幕的布局文件夹layout-sw600dp,在其下创建activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>                    

Model层: 

 新闻类:News.java

public class News {    private String title;    private String content;    public void setContent(String content) {        this.content = content;    }    public String getContent() {        return content;    }    public void setTitle(String title) {        this.title = title;    }    public String getTitle() {        return title;    }}

 Control层:

创建两种模式下共用新闻内容的Fragment:NewsContentFragment.java:

public class NewsContentFragment extends Fragment {    private View view;    @Nullable    @Override    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        view=inflater.inflate(R.layout.news_content_frag,container,false);//获取布局        return view;    }    /**     * 将新闻内容和标题显示到界面上     */    public void refresh(String newsTitle,String newsContent){        View visibilityLayout=view.findViewById(R.id.visibility_layout);//获取子布局        visibilityLayout.setVisibility(View.VISIBLE);//布局设置为可见        TextView newsTitleText= (TextView) view.findViewById(R.id.news_title);        TextView newsContentText= (TextView) view.findViewById(R.id.news_content);        newsTitleText.setText(newsTitle);//刷新标题        newsContentText.setText(newsContent);//刷新内容    }}

 单页模式下引用其上Fragment的Activity:NewsContentActivity.java:

public class NewsContentActivity extends AppCompatActivity {    public static void actionStart(Context context,String newsTitle,String newsContent){        Intent intent=new Intent(context,NewsContentActivity.class);        intent.putExtra("news_title",newsTitle);        intent.putExtra("news_content",newsContent);        context.startActivity(intent);    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_news_content);        String newsTitle=getIntent().getStringExtra("news_title");//获取标题        String newsContent=getIntent().getStringExtra("news_content");//获取内容        NewsContentFragment newsContentFragment= (NewsContentFragment) getSupportFragmentManager().                findFragmentById(R.id.news_content_fragment);        newsContentFragment.refresh(newsTitle,newsContent);//刷新NewsContentFragment界面    }}

两种模式下新闻标题部分的碎片NewsTitleFragment.java:

public class NewsTitleFragment extends Fragment {    private boolean isTwoPane;    @Nullable    @Override    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.news_title_frag, container, false);        RecyclerView newsTitleRecyclerView= (RecyclerView) view.findViewById(R.id.news_title_recycler_view);        LinearLayoutManager manager=new LinearLayoutManager(view.getContext());        newsTitleRecyclerView.setLayoutManager(manager);        NewsAdapter newsAdapter=new NewsAdapter(getNews());        newsTitleRecyclerView.setAdapter(newsAdapter);        return view;    }    private List getNews() {//初始化标题列表        List newsList=new ArrayList<>();        for (int i=1;i<=50;i++){            News news=new News();            news.setTitle("This is the title"+i);            news.setContent(getRandomLengthContent("This is new content"+i+","));            newsList.add(news);        }        return newsList;    }    private String getRandomLengthContent(String content){//随机添加内容        Random random=new Random();        int length=random.nextInt(20)+1;        StringBuilder builder=new StringBuilder();        for (int i=0;i {        private List mNewsList;        class ViewHolder extends RecyclerView.ViewHolder {            TextView newsTitleText;            public ViewHolder(@NonNull View itemView) {                super(itemView);                newsTitleText = (TextView) itemView.findViewById(R.id.news_title);            }        }        private NewsAdapter(List newsList) {            mNewsList = newsList;        }        @NonNull        @Override        public ViewHolder onCreateViewHolder(@NonNull final ViewGroup viewGroup, final int i) {            View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.news_item, viewGroup, false);            final ViewHolder holder = new ViewHolder(view);            view.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    News news = mNewsList.get(holder.getAdapterPosition());                    if (isTwoPane) {                        //如果是双页模式,刷新NewsContentFragment内容                        NewsContentFragment newsContentFragment = (NewsContentFragment) getFragmentManager()                                .findFragmentById(R.id.news_content_fragment);                        newsContentFragment.refresh(news.getTitle(), news.getContent());                    } else {                        //如果是单页模式,直接启动NewsContentActivity                        NewsContentActivity.actionStart(getActivity(), news.getTitle(), news.getContent());                    }                }            });            return holder;        }        @Override        public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {             News news=mNewsList.get(i);             viewHolder.newsTitleText.setText(news.getTitle());        }        @Override        public int getItemCount() {            return mNewsList.size();        }    }}

 主活动MainActivity.java:

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }}

运行效果:

           

Github  源码

更多相关文章

  1. Android入门:布局介绍
  2. AcitonBar自定义布局
  3. Android(安卓)使用RecycleView实现吸附小标题的Demo(附源码)
  4. android六大布局和UI组件
  5. Android的权限机制、通知
  6. android TextInputLayout 更换系统自带眼睛图标
  7. LayoutInflater的使用
  8. kotlin配置
  9. Android(安卓)众多的布局属性详解

随机推荐

  1. Android周学习Step By Step(3)--应用工程文
  2. Android手机直播(三)声音采集
  3. Android多媒体--访问网络上的Audio对应的
  4. 在eclipse 上如何安装 Android 插件
  5. Android中Webview与原生界面交互及二维码
  6. 电池驱动调试总结,电池服务+电量计驱动+调
  7. Android之屏幕适配
  8. Android Studio 删除多余的module Mac 和
  9. Android(安卓)轻松实现仿QQ消息下拉刷新
  10. ShareSDK 第三方分享