当前位置:   article > 正文

利用Fragment编写简易新闻界面,布局同时适应Android手机和平板电脑_fragment简易新闻

fragment简易新闻

        大家好,最近从事培训工作碰到一个练习题,利用Fragment编写简易新闻界面,并且布局能同时适应手机和平板电脑,这是书本上的一个练习题,题目本身没多大难度,个人觉得作者代码的模块化做得比较好,所以拿出来分享,同时自己学习也复习、巩固一下。

        首先大体介绍下界面布局,如下图:

分为手机、平板两个界面:

        对于手机界面是个ListView,各个项显示新闻标题,点击某ListView的某一项跳转到另一个Activity显示新闻正文;

        对于平板电脑界面,左边是个ListView,用于显示新闻标题,右边是垂直摆放的两个TextView,分别显示新闻标题和新闻内容,这两边都是Fragment。

下面介绍代码,布局的具体实现。

1、新建News.java类,用于管理储存、获取新闻数据的类,代码如下:

  1. package com.gta.newsapptest;
  2. public class News {
  3. private String title;
  4. private String content;
  5. public News() {
  6. }
  7. public String getTitle(){
  8. return this.title;
  9. }
  10. public String getContent(){
  11. return content;
  12. }
  13. public void setTitle(String title){
  14. this.title = title;
  15. }
  16. public void setContent(String content){
  17. this.content = content;
  18. }
  19. }

2、在Layout文件下新建new_item.xml,此文件会被加载到ListView的单项中,里面只是一个TextView,用于显示新闻标题,代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6. <TextView
  7. android:id="@+id/news_title"
  8. android:layout_width="match_parent"
  9. android:layout_height="wrap_content"
  10. android:singleLine="true"
  11. android:ellipsize="end"
  12. android:textSize="18sp"
  13. android:paddingLeft="10dp"
  14. android:paddingTop="15dp"
  15. android:paddingRight="10dp"
  16. android:paddingBottom="15dp"/>
  17. </LinearLayout>
3、新建NewsAdapter.java,此类继承ArrayAdapter<News>适配器,通过getView()方法给ListView的每一项填充new_item.xml布局和新闻标题数据,代码如下:

  1. package com.gta.newsapptest;
  2. import java.util.List;
  3. import android.content.Context;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.ViewGroup;
  7. import android.widget.ArrayAdapter;
  8. import android.widget.TextView;
  9. public class NewsAdapter extends ArrayAdapter<News>{
  10. private static final String TAG = "TAG";
  11. private int resourceId;
  12. public NewsAdapter(Context context, int resource, List<News> objects) {
  13. super(context, resource, objects);
  14. resourceId = resource;
  15. // Log.d(TAG, objects.size() + "");
  16. }
  17. @Override
  18. public View getView(int position, View convertView, ViewGroup parent) {
  19. // super.getView(position, convertView, parent);
  20. View view ;
  21. // News news = newsList.get(position);
  22. News news = getItem(position);//获取position位置的新闻数据
  23. // Log.d(TAG, news.getTitle());
  24. //如果当前项视图没有加载布局,则进行加载否则直接从converView对象中获取,防止重复加载降低效率
  25. if(convertView == null){
  26. view = LayoutInflater.from(getContext()).inflate(resourceId, null);
  27. }
  28. else {
  29. view = convertView;
  30. }
  31. TextView tv = (TextView) view.findViewById(R.id.news_title);
  32. tv.setText(news.getTitle());
  33. return view;
  34. }
  35. }

4、在Layout文件下新建news_title_frag.xml文件,此文件中放置一个ListView控件用于显示新闻标题,下一步将在Fragment中加载此布局文件,代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6. <ListView
  7. android:id="@+id/news_title_list_view"
  8. android:layout_width="match_parent"
  9. android:layout_height="wrap_content">
  10. </ListView>
  11. </LinearLayout>

到这里ListView新闻列表布局已经完成,下面编写新闻标题和内容布局

5、在layout文件下新建news_content_frag.xml文件,此文件的作用是为新闻的标题和正文设置布局,分别是两个TextView,同时下一步将会继承Fragment加载此布局,代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent" >
  5. <LinearLayout
  6. android:id="@+id/visibility_layout"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"
  9. android:orientation="vertical"
  10. android:visibility="invisible">
  11. <TextView
  12. android:id="@+id/news_title"
  13. android:layout_width="match_parent"
  14. android:layout_height="wrap_content"
  15. android:gravity="center_horizontal"
  16. android:padding="10dp"
  17. android:textSize="20sp"/>
  18. <ImageView
  19. android:layout_width="match_parent"
  20. android:layout_height="1dp"
  21. android:background="#000000"/>
  22. <TextView
  23. android:id="@+id/news_content"
  24. android:layout_width="match_parent"
  25. android:layout_height="0dp"
  26. android:layout_weight="1"
  27. android:padding="15dp"
  28. android:textSize="18sp"/>
  29. </LinearLayout>
  30. <ImageView
  31. android:layout_width="1dp"
  32. android:layout_height="match_parent"
  33. android:background="#000000"/>
  34. </RelativeLayout>

