一个简易版的新闻应用(同时兼容手机和平板)

代码可能有点长,需要耐心看几遍。前前后后我看了5遍才把整个流程吃透,相信你一定比我聪明!!!


新建一个FragmentBestPractice项目 (让ADT帮我们自动创建活动--活动名:MainActivity   布局名:activity_main.xml)

1、准备好一个新闻的实体类: News  

代码如下   :

package com.example.fragmentbestpractice;

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

(title 字段表示新闻标题,content字段表示新闻内容。)

2、新建一个news_item.xml布局,用于作为新闻列表中子项的布局(ListView 中子项目的布局)。

代码如下:

<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:singleLine设置为True表示让这个TextView只能单行显示
    android:ellipsize="end"                          // android:ellipsize 设定当文本内容超出控件宽度时,文本的缩略方式,这里指定成end表示在尾部进行缩略。
    android:textSize="18sp"                       // android:textSize  设定文本字体大小
    android:paddingLeft="10dp"                // android:padding 表示给控件的周围加上补白,不至于让文本内容紧靠边缘。 
    android:paddingRight="10dp"
    android:paddingTop="15dp"
    android:paddingBottom="15dp"/>
</LinearLayout>

3、创建新闻列表的适配器,让这个适配器继承ArrayAdapter,并泛型为News类

(由于News的数据无法直接传递给ListView,所以需要借助适配器)

代码如下:

package com.example.fragmentbestpractice;

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 int resourceId;
public NewsAdapter (Context context,int textViewResourceId,List<News>objects){
super(context,textViewResourceId,objects);
resourceId=textViewResourceId;                                                          // 重写父类ArrayAdapter的方法 ,textViewResourceId即为news_item.xml布局的id(ListView子项布局的id)
}
@Override
public View getView(int position,View convertView,ViewGroup parent){           //重写父类ArrayAdapterd的getView方法 
News news=(News) getItem(position);                                                   // 得到当前ListView中子项的实例
View view;
if(convertView==null){                                                                          
view=LayoutInflater.from(getContext()).inflate(resourceId,null );    //为实例加载布局(即为news_item.xml的布局,ListView子项的布局)
}
else{
view=convertView;                                                 //convertView参数:这个参数用于将之前加载好的布局进行缓存,提高ListView的运行效率
}
TextView newsTitleText=(TextView) view.findViewById(R.id.news_title);        //实例化新闻标题
newsTitleText.setText(news.getTitle());                                                          //让新闻的标题在列表中进行显示
return view;
}
}


4、编写新闻内容,新建news_content_frag.xml (为下文碎片NewsContentFragment提供布局)

(新闻内容的布局主要分为两部分:头部显示完整的新闻标题,正文部分显示新闻内容。)

代码如下:

<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" >                              //android:visibility 设置布局的可见性,invisibe为不可见
        <TextView
            android:id="@+id/news_title"                       // 新闻标题的控件
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="10dp"
            android:textSize="20sp" />
        <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:layout_alignParentLeft="true"
        android:scaleType="fitXY"
        android:src="@drawable/ic_launcher"  />"
</RelativeLayout>

5、新建一个NewsContentFragment类,继承自Fragment  (碎片)

代码如下:

package com.example.fragmentbestpractice;

import android.app.Fragment;                //注意这里可能会有两个不同包下的Fragment供你选择,建议使用android.app.Fragment(面向4.0以上系统的)
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 {                            //重写父类Fragment的方法
private View view;
@Override 
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
view=inflater.inflate(R.layout.news_content_frag, container,false);                            //为碎片加载布局news_content_frag.xml
return view;

}
public void refresh (String newsTitle, String newsContent){                                            //创建refresh()方法,这个方法用于将新闻的标题和内容显示在界面上
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);                                                                    //刷新新闻的内容
}
}

6、创建一个在活动中使用的新闻内容布局,新建news_content.xml,为下文NewContentActivity提供布局(给小尺寸的android手机用的)

代码如下:

<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:name="com.example.fragmentbestpractice.NewsContentFragment"              //在布局中引入了com.example.fragmentbestpractice.NewsContentFragment
    android:layout_width="match_parent"                                                                            // (充分发挥了代码的复用性,相当于把new_content_frag.xml布局的内容自动加进来了)
    android:layout_height="match_parent"/>                              
</LinearLayout>

7、新建一个活动,NewsContentActivity,作为显示新闻内容的活动(给小尺寸的手机用的)

代码如下:

package com.example.fragmentbestpractice;

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 {
public static void actionStart(Context context,String newsTitle,String newsContent){        //actionStart()方法,将启动NewsActivity所需要的参数导入进来
Intent intent=new Intent(context,NewsContentActivity.class);
intent.putExtra("news_title", newsTitle);                                                                    //将参数新闻标题、新闻内容(参数)保存到intent
intent.putExtra("news_content", newsContent);                                                       
    context.startActivity(intent);                       
 }
@Override
protected void onCreate(Bundle savedInstanceState){                                            //重写父类Activity的onCreate方法
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);                              //隐藏该活动自带的标题
setContentView(R.layout.news_content);                                                       //加载news_content.xml的布局
String newsTitle=getIntent().getStringExtra("news_title");                                //取出Intent中保存的参数(即为新闻的标题、新闻的内容)
String newsContent=getIntent().getStringExtra("news_content");
NewsContentFragment newsContentFragment=(NewsContentFragment) getFragmentManager().findFragmentById(R.id.news_content_fragment);
    newsContentFragment.refresh(newsTitle,newsContent);                            // 通过findFragment()方法,在活动中得到碎片NewsContentFragment的实例,从而调用其refresh()
}                                                                                                 
}

