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

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

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

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

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

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

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

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

package com.gta.newsapptest;

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

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

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

package com.gta.newsapptest;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class NewsAdapter extends ArrayAdapter<News>{
	private static final String TAG = "TAG";
	private int resourceId;
	public NewsAdapter(Context context, int resource, List<News> objects) {
		super(context, resource, objects);
		resourceId = resource;
//		Log.d(TAG, objects.size() + "");
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
//		super.getView(position, convertView, parent);
		View view ;
//		News news = newsList.get(position);
		News news = getItem(position);//获取position位置的新闻数据
//		Log.d(TAG, news.getTitle());
		//如果当前项视图没有加载布局,则进行加载否则直接从converView对象中获取,防止重复加载降低效率
		if(convertView == null){
			view = LayoutInflater.from(getContext()).inflate(resourceId, null);
		}
		else {
			view = convertView;
		}
		TextView tv = (TextView) view.findViewById(R.id.news_title);
		tv.setText(news.getTitle());
		return view; 
	}
}

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <ListView 
        android:id="@+id/news_title_list_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>
</LinearLayout>

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

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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    <LinearLayout 
        android:id="@+id/visibility_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:visibility="invisible">
    	<TextView 
    	    android:id="@+id/news_title"
    	    android:layout_width="match_parent"
    	    android:layout_height="wrap_content"
    	    android:gravity="center_horizontal"
    	    android:padding="10dp"
    	    android:textSize="20sp"/>
    	<ImageView 
    	    android:layout_width="match_parent"
    	    android:layout_height="1dp"
    	    android:background="#000000"/>
    	<TextView 
    	    android:id="@+id/news_content"
    	    android:layout_width="match_parent"
    	    android:layout_height="0dp"
    	    android:layout_weight="1"
    	    android:padding="15dp"
    	    android:textSize="18sp"/>
    </LinearLayout>
    <ImageView 
        android:layout_width="1dp"
        android:layout_height="match_parent"
        android:background="#000000"/>

</RelativeLayout>

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

package com.gta.newsapptest;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class NewsContentFragment extends Fragment {
	private View view;
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		super.onCreateView(inflater, container, savedInstanceState);
		//加载news_content_frag.xml布局
		view = inflater.inflate(R.layout.news_content_frag, container, false);
		return view;
	}
	/**
	 * 用于刷新新闻标题和内容
	 * @param newsTitle
	 * @param newsContent
	 */
	public void refresh(String newsTitle, String newsContent){
		View visibilityLayout = view.findViewById(R.id.visibility_layout);
		visibilityLayout.setVisibility(View.VISIBLE);
		TextView title = (TextView) view.findViewById(R.id.news_title);
		title.setText(newsTitle);
		TextView content = (TextView) view.findViewById(R.id.news_content);
		content.setText(newsContent);
	}
}
7、 新建news_content.xml文件,此文件定义了一个fragment和NewsContentFragment类相关联,下一步将在Activity中直接设置这个布局文件显示新闻内容,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <fragment 
        android:id="@+id/news_content_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.gta.newsapptest.NewsContentFragment"/>

</LinearLayout>

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

package com.gta.newsapptest;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Window;

public class NewsContentActivity extends Activity{
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//去掉标题栏
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		//设置活动布局
		setContentView(R.layout.news_content);
		//获取传入此活动的新闻标题
		String newsTitle = getIntent().getStringExtra("news_title");
		//获取传入此活动的新闻内容
		String newsContent = getIntent().getStringExtra("news_content");
		//获取NewsContentFragment类
		NewsContentFragment contentFragment = (NewsContentFragment) getFragmentManager().findFragmentById(R.id.news_content_fragment);
		//调用NewsContentFragment中refresh方法刷新新闻内容
		contentFragment.refresh(newsTitle, newsContent);
	}
	
	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);
	}
}

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

package com.gta.newsapptest;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

public class NewsTitleFragment extends Fragment implements OnItemClickListener {
	private static final String TAG = "TAG";
	private ListView newsTitleListView;
	private List<News> newsList;  //储存所有的新闻数据
	private NewsAdapter adapter;
	private boolean isTwoPane;  //是平板宽屏值为true,手机屏值为false
	/**
	 * 系统回调函数,在活动和碎片开始建立关联时调用
	 */
	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		newsList = getNews();  //初始化新闻数据
		//将ListView单项布局和新闻数据加载到Adapter中
		adapter = new NewsAdapter(activity, R.layout.new_item, newsList);
//		Log.d(TAG, "onAttach(): " + newsList.get(0).getTitle());
//		Log.d(TAG, "onAttach()");
	}
	/**
	 * 加载碎片布局时会被自动调用
	 */
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		super.onCreateView(inflater, container, savedInstanceState);
		//为Fragment加载布局
		View view = inflater.inflate(R.layout.news_title_frag, container, false);
		newsTitleListView = (ListView) view.findViewById(R.id.news_title_list_view);
		//为ListView设置适配器,将新闻标题显示在每一项
		newsTitleListView.setAdapter(adapter);
		//设置ListView每一项点击监听事件
		newsTitleListView.setOnItemClickListener(this);
		Log.d(TAG, "onCreateView()");
		return view;
	}
	/**
	 * 碎片和活动建立关联完成时会被自动调用
	 */
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		//这里判断news_content_layout控件是否存在,即可判断是手机还是平板电脑
		if(getActivity().findViewById(R.id.news_content_layout) != null){
			isTwoPane = true;
		}
		else {
			isTwoPane = false;
		}
		Log.d(TAG, "onActivityCreated()");
	}
	/**
	 * 此函数将返回储存在List中的模拟新闻数据
	 * @return
	 */
	private List<News> getNews() {
		List<News> newsList = new ArrayList<News>();
		News news1 = new News();
		news1.setTitle("Succeed in Cllege as a Learning Disabled Student");
		news1.setContent("College freshmen will soon learn to live with a roomote, adjust to a new social " +
				"scene and survive less-than-stellar dining hall food. Students with learning disabilities will face these" +
				"transitions while also grappling with afew more hurdles.");
		newsList.add(news1);
		News news2 = new News();
		news2.setTitle("Google Android exec poacjed byChina's Xiaomi");
		news2.setContent("China's Xiaomi has poached a key Google executive involved in the tech giant's Android phones," +
				"in a move seen as a coup for the rapidly growing Chinese smartphone maker.");
		newsList.add(news2);
		return newsList;
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		News news = newsList.get(position);
		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());
		}
	}
}

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

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

<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" >

    <fragment 
        android:id="@+id/new_title_fragment"
        android:name="com.gta.newsapptest.NewsTitleFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>
12、判别是手机、平板电脑的屏幕需要用到限位符的概念,操作比较简单,首先在 res/下面建立layout-sw600dp文件夹(意思是屏幕宽度大于600个像素时调用其下面的布局文件,其中sw600dp就是限位符),然后新建activity_main.xml文件在里面添加如下代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >
    
    <fragment 
        android:id="@+id/news_title_fragment"
        android:name="com.gta.newsapptest.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.gta.newsapptest.NewsContentFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </FrameLayout>
</LinearLayout>

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

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


  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值