Android 资讯类App项目实战 第三章 新闻模块

前言:

正在做一个资讯类app,打算一边做一边整理,供自己学习与巩固。用到的知识复杂度不高,仅适于新手。经验不多,如果写出来的代码有不好的地方欢迎讨论。

以往的内容

第一章 滑动顶部导航栏

第二章 retrofit获取网络数据

第三章 新闻模块

本章内容最终效果:

新闻模块效果.gif

知识点:

RecyclerView.Adapter,CoordinatorLayout,AppBarLayout,cardView,Glide,WebView

学习目标:

1、使用RecyclerView、cardView显示列表数据。

2、使用Glide加载图片。

3、WebView显示网页。

新闻模块是资讯类App的主体,主要内容包括新闻列表,新闻详情。

项目实战:

注意

本章用到的drawable资源、values资源皆存放在百度网盘

(请将values文件夹中的style.xml或color.xml更新一致后再运行,如有后续更新自行修改)

1.1 项目结构

本章增加的类和布局:


Android 资讯类App项目实战 第三章 新闻模块_第1张图片

Android 资讯类App项目实战 第三章 新闻模块_第2张图片
布局

需导入的库:
导入了cardView和图片加载库Glide。

Android 资讯类App项目实战 第三章 新闻模块_第3张图片
build.gradle

1.2 item_news及适配器

新闻的显示需要用RecyclerView,所以先完成每个新闻item的代码。

新建一个布局文件,命名为item_news。

 




    

    






然后为我们的item_news写上适配器代码。

新建一个java文件,命名为ItemNewsAdapter。

public class ItemNewsAdapter extends RecyclerView.Adapter {

private List objects = new ArrayList();

private Context context;

public ItemNewsAdapter(Context context) {
    this.context = context;
}

public void setData(List objects) {
    this.objects = objects;
}

@Override
public ItemNewsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_news, parent, false);
    return new ItemNewsHolder(view);
}

@Override
public void onBindViewHolder(ItemNewsHolder holder, int position) {
    NewsBean.Bean bean = objects.get(position);
    if (bean == null) {
        return;
    }
    Glide.with(context)
            .load(bean.getImgsrc())
            .into(holder.ivNewsImg);
    if (position == 0) {
        holder.tvNewsDigest.setVisibility(View.GONE);
        holder.tvNewsTitle.setText("图片:" + bean.getTitle());
    } else {
        holder.tvNewsTitle.setText(bean.getTitle());
        holder.tvNewsDigest.setText(bean.getMtime() + " : " + bean.getDigest());
    }
}


@Override
public long getItemId(int position) {
    return position;
}

@Override
public int getItemCount() {
    return objects.size();
}

protected class ItemNewsHolder extends RecyclerView.ViewHolder {
    private ImageView ivNewsImg;
    private TextView tvNewsTitle;
    private TextView tvNewsDigest;

    public ItemNewsHolder(View view) {
        super(view);
        ivNewsImg = (ImageView) view.findViewById(R.id.iv_news_img);
        tvNewsTitle = (TextView) view.findViewById(R.id.tv_news_title);
        tvNewsDigest = (TextView) view.findViewById(R.id.tv_news_digest);
    }
}
}

这里面的图片加载用到的是Glide,这是谷歌推荐的图片加载库,加载速度快,引用也很简单。只需下面3行代码就能用。

Glide

中间对控件的处理也是基于api返回的数据(网易新闻接口会图片新闻的数据),这里只是做了个简单的处理,具体优化还需要进一步分析接口数据。


Android 资讯类App项目实战 第三章 新闻模块_第4张图片
item里显示的内容

1.3 RecycleView

接下来我们让刚才做的item在fragment里显示出来。

首先修改fg_news_list的布局代码,加入RecycleView:

fg_news_list.xml







    



然后修改FgNewsListFragment的代码:

FgNewsListFragment.java
public class FgNewsListFragment extends Fragment implements INewsView {

private NewsPresenter presenter;
private int type;
private SwipeRefreshLayout srl_news;
private RecyclerView rv_news;
private ItemNewsAdapter adapter;
private List newsBeanList;
private TextView tv_news_list;

public static FgNewsListFragment newInstance(int type) {
    Bundle args = new Bundle();
    FgNewsListFragment fragment = new FgNewsListFragment();
    args.putInt("type", type);
    fragment.setArguments(args);
    return fragment;
}

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

    return inflater.inflate(R.layout.fg_news_list, null);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    type = getArguments().getInt("type");
    presenter = new NewsPresenter(this);
    rv_news = view.findViewById(R.id.rv_news);
    adapter = new ItemNewsAdapter(getActivity());
    tv_news_list = view.findViewById(R.id.tv_news_list);
    srl_news = view.findViewById(R.id.srl_news);
    srl_news.setColorSchemeColors(Color.parseColor("#ffce3d3a"));
    srl_news.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            presenter.loadNews(type, 0);
        }
    });
    presenter.loadNews(type, 0);
}

