android碎片与view,Android学习第7篇——碎片实践,结合ListView的简单阅读应用,自适应手机和平板...

在学过了碎片(Fragment)、ListView之后,实现一个自适应手机和平板的文章阅读应用

效果图:

手机:

4e81ced7dac00cf5639b21d7960a570d.png 

bd1e6b6357aaa014e4ca6a86b3f115b0.png

平板:

285f2c5b53f8f2631b39385d5044c0ff.png

7a9f33529b89e9586f923349bce91b15.png

二、实现过程:

1、新建一个文章实体类Newspublic class News {

private String title;

private String content;

public News(String title, String content) {

this.title = title;

this.content = 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;

}

}

包含标题和内容;

2、接着新建一个news_item.xml布局,用于作为文章列表中子项的布局:<?xml version="1.0" encoding="utf-8"?>

android:orientation="vertical" android:layout_width="match_parent"

android:layout_height="match_parent">

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:paddingRight="10dp"

android:paddingTop="15dp"

android:paddingBottom="15dp"

/>

android:singleLine设置为true表示让这个TextView只能单行显示。android:ellipsize用于设定当文本内容超出控

件宽度时,文本的缩略方式,这里指定成end表示在尾部进行缩略。

3、接下来需要创建文章列表的适配器,让这个适配器继承自ArrayAdapter,并将泛型指定为News类package com.csii.www.fragmentnews.adapter;

import android.content.Context;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ArrayAdapter;

import android.widget.TextView;

import com.csii.www.fragmentnews.R;

import com.csii.www.fragmentnews.entity.News;

import java.util.List;

/**

* Created by zhang on 2018/3/27.

*/

public class NewsAdapter extends ArrayAdapter {

private int resourceId;

public NewsAdapter(Context context, int textViewResourceId, List

objects) {

super(context, textViewResourceId, objects);

resourceId = textViewResourceId;

}

@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 newsTitleText = (TextView) view.findViewById(R.id.news_title);

newsTitleText.setText(news.getTitle());

return view;

}

}

可以看到,在getView()方法中,我们获取到了相应位置上的News类,并让文章的标题在列表中进行显示。

4、这样基本就把文章列表部分的代码编写完了,接下来我们看一下如何编写新闻内容部分的代码。新建布局文件的代码。新建布局文件 frag_news_content.xml,代码如下所示:<?xml version="1.0" encoding="utf-8"?>

android:orientation="vertical" android:layout_width="match_parent"

android:layout_height="match_parent">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

android:layout_width="1dp"

android:layout_height="match_parent"

android:scaleType="fitXY"

android:src="@drawable/spilt_line_vertical"

/>

android:id="@+id/visibility_layout"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:visibility="invisible"

android:orientation="vertical">

android:id="@+id/newsContentTitle"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:gravity="center"

android:padding="10dp"

android:textSize="20sp" />

android:layout_width="match_parent"

android:layout_height="1dp"

android:scaleType="fitXY"

android:src="@drawable/spilt_line"

/>

android:id="@+id/newsContent"

android:layout_width="match_parent"

android:layout_height="0dp"

android:layout_weight="1"

android:padding="15dp"

android:textSize="18sp"

/>

文章内容的布局主要可以分为两个部分,头部显示完整的文章标题,正文部分显示文章内容,中间使用一条细线分隔开。这里的细线是利用ImageView显示了一张很窄的图片来实现的,将ImageView的android:scaleType属性设置为fitXY,表示让这张图片填充满整个控件的大小。另外外部用了ScrollView布局,支持文章内容较长是可以滚动阅读。