6、新建NewsContentFragment.java类,此类继承Fragment加载news_content_frag.xml布局,同时编写refresh()函数用于刷新新闻标题和数据,代码如下:

  1. package com.gta.newsapptest;
  2. import android.app.Fragment;
  3. import android.os.Bundle;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.ViewGroup;
  7. import android.widget.TextView;
  8. public class NewsContentFragment extends Fragment {
  9. private View view;
  10. @Override
  11. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  12. Bundle savedInstanceState) {
  13. super.onCreateView(inflater, container, savedInstanceState);
  14. //加载news_content_frag.xml布局
  15. view = inflater.inflate(R.layout.news_content_frag, container, false);
  16. return view;
  17. }
  18. /**
  19. * 用于刷新新闻标题和内容
  20. * @param newsTitle
  21. * @param newsContent
  22. */
  23. public void refresh(String newsTitle, String newsContent){
  24. View visibilityLayout = view.findViewById(R.id.visibility_layout);
  25. visibilityLayout.setVisibility(View.VISIBLE);
  26. TextView title = (TextView) view.findViewById(R.id.news_title);
  27. title.setText(newsTitle);
  28. TextView content = (TextView) view.findViewById(R.id.news_content);
  29. content.setText(newsContent);
  30. }
  31. }
7、 新建news_content.xml文件,此文件定义了一个fragment和NewsContentFragment类相关联,下一步将在Activity中直接设置这个布局文件显示新闻内容,代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6. <fragment
  7. android:id="@+id/news_content_fragment"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent"
  10. android:name="com.gta.newsapptest.NewsContentFragment"/>
  11. </LinearLayout>

8、新建NewsContentActivity.java类,此类用于加载news_content.xml布局显示新闻标题和正文内容,里面有一个静态的actionStart()方法用于从任意活动跳转到当前活动,代码如下:

  1. package com.gta.newsapptest;
  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.os.Bundle;
  6. import android.view.Window;
  7. public class NewsContentActivity extends Activity{
  8. @Override
  9. protected void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. //去掉标题栏
  12. requestWindowFeature(Window.FEATURE_NO_TITLE);
  13. //设置活动布局
  14. setContentView(R.layout.news_content);
  15. //获取传入此活动的新闻标题
  16. String newsTitle = getIntent().getStringExtra("news_title");
  17. //获取传入此活动的新闻内容
  18. String newsContent = getIntent().getStringExtra("news_content");
  19. //获取NewsContentFragment类
  20. NewsContentFragment contentFragment = (NewsContentFragment) getFragmentManager().findFragmentById(R.id.news_content_fragment);
  21. //调用NewsContentFragment中refresh方法刷新新闻内容
  22. contentFragment.refresh(newsTitle, newsContent);
  23. }
  24. public static void actionStart(Context context, String newsTitle, String newsContent){
  25. Intent intent = new Intent(context, NewsContentActivity.class);
  26. intent.putExtra("news_title", newsTitle);
  27. intent.putExtra("news_content", newsContent);
  28. context.startActivity(intent);
  29. }
  30. }