@Override
public void showNews(final NewsBean newsBean) {
    switch (type) {
        case FgNewsFragment.NEWS_TYPE_TOP:
            newsBeanList = newsBean.getTop();
            break;
        case FgNewsFragment.NEWS_TYPE_NBA:
            newsBeanList = newsBean.getNba();
            break;
        case FgNewsFragment.NEWS_TYPE_JOKES:
            newsBeanList = newsBean.getJoke();
            break;
    }
    adapter.setData(newsBeanList);
    rv_news.setLayoutManager(new LinearLayoutManager(getActivity(),
            LinearLayoutManager.VERTICAL, false));
    rv_news.setAdapter(adapter);
    tv_news_list.setVisibility(View.GONE);

}

@Override
public void hideDialog() {
    srl_news.setRefreshing(false);
}

@Override
public void showDialog() {
    srl_news.setRefreshing(true);
}

@Override
public void showErrorMsg(String error) {
    tv_news_list.setText("加载失败:" + error);
}
}

效果:

Android 资讯类App项目实战 第三章 新闻模块_第5张图片
新闻模块效果1.gif

1.4 CardView

每一个新闻怎么做到卡片显示呢?这里我们用到了控件cardView。
cardView的使用非常简单,我把一些设置直接写在布局里了,不需要写别的逻辑代码,只要把item_news里的东西包裹进去就好了。

item_news.xml





    

    







效果:


Android 资讯类App项目实战 第三章 新闻模块_第6张图片
新闻模块效果2.gif

2.1 CoordinatorLayout与AppBarLayout

当滑动列表的时候,为了给屏幕腾出更多空间,上面的导航栏会有折叠的效果,这里就要用到CoordinatorLayout和AppBarLayout了。
到main_content文件里将最外层包裹上CoordinatorLayout,在将Toolbar放进AppBarLayout:

main_content.xml






    

        

            

                

                

                
            
        
    




    


AppBarLayout里有一个elevation属性,可以将bar浮起来,既然Toolbar浮到5,那么把fg_news里的TabLayout也浮到5吧。

fg_news.xml





    





效果:


Android 资讯类App项目实战 第三章 新闻模块_第7张图片
往上滑的是候最上面的导航会折叠

3.1 WebView打开新闻详情网页

点击每个新闻卡片后,出现的新闻详情我直接用WebView显示。
新建布局文件a_detail(新增加的图片资源到我上面的网盘地址里找):

a_detail.xml





    

        

        
    




   

然后写WebView的Activity代码:

ADetailActivity.java
public class ADetailActivity extends Activity {

private WebView wbNews;
private String loadUrl, title;
private WebViewClient webViewClient;
private TextView tv_bar_title;
private ImageView iv_back;
private ProgressBar pb_load;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.a_detail);
    loadUrl = getIntent().getStringExtra("url");
    title = getIntent().getStringExtra("title");
    initView();
    setWebViewClient();
}

private void setWebViewClient() {
    webViewClient = new WebViewClient() {
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            pb_load.setVisibility(View.VISIBLE);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            pb_load.setVisibility(View.GONE);
        }
    };
    wbNews.setWebViewClient(webViewClient);
}

private void initView() {
    wbNews = (WebView) findViewById(R.id.wb_news);
    wbNews.getSettings().setJavaScriptEnabled(true);
    wbNews.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
    wbNews.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
    wbNews.canGoBack();
    wbNews.canGoForward();
    wbNews.loadUrl(loadUrl);
    tv_bar_title = (TextView) findViewById(R.id.tv_bar_title);
    tv_bar_title.setText(title);
    iv_back = (ImageView) findViewById(R.id.iv_back);
    iv_back.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });
    pb_load = (ProgressBar) findViewById(R.id.pb_load);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    wbNews.destroy();
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == event.KEYCODE_BACK && wbNews.canGoBack()) {
        wbNews.goBack();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
}

在ItemNewsAdapter里把跳转页面的代码补上:

Android 资讯类App项目实战 第三章 新闻模块_第8张图片
ItemNewsAdapter.java

到manifest文件中声明Activity:

Android 资讯类App项目实战 第三章 新闻模块_第9张图片
AndroidManifest.xml

效果:


Android 资讯类App项目实战 第三章 新闻模块_第10张图片
新闻模块效果4.gif

本章的新闻模块显示的列表数量是有限的,这是因为还没做“加载更多”的功能,这些在以后有时间在慢慢优化。

项目源码:https://github.com/Huigesi/IdleReaderDemo

上一章:
第二章 滑动顶部导航栏

下一章:
第四章 电影模块

你可能感兴趣的:(Android 资讯类App项目实战 第三章 新闻模块)