Android(安卓)Fragment实践之简易的新闻应用
基本概念
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 源码
更多相关文章
- Android入门:布局介绍
- AcitonBar自定义布局
- Android(安卓)使用RecycleView实现吸附小标题的Demo(附源码)
- android六大布局和UI组件
- Android的权限机制、通知
- android TextInputLayout 更换系统自带眼睛图标
- LayoutInflater的使用
- kotlin配置
- Android(安卓)众多的布局属性详解