5、然后再新建一个NewsContentFragment类,继承自Fragment,代码如下所示:public class NewsContentFragment extends Fragment{

private View view;

//创建Fragment时候构建一个View

@Nullable

@Override

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {

view = inflater.inflate(R.layout.frag_news_content,container);

return view;

}

//渲染frament视图view

public void regresh(News news){

//点击文章的时候页面ScrollView滚动到顶部,否则页面在底部,影响体验

view.scrollTo(0,0);

//设置视图的属性显示

View visibilityLayout = view.findViewById(R.id.visibility_layout);

visibilityLayout.setVisibility(View.VISIBLE);

//通过传送过来的News实例,填充内容。

TextView newsTitle = view.findViewById(R.id.newsContentTitle);

TextView newsContent = view.findViewById(R.id.newsContent);

newsTitle.setText(news.getTitle());

newsContent.setText(news.getContent());

}

}

6、接下来还需要再创建一个用于显示新闻列表的布局,新建news_title_frag.xml,代码如下所示:<?xml version="1.0" encoding="utf-8"?>

android:orientation="vertical" android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/newList"

android:layout_width="match_parent"

android:layout_height="match_parent">

里面只有一个ListView。不过想必你已经猜到了,这个布局并不是给活动使用的,而是给碎片使用的,因此我们还需要创建一个碎片来加载这个布局。新建一个NewsListFragment类,继承自Fragment,代码如下所示: public class NewListFragment extends Fragment implements AdapterView.OnItemClickListener{

TitleAdapter titleAdapter;

List newsList = new ArrayList();

boolean isTwoPanel;

//当Fragment和Activity建立联系的时候初始化数据

@Override

public void onAttach(Context context) {

super.onAttach(context);

initNews();//初始化新闻数据

titleAdapter = new TitleAdapter(context, R.layout.news_item, newsList);

}

//创建Fragment时候构建一个View

@Nullable

@Override

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.frag_news_list, container, false);//这里是资源文件的名称

ListView titleList = view.findViewById(R.id.newList);

titleList.setAdapter(titleAdapter);

titleList.setOnItemClickListener(this);

return view;

}

//在活动与页面关联好后,判断是手机还是pad

@Override

public void onActivityCreated(@Nullable Bundle savedInstanceState) {

super.onActivityCreated(savedInstanceState);

if(getActivity().findViewById(R.id.news_content_layout) != null ){

isTwoPanel = true;

}else{

isTwoPanel = false;

}

}

private void initNews() {

newsList.add(new News("谁为新词谱一曲",

"林花谢,\n" +

"\n" +

"落尽春红。\n" +

"\n" +

"叹华年易逝,\n" +

"\n" +

"时光太匆匆。\n" +

"\n" +

"无奈人生,山重水复。\n" +

"\n" +

"人生无奈,水复山重。\n" +

"\n" +

"清早间潇潇冷雨,\n" +

"\n" +

"到晚来凄凄寒风。\n" +

"\n" +

"红颜一去,\n" +

"\n" +

"只留下,\n" +

"\n" +

"醉眼中摇曳的倩影;\n" +

"\n" +

"江山倾倒,\n" +

"\n" +

"只留下,\n" +

"\n" +

"心田里胭脂上泪痕。\n" +

"\n" +

"何时入梦里?\n" +

"\n" +

"与君相逢;\n" +

"\n" +

"何时入梦里?\n" +

"\n" +

"与君重逢。\n" +

"\n" +

"怕只怕,\n" +

"\n" +

"人生空余恨,似水东流;\n" +

"\n" +

"怕只怕,\n" +

"\n" +

"人生空余恨,似水长流。"));

newsList.add(new News("国庆节出行", "好急啊"));

}

@Override

public void onItemClick(AdapterView> parent, View view, int position, long id) {

News news = (News)newsList.get(position);

if(isTwoPanel == true ){//双屏显示,点击文章标题刷新右边碎片

//通过getFragmentManager(),然后fundFragmentById()获取页面中的Fragment

NewsContentFragment newContentFragment = (NewsContentFragment)getFragmentManager().findFragmentById(R.id.newContentFragment);

//将New实体传送过去

newContentFragment.regresh(news);

}else{

//如果是手机,直接启动下一个Activity显示文章内容。

NewsContentActivity.startAction(getActivity(),news);

}

}

}

