一.最终效果图
1.手机
单击新闻后
2.平板
二.构建一个新闻类News
public class News {
private String title;
private String content;
public News() {
}
public String getContent() {
return content;
}
public String getTitle() {
return title;
}
public void setContent(String content) {
this.content = content;
}
public void setTitle(String title) {
this.title = title;
}
}
三.构建一个listview的item项布局,用于显示新闻列表,news_item.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="vertical">
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/new_title"
android:textSize="18sp"
android:padding="15dp"
android:maxLines="1"
android:ellipsize="end"
/>
</LinearLayout>
四.构建listview适配器NewsAdapter
public class NewsAdapter extends ArrayAdapter<News> {
private int resourceId;
public NewsAdapter(Context context, int resource, List<News> objects) {
super(context, resource, objects);
resourceId = resource;
}
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
News news = getItem(position);
View view;
if( convertView == null ){
view = LayoutInflater.from(getContext()).inflate(resourceId, null);
}else {
view = convertView;
}
TextView newsTitle = (TextView)view.findViewById(R.id.new_title);
newsTitle.setText(news.getTitle());
return view;
}
}
五.构建显示新闻的Fragment,news_content_frag.xml,布局如下
<?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:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
android:id="@+id/visiable_layout"
android:visibility="invisible"
android:padding="15dp">
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/news_view_title"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:gravity="center"
android:textSize="20sp"
android:padding="15dp"/>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#ccc" />
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="@+id/news_view_title"
android:layout_alignParentStart="true"
android:id="@+id/new_content"
android:layout_weight="1"
android:lineSpacingMultiplier="1.5"
android:layout_marginTop="15dp"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"/>
</LinearLayout>
<View
android:layout_width="1px"
android:layout_height="match_parent"
android:background="#ccc"
android:layout_alignParentLeft="true"/>
</RelativeLayout>
六.构建news_content_frag对应的类:NewsContentFragment
public class NewsContentFragment extends Fragment {
private View view;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.new_content_frag, container, false);
return view;
}
public void refresh(String newsTitle, String newsContent){
View visiableLayout = view.findViewById(R.id.visiable_layout);
visiableLayout.setVisibility(View.VISIBLE);
TextView title = (TextView)view.findViewById(R.id.news_view_title);
TextView content = (TextView)view.findViewById(R.id.new_content);
content.setMovementMethod(ScrollingMovementMethod.getInstance());
title.setText(newsTitle);
content.setText(newsContent);
}
}
七.构建一个显示新闻内容的活动布局,news_content.xml
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.guo.newslist.NewsContentFragment"
android:id="@+id/news_content_fragment"
tools:layout="@layout/new_content_frag" />
</LinearLayout>
八.构建新闻内容活动页,NewsContentActivity
public class NewsContentActivity extends Activity {
public static void actionStart(Context context, String newsTitle, String content){
Intent intent = new Intent(context, NewsContentActivity.class);
intent.putExtra("title", newsTitle);
intent.putExtra("content", content);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_content);
String title = getIntent().getStringExtra("title");
String content = getIntent().getStringExtra("content");
NewsContentFragment newsContentFragment =
(NewsContentFragment)getFragmentManager().findFragmentById(R.id.news_content_fragment);
newsContentFragment.refresh(title, content);
}
}
相关知识点:
为了方便碎片和活动之间进行通信, FragmentManager 提供了一个类似于findViewById()的方法,专门用于从布局文件中获取碎片的实例,代码如下所示:
NewsContentFragment newsContentFragment =
(NewsContentFragment)getFragmentManager().findFragmentById(R.id.news_content_fragment);
调用FragmentManager 的findFragmentById()方法,可以在活动中得到相应碎片的实例,然后就能轻松地调用碎片里的方法了。
在碎片中调用活动:
MainActivity activity = (MainActivity) getActivity()
九.新建新闻标题列表Fragment,news_title_frag.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">
<ListView
android:id="@+id/news_title_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
十.构建news_title_frag.xml对应的Fragment类,NewsTitleFragment
public class NewsTitleFragment extends Fragment {
private ListView newsTitleListView;
private List<News> newsList;
private NewsAdapter adapter;
private boolean isTwoPage;
@Override
public void onAttach(Context context) {
super.onAttach(context);
newsList = getNewsList();
adapter = new NewsAdapter(getActivity(), R.layout.news_item, newsList);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if( getActivity().findViewById(R.id.fragment_content) != null ){
isTwoPage = true;
}else{
isTwoPage = false;
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
View view = inflater.inflate(R.layout.news_title_frag, container, false);
newsTitleListView = (ListView)view.findViewById(R.id.news_title_list_view);
newsTitleListView.setAdapter(adapter);
newsTitleListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
News news= newsList.get(position);
if( isTwoPage ){
// 双页模式,刷新NewsContentFragment中内容
NewsContentFragment newsContentFragment = (NewsContentFragment)
getFragmentManager().findFragmentById(R.id.fragment_content);
Log.e("title", news.getTitle());
newsContentFragment.refresh(news.getTitle(), news.getContent());
}else{
// 单页模式启动
NewsContentActivity.actionStart(getActivity(), news.getTitle(),
news.getContent());
}
}
});
return view;
}
public List<News> getNewsList() {
List<News> list = new ArrayList<News>();
News news1 = new News();
news1.setTitle("新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1");
news1.setContent("新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1" +
"新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1新闻1");
list.add(news1);
News news2 = new News();
news2.setTitle("新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2");
news2.setContent("新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2" +
"新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2" +
"新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2" +
"新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新" +
"闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻" +
"2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新" +
"闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2" +
"新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2" +
"新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2" +
"新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2新闻2");
list.add(news2);
return list;
}
}
基本解释:
根据碎片的生命周期,我们知道,onAttach()方法会首先执行,因此在这里做了一些数据初始化的操作,比如调用getNews()方法获取几条模拟的新闻数据,以及完成NewsAdapter 的创建。然后在onCreateView()方法中加载了news_title_frag 布局,并给新闻列表的ListView 注册了点击事件。接下来在onActivityCreated()方法中,我们通过是否能够找到一个id 为news_content_layout的View 来判断当前是双页模式还是单页模式,这个id 为news_content_layout 的View只在双页模式中才会出现,在稍后的布局里你将会看到。然后在ListView 的点击事件里我们就可以判断,如果当前是单页模式,就启动一个新的活动去显示新闻内容,如果当前是双页模式,就更新新闻内容碎片里的数据。
十一.修改activity_main.xml(单页模式,即手机模式)
<?xml version="1.0" encoding="utf-8"?>
<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/fragment_title"
android:name="com.example.guo.newslist.NewsTitleFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="@layout/news_title_frag" />
</LinearLayout>
十二,增加layout-sw600dp文件夹(平板模式布局),新建activity_main.xml,布局如下:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:orientation="horizontal">
<fragment
android:id="@+id/fragment_title"
android:name="com.example.guo.newslist.NewsTitleFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
tools:layout="@layout/news_title_frag"
android:layout_weight="1"/>
<fragment
android:id="@+id/fragment_content"
android:name="com.example.guo.newslist.NewsContentFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
tools:layout="@layout/new_content_frag" />
</LinearLayout>
至此完成了这个简单的新闻应用