9、新建NewsTitleFragment.java,这个类比较关键,继承了Fragment重写onCreateView()函数加载news_title_frag.xml布局,继承OnItemClickListener监听器重写onItemClick()函数设置ListView的每一项点击监听,代码如下:

  1. package com.gta.newsapptest;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import android.app.Activity;
  5. import android.app.Fragment;
  6. import android.os.Bundle;
  7. import android.util.Log;
  8. import android.view.LayoutInflater;
  9. import android.view.View;
  10. import android.view.ViewGroup;
  11. import android.widget.AdapterView;
  12. import android.widget.AdapterView.OnItemClickListener;
  13. import android.widget.ListView;
  14. public class NewsTitleFragment extends Fragment implements OnItemClickListener {
  15. private static final String TAG = "TAG";
  16. private ListView newsTitleListView;
  17. private List<News> newsList; //储存所有的新闻数据
  18. private NewsAdapter adapter;
  19. private boolean isTwoPane; //是平板宽屏值为true,手机屏值为false
  20. /**
  21. * 系统回调函数,在活动和碎片开始建立关联时调用
  22. */
  23. @Override
  24. public void onAttach(Activity activity) {
  25. super.onAttach(activity);
  26. newsList = getNews(); //初始化新闻数据
  27. //将ListView单项布局和新闻数据加载到Adapter中
  28. adapter = new NewsAdapter(activity, R.layout.new_item, newsList);
  29. // Log.d(TAG, "onAttach(): " + newsList.get(0).getTitle());
  30. // Log.d(TAG, "onAttach()");
  31. }
  32. /**
  33. * 加载碎片布局时会被自动调用
  34. */
  35. @Override
  36. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  37. Bundle savedInstanceState) {
  38. super.onCreateView(inflater, container, savedInstanceState);
  39. //为Fragment加载布局
  40. View view = inflater.inflate(R.layout.news_title_frag, container, false);
  41. newsTitleListView = (ListView) view.findViewById(R.id.news_title_list_view);
  42. //为ListView设置适配器,将新闻标题显示在每一项
  43. newsTitleListView.setAdapter(adapter);
  44. //设置ListView每一项点击监听事件
  45. newsTitleListView.setOnItemClickListener(this);
  46. Log.d(TAG, "onCreateView()");
  47. return view;
  48. }
  49. /**
  50. * 碎片和活动建立关联完成时会被自动调用
  51. */
  52. @Override
  53. public void onActivityCreated(Bundle savedInstanceState) {
  54. super.onActivityCreated(savedInstanceState);
  55. //这里判断news_content_layout控件是否存在,即可判断是手机还是平板电脑
  56. if(getActivity().findViewById(R.id.news_content_layout) != null){
  57. isTwoPane = true;
  58. }
  59. else {
  60. isTwoPane = false;
  61. }
  62. Log.d(TAG, "onActivityCreated()");
  63. }
  64. /**
  65. * 此函数将返回储存在List中的模拟新闻数据
  66. * @return
  67. */
  68. private List<News> getNews() {
  69. List<News> newsList = new ArrayList<News>();
  70. News news1 = new News();
  71. news1.setTitle("Succeed in Cllege as a Learning Disabled Student");
  72. news1.setContent("College freshmen will soon learn to live with a roomote, adjust to a new social " +
  73. "scene and survive less-than-stellar dining hall food. Students with learning disabilities will face these" +
  74. "transitions while also grappling with afew more hurdles.");
  75. newsList.add(news1);
  76. News news2 = new News();
  77. news2.setTitle("Google Android exec poacjed byChina's Xiaomi");
  78. news2.setContent("China's Xiaomi has poached a key Google executive involved in the tech giant's Android phones," +
  79. "in a move seen as a coup for the rapidly growing Chinese smartphone maker.");
  80. newsList.add(news2);
  81. return newsList;
  82. }
  83. @Override
  84. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  85. News news = newsList.get(position);
  86. if(isTwoPane){
  87. //是平板电脑,则为右边NewsContentFragment设置新闻标题和内容
  88. NewsContentFragment newsContentFragment = (NewsContentFragment) getFragmentManager().findFragmentById(R.id.news_content_fragment);
  89. newsContentFragment.refresh(news.getTitle(), news.getContent());
  90. }
  91. else {
  92. //是手机,则直接跳转到NewsContentActivity
  93. NewsContentActivity.actionStart(getActivity(), news.getTitle(), news.getContent());
  94. }
  95. }
  96. }

10、到此为止程序框架基本完成,下面编写主界面;

11、在layout下的activity_main.xml文件中添加fragment,代码如下:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent" >
  5. <fragment
  6. android:id="@+id/new_title_fragment"
  7. android:name="com.gta.newsapptest.NewsTitleFragment"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent"/>
  10. </LinearLayout>
12、判别是手机、平板电脑的屏幕需要用到限位符的概念,操作比较简单,首先在 res/下面建立layout-sw600dp文件夹(意思是屏幕宽度大于600个像素时调用其下面的布局文件,其中sw600dp就是限位符),然后新建activity_main.xml文件在里面添加如下代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="horizontal" >
  6. <fragment
  7. android:id="@+id/news_title_fragment"
  8. android:name="com.gta.newsapptest.NewsTitleFragment"
  9. android:layout_width="0dp"
  10. android:layout_height="match_parent"
  11. android:layout_weight="1"/>
  12. <FrameLayout
  13. android:id="@+id/news_content_layout"
  14. android:layout_width="0dp"
  15. android:layout_height="match_parent"
  16. android:layout_weight="3">
  17. <fragment
  18. android:id="@+id/news_content_fragment"
  19. android:name="com.gta.newsapptest.NewsContentFragment"
  20. android:layout_width="match_parent"
  21. android:layout_height="match_parent"/>
  22. </FrameLayout>
  23. </LinearLayout>

现在可以在不修改布局的情况下同时运行在手机和平板上。

下载地址:http://download.csdn.net/detail/yanwenmuc/9202955


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/355310
推荐阅读
相关标签
  

闽ICP备14008679号