8、创建新闻列表的布局,新建news_title_frag.xml  

(这个布局并不是给活动使用的,而是给碎片使用的。)

代码如下:



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
<ListView                                                                       //定义了一个ListView控件  (作为显示新闻列表)
    android:id="@+id/news_title_list_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
</ListView>
</LinearLayout>

9、创建一个碎片加载news_title_frag.xml的布局  。新建NewsTitleFragment类,继承自Fragment

代码如下:

package com.example.fragmentbestpractice;

import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
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 ListView newsTitleListView;
private List<News> newsList;
private NewsAdapter adapter;
private boolean isTwoPane;
@Override
public void onAttach(Activity activity){
super.onAttach(activity); 
newsList=getNews();                                                                                       //初始化新闻数据
adapter=new NewsAdapter(activity,R.layout.news_item,newsList);
}
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
View view=inflater.inflate(R.layout.news_title_frag, container,false);                          //加载news_title_frag.xml 布局
newsTitleListView=(ListView) view.findViewById(R.id.news_title_list_view);              //得到ListView的实例
newsTitleListView.setAdapter(adapter);                                                                     //启动ListView的适配器,这样ListView就能与适配器的数据相关联了
newsTitleListView.setOnItemClickListener(this);                                                      //为ListView中的子项设置监听器
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
if (getActivity().findViewById(R.id.news_content_layout) !=null){                             //判断是平板还是手机,即为双页模式还是单页模式
isTwoPane=true;                                                                                             // isTwoPane=true ,表示双页模式

else{
isTwoPane=false;                                                                                           //isTwoPane=false,表示单页模式                                                             
}
}
@Override
public void onItemClick(AdapterView<?> parent,View view,int position,long id){           //ListView子项目的点击事件
News news=newsList.get(position);
if(isTwoPane){
NewsContentFragment newsContentFragment=(NewsContentFragment) getFragmentManager().findFragmentById(R.id.news_content_fragment);  
newsContentFragment.refresh(news.getTitle(),news.getContent());                   //如果是双页模式(平板),就更新新闻内容碎片里数

else{
NewsContentActivity.actionStart(getActivity(),news.getTitle(),news.getContent());     //如果是单页模式(手机),就启动一个新的活动去显示新闻内容。

}


private List<News> getNews(){
List<News> newsList=new ArrayList<News>();                                                 //初始化新闻标题及内容
News news1=new News();
news1.setTitle("Succeed in College as a Learning Disabled Student");
news1.setContent("College freshmen will soon learn to live with a roommate,adjust to a new social scene and survive less-than-stellae dining ball food.Students with learning disabilities will face these transitions while also grappling with a few more hurdles.");
newsList.add(news1);
News new2=new News();
new2.setTitle("Google Android exec poached by China's Xiaomi");
new2.setContent("China's Xiaomi has poached a key google executive involed in the tech giant's Android phones,in a move seen as a coup for the rapidly growing Chinese smartphone market.");
newsList.add(new2);
return newsList;
}
}

10、修改主活动的布局文件 activity_main.xml (如果是单页模式,只会加载一个新闻标题的碎片)

代码如下:

<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_title_fragment"
        android:name="com.example.fragmentbestpractice.NewsTitleFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

11、在res 下新建一个文件夹layout-sw600dp ,在这个文件夹下新建一个activity_main.xml布局文件。(如果是双页模式,则会加载两个碎片)

(使用最小宽度限定符Smallest-width Qualifier,ws600dp表示:屏幕宽度大于600dp的设备就加载这个文件下的布局)

代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="false"    >
    
  <fragment 
      android:id="@+id/news_title_fragment"                                                                //新闻标题的碎片
      android:name="com.example.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.fragmentbestpractice.NewsContentFragment" 
          android:layout_width="match_parent"
          android:layout_height="match_parent" />     
  </FrameLayout>  


</LinearLayout>

12、最后再将MainActivity稍做修改,把标题栏去掉。

代码如下:

package com.example.fragmentbestpractice;


import android.app.Activity;
import android.os.Bundle;
import android.view.Window;


public class MainActivity extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);      //去掉自带的标题
setContentView(R.layout.activity_main);
}

}


13、最后记得在AndroidManifest.xml 注册新建的NewsContentActivity活动。(凡是活动,都必须在AndroidManifest.xml注册,才可以用)

代码如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.fragmentbestpractice"
    android:versionCode="1"
    android:versionName="1.0" >


    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />


    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>                                                                                             //<intent-filter>里面的两句话表示MainActivity为主活动
                <action android:name="android.intent.action.MAIN" />                                                  
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity
            android:name=".NewsContentActivity" >      //注册NewsContentActivity活动
            </activity>
    </application>


</manifest>


这样,一个简易版的新闻应用就大功告成了!!!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值