根据碎片的生命周期,我们知道,onAttach()方法会首先执行,因此在这里做了一些数据初始化的操作,比如调用getNews()方法获取几条模拟的文章数据,以及完成NewsAdapter的创建。然后在onCreateView()方法中加载了frag_news_list布局, 并给新闻列表的ListView注册了点击事件。 接下来在onActivityCreated()方法中,我们通过是否能够找到一个id为news_content_layout的View来判断当前是双页模式还是单页模式,这个id为news_content_layout的View只在双页模式中才会出现,在稍后的布局里你将会看到。然后在ListView的点击事件里我们就可以判断,如果当前是单页模式,就启动一个新的活动去显示新闻内容,如果当前是双页模式,就更新文章内容碎片里的数据。

7、修改activity_main.xml中的代码<?xml version="1.0" encoding="utf-8"?>

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"

android:layout_height="match_parent" tools:context="com.csii.www.newsfragment.MainActivity">

android:id="@+id/newListFragment"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:name="com.csii.www.newsfragment.fragment.NewListFragment"

>

上述代码表示, 在单页模式下, 只会加载一个新闻标题的碎片 。然后新建layout-sw600dp文件夹,在这个文件夹下再新建一个activity_main.xml文件,代码如下所示:<?xml version="1.0" encoding="utf-8"?>

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent" tools:context="com.csii.www.newsfragment.MainActivity">

android:id="@+id/newListFragment"

android:layout_width="0dp"

android:layout_weight="1"

android:layout_height="match_parent"

android:name="com.csii.www.newsfragment.fragment.NewListFragment"

>

android:id="@+id/news_content_layout"

android:layout_width="0dp"

android:layout_weight="3"

android:layout_height="match_parent">

android:id="@+id/newContentFragment"

android:name="com.csii.www.newsfragment.fragment.NewsContentFragment"

android:layout_width="match_parent"

android:layout_height="match_parent">

可以看出,在双页模式下我们同时引入了两个碎片,并将新闻内容的碎片放在了一个FrameLayout布局下,而这个布局的id正是news_content_layout。因此,能够找到这个id的时候就是双页模式,否则就是单面模式。

8、然后新建NewsContentActivity,作为显示新闻内容的活动,代码如下所示:package com.csii.www.newsfragment;

import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.widget.TextView;

import com.csii.www.newsfragment.entity.News;

public class NewsContentActivity extends AppCompatActivity {

public static void startAction(Context context, News news){

Intent intent = new Intent(context,NewsContentActivity.class);

intent.putExtra("newsTitle",news.getTitle());

intent.putExtra("newsContent",news.getContent());

context.startActivity(intent);

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_news_content);

Intent intent = getIntent();

String newsTitle = intent.getStringExtra("newsTitle");

String newsContent = intent.getStringExtra("newsContent");

TextView newsTitleView =(TextView) findViewById(R.id.newsContentTitle);

TextView newsContentView =(TextView) findViewById(R.id.newsContent);

newsTitleView.setText(newsTitle);

newsContentView.setText(newsContent);

}

}

对应布局文件:<?xml version="1.0" encoding="utf-8"?>

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="com.csii.www.newsfragment.NewsContentActivity">

android:id="@+id/newsContentTitle"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:gravity="center"

android:padding="10dp"

android:textSize="20sp" />

android:layout_width="match_parent"

android:layout_height="1dp"

android:scaleType="fitXY"

android:background="#000"

/>

android:layout_width="match_parent"

android:layout_height="0dp"

android:orientation="vertical"

android:layout_weight="1">

android:id="@+id/newsContent"

android:layout_width="match_parent"

android:layout_height="0dp"

android:padding="15dp"

android:layout_weight="1"

android:textSize="18sp"

/>

这里只对文章展示部分滑动,标题置顶显示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值