Material Design--新闻浏览APP

最近在学习一些material design下的控件的使用以及MVP框架,就索性做了一个APP来练练手,APP主要的功能就是通过爬虫从学校的新闻网网页上抓取新闻,然后显示在APP上。下面是展示的效果。




这是主界面的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:fitsSystemWindows="true"
            app:contentScrim="@color/colorPrimaryDark"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/app_bar_image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                android:src="@mipmap/bg"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin" />
        </android.support.design.widget.CollapsingToolbarLayout>

        <android.support.design.widget.TabLayout
            android:id="@+id/toolbar_tab"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:layout_gravity="bottom"
            android:background="#ffffff"
            android:fillViewport="false"
            app:layout_scrollFlags="scroll"
            app:tabIndicatorColor="#0835f8"
            app:tabIndicatorHeight="2.0dp"
            app:tabMode="scrollable"
            app:tabSelectedTextColor="#0835f8"
            app:tabTextColor="#ced0d3">

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="头条新闻" />

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="校园新闻" />

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="学术新闻" />

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="民大人物" />

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="校园纵横" />

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="理论学习" />

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="媒体民大" />
        </android.support.design.widget.TabLayout>
        >
    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_news_home" />
</android.support.design.widget.CoordinatorLayout>

主要内容是include中的布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:scrollbars="none"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</android.support.v4.widget.NestedScrollView>
就是通过ViewPager+Fragment来显示新闻内容

从网页上抓取数据,用的是Jsoup,CrawlerUtils.java里面就是处理从网页上抓取数据的逻辑:

package cn.swun.sp.stu.news_swun.utils;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import cn.swun.sp.stu.news_swun.Bean.New;

/**
 * Create time : 2016/6/4.
 * Created by :saipeng
 * Description:
 */
public class CrawlerUtils {

    private static final String TAG = "CRAWLER";
    private static String next_url;

    public static String getNext_url() {
        return next_url;
    }

    public static void setNext_url(String next_url) {
        CrawlerUtils.next_url = next_url;
    }


    public static ArrayList<String> getDetailToNew(String url) {
        Document doc = getDocument(url);
        if (doc == null) return null;
        return getDetailContent(doc);
    }

    @NonNull
    private static ArrayList<String> getDetailContent(Document doc) {
        ArrayList<String> infos = new ArrayList<>();

        //先获取第一段内容
        infos.add(doc.select("div.page_detail").first().getElementsByTag("p").first().text());
        //再获取第一张图片的url
        infos.add(doc.getElementsByTag("img").first().attr("abs:src"));
        //解析详细的时间
        infos.add(doc.select("div.newsTime").first().getElementsByTag("span").first().text());

        //接着对详细内容进行解析
        Elements elements = doc.select("div.page_detail").first().getElementsByTag("p");
        Log.i(TAG, "elements:" + elements.size());
        for (Element e : elements) {
            Element img = e.getElementsByTag("img").first();
            if (img != null) {
                infos.add(img.attr("abs:src"));
            } else {
                infos.add(e.text());
            }
        }
        for (String s : infos) {
            Log.i(TAG, s);
        }
        return infos;
    }

    //得到新闻的第一张图片资源以及第一段文本
    public static String[] getUrlByTitle(String url) {
        Document doc = getDocument(url);
        if (doc == null) return null;

        String[] result = new String[2];

        result[0] = doc.select("div.page_detail").first().getElementsByTag("p").first().text();

        result[1] = doc.getElementsByTag("img").first().attr("abs:src");

        return result;
    }

    public static List<New> getNewsByType(String url) {

        Document doc = getDocument(url);
        if (doc == null) return null;


        Elements elements = doc.select("li[id]");
        Log.i(TAG, "elements:" + elements.size());

        //抓取下一页的url
        Element e = doc.select("a.Next").first();
        if (e != null) {
            next_url = e.attr("abs:href");
            Log.i(TAG, "next_url:" + next_url);
        } else {
            next_url = "";
        }

        if (elements.size() != 0 && elements != null) {
            List<New> news = new ArrayList<>();
            for (Element element : elements) {
                String time = element.getElementsByTag("span").text();
                String content = element.getElementsByTag("a").text();
                String href = element.getElementsByTag("a").attr("abs:href");
                ArrayList<String> infos = getDetailToNew(href);

                news.add(new New(time, content, href, infos));
            }
            return news;
        }
        return null;
    }

    @Nullable
    private static Document getDocument(String url) {
        Connection conn = Jsoup.connect(url);
        conn.header("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:32.0) Gecko/    20100101 Firefox/32.0");
        Document doc = null;
        try {
            doc = conn.cookie("cookie", "sp").timeout(3000).get();
            if (doc == null) {
                Log.i(TAG, "document is null");
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return doc;
    }

}


源码请移步到:App源码


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值